diff --git a/.gitignore b/.gitignore index a01ee28..66afb2a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ .*.swp +composer.lock +vendor/ +tests/tmp/ diff --git a/Extension.php b/Extension.php index 7304aee..9b303bb 100644 --- a/Extension.php +++ b/Extension.php @@ -1,53 +1,59 @@ - */ namespace Bolt\Extension\Bolt\Labels; -require_once __DIR__ . '/include/Model.php'; - -use Bolt\Application; +use Bolt\BaseExtension; use Bolt\Library as Lib; +use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\Finder\Finder; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -class Extension extends \Bolt\BaseExtension +/** + * Labels Extension for Bolt + * + * @author Bob den Otter + */ +class Extension extends BaseExtension { - public function __construct(Application $app) - { - parent::__construct($app); - } + protected $labels; public function getName() { - return "labels"; + return 'labels'; } public function initialize() { + $this->app->before(array($this, 'before')); + + // Twig functions $this->addTwigFunction('l', 'twigL'); $this->addTwigFunction('setlanguage', 'twigSetLanguage'); - $this->before(); - - $this->boltPath = $this->app['config']->get('general/branding/path'); - - $this->fileName = $this->app['paths']['configpath'] . '/extensions/labels.json'; - - $this->addMenuOption("Label translations", "$this->boltPath/labels", "fa:flag"); - - $this->app->get($this->boltPath . '/labels', array($this, 'translationsGET'))->bind('labels'); - $this->app->get($this->boltPath . '/labels/list', array($this, 'listTranslations'))->bind('list_labels'); - $this->app->post($this->boltPath . '/labels/save', array($this, 'labelsSavePost'))->bind('save_labels'); - + $root = $this->app['resources']->getUrl('bolt'); + + // Admin menu + $this->addMenuOption('Label translations', $root . 'labels', 'fa:flag'); + + // Routess + $this->app->get($root . 'labels', array($this, 'translationsGET')) + ->bind('labels') + ; + $this->app->get($root . 'labels/list', array($this, 'listTranslations')) + ->bind('list_labels') + ; + $this->app->post($root . 'labels/save', array($this, 'labelsSavePost')) + ->bind('save_labels') + ; } /** * Set the current language + * + * @param Request $request */ - public function before() + public function before(Request $request) { $lang = $this->config['default']; @@ -72,6 +78,7 @@ public function before() public function extractLanguage($lang) { + $matches = array(); if (preg_match('/^([a-z]{2})\./', $lang, $matches)) { return $matches[1]; } else { @@ -81,22 +88,44 @@ public function extractLanguage($lang) public function loadLabels() { + $jsonFile = $this->app['resources']->getPath('extensionsconfig') . '/labels.json'; + $fs = new Filesystem(); + + // Check that the user's JSON file exists, else copy in the default + if (!$fs->exists($jsonFile)) { + try { + $fs->copy($this->getBasePath() . '/files/labels.json', $jsonFile); + } catch (IOException $e) { + $this->app['session']->getFlashBag()->set('error', + 'The labels file at app/config/extensions/labels.json does not exist, and can not be created. Changes can NOT saved, until you fix this.'); + } + } + // Check the file is writable try { - if (is_readable($this->fileName)) { - $labels = file_get_contents($this->fileName); - } else { - $labels = file_get_contents(__DIR__ . "/files/labels.json"); + $fs->touch($jsonFile); + } catch (IOException $e) { + $this->app['session']->getFlashBag()->set('error', + 'The labels file at app/config/extensions/labels.json is not writable. Changes can NOT saved, until you fix this.'); + } + + // Read the contents of the file + try { + $finder = new Finder(); + $finder + ->files() + ->name('labels.json') + ->in($this->app['resources']->getPath('extensionsconfig')) + ; + + foreach ($finder->files() as $file) { + $this->labels = json_decode($file->getContents(), true); + continue; } - $this->labels = json_decode($labels, true); } catch (\Exception $e) { - $this->app['session']->getFlashBag()->set('error', 'There was an issue loading the labels.'); - $this->labels = []; - return false; + $this->app['session']->getFlashBag()->set('error', sprintf('There was an issue loading the labels: %s', $e->getMessage())); + $this->labels = false; } - - return true; - } /** @@ -125,18 +154,16 @@ public function getCurrentLanguage() $twigGlobals = $this->app['twig']->getGlobals(); if (isset($twigGlobals['lang'])) { return $twigGlobals['lang']; - } - else { + } else { return null; } } - public function translationsGET(Request $request) { $this->requireUserPermission('labels'); - if (empty($this->labels)) { + if ($this->labels === null) { $this->loadLabels(); } @@ -146,25 +173,17 @@ public function translationsGET(Request $request) $data = []; - foreach($this->labels as $label => $row) { + foreach ($this->labels as $label => $row) { $values = []; - foreach($languages as $l) { + foreach ($languages as $l) { $values[] = $row[strtolower($l)] ?: ''; } $data[] = array_merge([$label], $values); } - if (!file_exists($this->fileName) && !is_writable(dirname($this->fileName))) { - $this->app['session']->getFlashBag()->set('error', - 'The labels file at ../app/config/extensions/labels.json does not exist, and can not be created. Changes can NOT saved, until you fix this.'); - } else if (file_exists($this->fileName) && !is_writable($this->fileName)) { - $this->app['session']->getFlashBag()->set('error', - 'The labels file at ../app/config/extensions/labels.json is not writable. Changes can NOT saved, until you fix this.'); - } - $twigvars = [ 'columns' => array_merge([ 'Label'], $languages), - 'data' => $data + 'data' => $data ]; return $this->render('import_form.twig', $twigvars); @@ -177,7 +196,7 @@ public function addLabel($label) $jsonarr = json_encode($this->labels); if (!file_put_contents($this->fileName, $jsonarr)) { - echo "[error saving labels]"; + echo '[error saving labels]'; } } @@ -191,7 +210,7 @@ public function labelsSavePost(Request $request) $arr = []; - foreach($labels as $labelrow) { + foreach ($labels as $labelrow) { $key = strtolower(trim(array_shift($labelrow))); $values = array_combine($columns, $labelrow); $arr[$key] = $values; @@ -204,23 +223,17 @@ public function labelsSavePost(Request $request) return Lib::redirect('labels'); } - if (!file_exists($this->fileName) && !is_writable(dirname($this->fileName))) { - $this->app['session']->getFlashBag()->set('error', - 'The labels file at ../app/config/extensions/labels.json does not exist, and can not be created. Changes were NOT saved.'); - } else if (file_exists($this->fileName) && !is_writable($this->fileName)) { + $fs = new Filesystem(); + try { + $jsonFile = $this->app['resources']->getPath('extensionsconfig') . '/labels.json'; + $fs->dumpFile($jsonFile, $jsonarr); + $this->app['session']->getFlashBag()->set('success', 'Changes to the labels have been saved.'); + } catch (IOException $e) { $this->app['session']->getFlashBag()->set('error', 'The labels file at ../app/config/extensions/labels.json is not writable. Changes were NOT saved.'); } - if (!file_put_contents($this->fileName, $jsonarr)) { - $this->app['session']->getFlashBag()->set('error', - 'There was an issue saving the file. Changes were NOT saved.'); - return Lib::redirect('labels'); - } - - $this->app['session']->getFlashBag()->set('success', 'Changes to the labels have been saved.'); return Lib::redirect('labels'); - } /** @@ -228,12 +241,11 @@ public function labelsSavePost(Request $request) */ public function twigL($label, $lang = false) { - if (!$this->isValidLanguage($lang)) { $lang = $this->getCurrentLanguage(); } - if (empty($this->labels)) { + if ($this->labels === null) { $this->loadLabels(); } @@ -251,28 +263,39 @@ public function twigL($label, $lang = false) if ($this->config['add_missing'] && empty($this->labels[$label])) { $this->addLabel($label); } - } return new \Twig_Markup($res, 'UTF-8'); } - public function twigSetLanguage($lang) { + public function twigSetLanguage($lang) + { $this->setCurrentLanguage($lang); return ''; } - public function __get($name) { - switch ($name) { - case 'currentLanguage': - return $this->getCurrentLanguage(); - } + public function __get($name) + { + return $name === 'currentLanguage' ? $this->getCurrentLanguage() : null; } - private function render($template, $data) { - $this->app['twig.loader.filesystem']->addPath(dirname(__FILE__) . '/templates'); + /** + * {@inheritDoc} + */ + protected function getDefaultConfig() + { + return array( + 'languages' => array('en', 'nl', 'de', 'fy', 'fr'), + 'default' => 'nl', + 'current' => 'nl', + ); + } + + private function render($template, $data) + { + $this->app['twig.loader.filesystem']->addPath(__DIR__ . '/templates'); - if ($this->app['config']->getWhichEnd()=='backend') { + if ($this->app['config']->getWhichEnd() === 'backend') { $this->app['htmlsnippets'] = true; $this->addCss('assets/handsontable.full.min.css'); $this->addJavascript('assets/handsontable.full.min.js', true); diff --git a/composer.json b/composer.json index c646a30..8b215fb 100644 --- a/composer.json +++ b/composer.json @@ -2,9 +2,14 @@ "name": "bolt/labels", "description": "Database-backed translation labels", "type": "bolt-extension", + "minimum-stability" : "dev", + "prefer-stable" : true, "require": { "bolt/bolt": ">=2.0.0,<3.0.0" }, + "require-dev" : { + "phpunit/phpunit" : "^4.7" + }, "license": "MIT", "authors": [ {"name": "Two Kings", "email": "info@twokings.nl"}, @@ -19,8 +24,18 @@ "Bolt\\Extension\\Bolt\\Labels\\": "" } }, - + "autoload-dev" : { + "psr-4" : { + "Bolt\\Tests\\" : { + "Bolt\\Extension\\Bolt\\Labels\\Tests\\" : "tests/", + "Bolt\\Tests\\" : "vendor/bolt/bolt/tests/phpunit/unit/" + } + } + }, "extra": { - "bolt-assets" : "assets/" + "bolt-assets" : "assets/", + "branch-alias" : { + "dev-master" : "2.1.*-dev" + } } } diff --git a/files/labels.json b/files/labels.json index 811ee1c..64d9855 100644 --- a/files/labels.json +++ b/files/labels.json @@ -1 +1 @@ -{"badger":{"nl":"das","la":"Meles meles","en":"badger","sl":"Badger","de":"Dachs ","fr":"blaireau","it":"tasso","pt":"texugo"},"bear":{"nl":"beer","la":"Ursus arctos","en":"bear","sl":"Bear","de":"B\u00e4r ","fr":"ours","it":"orso","pt":"Urso"},"beaver":{"nl":"bever","la":"Castor fiber","en":"beaver","sl":"Beaver","de":"Biber ","fr":"castor","it":"Castoro","pt":"castor"},"buffalo":{"nl":"buffalo","la":"Bos bubalus","en":"buffalo","sl":"buffalo","de":"B\u00fcffel ","fr":"buffle","it":"Bufalo","pt":"Bufalo"},"cat":{"nl":"cat","la":"Felis domesticus","en":"cat","sl":"cat","de":"Katze ","fr":"chat","it":"Gatto","pt":"gato"},"chamois":{"nl":"gems","la":"Rupicapra rupicapra","en":"chamois","sl":"gams","de":"Gams , Gemse ","fr":"chamois","it":"Camoscio","pt":"camur\u00e7a"},"cow":{"nl":"koe","la":"Bos primigenius","en":"cow","sl":"cattle, cow","de":"Rind , Kuh ","fr":"bovin, vache","it":"bovine, Vacca","pt":"bovine, vaca"},"deer (red)":{"nl":"hert","la":"Cervus elaphus","en":"deer (red)","sl":"deer","de":"Hirsch ","fr":"Cerf","it":"Cervo","pt":"veado, cervo"},"dog":{"nl":"hond","la":"Canis familiaris","en":"dog","sl":"dog","de":"Hund ","fr":"chien","it":"cane","pt":"cachorro, Cao"},"donkey":{"nl":"ezel","la":"Equus asinus","en":"donkey","sl":"Donkey","de":"Esel ","fr":"ane","it":"asino","pt":"burro"},"elephant":{"nl":"elephant","la":"Elephas maximus","en":"elephant","sl":"elephant","de":"Elefant ","fr":"Elephant","it":"elefante","pt":"elefante"},"ermine":{"nl":"hermelijn","la":"Mustela erminea","en":"ermine","sl":"hermelin","de":"Hermelin ","fr":"Hermine","it":"ermellino","pt":"arminho"},"ferret":{"nl":"fret","la":"Mustela putorius furo","en":"ferret","sl":"ferret","de":"Frettchen","fr":"furet","it":"furetto","pt":"fur\u0103o"},"fox":{"nl":"vos","la":"Vulpes vulpes","en":"fox","sl":"fox","de":"Fuchs ","fr":"Renard","it":"Volpe","pt":"Raposa"},"goat":{"nl":"geit","la":"Capra hircus","en":"goat","sl":"goat","de":"Ziege ","fr":"ch\u00e8vre","it":"Capra","pt":"Cabra"},"guinea pig":{"nl":"cavia","la":"Aperea Cavia","en":"guinea pig","sl":"guinea pig","de":"Meerschweinchen ","fr":"cobaye","it":"Cavia","pt":"cobaia"},"hamster":{"nl":"hamster","la":"Mesocricetus auratus","en":"hamster","sl":"Hamster","de":"Hamster ","fr":"hamster","it":"criceto","pt":"hamster"},"hare":{"nl":"hare","la":"Lepus europaeus","en":"hare","sl":"rabbit","de":"Hase ","fr":"LIEVRE","it":"lepre","pt":"lebre"},"hedgehog":{"nl":"hedgehog","la":"Erinaceus europaeus","en":"hedgehog","sl":"Hedgehog","de":"Needles ","fr":"h\u00e9risson","it":"Riccio","pt":"ouri\u00e7o"},"horse":{"nl":"horse","la":"Equus caballus","en":"horse","sl":"Horse","de":"Pferd ","fr":"cheval","it":"Cavallo","pt":"cavalo"},"ibex":{"nl":"ibex","la":"Capra ibex","en":"ibex","sl":"Capricorn","de":"Steinbock ","fr":"Bouquetin","it":"Stambecco","pt":"cabra alpina"},"lynx":{"nl":"lynx","la":"Lynx lynx","en":"lynx","sl":"ris","de":"Luchs ","fr":"lince ","it":"lynx","pt":"lince "},"marmot":{"nl":"marmot","la":"Marmota marmota","en":"marmot","sl":"Marmot","de":"Murmeltier ","fr":"marmotte","it":"Marmotte","pt":"marmota"},"marten":{"nl":"marter","la":"Martes Martes","en":"marten","sl":"Kuna","de":"Marder ","fr":"martre","it":"martora","pt":"marta"},"mole":{"nl":"mol","la":"Talpa europaea","en":"mole","sl":"krt","de":"Maulwurf ","fr":"taupe","it":"Talpa","pt":"toupeira"},"mouse":{"nl":"muis","la":"Mus musculus","en":"mouse","sl":"Mouse","de":"Maus","fr":"souris","it":"topo","pt":"Rato caseiro"},"otter":{"nl":"otter","la":"Lutra Lutra","en":"otter","sl":"Otter","de":"Otter ","fr":"Loutra","it":"lontra","pt":"lontra"},"pig":{"nl":"varken","la":"Sus domesticus","en":"pig","sl":"pig","de":"Schwein ","fr":"cochon","it":"maiale","pt":"porco"},"rabbit":{"nl":"konijn","la":"Oryctolagus cuniculus","en":"rabbit","sl":"rabbit","de":"Kaninchen ","fr":"lapin","it":"coniglio","pt":"Coelho"},"rat":{"nl":"rat","la":"Rattus rattus","en":"rat","sl":"rat","de":"Ratte ","fr":"rat","it":"ratto","pt":"Rato, ratazana"},"sheep":{"nl":"schaap","la":"Ovis aries","en":"sheep","sl":"Sheep","de":"Schaf ","fr":"gobeur","it":"pecora","pt":"ovelha"},"shrew":{"nl":"spitsmuis","la":"Sorex minitus","en":"shrew","sl":"rovka","de":"Spitzmaus ","fr":"musaraigne","it":"toporagno","pt":"musaranho"},"squirrel":{"nl":"eekhoorn","la":"Sciurus vulgaris","en":"squirrel","sl":"Squirrel","de":"H\u00f6rnchen ","fr":"\u00e9cureuil","it":"Scoiattolo","pt":"Esquel"},"vole":{"nl":"woelmuis","la":"Arvicola terrestris","en":"vole","sl":"voluhar","de":"Schermaus ","fr":"Campagnola","it":"Arvicola","pt":"Rato dos lameiros"},"weasel":{"nl":"wezel","la":"Mustela nivalis","en":"weasel","sl":"Weasel","de":"Wiesel ","fr":"belette","it":"donnola","pt":"doninha"},"wild boar":{"nl":"zwijn","la":"Sus Ferus","en":"wild boar","sl":"Wild Boar","de":"Wildschwein ","fr":"sanglier","it":"cinghiale","pt":"javali"},"wildcat":{"nl":"boskat","la":"Felis silvestris","en":"wildcat","sl":"wild cat","de":"Wildkatze ","fr":"chat sauvage","it":"Gatto Selvatico","pt":"gatobravo"},"wolf":{"nl":"wolf","la":"Canis lupus","en":"wolf","sl":"wolf","de":"Wolf ","fr":"loup","it":"loupe","pt":"lobo"}} \ No newline at end of file +{"badger":{"nl":"das","la":"Meles meles","en":"badger","sl":"Badger","de":"Dachs ","fr":"blaireau","it":"tasso","pt":"texugo"},"bear":{"nl":"beer","la":"Ursus arctos","en":"bear","sl":"Bear","de":"Bär ","fr":"ours","it":"orso","pt":"Urso"},"beaver":{"nl":"bever","la":"Castor fiber","en":"beaver","sl":"Beaver","de":"Biber ","fr":"castor","it":"Castoro","pt":"castor"},"buffalo":{"nl":"buffalo","la":"Bos bubalus","en":"buffalo","sl":"buffalo","de":"Büffel ","fr":"buffle","it":"Bufalo","pt":"Bufalo"},"cat":{"nl":"cat","la":"Felis domesticus","en":"cat","sl":"cat","de":"Katze ","fr":"chat","it":"Gatto","pt":"gato"},"chamois":{"nl":"gems","la":"Rupicapra rupicapra","en":"chamois","sl":"gams","de":"Gams , Gemse ","fr":"chamois","it":"Camoscio","pt":"camurça"},"cow":{"nl":"koe","la":"Bos primigenius","en":"cow","sl":"cattle, cow","de":"Rind , Kuh ","fr":"bovin, vache","it":"bovine, Vacca","pt":"bovine, vaca"},"deer (red)":{"nl":"hert","la":"Cervus elaphus","en":"deer (red)","sl":"deer","de":"Hirsch ","fr":"Cerf","it":"Cervo","pt":"veado, cervo"},"dog":{"nl":"hond","la":"Canis familiaris","en":"dog","sl":"dog","de":"Hund ","fr":"chien","it":"cane","pt":"cachorro, Cao"},"donkey":{"nl":"ezel","la":"Equus asinus","en":"donkey","sl":"Donkey","de":"Esel ","fr":"ane","it":"asino","pt":"burro"},"elephant":{"nl":"olifant","la":"Elephas maximus","en":"elephant","sl":"elephant","de":"Elefant ","fr":"Elephant","it":"elefante","pt":"elefante"},"ermine":{"nl":"hermelijn","la":"Mustela erminea","en":"ermine","sl":"hermelin","de":"Hermelin ","fr":"Hermine","it":"ermellino","pt":"arminho"},"ferret":{"nl":"fret","la":"Mustela putorius furo","en":"ferret","sl":"ferret","de":"Frettchen","fr":"furet","it":"furetto","pt":"furăo"},"fox":{"nl":"vos","la":"Vulpes vulpes","en":"fox","sl":"fox","de":"Fuchs ","fr":"Renard","it":"Volpe","pt":"Raposa"},"goat":{"nl":"geit","la":"Capra hircus","en":"goat","sl":"goat","de":"Ziege ","fr":"chèvre","it":"Capra","pt":"Cabra"},"guinea pig":{"nl":"cavia","la":"Aperea Cavia","en":"guinea pig","sl":"guinea pig","de":"Meerschweinchen ","fr":"cobaye","it":"Cavia","pt":"cobaia"},"hamster":{"nl":"hamster","la":"Mesocricetus auratus","en":"hamster","sl":"Hamster","de":"Hamster ","fr":"hamster","it":"criceto","pt":"hamster"},"hare":{"nl":"hare","la":"Lepus europaeus","en":"hare","sl":"rabbit","de":"Hase ","fr":"LIEVRE","it":"lepre","pt":"lebre"},"hedgehog":{"nl":"hedgehog","la":"Erinaceus europaeus","en":"hedgehog","sl":"Hedgehog","de":"Needles ","fr":"hérisson","it":"Riccio","pt":"ouriço"},"horse":{"nl":"horse","la":"Equus caballus","en":"horse","sl":"Horse","de":"Pferd ","fr":"cheval","it":"Cavallo","pt":"cavalo"},"ibex":{"nl":"ibex","la":"Capra ibex","en":"ibex","sl":"Capricorn","de":"Steinbock ","fr":"Bouquetin","it":"Stambecco","pt":"cabra alpina"},"lynx":{"nl":"lynx","la":"Lynx lynx","en":"lynx","sl":"ris","de":"Luchs ","fr":"lince ","it":"lynx","pt":"lince "},"marmot":{"nl":"marmot","la":"Marmota marmota","en":"marmot","sl":"Marmot","de":"Murmeltier ","fr":"marmotte","it":"Marmotte","pt":"marmota"},"marten":{"nl":"marter","la":"Martes Martes","en":"marten","sl":"Kuna","de":"Marder ","fr":"martre","it":"martora","pt":"marta"},"mole":{"nl":"mol","la":"Talpa europaea","en":"mole","sl":"krt","de":"Maulwurf ","fr":"taupe","it":"Talpa","pt":"toupeira"},"mouse":{"nl":"muis","la":"Mus musculus","en":"mouse","sl":"Mouse","de":"Maus","fr":"souris","it":"topo","pt":"Rato caseiro"},"otter":{"nl":"otter","la":"Lutra Lutra","en":"otter","sl":"Otter","de":"Otter ","fr":"Loutra","it":"lontra","pt":"lontra"},"pig":{"nl":"varken","la":"Sus domesticus","en":"pig","sl":"pig","de":"Schwein ","fr":"cochon","it":"maiale","pt":"porco"},"rabbit":{"nl":"konijn","la":"Oryctolagus cuniculus","en":"rabbit","sl":"rabbit","de":"Kaninchen ","fr":"lapin","it":"coniglio","pt":"Coelho"},"rat":{"nl":"rat","la":"Rattus rattus","en":"rat","sl":"rat","de":"Ratte ","fr":"rat","it":"ratto","pt":"Rato, ratazana"},"sheep":{"nl":"schaap","la":"Ovis aries","en":"sheep","sl":"Sheep","de":"Schaf ","fr":"gobeur","it":"pecora","pt":"ovelha"},"shrew":{"nl":"spitsmuis","la":"Sorex minitus","en":"shrew","sl":"rovka","de":"Spitzmaus ","fr":"musaraigne","it":"toporagno","pt":"musaranho"},"squirrel":{"nl":"eekhoorn","la":"Sciurus vulgaris","en":"squirrel","sl":"Squirrel","de":"Hörnchen ","fr":"écureuil","it":"Scoiattolo","pt":"Esquel"},"vole":{"nl":"woelmuis","la":"Arvicola terrestris","en":"vole","sl":"voluhar","de":"Schermaus ","fr":"Campagnola","it":"Arvicola","pt":"Rato dos lameiros"},"weasel":{"nl":"wezel","la":"Mustela nivalis","en":"weasel","sl":"Weasel","de":"Wiesel ","fr":"belette","it":"donnola","pt":"doninha"},"wild boar":{"nl":"zwijn","la":"Sus Ferus","en":"wild boar","sl":"Wild Boar","de":"Wildschwein ","fr":"sanglier","it":"cinghiale","pt":"javali"},"wildcat":{"nl":"boskat","la":"Felis silvestris","en":"wildcat","sl":"wild cat","de":"Wildkatze ","fr":"chat sauvage","it":"Gatto Selvatico","pt":"gatobravo"},"wolf":{"nl":"wolf","la":"Canis lupus","en":"wolf","sl":"wolf","de":"Wolf ","fr":"loup","it":"loupe","pt":"lobo"}} \ No newline at end of file diff --git a/include/Model.php b/include/Model.php deleted file mode 100644 index 4e565e6..0000000 --- a/include/Model.php +++ /dev/null @@ -1,213 +0,0 @@ -app = $app; - $this->prefix = $this->app['config']->get('general/database/prefix', "bolt_") . 'labels_'; - $this->cache = array(); - } - - public function getTablesSchema(Schema $schema) { - $tables = array(); - - $table = $schema->createTable($this->prefix . 'labels'); - $table->addColumn("id", "integer", array('autoincrement' => true)); - $table->setPrimaryKey(array("id")); - $table->addColumn("namespace", "string", array("length" => 255)); - $table->addColumn("label", "string", array("length" => 255)); - $table->addUniqueIndex(array('namespace', 'label')); - $tables[] = $table; - - $table = $schema->createTable($this->prefix . 'translations'); - $table->addColumn("id", "integer", array('autoincrement' => true)); - $table->setPrimaryKey(array("id")); - $table->addColumn("label_id", "integer", array()); - $table->addColumn("language", "string", array("length" => 2)); - $table->addColumn("translation", "string", array("length" => 255)); - $table->addUniqueIndex(array('label_id', 'language')); - $tables[] = $table; - - return $tables; - } - - private function escapeCacheKeyElement($elem) { - return str_replace( - array(':', '\\'), - array('\\:', '\\\\'), - $elem); - } - - private function makeCacheKey($namespace, $label, $language) { - return md5(implode(':', array( - $this->escapeCacheKeyElement($namespace), - $this->escapeCacheKeyElement($label), - $language))); - } - - private function _getTranslationInternal($namespace, $label, $language) - { - $db = $this->app['db']; - $query = - "SELECT t.id, t.translation, l.id as label_id " . - " FROM {$this->prefix}labels l " . - " LEFT JOIN {$this->prefix}translations t " . - " ON t.label_id = l.id AND t.language = :language " . - " WHERE l.namespace = :namespace AND l.label = :label " . - " LIMIT 1 "; - $params = array( - 'namespace' => $namespace, - 'label' => $label, - 'language' => $language - ); - $row = $db->fetchAssoc($query, $params); - if (!is_array($row) || !isset($row['label_id'])) { - // Label record does not exist - $labelRow = array( - 'namespace' => $namespace, - 'label' => $label); - $db->insert($this->prefix . 'labels', $labelRow); - $label_id = $db->lastInsertId(); - return array('translation' => $label, 'label_id' => $label_id, 'language' => $language); - } - else { - return $row; - } - } - - public function getTranslation($namespace, $label, $language) { - $cacheKey = $this->makeCacheKey($namespace, $label, $language); - if (isset($this->cache[$cacheKey])) { - return $this->cache[$cacheKey]; - } - $row = $this->_getTranslationInternal($namespace, $label, $language); - if (is_array($row) && isset($row['translation'])) { - $result = $row['translation']; - } - else { - $result = $label; - } - $this->cache[$cacheKey] = $result; - return $result; - } - - public function saveTranslation($namespace, $label, $language, $translation) { - $cacheKey = $this->makeCacheKey($namespace, $label, $language); - $this->cache[$cacheKey] = $translation; - $db = $this->app['db']; - - $labelRow = $this->_getTranslationInternal($namespace, $label, $language); - - if ($labelRow['translation'] == $translation) { - return 0; // already the same, no need to hit the DB again. - } - $labelRow['translation'] = $translation; - $labelRow['language'] = $language; - - if (is_null($labelRow['id'])) { - unset($labelRow['id']); - $db->insert($this->prefix . 'translations', $labelRow); - } - else { - $id = $labelRow['id']; - unset($labelRow['id']); - $ident = array('id' => $id); - $db->update($this->prefix . 'translations', $labelRow, $ident); - } - return 1; - } - - public function getTranslatableItems($sourceLanguage, $destLanguage, $untranslatedOnly = false, $pageIndex = 0, $pageSize = 10) { - $db = $this->app['db']; - $query = - "SELECT l.id as label_id, l.namespace, l.label, st.translation as source_translation, dt.translation as translation " . - " FROM {$this->prefix}labels l " . - " LEFT JOIN {$this->prefix}translations st ON st.label_id = l.id AND st.language = :source_language " . - " LEFT JOIN {$this->prefix}translations dt ON dt.label_id = l.id AND dt.language = :dest_language " . - " ORDER BY l.namespace, l.label "; - if ($untranslatedOnly) { - $query .= " WHERE dt.id IS NULL "; - } - $query .= " LIMIT " . intval($pageSize * $pageIndex) . ", " . intval($pageSize) . " "; - $params = array( - 'source_language' => $sourceLanguage, - 'dest_language' => $destLanguage, - 'offset' => $pageSize * $pageIndex, - 'page_size' => $pageSize); - return $db->fetchAll($query, $params); - } - - public function importCSV($handle) { - $header = fgetcsv($handle); - $languages = array_slice($header, 2); - $count = 0; - - while (!feof($handle)) { - $row = fgetcsv($handle); - if (!is_array($row)) { - continue; - } - $namespace = array_shift($row); - $label = array_shift($row); - foreach ($languages as $language) { - $translation = array_shift($row); - if (!empty($translation)) { - $count += $this->saveTranslation($namespace, $label, $language, $translation); - } - } - } - return $count; - } - - public function getExportableItems() { - $db = $this->app['db']; - $query = - " SELECT l.namespace, l.label, t.language, t.translation " . - " FROM {$this->prefix}labels l " . - " LEFT JOIN {$this->prefix}translations t " . - " ON t.label_id = l.id " . - " ORDER BY l.namespace, l.label, t.language "; - $stmt = $db->executeQuery($query); - $data = array(); - $languages = array('en' => 'en'); - while ($row = $stmt->fetch()) { - $language = $row['language']; - if (is_null($language)) { - $language = 'en'; - } - $key = $row['namespace'] . ':' . $row['label']; - $data[$key][$language] = $row['translation']; - $languages[$language] = $language; - } - $csvFile = fopen('php://temp', 'rw'); - $csvRow = array('namespace', 'label') + $languages; - fputcsv($csvFile, $csvRow); - foreach ($data as $key => $translations) { - $csvRow = explode(':', $key); - foreach ($languages as $language) { - if (isset($translations[$language])) { - $csvRow[] = $translations[$language]; - } - else { - $csvRow[] = ''; - } - } - fputcsv($csvFile, $csvRow); - } - rewind($csvFile); - $csv = ''; - while (!feof($csvFile)) { - $csv .= fread($csvFile, 1024); - } - fclose($csvFile); - return $csv; - } - -}; diff --git a/init.php b/init.php index 181ceca..246422a 100644 --- a/init.php +++ b/init.php @@ -2,5 +2,6 @@ namespace Bolt\Extension\Bolt\Labels; -$extension = new Extension($app); -$app['extensions']->register($extension); +if (isset($app)) { + $app['extensions']->register(new Extension($app)); +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..4039527 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,62 @@ + + + + + tests + + + + + + + + + + vendor/bolt/bolt/app/config/config.yml.dist + + + vendor/bolt/bolt/app/config/contenttypes.yml.dist + + + vendor/bolt/bolt/app/config/menu.yml.dist + + + vendor/bolt/bolt/app/config/permissions.yml.dist + + + vendor/bolt/bolt/app/config/routing.yml.dist + + + vendor/bolt/bolt/app/config/taxonomy.yml.dist + + + + + + theme/base-2014 + + + + + + + vendor/bolt/bolt/tests/phpunit/unit/resources/db/bolt.db + + + + true + + true + + + + \ No newline at end of file diff --git a/tests/AbstractExtensionTest.php b/tests/AbstractExtensionTest.php new file mode 100644 index 0000000..55f2ed3 --- /dev/null +++ b/tests/AbstractExtensionTest.php @@ -0,0 +1,40 @@ + + */ +abstract class AbstractExtensionTest extends BoltUnitTest +{ + /** \Bolt\Application */ + protected $app; + + protected function getApp($boot = true) + { + if ($this->app) { + return $this->app; + } + + $app = parent::getApp($boot); + $extension = new Extension($app); + + $app['extensions']->register($extension); + + return $this->app = $app; + } + + protected function getExtension() + { + if ($this->app === null) { + $this->getApp(); + } + + return $this->app['extensions.labels']; + } +} diff --git a/tests/ExtensionTest.php b/tests/ExtensionTest.php new file mode 100644 index 0000000..52e93d2 --- /dev/null +++ b/tests/ExtensionTest.php @@ -0,0 +1,22 @@ + + */ +class ExtensionTest extends AbstractExtensionTest +{ + public function testExtensionRegister() + { + $extension = $this->getExtension(); + + // Check getName() returns the correct value + $name = $extension->getName(); + $this->assertSame($name, 'labels'); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..45dc14b --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,7 @@ +