From 4eadb0959b574275ab5174c5405efc8f1bfe4fb1 Mon Sep 17 00:00:00 2001 From: Brendon Kozlowski Date: Tue, 22 Aug 2017 22:19:57 -0400 Subject: [PATCH 1/2] Quick fixes Fixed PHP notice level errors Fixed compatibility errors up to PHP 5.6 Updated Tags plugin to current version --- .gitignore | 1 + app/Config/core.php | 6 +- app/Controller/AppController.php | 19 +- app/Model/Behavior/SteppableBehavior.php | 10 +- app/Model/User.php | 6 +- .../Datasource/ZendSearchLuceneSource.php | 4 + app/Plugin/Tags/CHANGELOG.md | 29 + app/Plugin/Tags/CONTRIBUTING.md | 4 + .../Migration/001_initialize_tags_schema.php | 49 +- .../002_create_times_tagged_field.php | 24 +- .../003_occurrence_fields_for_tags.php | 24 +- app/Plugin/Tags/Config/Migration/map.php | 10 +- .../Config/Schema/{tags.php => schema.php} | 81 +-- .../Tags/Controller/TagsAppController.php | 5 +- app/Plugin/Tags/Controller/TagsController.php | 52 +- .../Tags/Docs/Documentation/Configuration.md | 63 ++ .../Tags/Docs/Documentation/Installation.md | 63 ++ .../Tags/Docs/Documentation/Overview.md | 25 + .../Documentation/The-Tag-Cloud-Helper.md | 49 ++ app/Plugin/Tags/Docs/Home.md | 27 + .../Docs/Tutorials/Find-Tagged-Objects.md | 34 ++ app/Plugin/Tags/Docs/Tutorials/Manage-Tags.md | 26 + app/Plugin/Tags/Docs/Tutorials/Quick-Start.md | 28 + .../Tags/Locale/deu/LC_MESSAGES/tags.po | 0 .../Tags/Locale/fre/LC_MESSAGES/tags.po | 0 .../Tags/Locale/por/LC_MESSAGES/tags.po | 0 .../Tags/Locale/rus/LC_MESSAGES/tags.po | 0 .../Tags/Locale/sau/LC_MESSAGES/tags.mo | Bin 0 -> 1602 bytes .../Tags/Locale/sau/LC_MESSAGES/tags.po | 140 +++++ .../Tags/Locale/spa/LC_MESSAGES/tags.po | 0 app/Plugin/Tags/Locale/tags.pot | 0 .../Tags/Model/Behavior/TaggableBehavior.php | 319 +++++++---- app/Plugin/Tags/Model/Tag.php | 71 ++- app/Plugin/Tags/Model/Tagged.php | 62 +- app/Plugin/Tags/Model/TagsAppModel.php | 17 +- .../Tags/Test/Case/AllTagsPluginTest.php | 25 - app/Plugin/Tags/Test/Case/AllTagsTest.php | 20 + .../Tags/Test/Case/Behavior/TaggableTest.php | 301 ---------- .../Case/Controller/TagsControllerTest.php | 83 ++- .../Tags/Test/Case/Helper/TagCloudTest.php | 115 ---- .../Model/Behavior/TaggableBehaviorTest.php | 538 ++++++++++++++++++ app/Plugin/Tags/Test/Case/Model/TagTest.php | 74 ++- .../Tags/Test/Case/Model/TaggedTest.php | 156 ++++- .../Case/View/Helper/TagCloudHelperTest.php | 177 ++++++ .../Tags/Test/Fixture/ArticleFixture.php | 30 +- app/Plugin/Tags/Test/Fixture/TagFixture.php | 63 +- .../Tags/Test/Fixture/TaggedFixture.php | 25 +- app/Plugin/Tags/Test/Fixture/UserFixture.php | 54 ++ .../Tags/View/Helper/TagCloudHelper.php | 43 +- app/Plugin/Tags/View/Helper/tag_cloud.php | 0 app/Plugin/Tags/View/Tags/admin_add.ctp | 4 +- app/Plugin/Tags/View/Tags/admin_edit.ctp | 4 +- app/Plugin/Tags/View/Tags/admin_index.ctp | 10 +- app/Plugin/Tags/View/Tags/admin_view.ctp | 9 +- app/Plugin/Tags/View/Tags/index.ctp | 12 +- app/Plugin/Tags/View/Tags/view.ctp | 9 +- app/Plugin/Tags/composer.json | 22 + app/Plugin/Tags/license.txt | 2 +- app/Plugin/Tags/readme.md | 79 +-- .../Model/Behavior/CsvImportBehavior.php | 2 +- app/webroot/.htaccess | 3 - config.sample.yml | 75 --- 62 files changed, 2058 insertions(+), 1125 deletions(-) create mode 100755 app/Plugin/Tags/CHANGELOG.md create mode 100755 app/Plugin/Tags/CONTRIBUTING.md mode change 100644 => 100755 app/Plugin/Tags/Config/Migration/001_initialize_tags_schema.php mode change 100644 => 100755 app/Plugin/Tags/Config/Migration/002_create_times_tagged_field.php mode change 100644 => 100755 app/Plugin/Tags/Config/Migration/003_occurrence_fields_for_tags.php mode change 100644 => 100755 app/Plugin/Tags/Config/Migration/map.php rename app/Plugin/Tags/Config/Schema/{tags.php => schema.php} (54%) mode change 100644 => 100755 mode change 100644 => 100755 app/Plugin/Tags/Controller/TagsAppController.php mode change 100644 => 100755 app/Plugin/Tags/Controller/TagsController.php create mode 100755 app/Plugin/Tags/Docs/Documentation/Configuration.md create mode 100755 app/Plugin/Tags/Docs/Documentation/Installation.md create mode 100755 app/Plugin/Tags/Docs/Documentation/Overview.md create mode 100755 app/Plugin/Tags/Docs/Documentation/The-Tag-Cloud-Helper.md create mode 100755 app/Plugin/Tags/Docs/Home.md create mode 100755 app/Plugin/Tags/Docs/Tutorials/Find-Tagged-Objects.md create mode 100755 app/Plugin/Tags/Docs/Tutorials/Manage-Tags.md create mode 100755 app/Plugin/Tags/Docs/Tutorials/Quick-Start.md mode change 100644 => 100755 app/Plugin/Tags/Locale/deu/LC_MESSAGES/tags.po mode change 100644 => 100755 app/Plugin/Tags/Locale/fre/LC_MESSAGES/tags.po mode change 100644 => 100755 app/Plugin/Tags/Locale/por/LC_MESSAGES/tags.po mode change 100644 => 100755 app/Plugin/Tags/Locale/rus/LC_MESSAGES/tags.po create mode 100755 app/Plugin/Tags/Locale/sau/LC_MESSAGES/tags.mo create mode 100755 app/Plugin/Tags/Locale/sau/LC_MESSAGES/tags.po mode change 100644 => 100755 app/Plugin/Tags/Locale/spa/LC_MESSAGES/tags.po mode change 100644 => 100755 app/Plugin/Tags/Locale/tags.pot mode change 100644 => 100755 app/Plugin/Tags/Model/Behavior/TaggableBehavior.php mode change 100644 => 100755 app/Plugin/Tags/Model/Tag.php mode change 100644 => 100755 app/Plugin/Tags/Model/Tagged.php mode change 100644 => 100755 app/Plugin/Tags/Model/TagsAppModel.php delete mode 100644 app/Plugin/Tags/Test/Case/AllTagsPluginTest.php create mode 100755 app/Plugin/Tags/Test/Case/AllTagsTest.php delete mode 100644 app/Plugin/Tags/Test/Case/Behavior/TaggableTest.php mode change 100644 => 100755 app/Plugin/Tags/Test/Case/Controller/TagsControllerTest.php delete mode 100644 app/Plugin/Tags/Test/Case/Helper/TagCloudTest.php create mode 100755 app/Plugin/Tags/Test/Case/Model/Behavior/TaggableBehaviorTest.php mode change 100644 => 100755 app/Plugin/Tags/Test/Case/Model/TagTest.php mode change 100644 => 100755 app/Plugin/Tags/Test/Case/Model/TaggedTest.php create mode 100755 app/Plugin/Tags/Test/Case/View/Helper/TagCloudHelperTest.php mode change 100644 => 100755 app/Plugin/Tags/Test/Fixture/ArticleFixture.php mode change 100644 => 100755 app/Plugin/Tags/Test/Fixture/TagFixture.php mode change 100644 => 100755 app/Plugin/Tags/Test/Fixture/TaggedFixture.php create mode 100755 app/Plugin/Tags/Test/Fixture/UserFixture.php mode change 100644 => 100755 app/Plugin/Tags/View/Helper/TagCloudHelper.php delete mode 100644 app/Plugin/Tags/View/Helper/tag_cloud.php mode change 100644 => 100755 app/Plugin/Tags/View/Tags/admin_add.ctp mode change 100644 => 100755 app/Plugin/Tags/View/Tags/admin_edit.ctp mode change 100644 => 100755 app/Plugin/Tags/View/Tags/admin_index.ctp mode change 100644 => 100755 app/Plugin/Tags/View/Tags/admin_view.ctp mode change 100644 => 100755 app/Plugin/Tags/View/Tags/index.ctp mode change 100644 => 100755 app/Plugin/Tags/View/Tags/view.ctp create mode 100755 app/Plugin/Tags/composer.json mode change 100644 => 100755 app/Plugin/Tags/license.txt mode change 100644 => 100755 app/Plugin/Tags/readme.md delete mode 100644 config.sample.yml diff --git a/.gitignore b/.gitignore index e753000..24ffaea 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ app/tmp/logs/*.log app/webroot/uploads /nbproject/private/ .idea +.DS_Store \ No newline at end of file diff --git a/app/Config/core.php b/app/Config/core.php index 96d8acb..efc216f 100644 --- a/app/Config/core.php +++ b/app/Config/core.php @@ -32,7 +32,7 @@ * In production mode, flash messages redirect after a time interval. * In development mode, you need to click the flash message to continue. */ - Configure::write('debug', 0); + Configure::write('debug', 2); /** * Configure the Error handler used to handle errors for your application. By default @@ -227,7 +227,7 @@ Configure::write('Acl.database', 'default'); /** - * Uncomment this line and correct your server timezone to fix + * Uncomment this line and correct your server timezone to fix * any date & time related errors. */ //date_default_timezone_set('UTC'); @@ -237,7 +237,7 @@ * If running via cli - apc is disabled by default. ensure it's available and enabled in this case * * Note: 'default' and other application caches should be configured in app/Config/bootstrap.php. - * Please check the comments in boostrap.php for more info on the cache engines available + * Please check the comments in boostrap.php for more info on the cache engines available * and their setttings. */ $engine = 'File'; diff --git a/app/Controller/AppController.php b/app/Controller/AppController.php index e68f57a..0b0da7f 100755 --- a/app/Controller/AppController.php +++ b/app/Controller/AppController.php @@ -4,8 +4,8 @@ class AppController extends Controller { - public $theme = 'GuideOnTheSide'; - + public $theme = 'GuideOnTheSide'; + // GD settings var $padding = 10; // not the CSS padding, but the padding inside the image var $character_width = 8; @@ -29,15 +29,18 @@ function beforeFilter() { $this->helpers[] = 'Js'; // provide the role to all actions - $role_id = $this->Auth->user('role_id'); - $this->loadModel('Role'); - $this->Role->recursive = 0; - $role = $this->Role->findById($role_id); - $this->Session->write('Role', $role['Role']); + $is_logged_in = $this->Auth->user(); + if ($is_logged_in) { + $role_id = $this->Auth->user('role_id'); + $this->loadModel('Role'); + $this->Role->recursive = 0; + $role = $this->Role->findById($role_id); + $this->Session->write('Role', $role['Role']); + } $this->set('is_admin', $this->Session->read('Role.name') == 'admin'); $this->set('show_password_link', !$this->Auth->user('noLoginForm')); - + if ($theme = Configure::read('user_config.theme')) { $this->theme = $theme; } diff --git a/app/Model/Behavior/SteppableBehavior.php b/app/Model/Behavior/SteppableBehavior.php index eea9735..3320283 100644 --- a/app/Model/Behavior/SteppableBehavior.php +++ b/app/Model/Behavior/SteppableBehavior.php @@ -9,16 +9,16 @@ class SteppableBehavior extends ModelBehavior { var $general_question_pattern = '/\]*class\="question"[^>]*src\="questions\/view_image\/(\d+)"[^>]*\/\>/'; - public function beforeSave(&$Model) { + public function beforeSave(Model $model, $options = array()) { // Sanitize the content on save. This does not sanitize definitions (done in getStepsWithContent()), questions // (done in question/answer models), or headings (done in _generateDefinition(Print)HTML) // A bit scattered, I know. Sorry about that. // TODO: Look into Cake's Sanitization stuff for this purpose. - if (isset($Model->data[$Model->alias]['content'])) { - $Model->data[$Model->alias]['content'] = - strip_tags($Model->data[$Model->alias]['content'], allowed_tags('strip_tags')); + if (isset($model->data[$model->alias]['content'])) { + $model->data[$model->alias]['content'] = + strip_tags($model->data[$model->alias]['content'], allowed_tags('strip_tags')); } -// $Model->data = Sanitize::clean($Model->data, array('encode' => false)); +// $model->data = Sanitize::clean($model->data, array('encode' => false)); return true; } diff --git a/app/Model/User.php b/app/Model/User.php index 795029f..17d5045 100644 --- a/app/Model/User.php +++ b/app/Model/User.php @@ -39,7 +39,7 @@ function enforceComplexity($check) { return $passes; } - function beforeValidate() { + function beforeValidate($options = array()) { if ($this->data['User']['keep_password']) { // don't validate and don't let the password be set unset($this->validate['password']); @@ -47,7 +47,7 @@ function beforeValidate() { } } - function beforeSave() { + function beforeSave($options = array()) { if (!$this->data['User']['keep_password']) { $this->data['User']['password'] = sha1(Configure::read('Security.salt') . $this->data['User']['password']); } @@ -62,7 +62,7 @@ public function beforeFind($queryData = array()) { return $queryData; } - public function delete($id = null) { + public function delete($id = null, $cascade = true) { if (is_numeric($id)) { $user = $this->findById($id); if (!$user['User']['deleted']) { diff --git a/app/Plugin/LuceneSource/Model/Datasource/ZendSearchLuceneSource.php b/app/Plugin/LuceneSource/Model/Datasource/ZendSearchLuceneSource.php index 8172394..29ee7b8 100644 --- a/app/Plugin/LuceneSource/Model/Datasource/ZendSearchLuceneSource.php +++ b/app/Plugin/LuceneSource/Model/Datasource/ZendSearchLuceneSource.php @@ -23,6 +23,10 @@ class ZendSearchLuceneSource extends DataSource { protected $sources = array('search_indices'); + protected $_queriesLog = ''; + protected $_queriesCnt = 0; + protected $_queriesTime = 0; + private $__index = null; diff --git a/app/Plugin/Tags/CHANGELOG.md b/app/Plugin/Tags/CHANGELOG.md new file mode 100755 index 0000000..ac3223d --- /dev/null +++ b/app/Plugin/Tags/CHANGELOG.md @@ -0,0 +1,29 @@ +Changelog +========= + +Release 1.6.0 +------------- + +https://github.com/CakeDC/tags/tree/1.6.0 + +* [d9c4af3](https://github.com/CakeDC/tags/commit/d9c4af3) Adding phpunit to travis +* [715bbac](https://github.com/CakeDC/tags/commit/715bbac) Changing the use of an anonymous function to php 5.2.8 compatible code +* [1b2f970](https://github.com/CakeDC/tags/commit/1b2f970) Adding the fix from https://github.com/CakeDC/tags/pull/71 to the correct branch +* [0a68301](https://github.com/CakeDC/tags/commit/c398e5b) Comparing model's name to tagClass. +* [c398e5b](https://github.com/CakeDC/tags/commit/c398e5b) Comparing name instead of alias. +* [948317b](https://github.com/CakeDC/tags/commit/948317b) Fixing the wrong behavior declartion in quick-start.md +* [b378ddd](https://github.com/CakeDC/tags/commit/b378ddd) Fixing to save tag with identifier. +* [d4c4e9e](https://github.com/CakeDC/tags/commit/d4c4e9e) Adding test. +* [dd74851](https://github.com/CakeDC/tags/commit/dd74851) Allowing to add existing tags. +* [0eb7d7a](https://github.com/CakeDC/tags/commit/0eb7d7a) Fixing pagings. +* [a8421c7](https://github.com/CakeDC/tags/commit/a8421c7) Fixing https://github.com/CakeDC/tags/issues/51, tags with an identifier (cakephp:developer) are not displayed with the identifier when returned from the9c4c9ed Fixing the use of the previosly removed weight field, as well some CS issues and a typoe in the readme.md +* [3592c6d](https://github.com/CakeDC/tags/commit/3592c6d) Working on the documentation +* [bc88020](https://github.com/CakeDC/tags/commit/bc88020) Renaming the test file that triggers all tests +* [c9cda46](https://github.com/CakeDC/tags/commit/c9cda46) Removing code from a wrong place +* [ede645a](https://github.com/CakeDC/tags/commit/ede645a) Changing a Hash call back to Set to provide backward compatibility +* [018c360](https://github.com/CakeDC/tags/commit/018c360) Fixing a typo in the .travis file +* [8be0b63](https://github.com/CakeDC/tags/commit/8be0b63) CS fixes and updating deprecated phpunit method calls +* [d8f39d6](https://github.com/CakeDC/tags/commit/d8f39d6) Fixing a php 5.4 compatibility issue +* [d8f39d6](https://github.com/CakeDC/tags/commit/d8f39d6) Fixed incorrect calculated size when using custom weight field +* [946a44a](https://github.com/CakeDC/tags/commit/946a44a) Refactoring: extracted sample tag data in a field +* [8e007c3](https://github.com/CakeDC/tags/commit/8e007c3) \#51 using modelClass as model name in Controller in order to allow extending the plugin. Fixed Taggable Behavior to use Tag alias \ No newline at end of file diff --git a/app/Plugin/Tags/CONTRIBUTING.md b/app/Plugin/Tags/CONTRIBUTING.md new file mode 100755 index 0000000..26f5308 --- /dev/null +++ b/app/Plugin/Tags/CONTRIBUTING.md @@ -0,0 +1,4 @@ +Contributing +============ + +This repository follows the [CakeDC Plugin Standard](http://cakedc.com/plugin-standard). If you'd like to contribute new features, enhancements or bug fixes to the plugin, please read our [Contribution Guidelines](http://cakedc.com/contribution-guidelines) for detailed instructions. diff --git a/app/Plugin/Tags/Config/Migration/001_initialize_tags_schema.php b/app/Plugin/Tags/Config/Migration/001_initialize_tags_schema.php old mode 100644 new mode 100755 index f1f0d8b..5ca746a --- a/app/Plugin/Tags/Config/Migration/001_initialize_tags_schema.php +++ b/app/Plugin/Tags/Config/Migration/001_initialize_tags_schema.php @@ -42,13 +42,13 @@ class M49ac311a54844a9d87o822502jedc423 extends CakeMigration { 'up' => array( 'create_table' => array( 'tagged' => array( - 'id' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 36, 'key' => 'primary'), - 'foreign_key' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 36), - 'tag_id' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 36), - 'model' => array('type' => 'string', 'null' => false, 'default' => NULL, 'key' => 'index'), - 'language' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 6), - 'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL), - 'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL), + 'id' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36, 'key' => 'primary'), + 'foreign_key' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36), + 'tag_id' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36), + 'model' => array('type' => 'string', 'null' => false, 'default' => null, 'key' => 'index'), + 'language' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 6), + 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), + 'modified' => array('type' => 'datetime', 'null' => true, 'default' => null), 'indexes' => array( 'PRIMARY' => array('column' => 'id', 'unique' => 1), 'UNIQUE_TAGGING' => array('column' => array('model', 'foreign_key', 'tag_id', 'language'), 'unique' => 1), @@ -57,13 +57,13 @@ class M49ac311a54844a9d87o822502jedc423 extends CakeMigration { ) ), 'tags' => array( - 'id' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 36, 'key' => 'primary'), - 'identifier' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 30, 'key' => 'index'), - 'name' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 30), - 'keyname' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 30), + 'id' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36, 'key' => 'primary'), + 'identifier' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 30, 'key' => 'index'), + 'name' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 30), + 'keyname' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 30), 'weight' => array('type' => 'integer', 'null' => false, 'default' => 0, 'length' => 2), - 'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL), - 'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL), + 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), + 'modified' => array('type' => 'datetime', 'null' => true, 'default' => null), 'indexes' => array( 'PRIMARY' => array('column' => 'id', 'unique' => 1), 'UNIQUE_TAG' => array('column' => array('identifier', 'keyname'), 'unique' => 1) @@ -76,27 +76,4 @@ class M49ac311a54844a9d87o822502jedc423 extends CakeMigration { ) ); -/** - * Before migration callback - * - * @param string $direction, up or down direction of migration process - * @return boolean Should process continue - * @access public - */ - public function before($direction) { - return true; - } - -/** - * After migration callback - * - * @param string $direction, up or down direction of migration process - * @return boolean Should process continue - * @access public - */ - public function after($direction) { - return true; - } - } -?> \ No newline at end of file diff --git a/app/Plugin/Tags/Config/Migration/002_create_times_tagged_field.php b/app/Plugin/Tags/Config/Migration/002_create_times_tagged_field.php old mode 100644 new mode 100755 index bf1914f..1bcf9c6 --- a/app/Plugin/Tags/Config/Migration/002_create_times_tagged_field.php +++ b/app/Plugin/Tags/Config/Migration/002_create_times_tagged_field.php @@ -42,8 +42,8 @@ class M4c0d42bcd12c4db099c105f40e8f3d6d extends CakeMigration { 'create_field' => array( 'tagged' => array( 'times_tagged' => array('type' => 'integer', 'null' => false, 'default' => 1), - ) ), + ), ), 'down' => array( 'drop_field' => array( @@ -52,26 +52,4 @@ class M4c0d42bcd12c4db099c105f40e8f3d6d extends CakeMigration { ), ); -/** - * Before migration callback - * - * @param string $direction, up or down direction of migration process - * @return boolean Should process continue - * @access public - */ - public function before($direction) { - return true; - } - -/** - * After migration callback - * - * @param string $direction, up or down direction of migration process - * @return boolean Should process continue - * @access public - */ - public function after($direction) { - return true; - } } -?> \ No newline at end of file diff --git a/app/Plugin/Tags/Config/Migration/003_occurrence_fields_for_tags.php b/app/Plugin/Tags/Config/Migration/003_occurrence_fields_for_tags.php old mode 100644 new mode 100755 index 1b46878..a1e9a6e --- a/app/Plugin/Tags/Config/Migration/003_occurrence_fields_for_tags.php +++ b/app/Plugin/Tags/Config/Migration/003_occurrence_fields_for_tags.php @@ -42,8 +42,8 @@ class M8d01880f01c11e0be500800200c9a66 extends CakeMigration { 'create_field' => array( 'tags' => array( 'occurrence' => array('type' => 'integer', 'null' => false, 'default' => 0, 'length' => 8), - ) ), + ), 'drop_field' => array( 'tags' => array('weight') ), @@ -60,26 +60,4 @@ class M8d01880f01c11e0be500800200c9a66 extends CakeMigration { ), ); -/** - * Before migration callback - * - * @param string $direction, up or down direction of migration process - * @return boolean Should process continue - * @access public - */ - public function before($direction) { - return true; - } - -/** - * After migration callback - * - * @param string $direction, up or down direction of migration process - * @return boolean Should process continue - * @access public - */ - public function after($direction) { - return true; - } } -?> \ No newline at end of file diff --git a/app/Plugin/Tags/Config/Migration/map.php b/app/Plugin/Tags/Config/Migration/map.php old mode 100644 new mode 100755 index 1439cc8..f279118 --- a/app/Plugin/Tags/Config/Migration/map.php +++ b/app/Plugin/Tags/Config/Migration/map.php @@ -17,10 +17,12 @@ $map = array( 1 => array( - '001_initialize_tags_schema' => 'M49ac311a54844a9d87o822502jedc423'), + '001_initialize_tags_schema' => 'M49ac311a54844a9d87o822502jedc423', + ), 2 => array( - '002_create_times_tagged_field' => 'M4c0d42bcd12c4db099c105f40e8f3d6d'), + '002_create_times_tagged_field' => 'M4c0d42bcd12c4db099c105f40e8f3d6d', + ), 3 => array( - '003_occurrence_fields_for_tags' => 'M8d01880f01c11e0be500800200c9a66'), + '003_occurrence_fields_for_tags' => 'M8d01880f01c11e0be500800200c9a66', + ), ); -?> \ No newline at end of file diff --git a/app/Plugin/Tags/Config/Schema/tags.php b/app/Plugin/Tags/Config/Schema/schema.php old mode 100644 new mode 100755 similarity index 54% rename from app/Plugin/Tags/Config/Schema/tags.php rename to app/Plugin/Tags/Config/Schema/schema.php index 92678fc..88388ee --- a/app/Plugin/Tags/Config/Schema/tags.php +++ b/app/Plugin/Tags/Config/Schema/schema.php @@ -1,58 +1,15 @@ - array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 36, 'key' => 'primary'), - 'foreign_key' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 36), - 'tag_id' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 36), - 'model' => array('type' => 'string', 'null' => false, 'default' => NULL, 'key' => 'index'), - 'language' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 6, 'key' => 'index'), + 'id' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36, 'key' => 'primary'), + 'foreign_key' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36), + 'tag_id' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36), + 'model' => array('type' => 'string', 'null' => false, 'default' => null, 'key' => 'index'), + 'language' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 6, 'key' => 'index'), 'times_tagged' => array('type' => 'integer', 'null' => false, 'default' => '1'), - 'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL), - 'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL), + 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), + 'modified' => array('type' => 'datetime', 'null' => true, 'default' => null), 'indexes' => array( 'PRIMARY' => array('column' => 'id', 'unique' => 1), 'UNIQUE_TAGGING' => array('column' => array('model', 'foreign_key', 'tag_id', 'language'), 'unique' => 1), @@ -84,13 +41,12 @@ public function after($event = array()) { * @access public */ public $tags = array( - 'id' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 36, 'key' => 'primary'), - 'identifier' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 30, 'key' => 'index'), - 'name' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 30), - 'keyname' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 30), - 'weight' => array('type' => 'integer', 'null' => false, 'default' => 0, 'length' => 2), - 'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL), - 'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL), + 'id' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36, 'key' => 'primary'), + 'identifier' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 30, 'key' => 'index'), + 'name' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 30), + 'keyname' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 30), + 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), + 'modified' => array('type' => 'datetime', 'null' => true, 'default' => null), 'indexes' => array( 'PRIMARY' => array('column' => 'id', 'unique' => 1), 'UNIQUE_TAG' => array('column' => array('identifier', 'keyname'), 'unique' => 1) @@ -98,4 +54,3 @@ public function after($event = array()) { ); } -?> \ No newline at end of file diff --git a/app/Plugin/Tags/Controller/TagsAppController.php b/app/Plugin/Tags/Controller/TagsAppController.php old mode 100644 new mode 100755 index 1252984..8465fa5 --- a/app/Plugin/Tags/Controller/TagsAppController.php +++ b/app/Plugin/Tags/Controller/TagsAppController.php @@ -1,13 +1,14 @@ Tag->recursive = 0; - $this->set('tags', $this->paginate()); + $this->{$this->modelClass}->recursive = 0; + $this->set('tags', $this->Paginator->paginate()); } /** * View * - * @param string + * @param string $keyName Tag key name * @return void */ public function view($keyName = null) { try { - $this->set('tag', $this->Tag->view($keyName)); + $this->set('tag', $this->{$this->modelClass}->view($keyName)); } catch (Exception $e) { $this->Session->setFlash($e->getMessage()); $this->redirect('/'); @@ -69,19 +77,19 @@ public function view($keyName = null) { * @return void */ public function admin_index() { - $this->Tag->recursive = 0; - $this->set('tags', $this->paginate()); + $this->{$this->modelClass}->recursive = 0; + $this->set('tags', $this->Paginator->paginate()); } /** * Views a single tag * - * @param string tag UUID + * @param string $keyName Tag key name * @return void */ public function admin_view($keyName) { try { - $this->set('tag', $this->Tag->view($keyName)); + $this->set('tag', $this->{$this->modelClass}->view($keyName)); } catch (Exception $e) { $this->Session->setFlash($e->getMessage()); $this->redirect('/'); @@ -95,7 +103,7 @@ public function admin_view($keyName) { */ public function admin_add() { if (!empty($this->request->data)) { - if ($this->Tag->add($this->request->data)) { + if ($this->{$this->modelClass}->add($this->request->data)) { $this->Session->setFlash(__d('tags', 'The Tags has been saved.')); $this->redirect(array('action' => 'index')); } @@ -105,12 +113,12 @@ public function admin_add() { /** * Edits a tag * - * @param string tag UUID + * @param string $tagId Tag UUID * @return void */ public function admin_edit($tagId = null) { try { - $result = $this->Tag->edit($tagId, $this->request->data); + $result = $this->{$this->modelClass}->edit($tagId, $this->request->data); if ($result === true) { $this->Session->setFlash(__d('tags', 'Tag saved.')); $this->redirect(array('action' => 'index')); @@ -123,18 +131,18 @@ public function admin_edit($tagId = null) { } if (empty($this->request->data)) { - $this->request->data = $this->Tag->data; + $this->request->data = $this->{$this->modelClass}->data; } } /** * Deletes a tag * - * @param string tag UUID + * @param string $tagId Tag UUID * @return void */ - public function admin_delete($id = null) { - if ($this->Tag->delete($id)) { + public function admin_delete($tagId = null) { + if ($this->{$this->modelClass}->delete($tagId)) { $this->Session->setFlash(__d('tags', 'Tag deleted.')); } else { $this->Session->setFlash(__d('tags', 'Invalid Tag.')); diff --git a/app/Plugin/Tags/Docs/Documentation/Configuration.md b/app/Plugin/Tags/Docs/Documentation/Configuration.md new file mode 100755 index 0000000..3868309 --- /dev/null +++ b/app/Plugin/Tags/Docs/Documentation/Configuration.md @@ -0,0 +1,63 @@ +Configuration +============= + +To turn an existing model into a taggable model, you only need to add the ```Tags.TaggableBehavior``` to it's Behavior list. + +```php +public $actsAs = array( + 'Tags.Taggable' +); +``` + +Once the Behavior is added to the Model it will: + +* Create a new HABTM relationship named Tag using the Tagged join class. +* Tag the object with tags contained in the ```Model.tags``` field on each save. +* Note: The tags field can contain several tags separated with a comma. +* Write the comma separated tag list in ```Model.tags``` field on each ```find()``` result. + +If you need different settings for the Behavior, check the available options below. + +Several TaggableBehavior configurations are customizable. To change a setting, you must add its new value to the $actsAs attribute as detailed below. If you want further information about Behaviors please read the CakePHP Documentation related pages. + +After adding the TaggableBehavior to your model, you will need to update your views so the data you save contains a tags field with the related tags (comma separated). + +```php +public $actsAs = array( + 'Tags.Taggable' => array( + 'separator' => ',', + 'tagAlias' => 'Tag', + 'tagClass' => 'Tags.Tag', + 'taggedAlias' => 'Tagged', + 'taggedClass' => 'Tags.Tagged', + 'field' => 'tags', + 'foreignKey' => 'foreign_key', + 'associationForeignKey' => 'tag_id', + 'cacheOccurrence' => true, + 'automaticTagging' => true, + 'taggedCounter' => false, + 'unsetInAfterFind' => false, + 'resetBinding' => false, + 'deleteTagsOnEmptyField' => false, + ) +); +``` + +The configuration above contains the default values for each setting. Here are some explanations: + +* **separator:** String used to separate tags in the Model.tags value. (Default: ```,```) +* **tagAlias:** Alias for the HABTM relationship between your Model and Tag. (Default: ```Tag```) +* **tagClass**: Name of the model representing Tags. (Default: ```Tags.Tag```) +* **taggedAlias:** Alias for the HABTM join model. (Default: ```Tagged```) +* **taggedClass:** Name of the HABTM join model. (Default: ```Tags.Tagged```) +* **field:** Name of the Model field containing the tag list. (Default: ```tags```) +* **foreignKey:** Name of the HABTM join model field containing the foreign key to the Tagable model. (Default: ```foreign_key```) +* **associationForeignKey:** Name of the HABTM join model field containing the foreign key to the Tag model. (Default: ```tag_id```) +* **cacheOccurrence:** Name of the HABTM join model field containing the foreign key to the Tag model. (Default: ```true```) +* **automaticTagging:** Whether or not the behavior will automatically call saveTags() after each save. (Default: ```true```) +* **taggedCounter:** True to update the number of times a particular tag was used for a specific record. +* **unsetInAfterFind:** Whether or not the related Tag entries have to be unset after a find. If this value is true, the ```$data['Tag']``` array will be unset and tags will only be available using the ```$data['Model']['tags']``` value. (Default: false) +* **resetBinding:** Value passed as the second param of to the ```bindModel()``` call when creating the HABTM association. If set to true, the binding will last only one query. (Default: false) +* **deleteTagsOnEmptyField:** Delete associated Tags if field is empty or empty string. + +Note that the ```tagClass```, ```taggedClass```, ```foreignKey``` and ```associationForeignKey``` values must not be changed if you use the plugin as it is shipped. Use these settings when you want to use your own models / tables structure. diff --git a/app/Plugin/Tags/Docs/Documentation/Installation.md b/app/Plugin/Tags/Docs/Documentation/Installation.md new file mode 100755 index 0000000..350b2b7 --- /dev/null +++ b/app/Plugin/Tags/Docs/Documentation/Installation.md @@ -0,0 +1,63 @@ +Installation +============ + +To install the plugin, place the files in a directory labelled "Tags/" in your "app/Plugin/" directory. + +Then, include the following line in your `app/Config/bootstrap.php` to load the plugin in your application. + +``` +CakePlugin::load('Tags'); +``` + +Git Submodule +------------- + +If you're using git for version control, you may want to add the **Tags** plugin as a submodule on your repository. To do so, run the following command from the base of your repository: + +``` +git submodule add git@github.com:CakeDC/tags.git app/Plugin/Tags +``` + +After doing so, you will see the submodule in your changes pending, plus the file ".gitmodules". Simply commit and push to your repository. + +To initialize the submodule(s) run the following command: + +``` +git submodule update --init --recursive +``` + +To retreive the latest updates to the plugin, assuming you're using the "master" branch, go to "app/Plugin/Tags" and run the following command: + +``` +git pull origin master +``` + +If you're using another branch, just change "master" for the branch you are currently using. + +If any updates are added, go back to the base of your own repository, commit and push your changes. This will update your repository to point to the latest updates to the plugin. + +Composer +-------- + +The plugin also provides a "composer.json" file, to easily use the plugin through the Composer dependency manager. + +Database Setup +-------------- + +The recommended way to install and maintain the database is using the [CakeDC Migrations](https://github.com/cakedc/migrations) plugin. + +To set up the **Tags** plugin tables run this command: + +``` +./Console/cake migrations.migration run all -p Tags +``` + +Alternately you can use the build in [Schema Shell](http://book.cakephp.org/2.0/en/console-and-shells/schema-management-and-migrations.html) of CakePHP: + +``` +./Console/cake schema create tag --plugin Tags + +``` + + + diff --git a/app/Plugin/Tags/Docs/Documentation/Overview.md b/app/Plugin/Tags/Docs/Documentation/Overview.md new file mode 100755 index 0000000..b1673d6 --- /dev/null +++ b/app/Plugin/Tags/Docs/Documentation/Overview.md @@ -0,0 +1,25 @@ +Overview +======== + +The **Tags** plugin includes the TaggableBehavior that allows you to simply tag everything. + +It saves all tags in a single tags table and connects any kind of records to them through the tagged table. + +Support +------- + +For bugs and feature requests, please use the [issues](https://github.com/CakeDC/tags/issues) section of this repository. + +Commercial support is also available, [contact us](http://cakedc.com/contact) for more information. + +Contributing +------------ + +If you'd like to contribute new features, enhancements or bug fixes to the plugin, just read our [Contribution Guidelines](http://cakedc.com/plugins) for detailed instructions. + +License +------- + +Copyright 2007-2014 Cake Development Corporation (CakeDC). All rights reserved. + +Licensed under the [MIT](http://www.opensource.org/licenses/mit-license.php) License. Redistributions of the source code included in this repository must retain the copyright notice found in each file. diff --git a/app/Plugin/Tags/Docs/Documentation/The-Tag-Cloud-Helper.md b/app/Plugin/Tags/Docs/Documentation/The-Tag-Cloud-Helper.md new file mode 100755 index 0000000..38ca055 --- /dev/null +++ b/app/Plugin/Tags/Docs/Documentation/The-Tag-Cloud-Helper.md @@ -0,0 +1,49 @@ +The Tag Cloud Helper +==================== + +A Tag cloud is a user friendly way to display a tag list to users. The Tags plugin is shipped with a helper permitting to generate a markup easily skinnable using CSS. + +Here are the necessary steps for displaying a tag cloud with some basic options. + +1. Add the TagCloud helper to your controller ```public $helpers = array('Tags.TagCloud');``` +2. In you controller action, get a list of tags and pass it to the view. The Tagged model contains a custom find method ```_findCloud()``` which retrieves all the tags and populates values. Here is an example code from a RecipesController, where Recipe actsAs Taggable: ```$this->set('tags', $this->Recipe->Tagged->find('cloud', array('limit' => 10)));``` +3. Call the ```display()``` helper method where you want to display the cloud. For instance: + +```php + +``` + +Will generate a code like: + +```html + +``` + +The helper generated links (with an unique DOM id `tag-{id}`) to the *index action of a search controller* in this example, the tag keyname being passed as a named param. The `%size%` string from the before param was replaced with a number based on the tag weight. + +Available Options of the TagCloud helper +---------------------------------------- + +The second param for the ```display()``` method is an array of options. The available keys are: + +* **shuffle:** true to shuffle the tag list, false to display them in the same order than passed. (Default: ```true```) +* **extract:** Set::extract() compatible format string. Path to extract weight values from the $tags array passed (first param). (Default: ```{n}.Tag.weight```) +* **before:** string to be displayed before each generated link. %size% will be replaced with tag size calculated from the weight. (Default: ```empty```) +* **after:** string to be displayed after each generated link. %size% will be replaced with tag size calculated from the weight. (Default: ```empty```) +* **maxSize:** size of the heaviest tag. (Default: ```160```) +* **minSize:** size of the lightest tag. (Default: ```80```) +* **url:** an array containing the default URL. (Default: ```array('controller' => 'search'```)) +* **named**: the named parameter used to send the tag keyname. (Default: ```by```) +* **paramType**: the type of URL parameters used (```named``` or ```querystring```). (Default: ```named```) diff --git a/app/Plugin/Tags/Docs/Home.md b/app/Plugin/Tags/Docs/Home.md new file mode 100755 index 0000000..21eca71 --- /dev/null +++ b/app/Plugin/Tags/Docs/Home.md @@ -0,0 +1,27 @@ +Home +==== + +The tags plugin includes the Taggable Behavior that allows you to simply tag everything. + +It saves all tags in a tags table and connects any kind of records to them through the tagged table. + +Requirements +------------ + +* CakePHP 2.5+ +* PHP 5.2.8+ + +Documentation +------------- + +* [Overview](Documentation/Overview.md) +* [Installation](Documentation/Installation.md) +* [Configuration](Documentation/Configuration.md) +* [The Tag Cloud Helper](Documentation/The-Tag-Cloud-Helper.md) + +Tutorials +--------- + +* [Quick Start](Tutorials/Quick-Start.md) +* [Find Tagged Objects](Tutorials/Find-Tagged-Objects.md) +* [Manage Tags](Tutorials/Manage-Tags.md) diff --git a/app/Plugin/Tags/Docs/Tutorials/Find-Tagged-Objects.md b/app/Plugin/Tags/Docs/Tutorials/Find-Tagged-Objects.md new file mode 100755 index 0000000..708c42e --- /dev/null +++ b/app/Plugin/Tags/Docs/Tutorials/Find-Tagged-Objects.md @@ -0,0 +1,34 @@ +Find Tagged Objects +=================== + +The Tagged model has a custom ```_findTagged()``` method to find or paginate objects tagged with a given tag. + +Find usage examples +------------------- + +* To find all Articles having at least one Tag the call would be: ```$this->Tagged->find('tagged', array('model' => 'Article'));``` +* To find all Articles tagged _cakephp_ the call would be: ```$this->Tagged->find('tagged', array('by' => 'cakephp', 'model' => 'Article'));``` + +Pagination usage example +------------------------ + +You can also use this custom find method with paginated results. It is expected that you know how CakePHPs ```Model::find()``` and costume find methods work. + +Below is a complete example of using the ```_findTagged``` method with pagination to filter elements by tag: + +```php +public function index() { + if (isset($this->passedArgs['by'])) { + $this->paginate['Tagged'] = array( + 'tagged', + 'model' => 'Recipe', + 'by' => $this->passedArgs['by']); + $recipes = $this->paginate('Tagged'); + } else { + $this->Recipe->recursive = 1; + $recipes = $this->paginate(); + } + $this->set('recipes', $recipes); + $this->set('tags', $this->Recipe->Tagged->find('cloud', array('limit' => 10))); +} +``` diff --git a/app/Plugin/Tags/Docs/Tutorials/Manage-Tags.md b/app/Plugin/Tags/Docs/Tutorials/Manage-Tags.md new file mode 100755 index 0000000..450e1d6 --- /dev/null +++ b/app/Plugin/Tags/Docs/Tutorials/Manage-Tags.md @@ -0,0 +1,26 @@ +Manage tags +=========== + +The **Tags** plugin is shipped with a TagsController allowing the administrator to perform generic administrative tasks on Tags. + +To link these actions, use a classic CakePHP array formatted url: + +```php +echo $this->Html->link(__('List Tags'), array( + 'plugin' => 'tags', + 'controller' => 'tags', + 'action' => 'index' +)); +``` + +The available actions are: + +* index(), +* view($keyName = null), +* admin_index(), +* admin_view($keyName), +* admin_add(), +* admin_edit($tagId = null), +* admin_delete($id = null) + +Note: rename these method names if you use a different admin prefix. \ No newline at end of file diff --git a/app/Plugin/Tags/Docs/Tutorials/Quick-Start.md b/app/Plugin/Tags/Docs/Tutorials/Quick-Start.md new file mode 100755 index 0000000..2fb8d73 --- /dev/null +++ b/app/Plugin/Tags/Docs/Tutorials/Quick-Start.md @@ -0,0 +1,28 @@ +Quick Start +=========== + +Make sure the plugin is loaded in the application. + +```php +CakePlugin::load('Tags'); +// or +CakePlugin::loadAll(); +``` + +Add the behavior to your model class. + +```php +public $actsAs = array( + 'Tags.Taggable' +); +``` + +In your edit and add form add this input + +```php +$this->Form->input('tags'); +``` + +You can now save comma separated tags in this field. + +That's all you need if you want to use the plugin out of the box without customization. diff --git a/app/Plugin/Tags/Locale/deu/LC_MESSAGES/tags.po b/app/Plugin/Tags/Locale/deu/LC_MESSAGES/tags.po old mode 100644 new mode 100755 diff --git a/app/Plugin/Tags/Locale/fre/LC_MESSAGES/tags.po b/app/Plugin/Tags/Locale/fre/LC_MESSAGES/tags.po old mode 100644 new mode 100755 diff --git a/app/Plugin/Tags/Locale/por/LC_MESSAGES/tags.po b/app/Plugin/Tags/Locale/por/LC_MESSAGES/tags.po old mode 100644 new mode 100755 diff --git a/app/Plugin/Tags/Locale/rus/LC_MESSAGES/tags.po b/app/Plugin/Tags/Locale/rus/LC_MESSAGES/tags.po old mode 100644 new mode 100755 diff --git a/app/Plugin/Tags/Locale/sau/LC_MESSAGES/tags.mo b/app/Plugin/Tags/Locale/sau/LC_MESSAGES/tags.mo new file mode 100755 index 0000000000000000000000000000000000000000..5524e8cde9342c5df6a1ca569c74d31ba6bdb690 GIT binary patch literal 1602 zcmZ9KPi$009LGlifdv$?D5B^ju%sN`vI_!b>k|tUv!SgGEZ|M1eZ%&d?R%T|W?On} zZ42ogZfcCd(uQVTK>}#Po#2HFGZ#4;Z-(H_gWuo0X^FRJ;6rdT_z0xB zPaU6u8=(IQQvTl{_4~*1UvLfdHTY2edXVaMfE52BxC7kdbRVSr<4&)DRDS>*!fqG9 zZO|Ve`AzV5uoHX+QoRl9vivO|?bQKNzYoAI;69M*9dY~=d>eWNd<(n?Qk-)76iD-2 z2RDJ=fK+e6+3$dq|EuE@km~;h?gF2KwD(pNp}bun>79;;K=&`Rdtp6>6!r%0JGl1E zz^%BHzY~`Z^`!miyqke_fOu|uUdNaAp;?v>%}aAtm~>aR!PN} z%*2#cMqy++e+#h`M(wPDax*j~Z4@{lncn6aCJ}_lx`(FLJnjzXY+A zi3cDaATeJm7C-S1^1XXA`D4FC83$KhG9dM093xpkD|Q?(3GBGt;X?a-i0I-8Pe}1ly472WC#Ux&FnDw}dHa4r(}wV)J^* z%rP?s;YXBM$a=tUqgOSvSuCG&?1%ok#jsmj-=;X`cB7G(mmvH9&FFW}mR)`cn(rz- o$u#=6xXXSy%odu__skXD#_+c4&t}$&v;YiqnSxpLO*6&*10-|Q;Q#;t literal 0 HcmV?d00001 diff --git a/app/Plugin/Tags/Locale/sau/LC_MESSAGES/tags.po b/app/Plugin/Tags/Locale/sau/LC_MESSAGES/tags.po new file mode 100755 index 0000000..de4dba7 --- /dev/null +++ b/app/Plugin/Tags/Locale/sau/LC_MESSAGES/tags.po @@ -0,0 +1,140 @@ +msgid "" +msgstr "" +"Project-Id-Version: CakePHP Tags Plugin\n" +"POT-Creation-Date: 2016-01-13 23:09+0200\n" +"PO-Revision-Date: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Last-Translator: Essam Ay \n" +"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n" +"%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n" +"Language: ar_SA\n" + +# LANGUAGE translation of the CakePHP Tags plugin +# +# Copyright 2010, Cake Development Corporation (http://cakedc.com) +# +# Licensed under The MIT License +# Redistributions of files must retain the above copyright notice. +# +# @copyright Copyright 2010, Cake Development Corporation (http://cakedc.com) +# @license MIT License (http://www.opensource.org/licenses/mit-license.php) +# +# +#: /controllers/tags_controller.php:105 +msgid "The Tags has been saved." +msgstr "لقد تم حفظ الوسم" + +#: /controllers/tags_controller.php:122 +msgid "Tag saved." +msgstr "تم حفظ الوسم" + +#: /controllers/tags_controller.php:146 +msgid "Tag deleted." +msgstr "تم حذف الوسم" + +#: /controllers/tags_controller.php:148 /models/tag.php:77;119 +msgid "Invalid Tag." +msgstr "وسم غير صالح" + +#: /views/tags/admin_add.ctp:16 +msgid "Add %s" +msgstr "إضافة وسم" + +#: /views/tags/admin_add.ctp:16 /views/tags/admin_edit.ctp:16 +#: /views/tags/admin_index.ctp:78 /views/tags/admin_view.ctp:14;55;56;58 +#: /views/tags/view.ctp:14 +msgid "Tag" +msgstr "وسم" + +#: /views/tags/admin_add.ctp:21 /views/tags/admin_edit.ctp:24 +msgid "Submit" +msgstr "إرسال" + +#: /views/tags/admin_add.ctp:25 /views/tags/admin_edit.ctp:29 +#: /views/tags/admin_view.ctp:57 /views/tags/view.ctp:55 +msgid "List %s" +msgstr "قائمة %s" + +#: /views/tags/admin_add.ctp:25 /views/tags/admin_edit.ctp:29 +#: /views/tags/admin_index.ctp:14 /views/tags/admin_view.ctp:57 +#: /views/tags/index.ctp:14 /views/tags/view.ctp:55 +msgid "Tags" +msgstr "وسوم" + +#: /views/tags/admin_edit.ctp:16 /views/tags/admin_view.ctp:55 +msgid "Edit %s" +msgstr "تعديل %s" + +#: /views/tags/admin_edit.ctp:28 /views/tags/admin_index.ctp:65 +msgid "Delete" +msgstr "حذف" + +#: /views/tags/admin_edit.ctp:28 /views/tags/admin_index.ctp:65 +#: /views/tags/admin_view.ctp:56 +msgid "Are you sure you want to delete # %s?" +msgstr "هل أنت متأكد من حذف #%s؟" + +#: /views/tags/admin_index.ctp:18 /views/tags/index.ctp:18 +msgid "" +"Page %page% of %pages%, showing %current% records out of %count% total, " +"starting on record %start%, ending on %end%" +msgstr "" + +#: /views/tags/admin_index.ctp:30 /views/tags/index.ctp:30 +msgid "Actions" +msgstr "الإجراءات" + +#: /views/tags/admin_index.ctp:63 /views/tags/index.ctp:63 +msgid "View" +msgstr "المظهر" + +#: /views/tags/admin_index.ctp:64 +msgid "Edit" +msgstr "تعديل" + +#: /views/tags/admin_index.ctp:72 /views/tags/index.ctp:70 +msgid "previous" +msgstr "السابق" + +#: /views/tags/admin_index.ctp:74 /views/tags/index.ctp:72 +msgid "next" +msgstr "التالي" + +#: /views/tags/admin_index.ctp:78 /views/tags/admin_view.ctp:58 +msgid "New %s" +msgstr "%s جديد" + +#: /views/tags/admin_view.ctp:16 /views/tags/view.ctp:16 +msgid "Id" +msgstr "معرف" + +#: /views/tags/admin_view.ctp:21 /views/tags/view.ctp:21 +msgid "Identifier" +msgstr "معرف" + +#: /views/tags/admin_view.ctp:26 /views/tags/view.ctp:26 +msgid "Name" +msgstr "اسم" + +#: /views/tags/admin_view.ctp:31 /views/tags/view.ctp:31 +msgid "Keyname" +msgstr "اسم مفتاحي" + +#: /views/tags/admin_view.ctp:36 /views/tags/view.ctp:36 +msgid "Weight" +msgstr "الوزن" + +#: /views/tags/admin_view.ctp:41 /views/tags/view.ctp:41 +msgid "Created" +msgstr "تم" + +#: /views/tags/admin_view.ctp:46 /views/tags/view.ctp:46 +msgid "Modified" +msgstr "تم التعديل" + +#: /views/tags/admin_view.ctp:56 +msgid "Delete %s" +msgstr "حذف %s" diff --git a/app/Plugin/Tags/Locale/spa/LC_MESSAGES/tags.po b/app/Plugin/Tags/Locale/spa/LC_MESSAGES/tags.po old mode 100644 new mode 100755 diff --git a/app/Plugin/Tags/Locale/tags.pot b/app/Plugin/Tags/Locale/tags.pot old mode 100644 new mode 100755 diff --git a/app/Plugin/Tags/Model/Behavior/TaggableBehavior.php b/app/Plugin/Tags/Model/Behavior/TaggableBehavior.php old mode 100644 new mode 100755 index 12d6294..c2fa759 --- a/app/Plugin/Tags/Model/Behavior/TaggableBehavior.php +++ b/app/Plugin/Tags/Model/Behavior/TaggableBehavior.php @@ -1,13 +1,14 @@ 'tag_id', 'cacheOccurrence' => true, 'automaticTagging' => true, + 'taggedCounter' => false, 'unsetInAfterFind' => false, 'resetBinding' => false, - 'taggedCounter' => false); + 'deleteTagsOnEmptyField' => false, + ); /** * Setup * - * @param AppModel $Model - * @param array $settings + * @param Model $model Model instance that behavior is attached to + * @param array $config Configuration settings from model + * @return void */ - public function setup(Model $Model, $settings = array()) { - if (!isset($this->settings[$Model->alias])) { - $this->settings[$Model->alias] = $this->_defaults; + public function setup(Model $model, $config = array()) { + if (!isset($this->settings[$model->alias])) { + $this->settings[$model->alias] = $this->_defaults; } - $this->settings[$Model->alias] = array_merge($this->settings[$Model->alias], $settings); - $this->settings[$Model->alias]['withModel'] = $this->settings[$Model->alias]['taggedClass']; - extract($this->settings[$Model->alias]); + $this->settings[$model->alias] = array_merge($this->settings[$model->alias], $config); + $this->settings[$model->alias]['withModel'] = $this->settings[$model->alias]['taggedClass']; + $this->bindTagAssociations($model); + } - $Model->bindModel(array('hasAndBelongsToMany' => array( - $tagAlias => array( - 'className' => $tagClass, - 'foreignKey' => $foreignKey, - 'associationForeignKey' => $associationForeignKey, - 'unique' => true, - 'conditions' => array( - 'Tagged.model' => $Model->name), - 'fields' => '', - 'dependent' => true, - 'with' => $withModel))), $resetBinding); - - $Model->$tagAlias->bindModel(array('hasMany' => array( - $taggedAlias => array( - 'className' => $taggedClass))), $resetBinding); +/** + * Bind tag assocations + * + * @param Model $model Model instance that behavior is attached to + * @return void + */ + public function bindTagAssociations(Model $model) { + extract($this->settings[$model->alias]); + + list($plugin, $withClass) = pluginSplit($withModel, true); + $model->bindModel(array( + 'hasAndBelongsToMany' => array( + $tagAlias => array( + 'className' => $tagClass, + 'foreignKey' => $foreignKey, + 'associationForeignKey' => $associationForeignKey, + 'unique' => true, + 'conditions' => array( + $withClass . '.model' => $model->name + ), + 'fields' => '', + 'dependent' => true, + 'with' => $withModel + ) + ) + ), $resetBinding); + + $model->$tagAlias->bindModel(array( + 'hasMany' => array( + $taggedAlias => array( + 'className' => $taggedClass + ) + ) + ), $resetBinding); } /** * Disassembles the incoming tag string by its separator and identifiers and trims the tags * - * @param object $Model Model instance + * @param Model $model Model instance * @param string $string incoming tag string - * @param striing $separator separator character + * @param string $separator separator character * @return array Array of 'tags' and 'identifiers', use extract to get both vars out of the array if needed */ - public function disassembleTags(Model $Model, $string = '', $separator = ',') { + public function disassembleTags(Model $model, $string = '', $separator = ',') { $array = explode($separator, $string); $tags = $identifiers = array(); @@ -109,8 +136,8 @@ public function disassembleTags(Model $Model, $string = '', $separator = ',') { } $tag = trim($tag); if (!empty($tag)) { - $key = $this->multibyteKey($Model, $tag); - if (empty($tags[$key])) { + $key = $this->multibyteKey($model, $tag); + if (empty($tags[$key]) && (empty($identifiers[$key]) || !in_array($identifier, $identifiers[$key]))) { $tags[] = array('name' => $tag, 'identifier' => $identifier, 'keyname' => $key); $identifiers[$key][] = $identifier; } @@ -123,34 +150,43 @@ public function disassembleTags(Model $Model, $string = '', $separator = ',') { /** * Saves a string of tags * - * @param AppModel $Model + * @param Model $model Model instance that behavior is attached to * @param string $string comma separeted list of tags to be saved - * Tags can contain special tokens called `identifiers´ to namespace tags or classify them into catageories. - * A valid string is "foo, bar, cakephp:special". The token `cakephp´ will end up as the identifier or category for the tag `special´ + * Tags can contain special tokens called `identifiers´ to namespace tags or classify them into catageories. + * A valid string is "foo, bar, cakephp:special". The token `cakephp´ will end up as the identifier or category for the tag `special´ * @param mixed $foreignKey the identifier for the record to associate the tags with - * @param boolean $update true will remove tags that are not in the $string, false wont - * do this and just add new tags without removing existing tags associated to - * the current set foreign key + * @param bool $update True will remove tags that are not in the $string, false won't + * do this and just add new tags without removing existing tags associated to + * the current set foreign key * @return array */ - public function saveTags(Model $Model, $string = null, $foreignKey = null, $update = true) { + public function saveTags(Model $model, $string = null, $foreignKey = null, $update = true) { if (is_string($string) && !empty($string) && (!empty($foreignKey) || $foreignKey === false)) { - $tagAlias = $this->settings[$Model->alias]['tagAlias']; - $taggedAlias = $this->settings[$Model->alias]['taggedAlias']; - $tagModel = $Model->{$tagAlias}; + $tagAlias = $this->settings[$model->alias]['tagAlias']; + $taggedAlias = $this->settings[$model->alias]['taggedAlias']; + $tagModel = $model->{$tagAlias}; - extract($this->disassembleTags($Model, $string, $this->settings[$Model->alias]['separator'])); + extract($this->disassembleTags($model, $string, $this->settings[$model->alias]['separator'])); if (!empty($tags)) { + $conditions = array(); + foreach ($tags as $tag) { + $conditions['OR'][] = array( + $tagModel->alias . '.identifier' => $tag['identifier'], + $tagModel->alias . '.keyname' => $tag['keyname'], + ); + } $existingTags = $tagModel->find('all', array( 'contain' => array(), - 'conditions' => array( - $tagAlias . '.keyname' => Set::extract($tags, '{n}.keyname')), + 'conditions' => $conditions, 'fields' => array( - $tagAlias . '.identifier', - $tagAlias . '.keyname', - $tagAlias . '.name', - $tagAlias . '.id'))); + $tagModel->alias . '.identifier', + $tagModel->alias . '.keyname', + $tagModel->alias . '.name', + $tagModel->alias . '.id' + ) + )); + if (!empty($existingTags)) { foreach ($existingTags as $existing) { $existingTagKeyNames[] = $existing[$tagAlias]['keyname']; @@ -158,7 +194,7 @@ public function saveTags(Model $Model, $string = null, $foreignKey = null, $upda $existingTagIdentifiers[$existing[$tagAlias]['keyname']][] = $existing[$tagAlias]['identifier']; } $newTags = array(); - foreach($tags as $possibleNewTag) { + foreach ($tags as $possibleNewTag) { $key = $possibleNewTag['keyname']; if (!in_array($key, $existingTagKeyNames)) { array_push($newTags, $possibleNewTag); @@ -176,8 +212,9 @@ public function saveTags(Model $Model, $string = null, $foreignKey = null, $upda } foreach ($newTags as $key => $newTag) { $tagModel->create(); - $tagModel->save($newTag); - $newTagIds[] = $tagModel->id; + if ($tagModel->save($newTag)) { + $newTagIds[] = $tagModel->getLastInsertId(); + } } if ($foreignKey !== false) { @@ -187,15 +224,16 @@ public function saveTags(Model $Model, $string = null, $foreignKey = null, $upda $tagged = $tagModel->{$taggedAlias}->find('all', array( 'contain' => array(), 'conditions' => array( - $taggedAlias . '.model' => $Model->name, + $taggedAlias . '.model' => $model->name, $taggedAlias . '.foreign_key' => $foreignKey, $taggedAlias . '.language' => Configure::read('Config.language'), $taggedAlias . '.tag_id' => $existingTagIds), - 'fields' => 'Tagged.tag_id')); + 'fields' => $taggedAlias . '.tag_id' + )); $deleteAll = array( $taggedAlias . '.foreign_key' => $foreignKey, - $taggedAlias . '.model' => $Model->name); + $taggedAlias . '.model' => $model->name); if (!empty($tagged)) { $alreadyTagged = Set::extract($tagged, "{n}.{$taggedAlias}.tag_id"); @@ -203,26 +241,30 @@ public function saveTags(Model $Model, $string = null, $foreignKey = null, $upda $deleteAll['NOT'] = array($taggedAlias . '.tag_id' => $alreadyTagged); } - $newTagIds = $oldTagIds = array(); + $oldTagIds = array(); if ($update == true) { $oldTagIds = $tagModel->{$taggedAlias}->find('all', array( 'contain' => array(), 'conditions' => array( - $taggedAlias . '.model' => $Model->name, + $taggedAlias . '.model' => $model->name, $taggedAlias . '.foreign_key' => $foreignKey, $taggedAlias . '.language' => Configure::read('Config.language')), - 'fields' => 'Tagged.tag_id')); + 'fields' => $taggedAlias . '.tag_id' + )); - $oldTagIds = Set::extract($oldTagIds, '/Tagged/tag_id'); + $oldTagIds = Set::extract($oldTagIds, '/' . $taggedAlias . '/tag_id'); $tagModel->{$taggedAlias}->deleteAll($deleteAll, false); - } elseif ($this->settings[$Model->alias]['taggedCounter'] && !empty($alreadyTagged)) { - $tagModel->{$taggedAlias}->updateAll(array('times_tagged' => 'times_tagged + 1'), array('Tagged.tag_id' => $alreadyTagged)); + } elseif ($this->settings[$model->alias]['taggedCounter'] && !empty($alreadyTagged)) { + $tagModel->{$taggedAlias}->updateAll( + array('times_tagged' => 'times_tagged + 1'), + array($taggedAlias . '.tag_id' => $alreadyTagged) + ); } foreach ($existingTagIds as $tagId) { $data[$taggedAlias]['tag_id'] = $tagId; - $data[$taggedAlias]['model'] = $Model->name; + $data[$taggedAlias]['model'] = $model->name; $data[$taggedAlias]['foreign_key'] = $foreignKey; $data[$taggedAlias]['language'] = Configure::read('Config.language'); $tagModel->{$taggedAlias}->create($data); @@ -230,19 +272,21 @@ public function saveTags(Model $Model, $string = null, $foreignKey = null, $upda } //To update occurrence - if ($this->settings[$Model->alias]['cacheOccurrence']) { + if ($this->settings[$model->alias]['cacheOccurrence']) { $newTagIds = $tagModel->{$taggedAlias}->find('all', array( 'contain' => array(), 'conditions' => array( - $taggedAlias . '.model' => $Model->name, + $taggedAlias . '.model' => $model->name, $taggedAlias . '.foreign_key' => $foreignKey, $taggedAlias . '.language' => Configure::read('Config.language')), - 'fields' => 'Tagged.tag_id')); + 'fields' => $taggedAlias . '.tag_id' + )); - $newTagIds = Set::extract($newTagIds, '{n}.Tagged.tag_id'); - $tagIds = array_merge($oldTagIds, $newTagIds); + if (!empty($newTagIds)) { + $newTagIds = Set::extract($newTagIds, '{n}.' . $taggedAlias . '.tag_id'); + } - $this->cacheOccurrence($Model, $tagIds); + $this->cacheOccurrence($model, array_merge($oldTagIds, $newTagIds)); } } } @@ -254,47 +298,58 @@ public function saveTags(Model $Model, $string = null, $foreignKey = null, $upda /** * Cache the weight or occurence of a tag in the tags table * - * @param object $Model instance of a model - * @param string $tagId Tag UUID + * @param Model $model Model instance that behavior is attached to + * @param int|string|array $tagIds Tag ID or list of tag IDs * @return void */ - public function cacheOccurrence(Model $Model, $tagIds) { - if (is_string($tagIds) || is_int($tagIds)) { + public function cacheOccurrence(Model $model, $tagIds) { + if (!is_array($tagIds)) { $tagIds = array($tagIds); } + $tagAlias = $this->settings[$model->alias]['tagAlias']; + $taggedAlias = $this->settings[$model->alias]['taggedAlias']; + + $tagModel = $model->{$tagAlias}; + $taggedModel = $tagModel->{$taggedAlias}; + + $fieldName = Inflector::underscore($model->name) . '_occurrence'; foreach ($tagIds as $tagId) { - $fieldName = Inflector::underscore($Model->name) . '_occurrence'; - $tagModel = $Model->{$this->settings[$Model->alias]['tagAlias']}; - $taggedModel = $tagModel->{$this->settings[$Model->alias]['taggedAlias']}; - $data = array('id' => $tagId); + $data = array($tagModel->primaryKey => $tagId); if ($tagModel->hasField($fieldName)) { $data[$fieldName] = $taggedModel->find('count', array( 'conditions' => array( - 'Tagged.tag_id' => $tagId, - 'Tagged.model' => $Model->name))); + $taggedAlias . '.tag_id' => $tagId, + $taggedAlias . '.model' => $model->name + ) + )); } $data['occurrence'] = $taggedModel->find('count', array( 'conditions' => array( - 'Tagged.tag_id' => $tagId))); - $tagModel->save($data, array('validate' => false, 'callbacks' => false)); + $taggedAlias . '.tag_id' => $tagId + ) + )); + $tagModel->save($data, array( + 'validate' => false, + 'callbacks' => false, + )); } } /** * Creates a multibyte safe unique key * - * @param object Model instance - * @param string Tag name string + * @param Model $model Model instance that behavior is attached to + * @param string $string Tag name string * @return string Multibyte safe key string */ - public function multibyteKey(Model $Model, $string = null) { + public function multibyteKey(Model $model, $string = null) { $str = mb_strtolower($string); $str = preg_replace('/\xE3\x80\x80/', ' ', $str); $str = str_replace(array('_', '-'), '', $str); - $str = preg_replace( '#[:\#\*"()~$^{}`@+=;,<>!&%\.\]\/\'\\\\|\[]#', "\x20", $str ); + $str = preg_replace('#[:\#\*"()~$^{}`@+=;,<>!&%\.\]\/\'\\\\|\[]#', "\x20", $str); $str = str_replace('?', '', $str); $str = trim($str); $str = preg_replace('#\x20+#', '', $str); @@ -306,18 +361,28 @@ public function multibyteKey(Model $Model, $string = null) { * initialization of data for text input * * Example usage (only 'Tag.name' field is needed inside of method): + * * * $this->Blog->hasAndBelongsToMany['Tag']['fields'] = array('name', 'keyname'); * $blog = $this->Blog->read(null, 123); * $blog['Blog']['tags'] = $this->Blog->Tag->tagArrayToString($blog['Tag']); * * - * @param array $string + * @param Model $model Model instance that behavior is attached to + * @param array $data Tag data array * @return string */ - public function tagArrayToString(Model $Model, $data = null) { + public function tagArrayToString(Model $model, $data = null) { if ($data) { - return join($this->settings[$Model->alias]['separator'].' ', Set::extract($data, '{n}.name')); + $tags = array(); + foreach ($data as $tag) { + if (!empty($tag['identifier'])) { + $tags[] = $tag['identifier'] . ':' . $tag['name']; + } else { + $tags[] = $tag['name']; + } + } + return join($this->settings[$model->alias]['separator'] . ' ', $tags); } return ''; } @@ -325,28 +390,65 @@ public function tagArrayToString(Model $Model, $data = null) { /** * afterSave callback * - * @param AppModel $Model + * @param Model $model Model instance that behavior is attached to + * @param bool $created True if this save created a new record + * @param array $options Options passed from Model::save() + * @return void */ - public function afterSave(Model $Model) { - if ($this->settings[$Model->alias]['automaticTagging'] == true && !empty($Model->data[$Model->alias][$this->settings[$Model->alias]['field']])) { - $this->saveTags($Model, $Model->data[$Model->alias][$this->settings[$Model->alias]['field']], $Model->id); + public function afterSave(Model $model, $created, $options = array()) { + if (!isset($model->data[$model->alias][$this->settings[$model->alias]['field']])) { + return; + } + $field = $model->data[$model->alias][$this->settings[$model->alias]['field']]; + $hasTags = !empty($field); + if ($this->settings[$model->alias]['automaticTagging'] === true && $hasTags) { + $this->saveTags($model, $field, $model->id); + } elseif (!$hasTags && $this->settings[$model->alias]['deleteTagsOnEmptyField']) { + $this->deleteTagged($model); } } +/** + * Delete associated Tags if record has no tags and deleteTagsOnEmptyField is true + * + * @param Model $model Model instance that behavior is attached to + * @param mixed $id Foreign key of the model, string for UUID or integer + * @return void + */ + public function deleteTagged(Model $model, $id = null) { + extract($this->settings[$model->alias]); + $tagModel = $model->{$tagAlias}; + if (is_null($id)) { + $id = $model->id; + } + $tagModel->{$taggedAlias}->deleteAll( + array( + $taggedAlias . '.model' => $model->name, + $taggedAlias . '.foreign_key' => $id, + ) + ); + } + /** * afterFind Callback * - * @param AppModel $Model - * @param array $results - * @param boolean $primary + * @param Model $model Model instance that behavior is attached to + * @param mixed $results The results of the find operation + * @param bool $primary Whether this model is being queried directly (vs. being queried as an association) * @return array */ - public function afterFind(Model $Model, $results, $primary) { - extract($this->settings[$Model->alias]); + public function afterFind(Model $model, $results, $primary = false) { + extract($this->settings[$model->alias]); + + list($plugin, $class) = pluginSplit($tagClass); + if ($model->name === $class) { + return $results; + } + foreach ($results as $key => $row) { - $row[$Model->alias][$field] = ''; + $row[$model->alias][$field] = ''; if (isset($row[$tagAlias]) && !empty($row[$tagAlias])) { - $row[$Model->alias][$field] = $this->tagArrayToString($Model, $row[$tagAlias]); + $row[$model->alias][$field] = $this->tagArrayToString($model, $row[$tagAlias]); if ($unsetInAfterFind == true) { unset($row[$tagAlias]); } @@ -355,4 +457,5 @@ public function afterFind(Model $Model, $results, $primary) { } return $results; } + } diff --git a/app/Plugin/Tags/Model/Tag.php b/app/Plugin/Tags/Model/Tag.php old mode 100644 new mode 100755 index 0608b63..38baf5e --- a/app/Plugin/Tags/Model/Tag.php +++ b/app/Plugin/Tags/Model/Tag.php @@ -1,13 +1,14 @@ array( 'className' => 'Tags.Tagged', - 'foreignKey' => 'tag_id')); + 'foreignKey' => 'tag_id' + ) + ); /** * HABTM associations @@ -47,42 +43,63 @@ class Tag extends TagsAppModel { * @var array */ public $validate = array( - 'name' => array('rule' => 'notEmpty'), - 'keyname' => array('rule' => 'notEmpty')); + 'name' => array('rule' => 'notBlank'), + 'keyname' => array('rule' => 'notBlank') + ); + +/** + * Custom validation for keeping BC to CakePHP version below 2.7 + * + * @param array $check + * @return bool + */ + public function notBlank($check) { + $value = array_values($check); + $value = $value[0]; + if (method_exists('Validation', 'notBlank')) { + return Validation::notBlank($value); + } else { + // below 2.7 + return Validation::notEmpty($value); + } + } /** * Returns the data for a single tag * - * @param string keyname + * @param string $keyName Tag key name + * @throws CakeException * @return array */ public function view($keyName = null) { $result = $this->find('first', array( 'conditions' => array( - $this->alias . '.keyname' => $keyName))); + $this->alias . '.keyname' => $keyName + ) + )); if (empty($result)) { - throw new Exception(__d('tags', 'Invalid Tag.')); + throw new CakeException(__d('tags', 'Invalid Tag.')); } return $result; } - /** * Pre-populates the tag table with entered tags * - * @param array post data, should be Contoller->data - * @return boolean + * @param array $postData Post data, should be Contoller->data + * @return bool */ public function add($postData = null) { if (isset($postData[$this->alias]['tags'])) { - $this->Behaviors->attach('Tags.Taggable', array( + $this->Behaviors->load('Tags.Taggable', array( 'resetBinding' => true, - 'automaticTagging' => false)); + 'automaticTagging' => false + )); $this->Tag = $this; $result = $this->saveTags($postData[$this->alias]['tags'], false, false); unset($this->Tag); - $this->Behaviors->detach('Tags.Taggable'); + $this->Behaviors->unload('Tags.Taggable'); return $result; } } @@ -90,19 +107,22 @@ public function add($postData = null) { /** * Edits an existing tag, allows only to modify upper/lowercased characters * - * @param string tag uuid - * @param array controller post data usually $this->request->data + * @param string $tagId Tag UUID + * @param array $postData Controller post data usually $this->request->data + * @throws CakeException * @return mixed True on successfully save else post data as array */ public function edit($tagId = null, $postData = null) { $tag = $this->find('first', array( 'contain' => array(), 'conditions' => array( - $this->alias . '.' . $this->primaryKey => $tagId))); + $this->alias . '.' . $this->primaryKey => $tagId + ) + )); $this->set($tag); if (empty($tag)) { - throw new Exception(__d('tags', 'Invalid Tag.')); + throw new CakeException(__d('tags', 'Invalid Tag.')); } if (!empty($postData[$this->alias]['name'])) { @@ -119,4 +139,5 @@ public function edit($tagId = null, $postData = null) { } } } + } diff --git a/app/Plugin/Tags/Model/Tagged.php b/app/Plugin/Tags/Model/Tagged.php old mode 100644 new mode 100755 index 0bba38c..4f0ae38 --- a/app/Plugin/Tags/Model/Tagged.php +++ b/app/Plugin/Tags/Model/Tagged.php @@ -1,13 +1,14 @@ true, - 'tagged' => true); + 'tagged' => true + ); /** * belongsTo associations @@ -47,25 +42,27 @@ class Tagged extends TagsAppModel { */ public $belongsTo = array( 'Tag' => array( - 'className' => 'Tags.Tag')); + 'className' => 'Tags.Tag' + ) + ); /** * Returns a tag cloud * * The result contains a "weight" field which has a normalized size of the tag - * occurrence set. The min and max size can be set by passing 'minSize" and - * 'maxSize' to the query. This value can be used in the view to controll the + * occurrence set. The min and max size can be set by passing 'minSize' and + * 'maxSize' to the query. This value can be used in the view to control the * size of the tag font. * + * @param string $state State string ('before' or 'after') + * @param array $query Query array + * @param array $results Result set for 'after' state * @todo Ideas to improve this are welcome - * @param string $state - * @param array $query - * @param array $results * @return array * @link https://github.com/CakeDC/tags/issues/10 */ public function _findCloud($state, $query, $results = array()) { - if ($state == 'before') { + if ($state === 'before') { // Support old code without the occurrence cache if (!$this->Tag->hasField('occurrence') || isset($query['occurrenceCache']) && $query['occurrenceCache'] === false) { $fields = 'Tagged.tag_id, Tag.id, Tag.identifier, Tag.name, Tag.keyname, Tag.weight, COUNT(*) AS occurrence'; @@ -88,7 +85,8 @@ public function _findCloud($state, $query, $results = array()) { 'contain' => 'Tag', 'conditions' => array(), 'fields' => $fields, - 'group' => $groupBy); + 'group' => $groupBy + ); foreach ($query as $key => $value) { if (!empty($value)) { @@ -135,22 +133,24 @@ public function _findCloud($state, $query, $results = array()) { /** * Find all the Model entries tagged with a given tag - * + * * The query must contain a Model name, and can contain a 'by' key with the Tag keyname to filter the results + * * * $this->Article->Tagged->find('tagged', array( * 'by' => 'cakephp', * 'model' => 'Article')); - * * - * @TODO Find a way to populate the "magic" field Article.tags - * @param string $state - * @param array $query - * @param array $results + * @param string $state State string ('before' or 'after') + * @param array $query Query array + * @param array $results Result set for 'after' state + * @todo Find a way to populate the "magic" field Article.tags + * @throws InvalidArgumentException if recursive setting is -1 * @return mixed Query array if state is before, array of results or integer (count) if state is after */ public function _findTagged($state, $query, $results = array()) { - if ($state == 'before') { + if ($state === 'before') { if (isset($query['model']) && $Model = ClassRegistry::init($query['model'])) { $this->bindModel(array( 'belongsTo' => array( @@ -159,7 +159,11 @@ public function _findTagged($state, $query, $results = array()) { 'foreignKey' => 'foreign_key', 'type' => 'INNER', 'conditions' => array( - $this->alias . '.model' => $Model->alias)))), false); + $this->alias . '.model' => $Model->alias + ) + ) + ) + ), false); if (!isset($query['recursive'])) { $query['recursive'] = 0; @@ -173,7 +177,11 @@ public function _findTagged($state, $query, $results = array()) { $query['fields'] = "COUNT(DISTINCT $Model->alias.$Model->primaryKey)"; $this->Behaviors->Containable->setup($this, array('autoFields' => false)); } else { - $query['fields'][] = "DISTINCT " . join(',', $this->getDataSource()->fields($Model)); + if ($query['fields'] === null) { + $query['fields'][] = "DISTINCT " . join(',', $this->getDataSource()->fields($Model)); + } else { + array_unshift($query['fields'], "DISTINCT " . join(',', $this->getDataSource()->fields($Model))); + } } if (!empty($query['by'])) { diff --git a/app/Plugin/Tags/Model/TagsAppModel.php b/app/Plugin/Tags/Model/TagsAppModel.php old mode 100644 new mode 100755 index 450c1bb..783b6e6 --- a/app/Plugin/Tags/Model/TagsAppModel.php +++ b/app/Plugin/Tags/Model/TagsAppModel.php @@ -1,14 +1,15 @@ find('count', array_merge($parameters, $extra)); } } + } diff --git a/app/Plugin/Tags/Test/Case/AllTagsPluginTest.php b/app/Plugin/Tags/Test/Case/AllTagsPluginTest.php deleted file mode 100644 index 7a9075f..0000000 --- a/app/Plugin/Tags/Test/Case/AllTagsPluginTest.php +++ /dev/null @@ -1,25 +0,0 @@ -addTestFile($basePath . 'Controller' . DS . 'TagsControllerTest.php'); - // behaviors - $suite->addTestFile($basePath . 'Behavior' . DS . 'TaggableTest.php'); - // models - $suite->addTestFile($basePath . 'Model' . DS . 'TagTest.php'); - $suite->addTestFile($basePath . 'Model' . DS . 'TaggedTest.php'); - // helpers - $suite->addTestFile($basePath . 'Helper' . DS . 'TagCloudTest.php'); - return $suite; - } - -} \ No newline at end of file diff --git a/app/Plugin/Tags/Test/Case/AllTagsTest.php b/app/Plugin/Tags/Test/Case/AllTagsTest.php new file mode 100755 index 0000000..fff711b --- /dev/null +++ b/app/Plugin/Tags/Test/Case/AllTagsTest.php @@ -0,0 +1,20 @@ +addTestDirectory($path . DS . 'Controller'); + $Suite->addTestDirectory($path . DS . 'View' . DS . 'Helper'); + $Suite->addTestDirectory($path . DS . 'Model'); + $Suite->addTestDirectory($path . DS . 'Model' . DS . 'Behavior'); + return $Suite; + } + +} \ No newline at end of file diff --git a/app/Plugin/Tags/Test/Case/Behavior/TaggableTest.php b/app/Plugin/Tags/Test/Case/Behavior/TaggableTest.php deleted file mode 100644 index f300cb1..0000000 --- a/app/Plugin/Tags/Test/Case/Behavior/TaggableTest.php +++ /dev/null @@ -1,301 +0,0 @@ -Article = ClassRegistry::init('Article'); - $this->Article->Behaviors->attach('Tags.Taggable', array()); - } - -/** - * Method executed after each test - * - * @return void - */ - public function tearDown() { - unset($this->Article); - ClassRegistry::flush(); - } - -/** - * Test the occurrence cache - * - * @return void - */ - public function testOccurrenceCache() { - $resultBefore = $this->Article->Tag->find('first', array( - 'contain' => array(), - 'conditions' => array( - 'Tag.keyname' => 'cakephp'))); - - // adding a new record with the cakephp tag to increase the occurrence - $data = array('title' => 'Test Article', 'tags' => 'cakephp, php'); - $this->Article->create(); - $this->Article->save($data, false); - - $resultAfter = $this->Article->Tag->find('first', array( - 'contain' => array(), - 'conditions' => array( - 'Tag.keyname' => 'cakephp'))); - - $this->assertEqual($resultAfter['Tag']['occurrence'] - $resultBefore['Tag']['occurrence'], 1); - - // updating the record to not have the cakephp tag anymore, decreases the occurrence - $data = array('id' => $this->Article->id, 'title' => 'Test Article', 'tags' => 'php, something, else'); - $this->Article->save($data, false); - $resultAfter = $this->Article->Tag->find('first', array( - 'contain' => array(), - 'conditions' => array( - 'Tag.keyname' => 'cakephp'))); - $this->assertEqual($resultAfter['Tag']['occurrence'], 1); - } - -/** - * Testings saving of tags trough the specified field in the tagable model - * - * @return void - */ - public function testTagSaving() { - $data['id'] = 'article-1'; - $data['tags'] = 'foo, bar, test'; - $this->Article->save($data, false); - $result = $this->Article->find('first', array( - 'conditions' => array( - 'id' => 'article-1'))); - $this->assertTrue(!empty($result['Article']['tags'])); - - $data['tags'] = 'foo, developer, developer, php'; - $this->Article->save($data, false); - $result = $this->Article->find('first', array( - 'contain' => array('Tag'), - 'conditions' => array( - 'id' => 'article-1'))); - $this->assertTrue(!empty($result['Article']['tags'])); - - - $data['tags'] = 'cakephp:foo, developer, cakephp:developer, cakephp:php'; - $this->Article->save($data, false); - $result = $this->Article->Tag->find('all', array( - 'recursive' => -1, - 'order' => 'Tag.identifier DESC', - 'conditions' => array( - 'Tag.identifier' => 'cakephp'))); - $result = Set::extract($result, '{n}.Tag.keyname'); - $this->assertEqual($result, array( - 'foo', 'developer', 'php')); - - $this->assertFalse($this->Article->saveTags('foo, bar', null)); - $this->assertFalse($this->Article->saveTags(array('foo', 'bar'), 'something')); - } - -/** - * Tests that toggling taggedCounter will update the time_tagged counter in the tagged table - * - * @return void - */ - function testSaveTimesTagged() { - $this->Article->Behaviors->Taggable->settings['Article']['taggedCounter'] = true; - $tags = 'foo, bar , test'; - $this->assertTrue($this->Article->saveTags($tags, 'article-1', false)); - $this->assertTrue($this->Article->saveTags($tags, 'article-1', false)); - - $result = $this->Article->Tagged->find('all', array( - 'conditions' => array('model' => 'Article'))); - - $fooCount = Set::extract('/Tag[keyname=foo]/../Tagged/times_tagged', $result); - $this->assertEqual($fooCount, array(2)); - - $barCount = Set::extract('/Tag[keyname=bar]/../Tagged/times_tagged', $result); - $this->assertEqual($barCount, array(2)); - - $testCount = Set::extract('/Tag[keyname=test]/../Tagged/times_tagged', $result); - $this->assertEqual($testCount, array(2)); - } - -/** - * Testings Taggable::tagArrayToString() - * - * @return void - */ - public function testTagArrayToString() { - $data['id'] = 'article-1'; - $data['tags'] = 'foo, bar, test'; - $this->Article->save($data, false); - $result = $this->Article->find('first', array( - 'conditions' => array( - 'id' => 'article-1'))); - $result = $this->Article->tagArrayToString($result['Tag']); - $this->assertTrue(!empty($result)); - $this->assertInternalType('string', $result); - - $result = $this->Article->tagArrayToString(); - $this->assertTrue(empty($result)); - $this->assertInternalType('string', $result); - } - -/** - * Testings Taggable::multibyteKey() - * - * @return void - */ - public function testMultibyteKey() { - $result = $this->Article->multibyteKey('this is _ a Nice ! - _ key!'); - $this->assertEqual('thisisanicekey', $result); - - $result = $this->Article->multibyteKey('Äü-Ü_ß'); - $this->assertEqual('äüüß', $result); - } - -/** - * testAfterFind callback method - * - * @return void - */ - public function testAfterFind() { - $data['id'] = 'article-1'; - $data['tags'] = 'foo, bar, test'; - $this->Article->save($data, false); - - $result = $this->Article->find('first', array( - 'conditions' => array( - 'id' => 'article-1'))); - $this->assertTrue(isset($result['Tag'])); - - $this->Article->Behaviors->Taggable->settings['Article']['unsetInAfterFind'] = true; - $result = $this->Article->find('first', array( - 'conditions' => array( - 'id' => 'article-1'))); - $this->assertTrue(!isset($result['Tag'])); - } - -/** - * testAfterFindFields - * - * @return void - */ - public function testAfterFindFields() { - $this->Article->Behaviors->detach('Taggable'); - $results = $this->Article->find('first', array( - 'recursive' => -1, - 'fields' => array('id'))); - $expected = array($this->Article->alias => array('id' => 'article-1')); - $this->assertIdentical($results, $expected); - } - -/** - * testGettingTagCloudThroughAssociation - * - * @link http://cakedc.lighthouseapp.com/projects/59622/tickets/6-tag-cloud-helper - * @return void - */ - public function testGettingTagCloudThroughAssociation() { - $result = $this->Article->Tagged->find('cloud'); - $this->assertTrue(is_array($result) && !empty($result)); - } - -} diff --git a/app/Plugin/Tags/Test/Case/Controller/TagsControllerTest.php b/app/Plugin/Tags/Test/Case/Controller/TagsControllerTest.php old mode 100644 new mode 100755 index db2e888..d3ab2d2 --- a/app/Plugin/Tags/Test/Case/Controller/TagsControllerTest.php +++ b/app/Plugin/Tags/Test/Case/Controller/TagsControllerTest.php @@ -1,17 +1,16 @@ redirectUrl`) + * @param int $status Optional HTTP status code (eg: 404) + * @param bool $exit If true, exit() will be called after the redirect * @return void */ public function redirect($url, $status = null, $exit = true) { @@ -47,11 +49,14 @@ public function redirect($url, $status = null, $exit = true) { /** * Override controller method for testing * + * @param string $view View to use for rendering + * @param string $layout Layout to use * @return void */ - public function render($action = null, $layout = null, $file = null) { - $this->renderedView = $action; + public function render($view = null, $layout = null) { + $this->renderedView = $view; } + } /** @@ -69,7 +74,8 @@ class TagsControllerTest extends CakeTestCase { */ public $fixtures = array( 'plugin.tags.tagged', - 'plugin.tags.tag'); + 'plugin.tags.tag' + ); /** * Tags Controller Instance @@ -84,10 +90,12 @@ class TagsControllerTest extends CakeTestCase { * @return void */ public function setUp() { + parent::setUp(); $this->Tags = new TestTagsController(new CakeRequest(null, false)); $this->Tags->params = array( 'named' => array(), - 'url' => array()); + 'url' => array() + ); $this->Tags->constructClasses(); $this->Tags->Session = $this->getMock('SessionComponent', array(), array(), '', false); } @@ -98,6 +106,7 @@ public function setUp() { * @return void */ public function tearDown() { + parent::tearDown(); unset($this->Tags); } @@ -128,10 +137,10 @@ public function testIndex() { public function testView() { $this->Tags->view('cakephp'); $this->assertTrue(!empty($this->Tags->viewVars['tag'])); - $this->assertEqual($this->Tags->viewVars['tag']['Tag']['keyname'], 'cakephp'); + $this->assertEquals($this->Tags->viewVars['tag']['Tag']['keyname'], 'cakephp'); $this->Tags->view('invalid-key-name!'); - $this->assertEqual($this->Tags->redirectUrl, '/'); + $this->assertEquals($this->Tags->redirectUrl, '/'); } /** @@ -142,10 +151,10 @@ public function testView() { public function testAdminView() { $this->Tags->admin_view('cakephp'); $this->assertTrue(!empty($this->Tags->viewVars['tag'])); - $this->assertEqual($this->Tags->viewVars['tag']['Tag']['keyname'], 'cakephp'); + $this->assertEquals($this->Tags->viewVars['tag']['Tag']['keyname'], 'cakephp'); $this->Tags->admin_view('invalid-key-name!'); - $this->assertEqual($this->Tags->redirectUrl, '/'); + $this->assertEquals($this->Tags->redirectUrl, '/'); } /** @@ -166,20 +175,19 @@ public function testAdminIndex() { public function testAdminDelete() { $this->Tags->Session->expects($this->at(0)) ->method('setFlash') - ->with($this->equalTo('Invalid Tag.')) + ->with($this->equalTo(__d('tags', 'Invalid Tag.'))) ->will($this->returnValue(true)); $this->Tags->Session->expects($this->at(1)) ->method('setFlash') - ->with($this->equalTo('Tag deleted.')) + ->with($this->equalTo(__d('tags', 'Tag deleted.'))) ->will($this->returnValue(true)); - $this->Tags->admin_delete('WRONG-ID!!!'); - $this->assertEqual($this->Tags->redirectUrl, array('action' => 'index')); + $this->assertEquals($this->Tags->redirectUrl, array('action' => 'index')); $this->Tags->admin_delete('tag-1'); - $this->assertEqual($this->Tags->redirectUrl, array('action' => 'index')); + $this->assertEquals($this->Tags->redirectUrl, array('action' => 'index')); } /** @@ -190,9 +198,20 @@ public function testAdminDelete() { public function testAdminAdd() { $this->Tags->data = array( 'Tag' => array( - 'tags' => 'tag1, tag2, tag3')); + 'tags' => 'tag1, tag2, tag3' + ) + ); + $this->Tags->admin_add(); + $this->assertEquals($this->Tags->redirectUrl, array('action' => 'index')); + + // adding same tags again. + $this->Tags->data = array( + 'Tag' => array( + 'tags' => 'tag1, tag2, tag3' + ) + ); $this->Tags->admin_add(); - $this->assertEqual($this->Tags->redirectUrl, array('action' => 'index')); + $this->assertEquals($this->Tags->redirectUrl, array('action' => 'index')); } /** @@ -204,23 +223,27 @@ public function testAdminEdit() { $this->Tags->admin_edit('tag-1'); $tag = array( 'Tag' => array( - 'id' => 'tag-1', - 'identifier' => null, - 'name' => 'CakePHP', - 'keyname' => 'cakephp', + 'id' => 'tag-1', + 'identifier' => null, + 'name' => 'CakePHP', + 'keyname' => 'cakephp', 'occurrence' => 1, 'article_occurrence' => 1, - 'created' => '2008-06-02 18:18:11', - 'modified' => '2008-06-02 18:18:37')); + 'created' => '2008-06-02 18:18:11', + 'modified' => '2008-06-02 18:18:37' + ) + ); - $this->assertEqual($this->Tags->data, $tag); + $this->assertEquals($this->Tags->data, $tag); $this->Tags->data = array( 'Tag' => array( 'id' => 'tag-1', - 'name' => 'CAKEPHP')); + 'name' => 'CAKEPHP' + ) + ); $this->Tags->admin_edit('tag-1'); - $this->assertEqual($this->Tags->redirectUrl, array('action' => 'index')); + $this->assertEquals($this->Tags->redirectUrl, array('action' => 'index')); } } diff --git a/app/Plugin/Tags/Test/Case/Helper/TagCloudTest.php b/app/Plugin/Tags/Test/Case/Helper/TagCloudTest.php deleted file mode 100644 index 770fef9..0000000 --- a/app/Plugin/Tags/Test/Case/Helper/TagCloudTest.php +++ /dev/null @@ -1,115 +0,0 @@ -View = new View($controller); - $this->TagCloud = new TagCloudHelper($this->View); - $this->TagCloud->Html = new HtmlHelper($this->View); - } - -/** - * Test display method - * - * @return void - */ - public function testDisplay() { - $this->assertEqual($this->TagCloud->display(), ''); - $tags = array( - array( - 'Tag' => array( - 'id' => 1, - 'identifier' => null, - 'name' => 'CakePHP', - 'keyname' => 'cakephp', - 'weight' => 2, - 'created' => '2008-06-02 18:18:11', - 'modified' => '2008-06-02 18:18:37')), - array( - 'Tag' => array( - 'id' => 2, - 'identifier' => null, - 'name' => 'CakeDC', - 'keyname' => 'cakedc', - 'weight' => 2, - 'created' => '2008-06-01 18:18:15', - 'modified' => '2008-06-01 18:18:15')), - ); - - // Test tags shuffling - $options = array( - 'shuffle' => true); - $expected = 'CakePHP CakeDC '; - $i = 100; - do { - $i--; - $result = $this->TagCloud->display($tags, $options); - } while ($result == $expected && $i > 0); - $this->assertNotEqual($result, $expected); - - // Test normal display - $options = array( - 'shuffle' => false); - $result = $this->TagCloud->display($tags, $options); - $this->assertEqual($result, $expected); - - // Test options - $options = array_merge($options, array( - 'before' => '', - 'after' => '', - 'maxSize' => 100, - 'minSize' => 1, - 'url' => array('controller' => 'search', 'from' => 'twitter'), - 'named' => 'query' - )); - $result = $this->TagCloud->display($tags, $options); - $expected = 'CakePHP '. - 'CakeDC '; - $this->assertEqual($result, $expected); - - $tags[1]['Tag']['weight'] = 1; - $result = $this->TagCloud->display($tags, $options); - $expected = 'CakePHP '. - 'CakeDC '; - $this->assertEqual($result, $expected); - } - -/** - * (non-PHPdoc) - * @see cake/tests/lib/CakeTestCase#tearDown($method) - */ - public function tearDown() { - unset($this->TagCloud, $this->View); - ClassRegistry::flush(); - } -} diff --git a/app/Plugin/Tags/Test/Case/Model/Behavior/TaggableBehaviorTest.php b/app/Plugin/Tags/Test/Case/Model/Behavior/TaggableBehaviorTest.php new file mode 100755 index 0000000..1cf72df --- /dev/null +++ b/app/Plugin/Tags/Test/Case/Model/Behavior/TaggableBehaviorTest.php @@ -0,0 +1,538 @@ + array(), + 'noPluginPrefix' => array( + 'tagClass' => 'Tag', + 'taggedClass' => 'Tagged', + ), + 'customAliasAndClass' => array( + 'tagAlias' => 'CustomTagAlias', + 'taggedAlias' => 'CustomTaggedAlias', + 'tagClass' => 'Tags.CustomTag', + 'taggedClass' => 'Tags.CustomTagged', + ), + ); + +/** + * Run test cases multiple times with different behavior settings + * + * @param PHPUnit_Framework_TestResult $result The test result object + * @return PHPUnit_Framework_TestResult + */ + public function run(PHPUnit_Framework_TestResult $result = null) { + foreach ($this->behaviorSettings as $behaviorSettings) { + $this->behaviorSettings = $behaviorSettings; + $result = parent::run($result); + } + + return $result; + } + +/** + * Method executed before each test + * + * @return void + */ + public function setUp() { + parent::setUp(); + $this->Article = ClassRegistry::init('Article'); + Configure::write('Config.language', 'eng'); + $this->Article->Behaviors->attach('Tags.Taggable', $this->behaviorSettings); + } + +/** + * Method executed after each test + * + * @return void + */ + public function tearDown() { + parent::tearDown(); + unset($this->Article); + ClassRegistry::flush(); + } + +/** + * Test the occurrence cache + * + * @return void + */ + public function testOccurrenceCache() { + $tagAlias = $this->Article->Behaviors->Taggable->settings['Article']['tagAlias']; + + $resultBefore = $this->Article->{$tagAlias}->find('first', array( + 'contain' => array(), + 'conditions' => array( + $tagAlias . '.keyname' => 'cakephp' + ) + )); + + // adding a new record with the cakephp tag to increase the occurrence + $data = array('title' => 'Test Article', 'tags' => 'cakephp, php'); + $this->Article->create(); + $this->Article->save($data, false); + + $resultAfter = $this->Article->{$tagAlias}->find('first', array( + 'contain' => array(), + 'conditions' => array( + $tagAlias . '.keyname' => 'cakephp' + ) + )); + + $this->assertEquals($resultAfter[$tagAlias]['occurrence'] - $resultBefore[$tagAlias]['occurrence'], 1); + + // updating the record to not have the cakephp tag anymore, decreases the occurrence + $data = array('id' => $this->Article->id, 'title' => 'Test Article', 'tags' => 'php, something, else'); + $this->Article->save($data, false); + $resultAfter = $this->Article->{$tagAlias}->find('first', array( + 'contain' => array(), + 'conditions' => array( + $tagAlias . '.keyname' => 'cakephp' + ) + )); + $this->assertEquals($resultAfter[$tagAlias]['occurrence'], 1); + } + +/** + * Testings saving of tags trough the specified field in the tagable model + * + * @return void + */ + public function testTagSaving() { + $data['id'] = 'article-1'; + $data['tags'] = 'foo, bar, test'; + $this->Article->save($data, false); + $result = $this->Article->find('first', array( + 'conditions' => array( + 'id' => 'article-1' + ) + )); + $this->assertTrue(!empty($result['Article']['tags'])); + + $data['tags'] = 'foo, developer, developer, php'; + $this->Article->save($data, false); + $result = $this->Article->find('first', array( + 'contain' => array('Tag'), + 'conditions' => array( + 'id' => 'article-1' + ) + )); + + $this->assertTrue(!empty($result['Article']['tags'])); + $this->assertEquals(3, count($result['Tag'])); + + $data['tags'] = 'cakephp:foo, developer, cakephp:developer, cakephp:php'; + $this->Article->save($data, false); + $result = $this->Article->Tag->find('all', array( + 'recursive' => -1, + 'order' => 'Tag.identifier DESC, Tag.name ASC', + 'conditions' => array( + 'Tag.identifier' => 'cakephp' + ) + )); + + $result = Set::extract($result, '{n}.Tag.keyname'); + $this->assertEquals($result, array( + 'developer', 'foo', 'php' + )); + + $this->assertFalse($this->Article->saveTags('foo, bar', null)); + $this->assertFalse($this->Article->saveTags(array('foo', 'bar'), 'something')); + } + +/** + * Tests that toggling taggedCounter will update the time_tagged counter in the tagged table + * + * @return void + */ + public function testSaveTimesTagged() { + $this->Article->Behaviors->Taggable->settings['Article']['taggedCounter'] = true; + $tags = 'foo, bar , test'; + $this->assertTrue($this->Article->saveTags($tags, 'article-1', false)); + $this->assertTrue($this->Article->saveTags($tags, 'article-1', false)); + + $result = $this->Article->Tagged->find('all', array( + 'conditions' => array('model' => 'Article'), + 'contain' => array('Tag'), + )); + $fooCount = Set::extract('/Tag[keyname=foo]/../Tagged/times_tagged', $result); + $this->assertEquals($fooCount, array(2)); + + $barCount = Set::extract('/Tag[keyname=bar]/../Tagged/times_tagged', $result); + $this->assertEquals($barCount, array(2)); + + $testCount = Set::extract('/Tag[keyname=test]/../Tagged/times_tagged', $result); + $this->assertEquals($testCount, array(2)); + } + +/** + * Testing Taggable::tagArrayToString() + * + * @return void + */ + public function testTagArrayToString() { + $data['id'] = 'article-1'; + $data['tags'] = 'foo, bar, test'; + $this->Article->save($data, false); + $result = $this->Article->find('first', array( + 'conditions' => array( + 'id' => 'article-1' + ) + )); + $result = $this->Article->tagArrayToString($result['Tag']); + $this->assertTrue(!empty($result)); + $this->assertInternalType('string', $result); + $this->assertEquals($result, 'test, bar, foo'); + + $result = $this->Article->tagArrayToString(); + $this->assertTrue(empty($result)); + $this->assertInternalType('string', $result); + + $data['tags'] = 'cakephp:foo, cakephp:bar, foo, bar'; + $this->Article->save($data, false); + $result = $this->Article->find('first', array( + 'conditions' => array( + 'id' => 'article-1' + ) + )); + + $result = $this->Article->tagArrayToString($result['Tag']); + $this->assertTrue(!empty($result)); + $this->assertInternalType('string', $result); + $this->assertEquals($result, 'cakephp:bar, cakephp:foo, bar, foo'); + } + +/** + * Testings Taggable::multibyteKey() + * + * @return void + */ + public function testMultibyteKey() { + $result = $this->Article->multibyteKey('this is _ a Nice ! - _ key!'); + $this->assertEquals('thisisanicekey', $result); + + $result = $this->Article->multibyteKey('Äü-Ü_ß'); + $this->assertEquals('äüüß', $result); + } + +/** + * testAfterFind callback method + * + * @return void + */ + public function testAfterFind() { + $tagAlias = $this->Article->Behaviors->Taggable->settings['Article']['tagAlias']; + + $data['id'] = 'article-1'; + $data['tags'] = 'foo, bar, test'; + $this->Article->save($data, false); + + $result = $this->Article->find('first', array( + 'conditions' => array( + 'id' => 'article-1' + ) + )); + $this->assertTrue(isset($result[$tagAlias])); + + $this->Article->Behaviors->Taggable->settings['Article']['unsetInAfterFind'] = true; + $result = $this->Article->find('first', array( + 'conditions' => array( + 'id' => 'article-1' + ) + )); + $this->assertTrue(!isset($result[$tagAlias])); + } + +/** + * testAfterFindFields + * + * @return void + */ + public function testAfterFindFields() { + $this->Article->Behaviors->detach('Taggable'); + $results = $this->Article->find('first', array( + 'recursive' => -1, + 'fields' => array('id') + )); + $expected = array($this->Article->alias => array('id' => 'article-1')); + $this->assertIdentical($results, $expected); + } + +/** + * testGettingTagCloudThroughAssociation + * + * @link http://cakedc.lighthouseapp.com/projects/59622/tickets/6-tag-cloud-helper + * @return void + */ + public function testGettingTagCloudThroughAssociation() { + $result = $this->Article->Tagged->find('cloud'); + $this->assertTrue(is_array($result) && !empty($result)); + } + +/** + * testSavingEmptyTagsDeleteAssociatedTags + * + * @return void + */ + public function testSavingEmptyTagsDeleteAssociatedTags() { + $this->Article->Behaviors->Taggable->settings['Article']['deleteTagsOnEmptyField'] = true; + $data = $this->Article->findById('article-1'); + $data['Article']['tags'] = ''; + $this->Article->save($data, false); + $result = $this->Article->find('first', array( + 'conditions' => array('id' => 'article-1') + )); + + $this->assertEmpty($result['Tag']); + } + +/** + * testSavingEmptyTagsDoNotDeleteAssociatedTags + * + * @return void + */ + public function testSavingEmptyTagsDoNotDeleteAssociatedTags() { + $this->Article->Behaviors->Taggable->settings['Article']['deleteTagsOnEmptyField'] = false; + $data = $this->Article->findById('article-1'); + $data['Article']['tags'] = ''; + $this->Article->save($data, false); + $result = $this->Article->find('first', array( + 'conditions' => array('id' => 'article-1') + )); + + $this->assertNotEmpty($result['Tag']); + } + +/** + * testSavingTagsDoesNotCreateEmptyRecords + * + * @return void + */ + public function testSavingTagsDoesNotCreateEmptyRecords() { + $count = $this->Article->Tag->find('count', array( + 'conditions' => array( + 'Tag.name' => '', + 'Tag.keyname' => '', + ) + )); + $this->assertEquals($count, 0); + + $data['id'] = 'article-1'; + $data['tags'] = 'foo, bar, test'; + $this->Article->save($data, false); + $result = $this->Article->find('first', array( + 'conditions' => array( + 'id' => 'article-1' + ) + )); + + $count = $this->Article->Tag->find('count', array( + 'conditions' => array( + 'Tag.name' => '', + 'Tag.keyname' => '', + ) + )); + $this->assertEquals($count, 0); + } + +/** + * testSavingTagsWithDefferentIdentifier + * + * @return void + */ + public function testSavingTagsWithDifferentIdentifier() { + $data = $this->Article->findById('article-1'); + $data['Article']['tags'] = 'foo:cakephp, bar:cakephp'; + $this->Article->save($data); + $data = $this->Article->findById('article-1'); + $this->assertEquals('bar:cakephp, foo:cakephp', $data['Article']['tags']); + } + +/** + * testDeletingMoreThanOneTagAtATime + * + * @link https://github.com/CakeDC/tags/issues/86 + * @return void + */ + public function testDeletingMoreThanOneTagAtATime() { + // Adding five tags for testing + $data = array( + 'Article' => array( + 'id' => 'article-test-delete-tags', + 'tags' => 'foo, bar, test, second, third', + ) + ); + $this->Article->create(); + $this->Article->save($data, false); + $result = $this->Article->find('first', array( + 'conditions' => array( + 'id' => 'article-test-delete-tags' + ) + )); + $this->assertEquals($result['Article']['tags'], 'third, second, test, bar, foo'); + // Removing three of the five previously added tags + $result['Article']['tags'] = 'third, second'; + $this->Article->save($result, false); + $result = $this->Article->find('first', array( + 'conditions' => array( + 'id' => 'article-test-delete-tags' + ) + )); + $this->assertEquals($result['Article']['tags'], 'second, third'); + // Removing all tags, empty string - WON'T work as expected because of deleteTagsOnEmptyField + $result['Article']['tags'] = ''; + $this->Article->save($result, false); + $result = $this->Article->find('first', array( + 'conditions' => array( + 'id' => 'article-test-delete-tags' + ) + )); + $this->assertEquals($result['Article']['tags'], 'third, second'); + // Now with deleteTagsOnEmptyField + $this->Article->Behaviors->load('Tags.Taggable', array( + 'deleteTagsOnEmptyField' => true + )); + $result['Article']['tags'] = ''; + $this->Article->save($result, false); + $result = $this->Article->find('first', array( + 'conditions' => array( + 'id' => 'article-test-delete-tags' + ) + )); + $this->assertEquals($result['Article']['tags'], ''); + } + +} diff --git a/app/Plugin/Tags/Test/Case/Model/TagTest.php b/app/Plugin/Tags/Test/Case/Model/TagTest.php old mode 100644 new mode 100755 index a243b50..43ca44f --- a/app/Plugin/Tags/Test/Case/Model/TagTest.php +++ b/app/Plugin/Tags/Test/Case/Model/TagTest.php @@ -1,23 +1,23 @@ Tag = ClassRegistry::init('Tags.Tag'); } @@ -50,6 +51,7 @@ public function setUp() { * @return void */ public function tearDown() { + parent::tearDown(); unset($this->Tag); } @@ -74,15 +76,17 @@ public function testTagFind() { $expected = array( 'Tag' => array( - 'id' => 'tag-1', - 'identifier' => null, - 'name' => 'CakePHP', - 'keyname' => 'cakephp', + 'id' => 'tag-1', + 'identifier' => null, + 'name' => 'CakePHP', + 'keyname' => 'cakephp', 'occurrence' => 1, 'article_occurrence' => 1, - 'created' => '2008-06-02 18:18:11', - 'modified' => '2008-06-02 18:18:37')); - $this->assertEqual($results, $expected); + 'created' => '2008-06-02 18:18:11', + 'modified' => '2008-06-02 18:18:37' + ) + ); + $this->assertEquals($results, $expected); } /** @@ -93,9 +97,9 @@ public function testTagFind() { public function testView() { $result = $this->Tag->view('cakephp'); $this->assertTrue(is_array($result)); - $this->assertEqual($result['Tag']['keyname'], 'cakephp'); + $this->assertEquals($result['Tag']['keyname'], 'cakephp'); - $this->expectException('Exception'); + $this->expectException('CakeException'); $this->Tag->view('invalid-key!!!'); } @@ -105,18 +109,30 @@ public function testView() { * @return void */ public function testAdd() { - $result = $this->Tag->add( - array('Tag' => array( - 'tags' => 'tag1, tag2, tag3'))); + $result = $this->Tag->add(array( + 'Tag' => array( + 'tags' => 'tag1, tag2, tag3' + ) + )); $this->assertTrue($result); $result = $this->Tag->find('all', array( 'recursive' => -1, 'fields' => array( - 'Tag.name'))); + 'Tag.name' + ) + )); $result = Set::extract($result, '{n}.Tag.name'); $this->assertTrue(in_array('tag1', $result)); $this->assertTrue(in_array('tag2', $result)); $this->assertTrue(in_array('tag3', $result)); + + // adding same tags again. + $result = $this->Tag->add(array( + 'Tag' => array( + 'tags' => 'tag1, tag2, tag3' + ) + )); + $this->assertTrue($result); } /** @@ -126,28 +142,34 @@ public function testAdd() { */ public function testEdit() { $this->assertNull($this->Tag->edit('tag-1')); - $this->assertEqual($this->Tag->data['Tag']['id'], 'tag-1'); - + $this->assertEquals($this->Tag->data['Tag']['id'], 'tag-1'); + $data = array( 'Tag' => array( 'id' => 'tag-1', - 'name' => 'CAKEPHP')); + 'name' => 'CAKEPHP' + ) + ); $this->assertTrue($this->Tag->edit('tag-1', $data)); $data = array( 'Tag' => array( 'id' => 'tag-1', - 'name' => 'CAKEPHP111')); + 'name' => 'CAKEPHP111' + ) + ); $this->assertFalse($this->Tag->edit('tag-1', $data)); $data = array( 'Tag' => array( 'id' => 'tag-1', 'name' => 'CAKEPHP', - 'keyname' => '')); - $this->assertEqual($this->Tag->edit('tag-1', $data), $data); - - $this->expectException('Exception'); + 'keyname' => '' + ) + ); + $this->assertEquals($this->Tag->edit('tag-1', $data), $data); + + $this->expectException('CakeException'); $this->assertTrue($this->Tag->edit('invalid-id', array())); } } diff --git a/app/Plugin/Tags/Test/Case/Model/TaggedTest.php b/app/Plugin/Tags/Test/Case/Model/TaggedTest.php old mode 100644 new mode 100755 index 097ff2b..b8c35f3 --- a/app/Plugin/Tags/Test/Case/Model/TaggedTest.php +++ b/app/Plugin/Tags/Test/Case/Model/TaggedTest.php @@ -1,15 +1,33 @@ Tagged = ClassRegistry::init('Tags.Tagged'); } @@ -50,9 +71,10 @@ public function startTest($method) { * * @return void */ - public function endTest($method) { + public function tearDown() { + parent::tearDown(); unset($this->Tagged); - ClassRegistry::flush(); + ClassRegistry::flush(); } /** @@ -83,9 +105,11 @@ public function testTaggedFind() { 'language' => 'eng', 'times_tagged' => 1, 'created' => '2008-12-02 12:32:31', - 'modified' => '2008-12-02 12:32:31')); + 'modified' => '2008-12-02 12:32:31' + ) + ); - $this->assertEqual($result, $expected); + $this->assertEquals($result, $expected); } /** @@ -95,42 +119,46 @@ public function testTaggedFind() { */ public function testFindCloud() { $result = $this->Tagged->find('cloud', array( - 'model' => 'Article')); - - $this->assertEqual(count($result), 3); + 'model' => 'Article' + )); + + $this->assertEquals(count($result), 3); $this->assertTrue(isset($result[0][0]['occurrence'])); - $this->assertEqual($result[0][0]['occurrence'], 1); + $this->assertEquals($result[0][0]['occurrence'], 1); $result = $this->Tagged->find('cloud'); $this->assertTrue(is_array($result) && !empty($result)); $result = $this->Tagged->find('cloud', array( - 'limit' => 1)); - $this->assertEqual(count($result), 1); + 'limit' => 1 + )); + $this->assertEquals(count($result), 1); } /** * Test custom _findTagged method - * + * * @return void */ public function testFindTagged() { $this->Tagged->recursive = -1; $result = $this->Tagged->find('tagged', array( 'by' => 'cakephp', - 'model' => 'Article')); - $this->assertEqual(count($result), 1); - $this->assertEqual($result[0]['Article']['id'], 'article-1'); + 'model' => 'Article' + )); + $this->assertEquals(count($result), 1); + $this->assertEquals($result[0]['Article']['id'], 'article-1'); $result = $this->Tagged->find('tagged', array( - 'model' => 'Article')); - $this->assertEqual(count($result), 2); - + 'model' => 'Article' + )); + $this->assertEquals(count($result), 2); // Test call to paginateCount by Controller::pagination() $result = $this->Tagged->paginateCount(array(), 1, array( 'model' => 'Article', - 'type' => 'tagged')); - $this->assertEqual($result, 2); + 'type' => 'tagged' + )); + $this->assertEquals($result, 2); } /** @@ -143,15 +171,83 @@ public function testFindTaggedWithConditions() { $result = $this->Tagged->find('tagged', array( 'by' => 'cakephp', 'model' => 'Article', - 'conditions' => array('Article.title LIKE' => 'Second %'))); - $this->assertEqual(count($result), 0); + 'conditions' => array('Article.title LIKE' => 'Second %') + )); + $this->assertEquals(count($result), 0); $result = $this->Tagged->find('tagged', array( 'by' => 'cakephp', 'model' => 'Article', - 'conditions' => array('Article.title LIKE' => 'First %'))); - $this->assertEqual(count($result), 1); - $this->assertEqual($result[0]['Article']['id'], 'article-1'); + 'conditions' => array('Article.title LIKE' => 'First %') + )); + $this->assertEquals(count($result), 1); + $this->assertEquals($result[0]['Article']['id'], 'article-1'); + } + +/** + * testDeepAssociations + * + * @link https://github.com/CakeDC/tags/issues/15 + * @return void + */ + public function testDeepAssociationsHasOne() { + $this->Tagged->bindModel(array( + 'belongsTo' => array( + 'Article' => array( + 'className' => 'TaggedArticle', + 'foreignKey' => 'foreign_key' + ) + ) + )); + + $this->Tagged->Article->bindModel(array( + 'hasOne' => array( + 'User' => array() + ) + )); + + $result = $this->Tagged->find('all', array( + 'contain' => array( + 'Article' => array( + 'User' + ) + ) + )); + + $this->assertEquals($result[0]['Article']['User']['name'], 'CakePHP'); + } + +/** + * testDeepAssociationsBelongsTo + * + * @link https://github.com/CakeDC/tags/issues/15 + * @return void + */ + public function testDeepAssociationsBelongsTo() { + $this->Tagged->bindModel(array( + 'belongsTo' => array( + 'Article' => array( + 'className' => 'TaggedArticle', + 'foreignKey' => 'foreign_key' + ) + ) + )); + + $this->Tagged->Article->bindModel(array( + 'belongsTo' => array( + 'User' => array() + ) + )); + + $result = $this->Tagged->find('all', array( + 'contain' => array( + 'Article' => array( + 'User' + ) + ) + )); + + $this->assertEquals($result[0]['Article']['User']['name'], 'CakePHP'); } } diff --git a/app/Plugin/Tags/Test/Case/View/Helper/TagCloudHelperTest.php b/app/Plugin/Tags/Test/Case/View/Helper/TagCloudHelperTest.php new file mode 100755 index 0000000..bd8e73d --- /dev/null +++ b/app/Plugin/Tags/Test/Case/View/Helper/TagCloudHelperTest.php @@ -0,0 +1,177 @@ + array( + 'id' => 1, + 'identifier' => null, + 'name' => 'CakePHP', + 'keyname' => 'cakephp', + 'weight' => 2, + 'created' => '2008-06-02 18:18:11', + 'modified' => '2008-06-02 18:18:37' + ) + ), + array( + 'Tag' => array( + 'id' => 2, + 'identifier' => null, + 'name' => 'CakeDC', + 'keyname' => 'cakedc', + 'weight' => 2, + 'created' => '2008-06-01 18:18:15', + 'modified' => '2008-06-01 18:18:15' + ) + ), + ); + +/** + * Helper being tested + * + * @var TagCloudHelper + */ + public $TagCloud; + +/** + * Setup the test case + * + * @return void + */ + public function setUp() { + parent::setUp(); + $controller = null; + $this->View = new View($controller); + $this->TagCloud = new TagCloudHelper($this->View); + $this->TagCloud->Html = new HtmlHelper($this->View); + } + +/** + * Test display method + * + * @return void + */ + public function testDisplay() { + $this->assertEquals($this->TagCloud->display(), ''); + + // Test tags shuffling + $options = array( + 'shuffle' => true + ); + $expected = 'CakePHP CakeDC '; + $i = 100; + do { + $i--; + $result = $this->TagCloud->display($this->sampleTags, $options); + } while ($result == $expected && $i > 0); + $this->assertNotEqual($result, $expected); + + // Test normal display + $options = array( + 'shuffle' => false + ); + $result = $this->TagCloud->display($this->sampleTags, $options); + $this->assertEquals($result, $expected); + + // Test options + $options = array_merge($options, array( + 'before' => '', + 'after' => '', + 'maxSize' => 100, + 'minSize' => 1, + 'url' => array('controller' => 'search', 'from' => 'twitter'), + 'named' => 'query' + )); + $result = $this->TagCloud->display($this->sampleTags, $options); + $expected = 'CakePHP ' . + 'CakeDC '; + $this->assertEquals($result, $expected); + + $tags = $this->sampleTags; + $tags[1]['Tag']['weight'] = 1; + $result = $this->TagCloud->display($tags, $options); + $expected = 'CakePHP ' . + 'CakeDC '; + $this->assertEquals($result, $expected); + } + +/** + * Test that display method defines correct size when using custom weight fields + * + * @return void + */ + public function testDisplayShouldDefineCorrectSizeWhenCustomWeightField() { + $tags = $this->sampleTags; + $tags[0]['Tag']['custom_weight'] = 6; + $tags[1]['Tag']['custom_weight'] = 3; + + $options = array( + 'before' => '', + 'shuffle' => false, + 'extract' => '{n}.Tag.custom_weight', + ); + + $result = $this->TagCloud->display($tags, $options); + $expected = 'CakePHP ' . + 'CakeDC '; + $this->assertEquals($result, $expected); + } + +/** + * Test query string param type + * + * @return void + */ + public function testQueryStringUrlParams() { + $tags = $this->sampleTags; + $tags[0]['Tag']['custom_weight'] = 6; + $tags[1]['Tag']['custom_weight'] = 3; + + $options = array( + 'shuffle' => false, + 'extract' => '{n}.Tag.custom_weight', + 'paramType' => 'querystring' + ); + + $result = $this->TagCloud->display($tags, $options); + $expected = 'CakePHP ' . + 'CakeDC '; + $this->assertEquals($result, $expected); + } + +/** + * Tear down the test case + * + * @return void + */ + public function tearDown() { + parent::tearDown(); + unset($this->TagCloud, $this->View); + ClassRegistry::flush(); + } +} diff --git a/app/Plugin/Tags/Test/Fixture/ArticleFixture.php b/app/Plugin/Tags/Test/Fixture/ArticleFixture.php old mode 100644 new mode 100755 index cdf4c71..c7a094d --- a/app/Plugin/Tags/Test/Fixture/ArticleFixture.php +++ b/app/Plugin/Tags/Test/Fixture/ArticleFixture.php @@ -1,11 +1,11 @@ array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 36), - 'title' => array('type' => 'string', 'null' => false)); + 'id' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36), + 'title' => array('type' => 'string', 'null' => false), + 'user_id' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36) + ); /** * records property @@ -41,11 +36,18 @@ class ArticleFixture extends CakeTestFixture { public $records = array( array( 'id' => 'article-1', - 'title' => 'First Article'), + 'title' => 'First Article', + 'user_id' => 'user-1' + ), array( 'id' => 'article-2', - 'title' => 'Second Article'), + 'title' => 'Second Article', + 'user_id' => 'user-2' + ), array( 'id' => 'article-3', - 'title' => 'Third Article')); + 'title' => 'Third Article', + 'user_id' => 'user-3' + ) + ); } diff --git a/app/Plugin/Tags/Test/Fixture/TagFixture.php b/app/Plugin/Tags/Test/Fixture/TagFixture.php old mode 100644 new mode 100755 index 9983630..132154f --- a/app/Plugin/Tags/Test/Fixture/TagFixture.php +++ b/app/Plugin/Tags/Test/Fixture/TagFixture.php @@ -1,11 +1,11 @@ array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 36, 'key' => 'primary'), - 'identifier' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 30, 'key' => 'index'), - 'name' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 30), - 'keyname' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 30), + 'id' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36, 'key' => 'primary'), + 'identifier' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 30, 'key' => 'index'), + 'name' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 30), + 'keyname' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 30), 'occurrence' => array('type' => 'integer', 'null' => false, 'default' => 0, 'length' => 8), 'article_occurrence' => array('type' => 'integer', 'null' => false, 'default' => 0, 'length' => 8), - 'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL), - 'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL), + 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), + 'modified' => array('type' => 'datetime', 'null' => true, 'default' => null), 'indexes' => array( 'PRIMARY' => array('column' => 'id', 'unique' => 1), 'UNIQUE_TAG' => array('column' => array('identifier', 'keyname'), 'unique' => 1) @@ -58,31 +51,35 @@ class TagFixture extends CakeTestFixture { */ public $records = array( array( - 'id' => 'tag-1', - 'identifier' => null, - 'name' => 'CakePHP', - 'keyname' => 'cakephp', + 'id' => 'tag-1', + 'identifier' => null, + 'name' => 'CakePHP', + 'keyname' => 'cakephp', 'occurrence' => 1, 'article_occurrence' => 1, - 'created' => '2008-06-02 18:18:11', - 'modified' => '2008-06-02 18:18:37'), + 'created' => '2008-06-02 18:18:11', + 'modified' => '2008-06-02 18:18:37' + ), array( - 'id' => 'tag-2', - 'identifier' => null, - 'name' => 'CakeDC', - 'keyname' => 'cakedc', + 'id' => 'tag-2', + 'identifier' => null, + 'name' => 'CakeDC', + 'keyname' => 'cakedc', 'occurrence' => 1, 'article_occurrence' => 1, - 'created' => '2008-06-01 18:18:15', - 'modified' => '2008-06-01 18:18:15'), + 'created' => '2008-06-01 18:18:15', + 'modified' => '2008-06-01 18:18:15' + ), array( - 'id' => 'tag-3', - 'identifier' => null, - 'name' => 'CakeDC', - 'keyname' => 'cakedc', + 'id' => 'tag-3', + 'identifier' => null, + 'name' => 'CakeDC', + 'keyname' => 'cakedc', 'occurrence' => 1, 'article_occurrence' => 1, - 'created' => '2008-06-01 18:18:15', - 'modified' => '2008-06-01 18:18:15')); + 'created' => '2008-06-01 18:18:15', + 'modified' => '2008-06-01 18:18:15' + ) + ); } diff --git a/app/Plugin/Tags/Test/Fixture/TaggedFixture.php b/app/Plugin/Tags/Test/Fixture/TaggedFixture.php old mode 100644 new mode 100755 index eec4090..1c5698d --- a/app/Plugin/Tags/Test/Fixture/TaggedFixture.php +++ b/app/Plugin/Tags/Test/Fixture/TaggedFixture.php @@ -1,11 +1,11 @@ array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 36, 'key' => 'primary'), - 'foreign_key' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 36), - 'tag_id' => array('type' => 'string', 'null' => false, 'default' => NULL, 'length' => 36), - 'model' => array('type' => 'string', 'null' => false, 'default' => NULL, 'key' => 'index'), - 'language' => array('type' => 'string', 'null' => true, 'default' => NULL, 'length' => 6), + 'id' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36, 'key' => 'primary'), + 'foreign_key' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36), + 'tag_id' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36), + 'model' => array('type' => 'string', 'null' => false, 'default' => null, 'key' => 'index'), + 'language' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 6), 'times_tagged' => array('type' => 'integer', 'null' => false, 'default' => 1), - 'created' => array('type' => 'datetime', 'null' => true, 'default' => NULL), - 'modified' => array('type' => 'datetime', 'null' => true, 'default' => NULL), + 'created' => array('type' => 'datetime', 'null' => true, 'default' => null), + 'modified' => array('type' => 'datetime', 'null' => true, 'default' => null), 'indexes' => array( 'PRIMARY' => array('column' => 'id', 'unique' => 1), 'UNIQUE_TAGGING' => array('column' => array('model', 'foreign_key', 'tag_id', 'language'), 'unique' => 1), diff --git a/app/Plugin/Tags/Test/Fixture/UserFixture.php b/app/Plugin/Tags/Test/Fixture/UserFixture.php new file mode 100755 index 0000000..f225186 --- /dev/null +++ b/app/Plugin/Tags/Test/Fixture/UserFixture.php @@ -0,0 +1,54 @@ + array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36), + 'name' => array('type' => 'string', 'null' => false), + 'article_id' => array('type' => 'string', 'null' => false, 'default' => null, 'length' => 36) + ); + +/** + * records property + * + * @var array + */ + public $records = array( + array( + 'id' => 'user-1', + 'name' => 'CakePHP', + 'article_id' => 'article-1' + ), + array( + 'id' => 'user-2', + 'name' => 'Second User', + 'article_id' => 'article-2' + ), + array( + 'id' => 'user-3', + 'name' => 'Third User', + 'article_id' => 'article-3' + ) + ); + +} diff --git a/app/Plugin/Tags/View/Helper/TagCloudHelper.php b/app/Plugin/Tags/View/Helper/TagCloudHelper.php old mode 100644 new mode 100755 index 1c15cf7..c5caf04 --- a/app/Plugin/Tags/View/Helper/TagCloudHelper.php +++ b/app/Plugin/Tags/View/Helper/TagCloudHelper.php @@ -1,14 +1,16 @@ array( 'controller' => 'search' ), - 'named' => 'by' + 'named' => 'by', + 'paramType' => 'named' ); $options = array_merge($defaults, $options); @@ -74,21 +78,42 @@ public function display($tags = null, $options = array()) { $cloud = null; foreach ($tags as $tag) { - $options['url'][$options['named']] = $tag[$options['tagModel']]['keyname']; + $data = Set::extract(array($tag), $options['extract']); + $tagWeight = array_pop($data); - $size = $options['minSize'] + (($tag[$options['tagModel']]['weight'] - $minWeight) * (($options['maxSize'] - $options['minSize']) / ($spread))); - $size = ceil($size); + $size = $options['minSize'] + (($tagWeight - $minWeight) * (($options['maxSize'] - $options['minSize']) / ($spread))); + $size = $tag[$options['tagModel']]['size'] = ceil($size); $cloud .= $this->_replace($options['before'], $size); - $cloud .= $this->Html->link($tag[$options['tagModel']]['name'], $options['url'], array('id' => 'tag-' . $tag[$options['tagModel']]['id'])) . ' '; + $cloud .= $this->Html->link($tag[$options['tagModel']]['name'], $this->_tagUrl($tag, $options), array('id' => 'tag-' . $tag[$options['tagModel']]['id'])) . ' '; $cloud .= $this->_replace($options['after'], $size); } + return $cloud; } +/** + * Generates the URL for a tag + * + * @param array $tag Tag data array + * @param array $options Display options + * @return array|string + */ + protected function _tagUrl($tag, $options) { + if ($options['paramType'] === 'named') { + $options['url'][$options['named']] = $tag[$options['tagModel']]['keyname']; + } else { + $options['url']['?'][$options['named']] = $tag[$options['tagModel']]['keyname']; + } + + return $options['url']; + } + /** * Replaces %size% in strings with the calculated "size" of the tag * + * @param string $string Before or after string + * @param float $size Calculated size * @return string */ protected function _replace($string, $size) { diff --git a/app/Plugin/Tags/View/Helper/tag_cloud.php b/app/Plugin/Tags/View/Helper/tag_cloud.php deleted file mode 100644 index e69de29..0000000 diff --git a/app/Plugin/Tags/View/Tags/admin_add.ctp b/app/Plugin/Tags/View/Tags/admin_add.ctp old mode 100644 new mode 100755 index 818b444..185d1b4 --- a/app/Plugin/Tags/View/Tags/admin_add.ctp +++ b/app/Plugin/Tags/View/Tags/admin_add.ctp @@ -1,11 +1,11 @@ diff --git a/app/Plugin/Tags/View/Tags/admin_edit.ctp b/app/Plugin/Tags/View/Tags/admin_edit.ctp old mode 100644 new mode 100755 index e25da83..4d549c1 --- a/app/Plugin/Tags/View/Tags/admin_edit.ctp +++ b/app/Plugin/Tags/View/Tags/admin_edit.ctp @@ -1,11 +1,11 @@ diff --git a/app/Plugin/Tags/View/Tags/admin_index.ctp b/app/Plugin/Tags/View/Tags/admin_index.ctp old mode 100644 new mode 100755 index 9187d4a..7c07e8b --- a/app/Plugin/Tags/View/Tags/admin_index.ctp +++ b/app/Plugin/Tags/View/Tags/admin_index.ctp @@ -1,11 +1,11 @@ @@ -23,7 +23,6 @@ echo $this->Paginator->counter(array( Paginator->sort('identifier');?> Paginator->sort('name');?> Paginator->sort('keyname');?> - Paginator->sort('weight');?> Paginator->sort('created');?> Paginator->sort('modified');?> @@ -49,9 +48,6 @@ foreach ($tags as $tag): - - - @@ -66,12 +62,12 @@ foreach ($tags as $tag): -
Paginator->prev('<< '.__d('tags', 'previous'), array(), null, array('class'=>'disabled'));?> | Paginator->numbers();?> Paginator->next(__d('tags', 'next').' >>', array(), null, array('class' => 'disabled'));?>
+
  • Html->link(sprintf(__d('tags', 'New %s'), __d('tags', 'Tag')), array('action' => 'add')); ?>
  • diff --git a/app/Plugin/Tags/View/Tags/admin_view.ctp b/app/Plugin/Tags/View/Tags/admin_view.ctp old mode 100644 new mode 100755 index f69166a..d802ba0 --- a/app/Plugin/Tags/View/Tags/admin_view.ctp +++ b/app/Plugin/Tags/View/Tags/admin_view.ctp @@ -1,11 +1,11 @@ @@ -32,11 +32,6 @@   - > - > - -   - > > diff --git a/app/Plugin/Tags/View/Tags/index.ctp b/app/Plugin/Tags/View/Tags/index.ctp old mode 100644 new mode 100755 index 4626361..a00dcd7 --- a/app/Plugin/Tags/View/Tags/index.ctp +++ b/app/Plugin/Tags/View/Tags/index.ctp @@ -1,11 +1,11 @@ @@ -23,7 +23,6 @@ echo $this->Paginator->counter(array( Paginator->sort('identifier');?> Paginator->sort('name');?> Paginator->sort('keyname');?> - Paginator->sort('weight');?> Paginator->sort('created');?> Paginator->sort('modified');?> @@ -49,9 +48,6 @@ foreach ($tags as $tag): - - - @@ -64,9 +60,9 @@ foreach ($tags as $tag): -
Paginator->prev('<< '.__d('tags', 'previous'), array(), null, array('class'=>'disabled'));?> | Paginator->numbers();?> Paginator->next(__d('tags', 'next').' >>', array(), null, array('class' => 'disabled'));?> -
\ No newline at end of file + + diff --git a/app/Plugin/Tags/View/Tags/view.ctp b/app/Plugin/Tags/View/Tags/view.ctp old mode 100644 new mode 100755 index 78c0c90..8864534 --- a/app/Plugin/Tags/View/Tags/view.ctp +++ b/app/Plugin/Tags/View/Tags/view.ctp @@ -1,11 +1,11 @@ @@ -32,11 +32,6 @@   - > - > - -   - > > diff --git a/app/Plugin/Tags/composer.json b/app/Plugin/Tags/composer.json new file mode 100755 index 0000000..37f92ef --- /dev/null +++ b/app/Plugin/Tags/composer.json @@ -0,0 +1,22 @@ +{ + "name": "cakedc/tags", + "type": "cakephp-plugin", + "description": "Tags plugin for CakePHP.", + "homepage": "http://github.com/CakeDC/tags", + "keywords": ["cakephp", "tags", "plugin"], + "license": "MIT", + "authors": [ + { + "name": "Cake Development Corporation", + "email": "team@cakedc.com", + "homepage": "http://cakedc.com" + } + ], + "require": { + "php": ">=5.3.0", + "composer/installers": "*" + }, + "extra": { + "installer-name": "Tags" + } +} diff --git a/app/Plugin/Tags/license.txt b/app/Plugin/Tags/license.txt old mode 100644 new mode 100755 index 25e5ee2..2e3e391 --- a/app/Plugin/Tags/license.txt +++ b/app/Plugin/Tags/license.txt @@ -1,6 +1,6 @@ The MIT License -Copyright 2009-2010 +Copyright 2009-2012 Cake Development Corporation 1785 E. Sahara Avenue, Suite 490-423 Las Vegas, Nevada 89104 diff --git a/app/Plugin/Tags/readme.md b/app/Plugin/Tags/readme.md old mode 100644 new mode 100755 index ce637c0..4536726 --- a/app/Plugin/Tags/readme.md +++ b/app/Plugin/Tags/readme.md @@ -1,69 +1,40 @@ -# Tags Plugin for CakePHP # +Tags Plugin for CakePHP +======================= -Version 1.2 +[![Bake Status](https://secure.travis-ci.org/CakeDC/tags.png?branch=master)](http://travis-ci.org/CakeDC/tags) +[![Downloads](https://poser.pugx.org/CakeDC/tags/d/total.png)](https://packagist.org/packages/CakeDC/tags) +[![Latest Version](https://poser.pugx.org/CakeDC/tags/v/stable.png)](https://packagist.org/packages/CakeDC/tags) -The tags plugin includes the Taggable Behavior that allows you to simply tag everything. +The **Tags** plugin includes the TaggableBehavior that allows you to simply tag everything. -It saves all tags in a tags table and connects any kind of records to them through the tagged table. +It saves all tags in a single tags table and connects any kind of records to them through the tagged table. -To create tables you can use migrations plugin or schema shell. To create tables execute: +Requirements +------------ -cake schema create -plugin Tags -name tags +* CakePHP 2.5+ +* PHP 5.2.8+ -You can specify alternate tables for both in the case you get *A LOT* records tagged. +Documentation +------------- -## Usage ## +For documentation, as well as tutorials, see the [Docs](Docs/Home.md) directory of this repository. -To make something taggable you just need to do two things: +Support +------- -* Attach the taggable behavior -* Add a 'tags' field into your view for the model you just made taggable +For bugs and feature requests, please use the [issues](https://github.com/CakeDC/tags/issues) section of this repository. -The taggable behavior can be configured using the following parameters +Commercial support is also available, [contact us](http://cakedc.com/contact) for more information. -* separator - separator used to enter a lot of tags, comma by default -* tagAlias - model alias for Tag model -* tagClass - class name of the model storing the tags -* taggedClass - class name of the HABTM association table between tags and models -* field - the field name that contains the raw tags as string -* foreignKey - foreignKey used in the HABTM association -* associationForeignKey - associationForeignKey used in the HABTM association -* automaticTagging - if set to true you don't need to use saveTags() manually -* language - only tags in a certain language, string or array -* taggedCounter - true to update the number of times a particular tag was used for a specific record +Contributing +------------ -The Tagged model contains a method _findCloud which can be used like any other find $this->Model->find('cloud', $options); +This repository follows the [CakeDC Plugin Standard](http://cakedc.com/plugin-standard). If you'd like to contribute new features, enhancements or bug fixes to the plugin, please read our [Contribution Guidelines](http://cakedc.com/contribution-guidelines) for detailed instructions. -The result contains a "weight" field which has a normalized size of the tag occurrence set. The min and max size can be set by passing 'minSize" and 'maxSize' to the query. This value can be used in the view to control the size of the tag font. +License +------- -Tags can contain special tokens called "identifiers" to namespace tags or classify them into categories. +Copyright 2007-2014 Cake Development Corporation (CakeDC). All rights reserved. -A valid tags string to be saved is "foo, bar, cakephp:special". - -The token "cakephp" will end up as the identifier or category for the tag "special" - -## Requirements ## - -* PHP version: PHP 5.2+ -* CakePHP version: 1.3 Stable - -## Support ## - -For support and feature request, please visit the [Tags Plugin Support Site](http://cakedc.lighthouseapp.com/projects/59622-tags-plugin/). - -For more information about our Professional CakePHP Services please visit the [Cake Development Corporation website](http://cakedc.com). - -## License ## - -Copyright 2009-2010, [Cake Development Corporation](http://cakedc.com) - -Licensed under [The MIT License](http://www.opensource.org/licenses/mit-license.php)
-Redistributions of files must retain the above copyright notice. - -## Copyright ### - -Copyright 2009-2011
-[Cake Development Corporation](http://cakedc.com)
-1785 E. Sahara Avenue, Suite 490-423
-Las Vegas, Nevada 89104
-http://cakedc.com
+Licensed under the [MIT](http://www.opensource.org/licenses/mit-license.php) License. Redistributions of the source code included in this repository must retain the copyright notice found in each file. diff --git a/app/Plugin/Utils/Model/Behavior/CsvImportBehavior.php b/app/Plugin/Utils/Model/Behavior/CsvImportBehavior.php index fed85ef..3a6494b 100755 --- a/app/Plugin/Utils/Model/Behavior/CsvImportBehavior.php +++ b/app/Plugin/Utils/Model/Behavior/CsvImportBehavior.php @@ -47,7 +47,7 @@ class CsvImportBehavior extends ModelBehavior { * @param array $settigs list of settings to be used for this model * @return void */ - public function setup(Model &$Model, $settings = array()) { + public function setup(Model $Model, $settings = array()) { if (!isset($this->settings[$Model->alias])) { $this->settings[$Model->alias] = array( 'delimiter' => ';', diff --git a/app/webroot/.htaccess b/app/webroot/.htaccess index 49b427e..e219052 100755 --- a/app/webroot/.htaccess +++ b/app/webroot/.htaccess @@ -1,6 +1,3 @@ -# TinyMCE 3.x and CakePHP conflict if short_open_tag is on -php_flag short_open_tag off - AuthType Shibboleth ShibRequireSession off diff --git a/config.sample.yml b/config.sample.yml deleted file mode 100644 index 5ec86f2..0000000 --- a/config.sample.yml +++ /dev/null @@ -1,75 +0,0 @@ -application_title: Guide on the Side -theme: GuideOnTheSide - -language: - app_language: eng - editor_language: en - -feedback_link: - enabled: true - default_text: "What did you think of this tutorial?" - -database: - datasource: Database/Mysql - host: localhost - login: - password: - database: - -lucene: - enabled: false - -email: - # smtp (recommended) or php - transport: smtp - send_from: - send_all_feedback_to: - log: false - -# only if you chose smtp above -smtp: - host: - port: 587 - username: - password: - timeout: 30 - # none, ssl, or tls - encryption: tls - -# Settings for Universal Analytics accounts -universal_analytics: - enabled: false - account_id: UA-something - -# Settings for Classic Google Analytics accounts -# If you're unsure if you're using Classic Google Analytics or Universal -# Analytics, see: https://support.google.com/analytics/answer/4457764?hl=en -google_analytics: - enabled: false - account_id: UA-something - domain_name: your-domain-name.edu - -piwik_analytics: - enabled: false - piwik_server: piwik.server.com # Your Piwik server address (no leading http:///https://) - site_id: 99 # Number provided by Piwik - -authentication: - # local, shibboleth, or cas - method: local - -# only fill these out if you selected shibboleth above -shibboleth: - login_url: https://%HOST%/Shibboleth.sso/Login - logout_url: https://%HOST%/Shibboleth.sso/Logout - login_link_text: Log in via Shibboleth - username_field: Shib-uid - -# To make use of CAS, set authentication.method to cas and fill in these values -# The following sample configuration would work if your CAS login url is https://cas.example.com/cas/login -# Enable force_ssl_redirect if your CAS server requires SSL. -cas: - hostname: cas.example.com - port: 443 - uri: cas - force_ssl_redirect: false From 53dfdae224a4321c962ff6ba67306d7ee3498a27 Mon Sep 17 00:00:00 2001 From: Brendon Kozlowski Date: Sun, 10 Sep 2017 22:21:36 -0400 Subject: [PATCH 2/2] Fixed PHP errors for php5.6 Fixed all errors that were being displayed with regard to PHP v5.6. Cleaned up some syntax inconsistencies in various files. --- app/Controller/AppController.php | 1 + app/Controller/TutorialsController.php | 54 ++++----- app/Controller/UsersController.php | 157 ++++++++++++------------- app/Model/Tutorial.php | 2 +- app/Model/User.php | 2 +- 5 files changed, 108 insertions(+), 108 deletions(-) diff --git a/app/Controller/AppController.php b/app/Controller/AppController.php index 0b0da7f..956dc93 100755 --- a/app/Controller/AppController.php +++ b/app/Controller/AppController.php @@ -5,6 +5,7 @@ class AppController extends Controller { public $theme = 'GuideOnTheSide'; + public $paginate = array(); // GD settings var $padding = 10; // not the CSS padding, but the padding inside the image diff --git a/app/Controller/TutorialsController.php b/app/Controller/TutorialsController.php index 3e4b65a..90bcffb 100644 --- a/app/Controller/TutorialsController.php +++ b/app/Controller/TutorialsController.php @@ -528,11 +528,11 @@ function view_tutorial_only($id = null, $revision_id = null) { //$this->Tutorial->FinalQuiz->useDbConfig = 'default'; } - function add() { + public function add() { if (!empty($this->data)) { - $this->Tutorial->create(); - $this->data['Revision']['message'] = 'created'; + $this->data = array_merge($this->data, array('Revision' => array('message' => 'created'))); $this->Tutorial->user_id = $this->Session->read('Auth.User.id'); + $this->Tutorial->create(); if ($this->Tutorial->save($this->data)) { $this->Session->setFlash(__('The tutorial has been saved')); if ($this->data['Tutorial']['tutorial_type_id'] == TUTORIAL_TYPE_SIDEBYSIDE) { @@ -776,7 +776,7 @@ function view_heading_image($type = 'chapter', $text = '') { $this->layout = 'image'; $text = QH_urldecode($text); - + if ($type == 'chapter') { $string = ucfirst($type); if (!empty($text)) { @@ -841,7 +841,7 @@ function view_definition_image($link_text, $definition = '') { } else { $box_width = $this->padding * 2 + $this->number_of_characters * $this->character_width; } - + $image = imagecreatetruecolor($box_width, $box_height); $background = imagecolorallocate($image, 128, 194, 120); @@ -864,7 +864,7 @@ function view_text_box_image($type = 'one-line', $prompt = '', $placeholder = '' $this->layout = 'image'; $text = QH_urldecode($prompt); - + if ($type == 'one-line' || $type == 'multi-line') { $string = ucfirst($type); if (!empty($text)) { @@ -887,10 +887,10 @@ function view_text_box_image($type = 'one-line', $prompt = '', $placeholder = '' $black = imagecolorallocate($image, 0, 0, 0); $white = imagecolorallocate($image, 255, 255, 255); - + imagefill($image, 0, 0, $white); imagerectangle($image, 0, 0, $box_width - 1, $box_height - 1, $black); - + $y = $this->padding + $this->character_height; foreach ($text as $line) { imagettftext($image, $this->font_size, 0, $this->padding, $y, $black, APP . 'Lib/unifont_5.1.20080907.ttf', $line); @@ -901,8 +901,8 @@ function view_text_box_image($type = 'one-line', $prompt = '', $placeholder = '' imagepng($image); imagedestroy($image); $this->autoRender = false; - } - + } + function provide_feedback($id = null, $mode = null) { $this->set('noGoogleAnalytics', true); if (!$id || !is_numeric($id)) { @@ -924,18 +924,18 @@ function provide_feedback($id = null, $mode = null) { htmlentities($this->data['Tutorial']['comment']); $tutorialUrl = Router::url(array('action' => $action, $id), true); $body .= "

" . __('This feedback was sent from %s', $tutorialUrl) . "

"; - + $message = new CakeEmail('default'); $message->subject(__('Feedback for %s tutorial', $tutorial['Tutorial']['title'])); $message->emailFormat('html'); - + $to_array = explode(',', Configure::read('user_config.email.send_all_feedback_to')); $to_array[] = $tutorial['Tutorial']['contact_email']; foreach ($to_array as $to) { $message->addBcc(trim($to)); } - + try { // haddress ("Honeypot address") is the honeypot field. // If it's filled out, pretend to send, but don't really. @@ -946,9 +946,9 @@ function provide_feedback($id = null, $mode = null) { exit(); } catch (Exception $e) { echo $e->getMessage(); - exit(); - } - + exit(); + } + } else { $this->layout = 'public'; $this->set(compact('tutorial', 'mode')); @@ -964,7 +964,7 @@ function view_certificate() { $is_quiz = false; $this->set('tutorial_grades', array()); $this->set('quiz_grades', array()); - + if (array_key_exists('tutorial_id', $this->request->data) && is_numeric($this->request->data['tutorial_id'])) { $tutorial = $this->Tutorial->read(null, $this->request->data['tutorial_id']); if ($tutorial['Tutorial']['certificate']) { @@ -973,16 +973,16 @@ function view_certificate() { if (!isset($this->request->data['questions'])) { $this->request->data['questions'] = array(); } - $this->set('tutorial_grades', $this->Tutorial->grade($this->request->data['tutorial_id'], + $this->set('tutorial_grades', $this->Tutorial->grade($this->request->data['tutorial_id'], $this->request->data['questions'])); - } + } } - + if (!isset($this->request->data['free-response'])) { $this->request->data['free-response'] = array(); } $this->set('free_responses', $this->request->data['free-response']); - + if (array_key_exists('quiz_id', $this->request->data) && is_numeric($this->request->data['quiz_id'])) { $final_quiz = $this->Tutorial->FinalQuiz->read(null, $this->request->data['quiz_id']); if ($final_quiz['FinalQuiz']['certificate']) { @@ -994,7 +994,7 @@ function view_certificate() { $this->set('quiz_grades', $this->Tutorial->FinalQuiz->grade($this->request->data['quiz_id'], $this->request->data['questions'])); } } - + // parse supplied email fields if ($is_tutorial || $is_quiz) { @@ -1008,18 +1008,18 @@ function view_certificate() { } $to_string .= $this->request->data['certificate_email']; } - + $this->set('date', date('F j, Y')); $this->set('time', date('g:ia')); $this->set('name', Sanitize::paranoid($this->request->data['certificate_name'], array(' '))); $this->set('title', $subject); - + $message = new CakeEmail('default'); $message->subject(__('Certificate of Completion for %s', $subject)); $message->template('certificate_of_completion'); $message->emailFormat('html'); $message->viewVars($this->viewVars); - + $to_array = explode(',', $to_string); foreach ($to_array as $key => $to) { if ($to == 'Emailaddresses' || empty($to)) { @@ -1034,7 +1034,7 @@ function view_certificate() { $email_success = true; } catch (Exception $e) { $email_success = $e->getMessage(); - } + } $this->viewPath = 'Emails/html'; $this->layout = 'Emails/html/default'; @@ -1049,7 +1049,7 @@ function view_certificate() { $this->Session->setFlash(__('The following message could not be sent.')); } } - + return $this->render('certificate_of_completion'); } else { return __('This certificate cannot be generated.'); diff --git a/app/Controller/UsersController.php b/app/Controller/UsersController.php index 4050d50..5d947b2 100644 --- a/app/Controller/UsersController.php +++ b/app/Controller/UsersController.php @@ -2,101 +2,100 @@ class UsersController extends AppController { - var $paginate = - array( - 'limit' => 10, - 'order' => 'username ASC', - 'recursive' => 0, - ); + var $paginate = array( + 'limit' => 10, + 'order' => 'username ASC', + 'recursive' => 0, + ); - function beforeFilter() { - parent::beforeFilter(); - $user = $this->Auth->user(); - if (!in_array($this->action, $this->Auth->allowedActions)) { // if the action is not public - if (($this->action == 'edit') && ($user['id'] == $this->passedArgs[0]) && - (!$this->Auth->user('noLoginForm'))) { - ; // fall through to allow user to change password - } elseif (!$user || !($this->Session->read('Role.name') == 'admin')) { - // if they're not logged in or not admin - $this->redirect(array('controller' => 'tutorials')); - return; - } - } - } + function beforeFilter() { + parent::beforeFilter(); + $user = $this->Auth->user(); + if (!in_array($this->action, $this->Auth->allowedActions)) { // if the action is not public + if (($this->action == 'edit') && ($user['id'] == $this->passedArgs[0]) && + (!$this->Auth->user('noLoginForm'))) { + ; // fall through to allow user to change password + } elseif (!$user || !($this->Session->read('Role.name') == 'admin')) { + // if they're not logged in or not admin + $this->redirect(array('controller' => 'tutorials')); + return; + } + } + } function index() { $this->set('users', $this->paginate()); } function add() { - $hasLoginForm = !$this->Auth->user('noLoginForm'); + $hasLoginForm = !$this->Auth->user('noLoginForm'); if (!empty($this->data)) { - $this->data['User']['keep_password'] = false; - if (!$hasLoginForm) { - $this->data['User']['password'] = sha1(date('Y-m-d H:i:s') . mt_rand()); - $this->data['User']['password'] .= strtoupper($this->data['User']['password']); - // because the User model validates on this - $this->data['User']['password_confirmation'] = $this->data['User']['password']; - } - $this->User->create(); - if ($this->User->save($this->data)) { - $this->Session->setFlash(__('The user has been saved')); - $this->redirect(array('action' => 'index')); - } else { - $this->Session->setFlash(__('The user could not be saved. Please try again.'), 'default', - array('class' => 'page-error message')); - } - } - + $this->data = array_merge_recursive($this->data, array('User' => array('keep_password' => false))); + if (!$hasLoginForm) { + $this->data['User']['password'] = sha1(date('Y-m-d H:i:s') . mt_rand()); + $this->data['User']['password'] .= strtoupper($this->data['User']['password']); + // because the User model validates on this + $this->data['User']['password_confirmation'] = $this->data['User']['password']; + } + $this->User->create(); + if ($this->User->save($this->data)) { + $this->Session->setFlash(__('The user has been saved')); + $this->redirect(array('action' => 'index')); + } else { + $this->Session->setFlash(__('The user could not be saved. Please try again.'), 'default', + array('class' => 'page-error message')); + } + } + $roles = $this->User->Role->find('list'); $this->set(compact('roles', 'hasLoginForm')); } function edit($id = null) { - $hasLoginForm = !$this->Auth->user('noLoginForm'); - $user_is_self = ($this->Auth->user('id') == $id); - $this->User->id = $id; - + $hasLoginForm = !$this->Auth->user('noLoginForm'); + $user_is_self = ($this->Auth->user('id') == $id); + $this->User->id = $id; + if (!$id && empty($this->request->data)) { $this->Session->setFlash(__('Invalid user')); $this->redirect(array('action' => 'index')); } if (!empty($this->request->data)) { - $this->request->data['User']['keep_password'] = false; - if (!$hasLoginForm) { // Assuming that the only time we have a password field is when we have a form - $this->request->data['User']['keep_password'] = true; - } else { - // if empty, don't change password - if (empty($this->request->data['User']['password']) && empty($this->request->data['User']['password_confirmation'])) { - $this->request->data['User']['keep_password'] = true; - } - } - if ($user_is_self) { // don't allow user to change own username or role - $user = $this->User->findById($id); - if (isset($this->request->data['User']['username'])) { - $this->Session->setFlash(__('Don\'t change yourself. I like you the way you are.')); - $this->request->data['User']['username'] = $user['User']['username']; - } - if (isset($this->request->data['User']['role_id'])) { - $this->Session->setFlash(__('Don\'t change yourself. I like you the way you are.')); - $this->request->data['User']['role_id'] = $user['User']['role_id']; - } - } - if ($this->User->save($this->data)) { - $this->Session->setFlash(__('The user has been saved')); - $this->redirect(array('action' => 'index')); + $this->request->data['User']['keep_password'] = false; + if (!$hasLoginForm) { // Assuming that the only time we have a password field is when we have a form + $this->request->data['User']['keep_password'] = true; + } else { + // if empty, don't change password + if (empty($this->request->data['User']['password']) && empty($this->request->data['User']['password_confirmation'])) { + $this->request->data['User']['keep_password'] = true; + } + } + if ($user_is_self) { // don't allow user to change own username or role + $user = $this->User->findById($id); + if (isset($this->request->data['User']['username'])) { + $this->Session->setFlash(__('Don\'t change yourself. I like you the way you are.')); + $this->request->data['User']['username'] = $user['User']['username']; + } + if (isset($this->request->data['User']['role_id'])) { + $this->Session->setFlash(__('Don\'t change yourself. I like you the way you are.')); + $this->request->data['User']['role_id'] = $user['User']['role_id']; + } + } + if ($this->User->save($this->data)) { + $this->Session->setFlash(__('The user has been saved')); + $this->redirect(array('action' => 'index')); } else { - $this->Session->setFlash(__('The user could not be saved. Please try again.')); + $this->Session->setFlash(__('The user could not be saved. Please try again.')); } - } + } if (empty($this->request->data)) { $this->request->data = $this->User->read(null, $id); } - if (!$hasLoginForm && $user_is_self) { - $this->Session->setFlash(__('Don\'t change yourself. I like you the way you are.')); - $this->redirect(array('action' => 'index')); - } + if (!$hasLoginForm && $user_is_self) { + $this->Session->setFlash(__('Don\'t change yourself. I like you the way you are.')); + $this->redirect(array('action' => 'index')); + } $roles = $this->User->Role->find('list'); $this->set(compact('roles', 'hasLoginForm', 'user_is_self')); } @@ -106,15 +105,15 @@ function delete($id = null) { $this->Session->setFlash(__('Invalid id for user')); $this->redirect(array('action'=>'index')); } - if ($this->Auth->user('id') == $id) { - $this->Session->setFlash(__("Don't delete yourself!")); + if ($this->Auth->user('id') == $id) { + $this->Session->setFlash(__("Don't delete yourself!")); $this->redirect(array('action' => 'index')); - } else { - if ($this->User->delete($id)) { - $this->Session->setFlash(__('User deleted')); - $this->redirect(array('action'=>'index')); - } - } + } else { + if ($this->User->delete($id)) { + $this->Session->setFlash(__('User deleted')); + $this->redirect(array('action'=>'index')); + } + } $this->Session->setFlash(__('User was not deleted')); $this->redirect(array('action' => 'index')); } diff --git a/app/Model/Tutorial.php b/app/Model/Tutorial.php index 80de256..27bcd8d 100644 --- a/app/Model/Tutorial.php +++ b/app/Model/Tutorial.php @@ -80,7 +80,7 @@ function checkTitleLength($check, $sidebysideLimit, $externalLimit) { // Why isn't this field always included? Probably because it's not in the post data. $full_data = $this->findById($this->id); - if ($full_data['Tutorial']['tutorial_type_id'] == 1) { // Side-by-side (QuickHelp) tutorials + if (isset($full_data['Tutorial']) && $full_data['Tutorial']['tutorial_type_id'] == 1) { // Side-by-side (QuickHelp) tutorials $maxlength = $sidebysideLimit; $error = "Titles of QuickHelp tutorials cannot be longer than $maxlength characters."; } else { diff --git a/app/Model/User.php b/app/Model/User.php index 17d5045..e7c3e5c 100644 --- a/app/Model/User.php +++ b/app/Model/User.php @@ -40,7 +40,7 @@ function enforceComplexity($check) { } function beforeValidate($options = array()) { - if ($this->data['User']['keep_password']) { + if (isset($this->data['User']['keep_password']) && $this->data['User']['keep_password']) { // don't validate and don't let the password be set unset($this->validate['password']); unset($this->data['User']['password']);