diff --git a/administrator/components/com_admin/sql/updates/mysql/3.4.2-2015-05-03.sql b/administrator/components/com_admin/sql/updates/mysql/3.4.2-2015-05-03.sql new file mode 100644 index 0000000000000..e2921fc346193 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.4.2-2015-05-03.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(452, 'plg_system_updatenotification', 'plugin', 'updatenotification', 'system', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.4.2-2015-05-03.sql b/administrator/components/com_admin/sql/updates/postgresql/3.4.2-2015-05-03.sql new file mode 100644 index 0000000000000..895cf8faf99e6 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.4.2-2015-05-03.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(452, 'plg_system_updatenotification', 'plugin', 'updatenotification', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.4.2-2015-05-03.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.4.2-2015-05-03.sql new file mode 100644 index 0000000000000..0435fa8fa6402 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.4.2-2015-05-03.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT [#__extensions] ON; + +INSERT [#__extensions] ([extension_id], [name], [type], [element], [folder], [client_id], [enabled], [access], [protected], [manifest_cache], [params], [custom_data], [system_data], [checked_out], [checked_out_time], [ordering], [state]) +SELECT 452, 'plg_system_updatenotification', 'plugin', 'updatenotification', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0; + +SET IDENTITY_INSERT [#__extensions] OFF; diff --git a/administrator/language/en-GB/en-GB.plg_system_updatenotification.ini b/administrator/language/en-GB/en-GB.plg_system_updatenotification.ini new file mode 100644 index 0000000000000..bca688cb3049c --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_system_updatenotification.ini @@ -0,0 +1,23 @@ +; Joomla! Project +; Copyright (C) 2005 - 2015 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_UPDATENOTIFICATION="System - Joomla! Update Notification" +PLG_SYSTEM_UPDATENOTIFICATION_DESCRIPTION="This plugin periodically checks for the availability of new Joomla! versions. When one is found it will send you an email, reminding you to update Joomla!. Pro Tip: You can customise the email message by overriding the language string keys PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_SUBJECT and PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_BODY." + +PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_LBL="Super User Emails" +PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_DESC="A comma separated list of the email addresses which will receive the update notification emails. The addresses in the list MUST belong to existing users of your site who have the Super User privilege. If none of the listed emails belogns to Super Users, or if it's left blank, all Super Users of this site will receive the update notification email." +PLG_SYSTEM_UPDATENOTIFICATION_LANGUAGE_OVERRIDE_LBL="Email language" +PLG_SYSTEM_UPDATENOTIFICATION_LANGUAGE_OVERRIDE_DESC="If you choose Auto (default), the update notification email to Super Users will be in the logged in user's front-end language at the time the plugin is triggered. In multi-language sites this can create confusion: the user's language may be one the Super User receiving the email doesn't speak. By selecting a language here you are forcing the update notification emails to be sent in this specific language." +PLG_SYSTEM_UPDATENOTIFICATION_LANGUAGE_OVERRIDE_NONE="Auto" + +; You can use the following merge codes: +; [NEWVERSION] New Joomla! version, e.g. 1.2.3 +; [CURVERSION] Currently installed Joomla! version, e.g. 1.2.0 +; [SITENAME] Site name, as set in Global Configuration. +; [URL] URL of the site's front-end page. +; [LINK] Update URL (link to com_joomlaupdate, will request login if the Super User isn't already logged in). +; \n Newline character. Use it to start a new line in the email. NO LINE SHOULD EXCEED 300 CHARACTERS! +PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_SUBJECT="Joomla! Update available for [SITENAME] – [URL]" +PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_BODY="This email IS NOT sent by Joomla.org It is sent automatically by your own site,\n[SITENAME]\n\n================================================================================\nUPDATE INFORMATION\n================================================================================\n\nYour site has discovered that there is an updated version of Joomla! available\nfor download.\n\nJoomla! version currently installed: [CURVERSION]\nJoomla! version available for installation: [NEWVERSION]\n\nThis email is sent to you by your site to remind you of this fact. The Joomla!\nproject will never contact you directly about available updates of Joomla! on\nyour site.\n\n================================================================================\nUPDATE INSTRUCTIONS\n================================================================================\n\nTo install the update on [SITENAME] please click the following link. (If the URL\nis not a link, simply copy & paste it to your browser).\n\nUpdate link: [LINK]\n\n================================================================================\nWHY AM I RECEIVING THIS EMAIL?\n================================================================================\n\nThis email has been automatically sent by a plugin provided by Joomla!, the\nsoftware which powers your site. This plugin looks for updated versions of\nJoomla! and sends an email notification to its administrators. You will receive\nseveral similar emails from your site until you either update the software or\ndisable these emails.\n\nTo disable these emails, please unpublish the 'System - Joomla! Update\nNotification' plugin in the Plugin Manager on your site.\n\nIf you do not understand what is Joomla! and what you need to do please do not\ncontact the Joomla! project. They are NOT sending you this email and they cannot\nhelp you. Instead, please contact the person who built or manages your site.\n\nIf you are the person who built or manages your website, please note that this\nplugin may have been activated automatically when you installed or updated Joomla!\non your site.\n\n================================================================================\nWHO SENT ME THIS EMAIL?\n================================================================================\n\nThis email is sent to you by your own site, [SITENAME]" \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_system_updatenotification.sys.ini b/administrator/language/en-GB/en-GB.plg_system_updatenotification.sys.ini new file mode 100644 index 0000000000000..894a51561a1ca --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_system_updatenotification.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2015 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_UPDATENOTIFICATION="System - Joomla! Update Notification" +PLG_SYSTEM_UPDATENOTIFICATION_DESCRIPTION="This plugin periodically checks for the availability of new Joomla! versions. When one is found it will send you an email, reminding you to update Joomla!. Pro Tip: You can customise the email message by overriding the language string keys PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_SUBJECT and PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_BODY." \ No newline at end of file diff --git a/composer.json b/composer.json index 6bde779989852..905e1614efdea 100644 --- a/composer.json +++ b/composer.json @@ -10,12 +10,14 @@ }, "require": { "php": ">=5.3.10", - "joomla/application": "~1.2", + "joomla/application": "~1.4", "joomla/di": "~1.2", - "joomla/registry": "~1.2", - "joomla/string": "~1.2", + "joomla/event": "~1.1", + "joomla/registry": "~1.4 >=1.4.5", + "joomla/session": "~1.2", + "joomla/string": "~1.3", "joomla/uri": "~1.1", - "joomla/utilities": "~1.3", + "joomla/utilities": "~1.3 >=1.3.3", "ircmaxell/password-compat": "1.*", "leafo/lessphp": "0.3.9", "phpmailer/phpmailer": "5.2.9", diff --git a/composer.lock b/composer.lock index 851ef2c8e375c..9de6606e5d5e1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "385d58b11d816b21d0484b902310db7e", + "hash": "a305fbfdb073d809dbff32a3210e110f", "packages": [ { "name": "ircmaxell/password-compat", @@ -50,32 +50,35 @@ }, { "name": "joomla/application", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/joomla-framework/application.git", - "reference": "b7745273664294387bdd7fb694d75e65b7491f28" + "reference": "185b68fe55537281385b637a90e11856ea01c8da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/joomla-framework/application/zipball/b7745273664294387bdd7fb694d75e65b7491f28", - "reference": "b7745273664294387bdd7fb694d75e65b7491f28", + "url": "https://api.github.com/repos/joomla-framework/application/zipball/185b68fe55537281385b637a90e11856ea01c8da", + "reference": "185b68fe55537281385b637a90e11856ea01c8da", "shasum": "" }, "require": { "joomla/input": "~1.2", "joomla/registry": "~1.1", - "joomla/session": "~1.1", - "joomla/string": "~1.1", - "joomla/uri": "~1.1", "php": ">=5.3.10", "psr/log": "~1.0" }, "require-dev": { + "joomla/session": "~1.1", "joomla/test": "~1.1", + "joomla/uri": "~1.1", "phpunit/phpunit": "4.*", "squizlabs/php_codesniffer": "1.*" }, + "suggest": { + "joomla/session": "To use AbstractWebApplication with session support, install joomla/session", + "joomla/uri": "To use AbstractWebApplication, install joomla/uri" + }, "type": "joomla-package", "extra": { "branch-alias": { @@ -99,7 +102,7 @@ "framework", "joomla" ], - "time": "2014-10-13 12:43:54" + "time": "2015-03-06 17:37:01" }, { "name": "joomla/compat", @@ -325,21 +328,21 @@ }, { "name": "joomla/registry", - "version": "1.4.4", + "version": "1.4.5", "source": { "type": "git", "url": "https://github.com/joomla-framework/registry.git", - "reference": "730467978ad52677903e973bb33be2306eb161eb" + "reference": "4f926ba961ca45eb95076a1598c3ae689cb02fc5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/joomla-framework/registry/zipball/730467978ad52677903e973bb33be2306eb161eb", - "reference": "730467978ad52677903e973bb33be2306eb161eb", + "url": "https://api.github.com/repos/joomla-framework/registry/zipball/4f926ba961ca45eb95076a1598c3ae689cb02fc5", + "reference": "4f926ba961ca45eb95076a1598c3ae689cb02fc5", "shasum": "" }, "require": { "joomla/compat": "~1.0", - "joomla/string": "~1.2", + "joomla/string": "~1.3", "joomla/utilities": "~1.0", "php": ">=5.3.10" }, @@ -375,7 +378,7 @@ "joomla", "registry" ], - "time": "2015-03-16 18:49:29" + "time": "2015-03-28 17:54:38" }, { "name": "joomla/session", @@ -424,16 +427,16 @@ }, { "name": "joomla/string", - "version": "1.2.2", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/joomla-framework/string.git", - "reference": "9f7b27d6b2d48d65b2fe81b5c6d72225629ad692" + "reference": "0df8ead8c726a1f648e624d3bcbef8cf05c1d0da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/joomla-framework/string/zipball/9f7b27d6b2d48d65b2fe81b5c6d72225629ad692", - "reference": "9f7b27d6b2d48d65b2fe81b5c6d72225629ad692", + "url": "https://api.github.com/repos/joomla-framework/string/zipball/0df8ead8c726a1f648e624d3bcbef8cf05c1d0da", + "reference": "0df8ead8c726a1f648e624d3bcbef8cf05c1d0da", "shasum": "" }, "require": { @@ -467,7 +470,7 @@ "joomla", "string" ], - "time": "2015-03-13 12:29:00" + "time": "2015-03-26 01:02:20" }, { "name": "joomla/uri", @@ -508,20 +511,20 @@ }, { "name": "joomla/utilities", - "version": "1.3.2", + "version": "1.3.3", "source": { "type": "git", "url": "https://github.com/joomla-framework/utilities.git", - "reference": "2e7f37a69162fea02059c764a318a920121f8b4a" + "reference": "3e43b0806c194a92b58a176b73d6cc2dc6c9c3a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/joomla-framework/utilities/zipball/2e7f37a69162fea02059c764a318a920121f8b4a", - "reference": "2e7f37a69162fea02059c764a318a920121f8b4a", + "url": "https://api.github.com/repos/joomla-framework/utilities/zipball/3e43b0806c194a92b58a176b73d6cc2dc6c9c3a4", + "reference": "3e43b0806c194a92b58a176b73d6cc2dc6c9c3a4", "shasum": "" }, "require": { - "joomla/string": "~1.0", + "joomla/string": "~1.3", "php": ">=5.3.10" }, "require-dev": { @@ -551,7 +554,7 @@ "joomla", "utilities" ], - "time": "2015-03-16 18:50:58" + "time": "2015-03-28 17:52:43" }, { "name": "leafo/lessphp", diff --git a/installation/sql/mysql/joomla.sql b/installation/sql/mysql/joomla.sql index 1fcc2322cd4e1..1c6bc04112472 100644 --- a/installation/sql/mysql/joomla.sql +++ b/installation/sql/mysql/joomla.sql @@ -610,6 +610,7 @@ INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder` (449, 'plg_authentication_cookie', 'plugin', 'cookie', 'authentication', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (450, 'plg_twofactorauth_yubikey', 'plugin', 'yubikey', 'twofactorauth', 0, 0, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (451, 'plg_search_tags', 'plugin', 'tags', 'search', 0, 1, 1, 0, '', '{"search_limit":"50","show_tagged_items":"1"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(452, 'plg_system_updatenotification', 'plugin', 'updatenotification', 'system', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (503, 'beez3', 'template', 'beez3', '', 0, 1, 1, 0, '', '{"wrapperSmall":"53","wrapperLarge":"72","sitetitle":"","sitedescription":"","navposition":"center","templatecolor":"nature"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (504, 'hathor', 'template', 'hathor', '', 1, 1, 1, 0, '', '{"showSiteName":"0","colourChoice":"0","boldText":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (506, 'protostar', 'template', 'protostar', '', 0, 1, 1, 0, '', '{"templateColor":"","logoFile":"","googleFont":"1","googleFontName":"Open+Sans","fluidContainer":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), diff --git a/installation/sql/postgresql/joomla.sql b/installation/sql/postgresql/joomla.sql index 876d4263487aa..cdf03653eaece 100644 --- a/installation/sql/postgresql/joomla.sql +++ b/installation/sql/postgresql/joomla.sql @@ -610,7 +610,8 @@ INSERT INTO "#__extensions" ("extension_id", "name", "type", "element", "folder" (448, 'plg_twofactorauth_totp', 'plugin', 'totp', 'twofactorauth', 0, 0, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), (449, 'plg_authentication_cookie', 'plugin', 'cookie', 'authentication', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), (450, 'plg_twofactorauth_yubikey', 'plugin', 'yubikey', 'twofactorauth', 0, 0, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(451, 'plg_search_tags', 'plugin', 'tags', 'search', 0, 1, 1, 0, '', '{"search_limit":"50","show_tagged_items":"1"}', '', '', 0, '1970-01-01 00:00:00', 0, 0); +(451, 'plg_search_tags', 'plugin', 'tags', 'search', 0, 1, 1, 0, '', '{"search_limit":"50","show_tagged_items":"1"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(452, 'plg_system_updatenotification', 'plugin', 'updatenotification', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); -- Templates INSERT INTO "#__extensions" ("extension_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES diff --git a/installation/sql/sqlazure/joomla.sql b/installation/sql/sqlazure/joomla.sql index 9ef97578f6c9d..b0d54edddb22a 100644 --- a/installation/sql/sqlazure/joomla.sql +++ b/installation/sql/sqlazure/joomla.sql @@ -1011,7 +1011,9 @@ SELECT 449, 'plg_authentication_cookie', 'plugin', 'cookie', 'authentication', 0 UNION ALL SELECT 450, 'plg_twofactorauth_yubikey', 'plugin', 'yubikey', 'twofactorauth', 0, 0, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 UNION ALL -SELECT 451, 'plg_search_tags', 'plugin', 'tags', 'search', 0, 1, 1, 0, '', '{"search_limit":"50","show_tagged_items":"1"}', '', '', 0, '1900-01-01 00:00:00', 0, 0; +SELECT 451, 'plg_search_tags', 'plugin', 'tags', 'search', 0, 1, 1, 0, '', '{"search_limit":"50","show_tagged_items":"1"}', '', '', 0, '1900-01-01 00:00:00', 0, 0 +UNION ALL +SELECT 452, 'plg_system_updatenotification', 'plugin', 'updatenotification', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0; INSERT [#__extensions] ([extension_id], [name], [type], [element], [folder], [client_id], [enabled], [access], [protected], [manifest_cache], [params], [custom_data], [system_data], [checked_out], [checked_out_time], [ordering], [state]) diff --git a/libraries/cms/component/router/base.php b/libraries/cms/component/router/base.php index a75a5924892c9..bdf19b48859f5 100644 --- a/libraries/cms/component/router/base.php +++ b/libraries/cms/component/router/base.php @@ -48,7 +48,7 @@ public function __construct($app = null, $menu = null) } else { - $this->app = JFactory::getApplication(); + $this->app = JFactory::getApplication('site'); } if ($menu) diff --git a/libraries/cms/component/router/rules/menu.php b/libraries/cms/component/router/rules/menu.php new file mode 100644 index 0000000000000..b2227693b3266 --- /dev/null +++ b/libraries/cms/component/router/rules/menu.php @@ -0,0 +1,215 @@ +router = $router; + + $this->buildLookup(); + } + + /** + * Finds the right Itemid for this query + * + * @param array &$query The query array to process + * + * @return void + * + * @since 3.4 + */ + public function preprocess(&$query) + { + if (isset($query['Itemid']) && $query['Itemid'] != $this->router->menu->getActive()->id) + { + return; + } + + $language = '*'; + if (isset($query['lang'])) + { + $language = $query['lang']; + + if (!isset($this->lookup[$query['lang']])) + { + $this->buildLookup($query['lang']); + } + } + + $needles = $this->router->getPath($query); + + if ($needles) + { + foreach ($needles as $view => $ids) + { + if (isset($this->lookup[$language][$view])) + { + if (is_bool($ids)) + { + $query['Itemid'] = $this->lookup[$language][$view]; + return; + } + foreach ($ids as $id) + { + if (isset($this->lookup[$language][$view][(int) $id])) + { + $query['Itemid'] = $this->lookup[$language][$view][(int) $id]; + return; + } + } + } + } + } + + // Check if the active menuitem matches the requested language + $active = $this->router->menu->getActive(); + + if ($active && $active->component == 'com_' . $this->router->getName() + && ($language == '*' || in_array($active->language, array('*', $language)) || !JLanguageMultilang::isEnabled())) + { + $query['Itemid'] = $active->id; + return; + } + + // If not found, return language specific home link + $default = $this->router->menu->getDefault($language); + + if (!empty($default->id)) + { + $query['Itemid'] = $default->id; + } + } + + /** + * Method to build the lookup array + * + * @param string $language The language that the lookup should be built up for + * + * @return void + * + * @since 3.4 + */ + protected function buildLookup($language = '*') + { + // Prepare the reverse lookup array. + if (!isset($this->lookup[$language])) + { + $this->lookup[$language] = array(); + + $component = JComponentHelper::getComponent('com_' . $this->router->getName()); + $views = $this->router->getViews(); + + $attributes = array('component_id'); + $values = array((int) $component->id); + + $attributes[] = 'language'; + $values[] = array($language, '*'); + + $items = $this->router->menu->getItems($attributes, $values); + + foreach ($items as $item) + { + if (isset($item->query) && isset($item->query['view'])) + { + $view = $item->query['view']; + + if ($views[$view]->key) + { + if (!isset($this->lookup[$language][$view])) + { + $this->lookup[$language][$view] = array(); + } + + /** + * Here it will become a bit tricky + * language != * can override existing entries + * language == * cannot override existing entries + */ + if (isset($item->query[$views[$view]->key]) + && (!isset($this->lookup[$language][$view][$item->query[$views[$view]->key]]) || $item->language != '*')) + { + $this->lookup[$language][$view][$item->query['id']] = $item->id; + } + } + else + { + /** + * Here it will become a bit tricky + * language != * can override existing entries + * language == * cannot override existing entries + */ + if (!isset($this->lookup[$language][$view]) || $item->language != '*') + { + $this->lookup[$language][$view] = $item->id; + } + } + } + } + } + } + + /** + * Dummymethod to fullfill the interface requirements + * + * @param array &$segments The URL segments to parse + * @param array &$vars The vars that result from the segments + * + * @return void + * + * @since 3.4 + * @codeCoverageIgnore + */ + public function parse(&$segments, &$vars) + { + } + + /** + * Dummymethod to fullfill the interface requirements + * + * @param array &$query The vars that should be converted + * @param array &$segments The URL segments to create + * + * @return void + * + * @since 3.4 + * @codeCoverageIgnore + */ + public function build(&$query, &$segments) + { + } +} diff --git a/libraries/cms/component/router/rules/nomenu.php b/libraries/cms/component/router/rules/nomenu.php new file mode 100644 index 0000000000000..f0d269d23b2d7 --- /dev/null +++ b/libraries/cms/component/router/rules/nomenu.php @@ -0,0 +1,110 @@ +router = $router; + } + + /** + * Dummymethod to fullfill the interface requirements + * + * @param array &$query The query array to process + * + * @return void + * + * @since 3.4 + * @codeCoverageIgnore + */ + public function preprocess(&$query) + { + } + + /** + * Parse a menu-less URL + * + * @param array &$segments The URL segments to parse + * @param array &$vars The vars that result from the segments + * + * @return void + * + * @since 3.4 + */ + public function parse(&$segments, &$vars) + { + $active = $this->router->menu->getActive(); + + if (!is_object($active)) + { + $views = $this->router->getViews(); + + if (isset($views[$segments[0]])) + { + $vars['view'] = array_shift($segments); + + if (isset($views[$vars['view']]->key) && isset($segments[0])) + { + $vars[$views[$vars['view']]->key] = preg_replace('/-/', ':', array_shift($segments), 1); + } + } + } + } + + /** + * Build a menu-less URL + * + * @param array &$query The vars that should be converted + * @param array &$segments The URL segments to create + * + * @return void + * + * @since 3.4 + */ + public function build(&$query, &$segments) + { + if (!isset($query['Itemid']) && isset($query['view'])) + { + $views = $this->router->getViews(); + if (isset($views[$query['view']])) + { + $segments[] = $query['view']; + + if ($views[$query['view']]->key) + { + $key = $views[$query['view']]->key; + $segments[] = str_replace(':', '-', $query[$key]); + unset($query[$views[$query['view']]->key]); + } + unset($query['view']); + } + } + } +} diff --git a/libraries/cms/component/router/view.php b/libraries/cms/component/router/view.php new file mode 100644 index 0000000000000..91e8f32285183 --- /dev/null +++ b/libraries/cms/component/router/view.php @@ -0,0 +1,264 @@ +views[$view->name] = $view; + } + + /** + * Return an array of registered view objects + * + * @return JComponentRouterViewconfiguration[] Array of registered view objects + * + * @since 3.4 + */ + public function getViews() + { + return $this->views; + } + + /** + * Get the path of views from target view to root view + * including content items of a nestable view + * + * @param array $query Array of query elements + * + * @return array List of views including IDs of content items + */ + public function getPath($query) + { + $views = $this->getViews(); + $result = array(); + $key = false; + + // Get the right view object + if (isset($query['view']) && $views[$query['view']]) + { + $viewobj = $views[$query['view']]; + } + + // Get the path from the current item to the root view with all IDs + if (isset($viewobj)) + { + $path = array_reverse($viewobj->path); + $start = true; + $childkey = false; + + foreach ($path as $element) + { + $view = $views[$element]; + + if ($start) + { + $key = $view->key; + $start = false; + } + else + { + $key = $childkey; + } + $childkey = $view->parent_key; + + if ($key && isset($query[$key]) && is_callable(array($this, 'get' . ucfirst($view->name) . 'Segment'))) + { + $result[$view->name] = call_user_func_array(array($this, 'get' . ucfirst($view->name) . 'Segment'), array($query[$key], $query)); + } + else + { + $result[$view->name] = true; + } + } + } + return $result; + } + + /** + * Get all currently attached rules + * + * @return JComponentRouterRulesInterface[] All currently attached rules in an array + * + * @since 3.4 + */ + public function getRules() + { + return $this->rules; + } + + /** + * Add a number of router rules to the object + * + * @param JComponentRouterRulesInterface[] $rules Array of JComponentRouterRulesInterface objects + * + * @return void + * + * @since 3.4 + */ + public function attachRules($rules) + { + foreach ($rules as $rule) + { + $this->attachRule($rule); + } + } + + /** + * Attach a build rule + * + * @param JComponentRouterRulesInterface $rule The function to be called. + * + * @return void + */ + public function attachRule(JComponentRouterRulesInterface $rule) + { + $this->rules[] = $rule; + } + + /** + * Remove a build rule + * + * @param JComponentRouterRulesInterface $rule The rule to be removed. + * + * @return boolean Was a rule removed? + */ + public function detachRule(JComponentRouterRulesInterface $rule) + { + foreach ($this->rules as $id => $r) + { + if ($r == $rule) + { + unset($this->rules[$id]); + return true; + } + } + + return false; + } + + /** + * Generic method to preprocess a URL + * + * @param array $query An associative array of URL arguments + * + * @return array The URL arguments to use to assemble the subsequent URL. + * + * @since 3.3 + */ + public function preprocess($query) + { + // Process the parsed variables based on custom defined rules + foreach ($this->rules as $rule) + { + $rule->preprocess($query); + } + return $query; + } + + /** + * Build method for URLs + * + * @param array &$query Array of query elements + * + * @return array Array of URL segments + */ + public function build(&$query) + { + $segments = array(); + + // Process the parsed variables based on custom defined rules + foreach ($this->rules as $rule) + { + $rule->build($query, $segments); + } + return $segments; + } + + /** + * Parse method for URLs + * + * @param array &$segments Array of URL string-segments + * + * @return array Associative array of query values + */ + public function parse(&$segments) + { + $vars = array(); + + // Process the parsed variables based on custom defined rules + foreach ($this->rules as $rule) + { + $rule->parse($segments, $vars); + } + return $vars; + } + + /** + * Method to return the name of the router + * + * @return string Name of the router + * + * @since 3.4 + */ + public function getName() + { + if (empty($this->name)) + { + $r = null; + if (!preg_match('/(.*)Router/i', get_class($this), $r)) + { + throw new Exception('JLIB_APPLICATION_ERROR_ROUTER_GET_NAME', 500); + } + $this->name = strtolower($r[1]); + } + + return $this->name; + } +} diff --git a/libraries/cms/component/router/viewconfiguration.php b/libraries/cms/component/router/viewconfiguration.php new file mode 100644 index 0000000000000..1511e805f0f58 --- /dev/null +++ b/libraries/cms/component/router/viewconfiguration.php @@ -0,0 +1,229 @@ +name = $name; + $this->path[] = $name; + } + + /** + * Set the name of the view + * + * @param string $name Name of the view + * + * @return JComponentRouterViewconfiguration This object for chaining + * @since 3.4 + */ + public function setName($name) + { + $this->name = $name; + + array_pop($this->path); + $this->path[] = $name; + + return $this; + } + + /** + * Set the key-identifier for the view + * + * @param string $key Key of the view + * + * @return JComponentRouterViewconfiguration This object for chaining + * @since 3.4 + */ + public function setKey($key) + { + $this->key = $key; + + return $this; + } + + /** + * Set the parent view of this view + * + * @param JComponentRouterViewconfiguration $parent Parent view object + * @param string $parent_key Key of the parent view in this context + * + * @return JComponentRouterViewconfiguration This object for chaining + * @since 3.4 + */ + public function setParent(JComponentRouterViewconfiguration $parent, $parent_key = false) + { + if ($this->parent) + { + $key = array_search($this, $this->parent->children); + + if ($key !== false) + { + unset($this->parent->children[$key]); + } + + if ($this->parent_key) { + $child_key = array_search($this->parent_key, $this->parent->child_keys); + unset($this->parent->child_keys[$child_key]); + } + } + + $this->parent = $parent; + $parent->children[] = $this; + + $this->path = $parent->path; + $this->path[] = $this->name; + + $this->parent_key = $parent_key; + + if ($parent_key) + { + $parent->child_keys[] = $parent_key; + } + + return $this; + } + + /** + * Set if this view is nestable or not + * + * @param bool $isNestable If set to true, the view is nestable + * + * @return JComponentRouterViewconfiguration This object for chaining + * @since 3.4 + */ + public function setNestable($isNestable = true) + { + $this->nestable = (bool) $isNestable; + + return $this; + } + + /** + * Add a layout to this view + * + * @param string $layout Layouts that this view supports + * + * @return JComponentRouterViewconfiguration This object for chaining + * @since 3.4 + */ + public function addLayout($layout) + { + array_push($this->layouts, $layout); + $this->layouts = array_unique($this->layouts); + + return $this; + } + + /** + * Remove a layout from this view + * + * @param string $layout Layouts that this view supports + * + * @return JComponentRouterViewconfiguration This object for chaining + * @since 3.4 + */ + public function removeLayout($layout) + { + $key = array_search($layout, $this->layouts); + + if ($key !== false) + { + unset($this->layouts[$key]); + } + + return $this; + } +} diff --git a/libraries/joomla/string/string.php b/libraries/joomla/string/string.php index 2d06d771097ff..526c2e4102888 100644 --- a/libraries/joomla/string/string.php +++ b/libraries/joomla/string/string.php @@ -9,7 +9,7 @@ defined('JPATH_PLATFORM') or die; -use Joomla\String\String; +use Joomla\String\StringHelper; /** * String handling class for utf-8 data @@ -17,9 +17,9 @@ * All functions assume the validity of utf-8 strings. * * @since 11.1 - * @deprecated 4.0 Use {@link \Joomla\String\String} instead unless otherwise noted. + * @deprecated 4.0 Use {@link \Joomla\String\StringHelper} instead unless otherwise noted. */ -abstract class JString extends String +abstract class JString extends StringHelper { /** * Split a string in camel case format diff --git a/libraries/joomla/updater/updater.php b/libraries/joomla/updater/updater.php index b260b701d5ae8..be96c27d51aec 100644 --- a/libraries/joomla/updater/updater.php +++ b/libraries/joomla/updater/updater.php @@ -100,9 +100,9 @@ public static function getInstance() /** * Finds an update for an extension * - * @param integer $eid Extension Identifier; if zero use all sites - * @param integer $cacheTimeout How many seconds to cache update information; if zero, force reload the update information - * @param integer $minimum_stability Minimum stability for the updates; 0=dev, 1=alpha, 2=beta, 3=rc, 4=stable + * @param int|array $eid Extension Identifier or list of Extension Identifiers; if zero use all sites + * @param integer $cacheTimeout How many seconds to cache update information; if zero, force reload the update information + * @param integer $minimum_stability Minimum stability for the updates; 0=dev, 1=alpha, 2=beta, 3=rc, 4=stable * * @return boolean True if there are updates * diff --git a/libraries/vendor/autoload.php b/libraries/vendor/autoload.php index baecd9740292a..4cc388d9f7229 100644 --- a/libraries/vendor/autoload.php +++ b/libraries/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer' . '/autoload_real.php'; -return ComposerAutoloaderInitf9aed076f12471aff0049364a504b3f7::getLoader(); +return ComposerAutoloaderInit0efb534ee20646bcb987f4359c38b3aa::getLoader(); diff --git a/libraries/vendor/composer/autoload_real.php b/libraries/vendor/composer/autoload_real.php index 60bdad1198a32..024522060c11a 100644 --- a/libraries/vendor/composer/autoload_real.php +++ b/libraries/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInitf9aed076f12471aff0049364a504b3f7 +class ComposerAutoloaderInit0efb534ee20646bcb987f4359c38b3aa { private static $loader; @@ -19,9 +19,9 @@ public static function getLoader() return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInitf9aed076f12471aff0049364a504b3f7', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit0efb534ee20646bcb987f4359c38b3aa', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInitf9aed076f12471aff0049364a504b3f7', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit0efb534ee20646bcb987f4359c38b3aa', 'loadClassLoader')); $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -42,14 +42,14 @@ public static function getLoader() $includeFiles = require __DIR__ . '/autoload_files.php'; foreach ($includeFiles as $file) { - composerRequiref9aed076f12471aff0049364a504b3f7($file); + composerRequire0efb534ee20646bcb987f4359c38b3aa($file); } return $loader; } } -function composerRequiref9aed076f12471aff0049364a504b3f7($file) +function composerRequire0efb534ee20646bcb987f4359c38b3aa($file) { require $file; } diff --git a/libraries/vendor/composer/installed.json b/libraries/vendor/composer/installed.json index 1f834aefe431c..dbd823136ee3d 100644 --- a/libraries/vendor/composer/installed.json +++ b/libraries/vendor/composer/installed.json @@ -116,92 +116,6 @@ "uri" ] }, - { - "name": "joomla/event", - "version": "1.1.1", - "version_normalized": "1.1.1.0", - "source": { - "type": "git", - "url": "https://github.com/joomla-framework/event.git", - "reference": "bb957bc45aba897e465384bbe21cd0eb79aca901" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/joomla-framework/event/zipball/bb957bc45aba897e465384bbe21cd0eb79aca901", - "reference": "bb957bc45aba897e465384bbe21cd0eb79aca901", - "shasum": "" - }, - "require": { - "php": ">=5.3.10" - }, - "time": "2014-02-09 01:30:54", - "type": "joomla-package", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Joomla\\Event\\": "src/", - "Joomla\\Event\\Tests\\": "Tests/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-2.0+" - ], - "description": "Joomla Event Package", - "homepage": "https://github.com/joomla-framework/event", - "keywords": [ - "event", - "framework", - "joomla" - ] - }, - { - "name": "joomla/session", - "version": "1.2.3", - "version_normalized": "1.2.3.0", - "target-dir": "Joomla/Session", - "source": { - "type": "git", - "url": "https://github.com/joomla-framework/session.git", - "reference": "ef955cf9642793c4ad5874f334069051c33ba604" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/joomla-framework/session/zipball/ef955cf9642793c4ad5874f334069051c33ba604", - "reference": "ef955cf9642793c4ad5874f334069051c33ba604", - "shasum": "" - }, - "require": { - "joomla/event": "~1.1", - "joomla/filter": "~1.0", - "php": ">=5.3.10" - }, - "require-dev": { - "joomla/test": "~1.0" - }, - "suggest": { - "joomla/database": "Install joomla/database if you want to use Database session storage." - }, - "time": "2014-08-18 17:41:06", - "type": "joomla-package", - "installation-source": "dist", - "autoload": { - "psr-0": { - "Joomla\\Session": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-2.0+" - ], - "description": "Joomla Session Package", - "homepage": "https://github.com/joomla-framework/session", - "keywords": [ - "framework", - "joomla", - "session" - ] - }, { "name": "leafo/lessphp", "version": "v0.3.9", @@ -295,61 +209,6 @@ "joomla" ] }, - { - "name": "joomla/application", - "version": "1.3.0", - "version_normalized": "1.3.0.0", - "source": { - "type": "git", - "url": "https://github.com/joomla-framework/application.git", - "reference": "b7745273664294387bdd7fb694d75e65b7491f28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/joomla-framework/application/zipball/b7745273664294387bdd7fb694d75e65b7491f28", - "reference": "b7745273664294387bdd7fb694d75e65b7491f28", - "shasum": "" - }, - "require": { - "joomla/input": "~1.2", - "joomla/registry": "~1.1", - "joomla/session": "~1.1", - "joomla/string": "~1.1", - "joomla/uri": "~1.1", - "php": ">=5.3.10", - "psr/log": "~1.0" - }, - "require-dev": { - "joomla/test": "~1.1", - "phpunit/phpunit": "4.*", - "squizlabs/php_codesniffer": "1.*" - }, - "time": "2014-10-13 12:43:54", - "type": "joomla-package", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Joomla\\Application\\": "src/", - "Joomla\\Application\\Tests\\": "Tests/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-2.0+" - ], - "description": "Joomla Application Package", - "homepage": "https://github.com/joomla-framework/application", - "keywords": [ - "application", - "framework", - "joomla" - ] - }, { "name": "ircmaxell/password-compat", "version": "v1.0.4", @@ -605,17 +464,17 @@ }, { "name": "joomla/string", - "version": "1.2.2", - "version_normalized": "1.2.2.0", + "version": "1.3.0", + "version_normalized": "1.3.0.0", "source": { "type": "git", "url": "https://github.com/joomla-framework/string.git", - "reference": "9f7b27d6b2d48d65b2fe81b5c6d72225629ad692" + "reference": "0df8ead8c726a1f648e624d3bcbef8cf05c1d0da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/joomla-framework/string/zipball/9f7b27d6b2d48d65b2fe81b5c6d72225629ad692", - "reference": "9f7b27d6b2d48d65b2fe81b5c6d72225629ad692", + "url": "https://api.github.com/repos/joomla-framework/string/zipball/0df8ead8c726a1f648e624d3bcbef8cf05c1d0da", + "reference": "0df8ead8c726a1f648e624d3bcbef8cf05c1d0da", "shasum": "" }, "require": { @@ -626,7 +485,7 @@ "phpunit/phpunit": "4.*", "squizlabs/php_codesniffer": "1.*" }, - "time": "2015-03-13 12:29:00", + "time": "2015-03-26 01:02:20", "type": "joomla-package", "extra": { "branch-alias": { @@ -652,24 +511,73 @@ "string" ] }, + { + "name": "joomla/utilities", + "version": "1.3.3", + "version_normalized": "1.3.3.0", + "source": { + "type": "git", + "url": "https://github.com/joomla-framework/utilities.git", + "reference": "3e43b0806c194a92b58a176b73d6cc2dc6c9c3a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/joomla-framework/utilities/zipball/3e43b0806c194a92b58a176b73d6cc2dc6c9c3a4", + "reference": "3e43b0806c194a92b58a176b73d6cc2dc6c9c3a4", + "shasum": "" + }, + "require": { + "joomla/string": "~1.3", + "php": ">=5.3.10" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "squizlabs/php_codesniffer": "1.*" + }, + "time": "2015-03-28 17:52:43", + "type": "joomla-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Joomla\\Utilities\\": "src/", + "Joomla\\Utilities\\Tests\\": "Tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "description": "Joomla Utilities Package", + "homepage": "https://github.com/joomla-framework/utilities", + "keywords": [ + "framework", + "joomla", + "utilities" + ] + }, { "name": "joomla/registry", - "version": "1.4.4", - "version_normalized": "1.4.4.0", + "version": "1.4.5", + "version_normalized": "1.4.5.0", "source": { "type": "git", "url": "https://github.com/joomla-framework/registry.git", - "reference": "730467978ad52677903e973bb33be2306eb161eb" + "reference": "4f926ba961ca45eb95076a1598c3ae689cb02fc5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/joomla-framework/registry/zipball/730467978ad52677903e973bb33be2306eb161eb", - "reference": "730467978ad52677903e973bb33be2306eb161eb", + "url": "https://api.github.com/repos/joomla-framework/registry/zipball/4f926ba961ca45eb95076a1598c3ae689cb02fc5", + "reference": "4f926ba961ca45eb95076a1598c3ae689cb02fc5", "shasum": "" }, "require": { "joomla/compat": "~1.0", - "joomla/string": "~1.2", + "joomla/string": "~1.3", "joomla/utilities": "~1.0", "php": ">=5.3.10" }, @@ -682,7 +590,7 @@ "suggest": { "symfony/yaml": "Install 2.* if you require YAML support." }, - "time": "2015-03-16 18:49:29", + "time": "2015-03-28 17:54:38", "type": "joomla-package", "extra": { "branch-alias": { @@ -709,29 +617,38 @@ ] }, { - "name": "joomla/utilities", - "version": "1.3.2", - "version_normalized": "1.3.2.0", + "name": "joomla/application", + "version": "1.4.0", + "version_normalized": "1.4.0.0", "source": { "type": "git", - "url": "https://github.com/joomla-framework/utilities.git", - "reference": "2e7f37a69162fea02059c764a318a920121f8b4a" + "url": "https://github.com/joomla-framework/application.git", + "reference": "185b68fe55537281385b637a90e11856ea01c8da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/joomla-framework/utilities/zipball/2e7f37a69162fea02059c764a318a920121f8b4a", - "reference": "2e7f37a69162fea02059c764a318a920121f8b4a", + "url": "https://api.github.com/repos/joomla-framework/application/zipball/185b68fe55537281385b637a90e11856ea01c8da", + "reference": "185b68fe55537281385b637a90e11856ea01c8da", "shasum": "" }, "require": { - "joomla/string": "~1.0", - "php": ">=5.3.10" + "joomla/input": "~1.2", + "joomla/registry": "~1.1", + "php": ">=5.3.10", + "psr/log": "~1.0" }, "require-dev": { + "joomla/session": "~1.1", + "joomla/test": "~1.1", + "joomla/uri": "~1.1", "phpunit/phpunit": "4.*", "squizlabs/php_codesniffer": "1.*" }, - "time": "2015-03-16 18:50:58", + "suggest": { + "joomla/session": "To use AbstractWebApplication with session support, install joomla/session", + "joomla/uri": "To use AbstractWebApplication, install joomla/uri" + }, + "time": "2015-03-06 17:37:01", "type": "joomla-package", "extra": { "branch-alias": { @@ -741,20 +658,106 @@ "installation-source": "dist", "autoload": { "psr-4": { - "Joomla\\Utilities\\": "src/", - "Joomla\\Utilities\\Tests\\": "Tests/" + "Joomla\\Application\\": "src/", + "Joomla\\Application\\Tests\\": "Tests/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "GPL-2.0+" ], - "description": "Joomla Utilities Package", - "homepage": "https://github.com/joomla-framework/utilities", + "description": "Joomla Application Package", + "homepage": "https://github.com/joomla-framework/application", + "keywords": [ + "application", + "framework", + "joomla" + ] + }, + { + "name": "joomla/event", + "version": "1.1.1", + "version_normalized": "1.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/joomla-framework/event.git", + "reference": "bb957bc45aba897e465384bbe21cd0eb79aca901" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/joomla-framework/event/zipball/bb957bc45aba897e465384bbe21cd0eb79aca901", + "reference": "bb957bc45aba897e465384bbe21cd0eb79aca901", + "shasum": "" + }, + "require": { + "php": ">=5.3.10" + }, + "time": "2014-02-09 01:30:54", + "type": "joomla-package", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Joomla\\Event\\": "src/", + "Joomla\\Event\\Tests\\": "Tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "description": "Joomla Event Package", + "homepage": "https://github.com/joomla-framework/event", + "keywords": [ + "event", + "framework", + "joomla" + ] + }, + { + "name": "joomla/session", + "version": "1.2.3", + "version_normalized": "1.2.3.0", + "target-dir": "Joomla/Session", + "source": { + "type": "git", + "url": "https://github.com/joomla-framework/session.git", + "reference": "ef955cf9642793c4ad5874f334069051c33ba604" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/joomla-framework/session/zipball/ef955cf9642793c4ad5874f334069051c33ba604", + "reference": "ef955cf9642793c4ad5874f334069051c33ba604", + "shasum": "" + }, + "require": { + "joomla/event": "~1.1", + "joomla/filter": "~1.0", + "php": ">=5.3.10" + }, + "require-dev": { + "joomla/test": "~1.0" + }, + "suggest": { + "joomla/database": "Install joomla/database if you want to use Database session storage." + }, + "time": "2014-08-18 17:41:06", + "type": "joomla-package", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Joomla\\Session": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "description": "Joomla Session Package", + "homepage": "https://github.com/joomla-framework/session", "keywords": [ "framework", "joomla", - "utilities" + "session" ] } ] diff --git a/libraries/vendor/joomla/application/src/AbstractApplication.php b/libraries/vendor/joomla/application/src/AbstractApplication.php index a921e1fa07a88..9842c80ecfb23 100644 --- a/libraries/vendor/joomla/application/src/AbstractApplication.php +++ b/libraries/vendor/joomla/application/src/AbstractApplication.php @@ -2,7 +2,7 @@ /** * Part of the Joomla Framework Application Package * - * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ diff --git a/libraries/vendor/joomla/application/src/AbstractCliApplication.php b/libraries/vendor/joomla/application/src/AbstractCliApplication.php index 9c1c601bfcb69..6ba345c5511af 100644 --- a/libraries/vendor/joomla/application/src/AbstractCliApplication.php +++ b/libraries/vendor/joomla/application/src/AbstractCliApplication.php @@ -2,7 +2,7 @@ /** * Part of the Joomla Framework Application Package * - * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ diff --git a/libraries/vendor/joomla/application/src/AbstractDaemonApplication.php b/libraries/vendor/joomla/application/src/AbstractDaemonApplication.php index 0fb8ebf8d2c5e..4fadb812483cd 100644 --- a/libraries/vendor/joomla/application/src/AbstractDaemonApplication.php +++ b/libraries/vendor/joomla/application/src/AbstractDaemonApplication.php @@ -2,13 +2,12 @@ /** * Part of the Joomla Framework Application Package * - * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Application; -use Joomla\Filesystem\Folder; use Joomla\Registry\Registry; use Joomla\Input\Cli; use Psr\Log\LoggerAwareInterface; diff --git a/libraries/vendor/joomla/application/src/AbstractWebApplication.php b/libraries/vendor/joomla/application/src/AbstractWebApplication.php index 961bc69f47290..fcdcd0786febc 100644 --- a/libraries/vendor/joomla/application/src/AbstractWebApplication.php +++ b/libraries/vendor/joomla/application/src/AbstractWebApplication.php @@ -2,7 +2,7 @@ /** * Part of the Joomla Framework Application Package * - * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ @@ -10,7 +10,6 @@ use Joomla\Uri\Uri; use Joomla\Input\Input; -use Joomla\String\String; use Joomla\Session\Session; use Joomla\Registry\Registry; @@ -285,7 +284,7 @@ public function redirect($url, $moved = false) */ if (!preg_match('#^[a-z]+\://#i', $url)) { - // Get a JURI instance for the requested URI. + // Get a Uri instance for the requested URI. $uri = new Uri($this->get('uri.request')); // Get a base URL to prepend from the requested URI. @@ -314,7 +313,7 @@ public function redirect($url, $moved = false) else { // We have to use a JavaScript redirect here because MSIE doesn't play nice with utf-8 URLs. - if (($this->client->engine == Web\WebClient::TRIDENT) && !String::is_ascii($url)) + if (($this->client->engine == Web\WebClient::TRIDENT) && !$this->isAscii($url)) { $html = ''; $html .= ''; @@ -526,6 +525,11 @@ public function getBody($asArray = false) */ public function getSession() { + if ($this->session === null) + { + throw new \RuntimeException('A \Joomla\Session\Session object has not been set.'); + } + return $this->session; } @@ -776,7 +780,7 @@ public function checkToken($method = 'post') if (!$this->input->$method->get($token, '', 'alnum')) { - if ($this->session->isNew()) + if ($this->getSession()->isNew()) { // Redirect to login screen. $this->redirect('index.php'); @@ -808,6 +812,25 @@ public function getFormToken($forceNew = false) // @todo we need the user id somehow here $userId = 0; - return md5($this->get('secret') . $userId . $this->session->getToken($forceNew)); + return md5($this->get('secret') . $userId . $this->getSession()->getToken($forceNew)); + } + + /** + * Tests whether a string contains only 7bit ASCII bytes. + * + * You might use this to conditionally check whether a string + * needs handling as UTF-8 or not, potentially offering performance + * benefits by using the native PHP equivalent if it's just ASCII e.g.; + * + * @param string $str The string to test. + * + * @return boolean True if the string is all ASCII + * + * @since 1.4.0 + */ + public static function isAscii($str) + { + // Search for any bytes which are outside the ASCII range... + return (preg_match('/(?:[^\x00-\x7F])/', $str) !== 1); } } diff --git a/libraries/vendor/joomla/application/src/Cli/CliOutput.php b/libraries/vendor/joomla/application/src/Cli/CliOutput.php index bd6a808d9085a..ecec4912906e4 100644 --- a/libraries/vendor/joomla/application/src/Cli/CliOutput.php +++ b/libraries/vendor/joomla/application/src/Cli/CliOutput.php @@ -2,7 +2,7 @@ /** * Part of the Joomla Framework Application Package * - * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ diff --git a/libraries/vendor/joomla/application/src/Cli/ColorProcessor.php b/libraries/vendor/joomla/application/src/Cli/ColorProcessor.php index 4349d034e75e2..1a19932eec53e 100644 --- a/libraries/vendor/joomla/application/src/Cli/ColorProcessor.php +++ b/libraries/vendor/joomla/application/src/Cli/ColorProcessor.php @@ -2,7 +2,7 @@ /** * Part of the Joomla Framework Application Package * - * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ diff --git a/libraries/vendor/joomla/application/src/Cli/ColorStyle.php b/libraries/vendor/joomla/application/src/Cli/ColorStyle.php index 7f4726b3cab3a..a0d7ee9752316 100644 --- a/libraries/vendor/joomla/application/src/Cli/ColorStyle.php +++ b/libraries/vendor/joomla/application/src/Cli/ColorStyle.php @@ -2,7 +2,7 @@ /** * Part of the Joomla Framework Application Package * - * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ diff --git a/libraries/vendor/joomla/application/src/Cli/Output/Processor/ColorProcessor.php b/libraries/vendor/joomla/application/src/Cli/Output/Processor/ColorProcessor.php index 74e83b74c8917..3084a49bb0f2a 100644 --- a/libraries/vendor/joomla/application/src/Cli/Output/Processor/ColorProcessor.php +++ b/libraries/vendor/joomla/application/src/Cli/Output/Processor/ColorProcessor.php @@ -2,7 +2,7 @@ /** * Part of the Joomla Framework Application Package * - * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ diff --git a/libraries/vendor/joomla/application/src/Cli/Output/Processor/ProcessorInterface.php b/libraries/vendor/joomla/application/src/Cli/Output/Processor/ProcessorInterface.php index 6531db36e3c85..a9665d4f94c05 100644 --- a/libraries/vendor/joomla/application/src/Cli/Output/Processor/ProcessorInterface.php +++ b/libraries/vendor/joomla/application/src/Cli/Output/Processor/ProcessorInterface.php @@ -2,7 +2,7 @@ /** * Part of the Joomla Framework Application Package * - * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ diff --git a/libraries/vendor/joomla/application/src/Cli/Output/Stdout.php b/libraries/vendor/joomla/application/src/Cli/Output/Stdout.php index ed789d52d9616..3291240845757 100644 --- a/libraries/vendor/joomla/application/src/Cli/Output/Stdout.php +++ b/libraries/vendor/joomla/application/src/Cli/Output/Stdout.php @@ -2,7 +2,7 @@ /** * Part of the Joomla Framework Application Package * - * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ diff --git a/libraries/vendor/joomla/application/src/Cli/Output/Xml.php b/libraries/vendor/joomla/application/src/Cli/Output/Xml.php index 056e40c71b086..adb945f88c926 100644 --- a/libraries/vendor/joomla/application/src/Cli/Output/Xml.php +++ b/libraries/vendor/joomla/application/src/Cli/Output/Xml.php @@ -2,7 +2,7 @@ /** * Part of the Joomla Framework Application Package * - * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ diff --git a/libraries/vendor/joomla/application/src/Web/WebClient.php b/libraries/vendor/joomla/application/src/Web/WebClient.php index ade33c3252b48..83109f8ea19c5 100644 --- a/libraries/vendor/joomla/application/src/Web/WebClient.php +++ b/libraries/vendor/joomla/application/src/Web/WebClient.php @@ -2,7 +2,7 @@ /** * Part of the Joomla Framework Application Package * - * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2014 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ diff --git a/libraries/vendor/joomla/registry/src/Format/Json.php b/libraries/vendor/joomla/registry/src/Format/Json.php index 16f3b597bf466..a2e9729eca659 100644 --- a/libraries/vendor/joomla/registry/src/Format/Json.php +++ b/libraries/vendor/joomla/registry/src/Format/Json.php @@ -9,7 +9,7 @@ namespace Joomla\Registry\Format; use Joomla\Registry\AbstractRegistryFormat; -use Joomla\String\String; +use Joomla\String\StringHelper; /** * JSON format handler for Registry. @@ -30,7 +30,7 @@ class Json extends AbstractRegistryFormat */ public function objectToString($object, $options = array()) { - return String::unicode_to_utf8(json_encode($object)); + return StringHelper::unicode_to_utf8(json_encode($object)); } /** diff --git a/libraries/vendor/joomla/string/src/Inflector.php b/libraries/vendor/joomla/string/src/Inflector.php index 4100b1c514de2..89b35aec5e892 100644 --- a/libraries/vendor/joomla/string/src/Inflector.php +++ b/libraries/vendor/joomla/string/src/Inflector.php @@ -2,7 +2,7 @@ /** * Part of the Joomla Framework String Package * - * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ diff --git a/libraries/vendor/joomla/string/src/Normalise.php b/libraries/vendor/joomla/string/src/Normalise.php index e11437666a058..ca73c8bdccd27 100644 --- a/libraries/vendor/joomla/string/src/Normalise.php +++ b/libraries/vendor/joomla/string/src/Normalise.php @@ -2,7 +2,7 @@ /** * Part of the Joomla Framework String Package * - * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ diff --git a/libraries/vendor/joomla/string/src/String.php b/libraries/vendor/joomla/string/src/String.php index 4eb3a2d1a113c..f535e0874efb9 100644 --- a/libraries/vendor/joomla/string/src/String.php +++ b/libraries/vendor/joomla/string/src/String.php @@ -2,840 +2,20 @@ /** * Part of the Joomla Framework String Package * - * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\String; -// PHP mbstring and iconv local configuration -if (version_compare(PHP_VERSION, '5.6', '>=')) -{ - @ini_set('default_charset', 'UTF-8'); -} -else -{ - // Check if mbstring extension is loaded and attempt to load it if not present except for windows - if (extension_loaded('mbstring')) - { - @ini_set('mbstring.internal_encoding', 'UTF-8'); - @ini_set('mbstring.http_input', 'UTF-8'); - @ini_set('mbstring.http_output', 'UTF-8'); - } - - // Same for iconv - if (function_exists('iconv')) - { - iconv_set_encoding('internal_encoding', 'UTF-8'); - iconv_set_encoding('input_encoding', 'UTF-8'); - iconv_set_encoding('output_encoding', 'UTF-8'); - } -} - -/** - * Include the utf8 package - */ -if (!defined('UTF8')) -{ - require_once __DIR__ . '/phputf8/utf8.php'; -} - -if (!function_exists('utf8_strcasecmp')) -{ - require_once __DIR__ . '/phputf8/strcasecmp.php'; -} - /** * String handling class for utf-8 data * Wraps the phputf8 library * All functions assume the validity of utf-8 strings. * - * @since 1.0 + * @since 1.0 + * @deprecated 2.0 Use StringHelper instead */ -abstract class String +abstract class String extends StringHelper { - /** - * Increment styles. - * - * @var array - * @since 1.0 - */ - protected static $incrementStyles = array( - 'dash' => array( - '#-(\d+)$#', - '-%d' - ), - 'default' => array( - array('#\((\d+)\)$#', '#\(\d+\)$#'), - array(' (%d)', '(%d)'), - ), - ); - - /** - * Increments a trailing number in a string. - * - * Used to easily create distinct labels when copying objects. The method has the following styles: - * - * default: "Label" becomes "Label (2)" - * dash: "Label" becomes "Label-2" - * - * @param string $string The source string. - * @param string $style The the style (default|dash). - * @param integer $n If supplied, this number is used for the copy, otherwise it is the 'next' number. - * - * @return string The incremented string. - * - * @since 1.0 - */ - public static function increment($string, $style = 'default', $n = 0) - { - $styleSpec = isset(self::$incrementStyles[$style]) ? self::$incrementStyles[$style] : self::$incrementStyles['default']; - - // Regular expression search and replace patterns. - if (is_array($styleSpec[0])) - { - $rxSearch = $styleSpec[0][0]; - $rxReplace = $styleSpec[0][1]; - } - else - { - $rxSearch = $rxReplace = $styleSpec[0]; - } - - // New and old (existing) sprintf formats. - if (is_array($styleSpec[1])) - { - $newFormat = $styleSpec[1][0]; - $oldFormat = $styleSpec[1][1]; - } - else - { - $newFormat = $oldFormat = $styleSpec[1]; - } - - // Check if we are incrementing an existing pattern, or appending a new one. - if (preg_match($rxSearch, $string, $matches)) - { - $n = empty($n) ? ($matches[1] + 1) : $n; - $string = preg_replace($rxReplace, sprintf($oldFormat, $n), $string); - } - else - { - $n = empty($n) ? 2 : $n; - $string .= sprintf($newFormat, $n); - } - - return $string; - } - - /** - * Tests whether a string contains only 7bit ASCII bytes. - * You might use this to conditionally check whether a string - * needs handling as UTF-8 or not, potentially offering performance - * benefits by using the native PHP equivalent if it's just ASCII e.g.; - * - * - * if (String::is_ascii($someString)) - * { - * // It's just ASCII - use the native PHP version - * $someString = strtolower($someString); - * } - * else - * { - * $someString = String::strtolower($someString); - * } - * - * - * @param string $str The string to test. - * - * @return boolean True if the string is all ASCII - * - * @since 1.0 - */ - public static function is_ascii($str) - { - require_once __DIR__ . '/phputf8/utils/ascii.php'; - - return utf8_is_ascii($str); - } - - /** - * UTF-8 aware alternative to strpos. - * - * Find position of first occurrence of a string. - * - * @param string $str String being examined - * @param string $search String being searched for - * @param integer $offset Optional, specifies the position from which the search should be performed - * - * @return mixed Number of characters before the first match or FALSE on failure - * - * @see http://www.php.net/strpos - * @since 1.0 - */ - public static function strpos($str, $search, $offset = false) - { - if ($offset === false) - { - return utf8_strpos($str, $search); - } - - return utf8_strpos($str, $search, $offset); - } - - /** - * UTF-8 aware alternative to strrpos - * Finds position of last occurrence of a string - * - * @param string $str String being examined. - * @param string $search String being searched for. - * @param integer $offset Offset from the left of the string. - * - * @return mixed Number of characters before the last match or false on failure - * - * @see http://www.php.net/strrpos - * @since 1.0 - */ - public static function strrpos($str, $search, $offset = 0) - { - return utf8_strrpos($str, $search, $offset); - } - - /** - * UTF-8 aware alternative to substr - * Return part of a string given character offset (and optionally length) - * - * @param string $str String being processed - * @param integer $offset Number of UTF-8 characters offset (from left) - * @param integer $length Optional length in UTF-8 characters from offset - * - * @return mixed string or FALSE if failure - * - * @see http://www.php.net/substr - * @since 1.0 - */ - public static function substr($str, $offset, $length = false) - { - if ($length === false) - { - return utf8_substr($str, $offset); - } - - return utf8_substr($str, $offset, $length); - } - - /** - * UTF-8 aware alternative to strtlower - * - * Make a string lowercase - * Note: The concept of a characters "case" only exists is some alphabets - * such as Latin, Greek, Cyrillic, Armenian and archaic Georgian - it does - * not exist in the Chinese alphabet, for example. See Unicode Standard - * Annex #21: Case Mappings - * - * @param string $str String being processed - * - * @return mixed Either string in lowercase or FALSE is UTF-8 invalid - * - * @see http://www.php.net/strtolower - * @since 1.0 - */ - public static function strtolower($str) - { - return utf8_strtolower($str); - } - - /** - * UTF-8 aware alternative to strtoupper - * Make a string uppercase - * Note: The concept of a characters "case" only exists is some alphabets - * such as Latin, Greek, Cyrillic, Armenian and archaic Georgian - it does - * not exist in the Chinese alphabet, for example. See Unicode Standard - * Annex #21: Case Mappings - * - * @param string $str String being processed - * - * @return mixed Either string in uppercase or FALSE is UTF-8 invalid - * - * @see http://www.php.net/strtoupper - * @since 1.0 - */ - public static function strtoupper($str) - { - return utf8_strtoupper($str); - } - - /** - * UTF-8 aware alternative to strlen. - * - * Returns the number of characters in the string (NOT THE NUMBER OF BYTES), - * - * @param string $str UTF-8 string. - * - * @return integer Number of UTF-8 characters in string. - * - * @see http://www.php.net/strlen - * @since 1.0 - */ - public static function strlen($str) - { - return utf8_strlen($str); - } - - /** - * UTF-8 aware alternative to str_ireplace - * Case-insensitive version of str_replace - * - * @param string $search String to search - * @param string $replace Existing string to replace - * @param string $str New string to replace with - * @param integer $count Optional count value to be passed by referene - * - * @return string UTF-8 String - * - * @see http://www.php.net/str_ireplace - * @since 1.0 - */ - public static function str_ireplace($search, $replace, $str, $count = null) - { - require_once __DIR__ . '/phputf8/str_ireplace.php'; - - if ($count === false) - { - return utf8_ireplace($search, $replace, $str); - } - - return utf8_ireplace($search, $replace, $str, $count); - } - - /** - * UTF-8 aware alternative to str_split - * Convert a string to an array - * - * @param string $str UTF-8 encoded string to process - * @param integer $split_len Number to characters to split string by - * - * @return array - * - * @see http://www.php.net/str_split - * @since 1.0 - */ - public static function str_split($str, $split_len = 1) - { - require_once __DIR__ . '/phputf8/str_split.php'; - - return utf8_str_split($str, $split_len); - } - - /** - * UTF-8/LOCALE aware alternative to strcasecmp - * A case insensitive string comparison - * - * @param string $str1 string 1 to compare - * @param string $str2 string 2 to compare - * @param mixed $locale The locale used by strcoll or false to use classical comparison - * - * @return integer < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal. - * - * @see http://www.php.net/strcasecmp - * @see http://www.php.net/strcoll - * @see http://www.php.net/setlocale - * @since 1.0 - */ - public static function strcasecmp($str1, $str2, $locale = false) - { - if ($locale) - { - // Get current locale - $locale0 = setlocale(LC_COLLATE, 0); - - if (!$locale = setlocale(LC_COLLATE, $locale)) - { - $locale = $locale0; - } - - // See if we have successfully set locale to UTF-8 - if (!stristr($locale, 'UTF-8') && stristr($locale, '_') && preg_match('~\.(\d+)$~', $locale, $m)) - { - $encoding = 'CP' . $m[1]; - } - elseif (stristr($locale, 'UTF-8') || stristr($locale, 'utf8')) - { - $encoding = 'UTF-8'; - } - else - { - $encoding = 'nonrecodable'; - } - - // If we successfully set encoding it to utf-8 or encoding is sth weird don't recode - if ($encoding == 'UTF-8' || $encoding == 'nonrecodable') - { - return strcoll(utf8_strtolower($str1), utf8_strtolower($str2)); - } - - return strcoll( - self::transcode(utf8_strtolower($str1), 'UTF-8', $encoding), - self::transcode(utf8_strtolower($str2), 'UTF-8', $encoding) - ); - } - - return utf8_strcasecmp($str1, $str2); - } - - /** - * UTF-8/LOCALE aware alternative to strcmp - * A case sensitive string comparison - * - * @param string $str1 string 1 to compare - * @param string $str2 string 2 to compare - * @param mixed $locale The locale used by strcoll or false to use classical comparison - * - * @return integer < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal. - * - * @see http://www.php.net/strcmp - * @see http://www.php.net/strcoll - * @see http://www.php.net/setlocale - * @since 1.0 - */ - public static function strcmp($str1, $str2, $locale = false) - { - if ($locale) - { - // Get current locale - $locale0 = setlocale(LC_COLLATE, 0); - - if (!$locale = setlocale(LC_COLLATE, $locale)) - { - $locale = $locale0; - } - - // See if we have successfully set locale to UTF-8 - if (!stristr($locale, 'UTF-8') && stristr($locale, '_') && preg_match('~\.(\d+)$~', $locale, $m)) - { - $encoding = 'CP' . $m[1]; - } - elseif (stristr($locale, 'UTF-8') || stristr($locale, 'utf8')) - { - $encoding = 'UTF-8'; - } - else - { - $encoding = 'nonrecodable'; - } - - // If we successfully set encoding it to utf-8 or encoding is sth weird don't recode - if ($encoding == 'UTF-8' || $encoding == 'nonrecodable') - { - return strcoll($str1, $str2); - } - - return strcoll(self::transcode($str1, 'UTF-8', $encoding), self::transcode($str2, 'UTF-8', $encoding)); - } - - return strcmp($str1, $str2); - } - - /** - * UTF-8 aware alternative to strcspn - * Find length of initial segment not matching mask - * - * @param string $str The string to process - * @param string $mask The mask - * @param integer $start Optional starting character position (in characters) - * @param integer $length Optional length - * - * @return integer The length of the initial segment of str1 which does not contain any of the characters in str2 - * - * @see http://www.php.net/strcspn - * @since 1.0 - */ - public static function strcspn($str, $mask, $start = null, $length = null) - { - require_once __DIR__ . '/phputf8/strcspn.php'; - - if ($start === false && $length === false) - { - return utf8_strcspn($str, $mask); - } - - if ($length === false) - { - return utf8_strcspn($str, $mask, $start); - } - - return utf8_strcspn($str, $mask, $start, $length); - } - - /** - * UTF-8 aware alternative to stristr - * Returns all of haystack from the first occurrence of needle to the end. - * needle and haystack are examined in a case-insensitive manner - * Find first occurrence of a string using case insensitive comparison - * - * @param string $str The haystack - * @param string $search The needle - * - * @return string the sub string - * - * @see http://www.php.net/stristr - * @since 1.0 - */ - public static function stristr($str, $search) - { - require_once __DIR__ . '/phputf8/stristr.php'; - - return utf8_stristr($str, $search); - } - - /** - * UTF-8 aware alternative to strrev - * Reverse a string - * - * @param string $str String to be reversed - * - * @return string The string in reverse character order - * - * @see http://www.php.net/strrev - * @since 1.0 - */ - public static function strrev($str) - { - require_once __DIR__ . '/phputf8/strrev.php'; - - return utf8_strrev($str); - } - - /** - * UTF-8 aware alternative to strspn - * Find length of initial segment matching mask - * - * @param string $str The haystack - * @param string $mask The mask - * @param integer $start Start optional - * @param integer $length Length optional - * - * @return integer - * - * @see http://www.php.net/strspn - * @since 1.0 - */ - public static function strspn($str, $mask, $start = null, $length = null) - { - require_once __DIR__ . '/phputf8/strspn.php'; - - if ($start === null && $length === null) - { - return utf8_strspn($str, $mask); - } - - if ($length === null) - { - return utf8_strspn($str, $mask, $start); - } - - return utf8_strspn($str, $mask, $start, $length); - } - - /** - * UTF-8 aware substr_replace - * Replace text within a portion of a string - * - * @param string $str The haystack - * @param string $repl The replacement string - * @param integer $start Start - * @param integer $length Length (optional) - * - * @return string - * - * @see http://www.php.net/substr_replace - * @since 1.0 - */ - public static function substr_replace($str, $repl, $start, $length = null) - { - // Loaded by library loader - if ($length === false) - { - return utf8_substr_replace($str, $repl, $start); - } - - return utf8_substr_replace($str, $repl, $start, $length); - } - - /** - * UTF-8 aware replacement for ltrim() - * - * Strip whitespace (or other characters) from the beginning of a string - * You only need to use this if you are supplying the charlist - * optional arg and it contains UTF-8 characters. Otherwise ltrim will - * work normally on a UTF-8 string - * - * @param string $str The string to be trimmed - * @param string $charlist The optional charlist of additional characters to trim - * - * @return string The trimmed string - * - * @see http://www.php.net/ltrim - * @since 1.0 - */ - public static function ltrim($str, $charlist = false) - { - if (empty($charlist) && $charlist !== false) - { - return $str; - } - - require_once __DIR__ . '/phputf8/trim.php'; - - if ($charlist === false) - { - return utf8_ltrim($str); - } - - return utf8_ltrim($str, $charlist); - } - - /** - * UTF-8 aware replacement for rtrim() - * Strip whitespace (or other characters) from the end of a string - * You only need to use this if you are supplying the charlist - * optional arg and it contains UTF-8 characters. Otherwise rtrim will - * work normally on a UTF-8 string - * - * @param string $str The string to be trimmed - * @param string $charlist The optional charlist of additional characters to trim - * - * @return string The trimmed string - * - * @see http://www.php.net/rtrim - * @since 1.0 - */ - public static function rtrim($str, $charlist = false) - { - if (empty($charlist) && $charlist !== false) - { - return $str; - } - - require_once __DIR__ . '/phputf8/trim.php'; - - if ($charlist === false) - { - return utf8_rtrim($str); - } - - return utf8_rtrim($str, $charlist); - } - - /** - * UTF-8 aware replacement for trim() - * Strip whitespace (or other characters) from the beginning and end of a string - * Note: you only need to use this if you are supplying the charlist - * optional arg and it contains UTF-8 characters. Otherwise trim will - * work normally on a UTF-8 string - * - * @param string $str The string to be trimmed - * @param string $charlist The optional charlist of additional characters to trim - * - * @return string The trimmed string - * - * @see http://www.php.net/trim - * @since 1.0 - */ - public static function trim($str, $charlist = false) - { - if (empty($charlist) && $charlist !== false) - { - return $str; - } - - require_once __DIR__ . '/phputf8/trim.php'; - - if ($charlist === false) - { - return utf8_trim($str); - } - - return utf8_trim($str, $charlist); - } - - /** - * UTF-8 aware alternative to ucfirst - * Make a string's first character uppercase or all words' first character uppercase - * - * @param string $str String to be processed - * @param string $delimiter The words delimiter (null means do not split the string) - * @param string $newDelimiter The new words delimiter (null means equal to $delimiter) - * - * @return string If $delimiter is null, return the string with first character as upper case (if applicable) - * else consider the string of words separated by the delimiter, apply the ucfirst to each words - * and return the string with the new delimiter - * - * @see http://www.php.net/ucfirst - * @since 1.0 - */ - public static function ucfirst($str, $delimiter = null, $newDelimiter = null) - { - require_once __DIR__ . '/phputf8/ucfirst.php'; - - if ($delimiter === null) - { - return utf8_ucfirst($str); - } - - if ($newDelimiter === null) - { - $newDelimiter = $delimiter; - } - - return implode($newDelimiter, array_map('utf8_ucfirst', explode($delimiter, $str))); - } - - /** - * UTF-8 aware alternative to ucwords - * Uppercase the first character of each word in a string - * - * @param string $str String to be processed - * - * @return string String with first char of each word uppercase - * - * @see http://www.php.net/ucwords - * @since 1.0 - */ - public static function ucwords($str) - { - require_once __DIR__ . '/phputf8/ucwords.php'; - - return utf8_ucwords($str); - } - - /** - * Transcode a string. - * - * @param string $source The string to transcode. - * @param string $from_encoding The source encoding. - * @param string $to_encoding The target encoding. - * - * @return mixed The transcoded string, or null if the source was not a string. - * - * @link https://bugs.php.net/bug.php?id=48147 - * - * @since 1.0 - */ - public static function transcode($source, $from_encoding, $to_encoding) - { - if (is_string($source)) - { - switch (ICONV_IMPL) - { - case 'glibc': - return @iconv($from_encoding, $to_encoding . '//TRANSLIT,IGNORE', $source); - - case 'libiconv': - default: - return iconv($from_encoding, $to_encoding . '//IGNORE//TRANSLIT', $source); - } - } - - return null; - } - - /** - * Tests a string as to whether it's valid UTF-8 and supported by the Unicode standard. - * - * Note: this function has been modified to simple return true or false. - * - * @param string $str UTF-8 encoded string. - * - * @return boolean true if valid - * - * @author - * @see http://hsivonen.iki.fi/php-utf8/ - * @see compliant - * @since 1.0 - */ - public static function valid($str) - { - require_once __DIR__ . '/phputf8/utils/validation.php'; - - return utf8_is_valid($str); - } - - /** - * Tests whether a string complies as UTF-8. This will be much - * faster than utf8_is_valid but will pass five and six octet - * UTF-8 sequences, which are not supported by Unicode and - * so cannot be displayed correctly in a browser. In other words - * it is not as strict as utf8_is_valid but it's faster. If you use - * it to validate user input, you place yourself at the risk that - * attackers will be able to inject 5 and 6 byte sequences (which - * may or may not be a significant risk, depending on what you are - * are doing) - * - * @param string $str UTF-8 string to check - * - * @return boolean TRUE if string is valid UTF-8 - * - * @see valid - * @see http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php#54805 - * @since 1.0 - */ - public static function compliant($str) - { - require_once __DIR__ . '/phputf8/utils/validation.php'; - - return utf8_compliant($str); - } - - /** - * Converts Unicode sequences to UTF-8 string - * - * @param string $str Unicode string to convert - * - * @return string UTF-8 string - * - * @since 1.2.0 - */ - public static function unicode_to_utf8($str) - { - if (extension_loaded('mbstring')) - { - return preg_replace_callback( - '/\\\\u([0-9a-fA-F]{4})/', - function ($match) - { - return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE'); - }, - $str - ); - } - - return $str; - } - - /** - * Converts Unicode sequences to UTF-16 string - * - * @param string $str Unicode string to convert - * - * @return string UTF-16 string - * - * @since 1.2.0 - */ - public static function unicode_to_utf16($str) - { - if (extension_loaded('mbstring')) - { - return preg_replace_callback( - '/\\\\u([0-9a-fA-F]{4})/', - function ($match) - { - return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UTF-16BE'); - }, - $str - ); - } - - return $str; - } } diff --git a/libraries/vendor/joomla/string/src/StringHelper.php b/libraries/vendor/joomla/string/src/StringHelper.php new file mode 100644 index 0000000000000..47cddd5b9c9ee --- /dev/null +++ b/libraries/vendor/joomla/string/src/StringHelper.php @@ -0,0 +1,841 @@ +=')) +{ + @ini_set('default_charset', 'UTF-8'); +} +else +{ + // Check if mbstring extension is loaded and attempt to load it if not present except for windows + if (extension_loaded('mbstring')) + { + @ini_set('mbstring.internal_encoding', 'UTF-8'); + @ini_set('mbstring.http_input', 'UTF-8'); + @ini_set('mbstring.http_output', 'UTF-8'); + } + + // Same for iconv + if (function_exists('iconv')) + { + iconv_set_encoding('internal_encoding', 'UTF-8'); + iconv_set_encoding('input_encoding', 'UTF-8'); + iconv_set_encoding('output_encoding', 'UTF-8'); + } +} + +/** + * Include the utf8 package + */ +if (!defined('UTF8')) +{ + require_once __DIR__ . '/phputf8/utf8.php'; +} + +if (!function_exists('utf8_strcasecmp')) +{ + require_once __DIR__ . '/phputf8/strcasecmp.php'; +} + +/** + * String handling class for utf-8 data + * Wraps the phputf8 library + * All functions assume the validity of utf-8 strings. + * + * @since 1.3.0 + */ +abstract class StringHelper +{ + /** + * Increment styles. + * + * @var array + * @since 1.3.0 + */ + protected static $incrementStyles = array( + 'dash' => array( + '#-(\d+)$#', + '-%d' + ), + 'default' => array( + array('#\((\d+)\)$#', '#\(\d+\)$#'), + array(' (%d)', '(%d)'), + ), + ); + + /** + * Increments a trailing number in a string. + * + * Used to easily create distinct labels when copying objects. The method has the following styles: + * + * default: "Label" becomes "Label (2)" + * dash: "Label" becomes "Label-2" + * + * @param string $string The source string. + * @param string $style The the style (default|dash). + * @param integer $n If supplied, this number is used for the copy, otherwise it is the 'next' number. + * + * @return string The incremented string. + * + * @since 1.3.0 + */ + public static function increment($string, $style = 'default', $n = 0) + { + $styleSpec = isset(self::$incrementStyles[$style]) ? self::$incrementStyles[$style] : self::$incrementStyles['default']; + + // Regular expression search and replace patterns. + if (is_array($styleSpec[0])) + { + $rxSearch = $styleSpec[0][0]; + $rxReplace = $styleSpec[0][1]; + } + else + { + $rxSearch = $rxReplace = $styleSpec[0]; + } + + // New and old (existing) sprintf formats. + if (is_array($styleSpec[1])) + { + $newFormat = $styleSpec[1][0]; + $oldFormat = $styleSpec[1][1]; + } + else + { + $newFormat = $oldFormat = $styleSpec[1]; + } + + // Check if we are incrementing an existing pattern, or appending a new one. + if (preg_match($rxSearch, $string, $matches)) + { + $n = empty($n) ? ($matches[1] + 1) : $n; + $string = preg_replace($rxReplace, sprintf($oldFormat, $n), $string); + } + else + { + $n = empty($n) ? 2 : $n; + $string .= sprintf($newFormat, $n); + } + + return $string; + } + + /** + * Tests whether a string contains only 7bit ASCII bytes. + * You might use this to conditionally check whether a string + * needs handling as UTF-8 or not, potentially offering performance + * benefits by using the native PHP equivalent if it's just ASCII e.g.; + * + * + * if (String::is_ascii($someString)) + * { + * // It's just ASCII - use the native PHP version + * $someString = strtolower($someString); + * } + * else + * { + * $someString = String::strtolower($someString); + * } + * + * + * @param string $str The string to test. + * + * @return boolean True if the string is all ASCII + * + * @since 1.3.0 + */ + public static function is_ascii($str) + { + require_once __DIR__ . '/phputf8/utils/ascii.php'; + + return utf8_is_ascii($str); + } + + /** + * UTF-8 aware alternative to strpos. + * + * Find position of first occurrence of a string. + * + * @param string $str String being examined + * @param string $search String being searched for + * @param integer $offset Optional, specifies the position from which the search should be performed + * + * @return mixed Number of characters before the first match or FALSE on failure + * + * @see http://www.php.net/strpos + * @since 1.3.0 + */ + public static function strpos($str, $search, $offset = false) + { + if ($offset === false) + { + return utf8_strpos($str, $search); + } + + return utf8_strpos($str, $search, $offset); + } + + /** + * UTF-8 aware alternative to strrpos + * Finds position of last occurrence of a string + * + * @param string $str String being examined. + * @param string $search String being searched for. + * @param integer $offset Offset from the left of the string. + * + * @return mixed Number of characters before the last match or false on failure + * + * @see http://www.php.net/strrpos + * @since 1.3.0 + */ + public static function strrpos($str, $search, $offset = 0) + { + return utf8_strrpos($str, $search, $offset); + } + + /** + * UTF-8 aware alternative to substr + * Return part of a string given character offset (and optionally length) + * + * @param string $str String being processed + * @param integer $offset Number of UTF-8 characters offset (from left) + * @param integer $length Optional length in UTF-8 characters from offset + * + * @return mixed string or FALSE if failure + * + * @see http://www.php.net/substr + * @since 1.3.0 + */ + public static function substr($str, $offset, $length = false) + { + if ($length === false) + { + return utf8_substr($str, $offset); + } + + return utf8_substr($str, $offset, $length); + } + + /** + * UTF-8 aware alternative to strtlower + * + * Make a string lowercase + * Note: The concept of a characters "case" only exists is some alphabets + * such as Latin, Greek, Cyrillic, Armenian and archaic Georgian - it does + * not exist in the Chinese alphabet, for example. See Unicode Standard + * Annex #21: Case Mappings + * + * @param string $str String being processed + * + * @return mixed Either string in lowercase or FALSE is UTF-8 invalid + * + * @see http://www.php.net/strtolower + * @since 1.3.0 + */ + public static function strtolower($str) + { + return utf8_strtolower($str); + } + + /** + * UTF-8 aware alternative to strtoupper + * Make a string uppercase + * Note: The concept of a characters "case" only exists is some alphabets + * such as Latin, Greek, Cyrillic, Armenian and archaic Georgian - it does + * not exist in the Chinese alphabet, for example. See Unicode Standard + * Annex #21: Case Mappings + * + * @param string $str String being processed + * + * @return mixed Either string in uppercase or FALSE is UTF-8 invalid + * + * @see http://www.php.net/strtoupper + * @since 1.3.0 + */ + public static function strtoupper($str) + { + return utf8_strtoupper($str); + } + + /** + * UTF-8 aware alternative to strlen. + * + * Returns the number of characters in the string (NOT THE NUMBER OF BYTES), + * + * @param string $str UTF-8 string. + * + * @return integer Number of UTF-8 characters in string. + * + * @see http://www.php.net/strlen + * @since 1.3.0 + */ + public static function strlen($str) + { + return utf8_strlen($str); + } + + /** + * UTF-8 aware alternative to str_ireplace + * Case-insensitive version of str_replace + * + * @param string $search String to search + * @param string $replace Existing string to replace + * @param string $str New string to replace with + * @param integer $count Optional count value to be passed by referene + * + * @return string UTF-8 String + * + * @see http://www.php.net/str_ireplace + * @since 1.3.0 + */ + public static function str_ireplace($search, $replace, $str, $count = null) + { + require_once __DIR__ . '/phputf8/str_ireplace.php'; + + if ($count === false) + { + return utf8_ireplace($search, $replace, $str); + } + + return utf8_ireplace($search, $replace, $str, $count); + } + + /** + * UTF-8 aware alternative to str_split + * Convert a string to an array + * + * @param string $str UTF-8 encoded string to process + * @param integer $split_len Number to characters to split string by + * + * @return array + * + * @see http://www.php.net/str_split + * @since 1.3.0 + */ + public static function str_split($str, $split_len = 1) + { + require_once __DIR__ . '/phputf8/str_split.php'; + + return utf8_str_split($str, $split_len); + } + + /** + * UTF-8/LOCALE aware alternative to strcasecmp + * A case insensitive string comparison + * + * @param string $str1 string 1 to compare + * @param string $str2 string 2 to compare + * @param mixed $locale The locale used by strcoll or false to use classical comparison + * + * @return integer < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal. + * + * @see http://www.php.net/strcasecmp + * @see http://www.php.net/strcoll + * @see http://www.php.net/setlocale + * @since 1.3.0 + */ + public static function strcasecmp($str1, $str2, $locale = false) + { + if ($locale) + { + // Get current locale + $locale0 = setlocale(LC_COLLATE, 0); + + if (!$locale = setlocale(LC_COLLATE, $locale)) + { + $locale = $locale0; + } + + // See if we have successfully set locale to UTF-8 + if (!stristr($locale, 'UTF-8') && stristr($locale, '_') && preg_match('~\.(\d+)$~', $locale, $m)) + { + $encoding = 'CP' . $m[1]; + } + elseif (stristr($locale, 'UTF-8') || stristr($locale, 'utf8')) + { + $encoding = 'UTF-8'; + } + else + { + $encoding = 'nonrecodable'; + } + + // If we successfully set encoding it to utf-8 or encoding is sth weird don't recode + if ($encoding == 'UTF-8' || $encoding == 'nonrecodable') + { + return strcoll(utf8_strtolower($str1), utf8_strtolower($str2)); + } + + return strcoll( + self::transcode(utf8_strtolower($str1), 'UTF-8', $encoding), + self::transcode(utf8_strtolower($str2), 'UTF-8', $encoding) + ); + } + + return utf8_strcasecmp($str1, $str2); + } + + /** + * UTF-8/LOCALE aware alternative to strcmp + * A case sensitive string comparison + * + * @param string $str1 string 1 to compare + * @param string $str2 string 2 to compare + * @param mixed $locale The locale used by strcoll or false to use classical comparison + * + * @return integer < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal. + * + * @see http://www.php.net/strcmp + * @see http://www.php.net/strcoll + * @see http://www.php.net/setlocale + * @since 1.3.0 + */ + public static function strcmp($str1, $str2, $locale = false) + { + if ($locale) + { + // Get current locale + $locale0 = setlocale(LC_COLLATE, 0); + + if (!$locale = setlocale(LC_COLLATE, $locale)) + { + $locale = $locale0; + } + + // See if we have successfully set locale to UTF-8 + if (!stristr($locale, 'UTF-8') && stristr($locale, '_') && preg_match('~\.(\d+)$~', $locale, $m)) + { + $encoding = 'CP' . $m[1]; + } + elseif (stristr($locale, 'UTF-8') || stristr($locale, 'utf8')) + { + $encoding = 'UTF-8'; + } + else + { + $encoding = 'nonrecodable'; + } + + // If we successfully set encoding it to utf-8 or encoding is sth weird don't recode + if ($encoding == 'UTF-8' || $encoding == 'nonrecodable') + { + return strcoll($str1, $str2); + } + + return strcoll(self::transcode($str1, 'UTF-8', $encoding), self::transcode($str2, 'UTF-8', $encoding)); + } + + return strcmp($str1, $str2); + } + + /** + * UTF-8 aware alternative to strcspn + * Find length of initial segment not matching mask + * + * @param string $str The string to process + * @param string $mask The mask + * @param integer $start Optional starting character position (in characters) + * @param integer $length Optional length + * + * @return integer The length of the initial segment of str1 which does not contain any of the characters in str2 + * + * @see http://www.php.net/strcspn + * @since 1.3.0 + */ + public static function strcspn($str, $mask, $start = null, $length = null) + { + require_once __DIR__ . '/phputf8/strcspn.php'; + + if ($start === false && $length === false) + { + return utf8_strcspn($str, $mask); + } + + if ($length === false) + { + return utf8_strcspn($str, $mask, $start); + } + + return utf8_strcspn($str, $mask, $start, $length); + } + + /** + * UTF-8 aware alternative to stristr + * Returns all of haystack from the first occurrence of needle to the end. + * needle and haystack are examined in a case-insensitive manner + * Find first occurrence of a string using case insensitive comparison + * + * @param string $str The haystack + * @param string $search The needle + * + * @return string the sub string + * + * @see http://www.php.net/stristr + * @since 1.3.0 + */ + public static function stristr($str, $search) + { + require_once __DIR__ . '/phputf8/stristr.php'; + + return utf8_stristr($str, $search); + } + + /** + * UTF-8 aware alternative to strrev + * Reverse a string + * + * @param string $str String to be reversed + * + * @return string The string in reverse character order + * + * @see http://www.php.net/strrev + * @since 1.3.0 + */ + public static function strrev($str) + { + require_once __DIR__ . '/phputf8/strrev.php'; + + return utf8_strrev($str); + } + + /** + * UTF-8 aware alternative to strspn + * Find length of initial segment matching mask + * + * @param string $str The haystack + * @param string $mask The mask + * @param integer $start Start optional + * @param integer $length Length optional + * + * @return integer + * + * @see http://www.php.net/strspn + * @since 1.3.0 + */ + public static function strspn($str, $mask, $start = null, $length = null) + { + require_once __DIR__ . '/phputf8/strspn.php'; + + if ($start === null && $length === null) + { + return utf8_strspn($str, $mask); + } + + if ($length === null) + { + return utf8_strspn($str, $mask, $start); + } + + return utf8_strspn($str, $mask, $start, $length); + } + + /** + * UTF-8 aware substr_replace + * Replace text within a portion of a string + * + * @param string $str The haystack + * @param string $repl The replacement string + * @param integer $start Start + * @param integer $length Length (optional) + * + * @return string + * + * @see http://www.php.net/substr_replace + * @since 1.3.0 + */ + public static function substr_replace($str, $repl, $start, $length = null) + { + // Loaded by library loader + if ($length === false) + { + return utf8_substr_replace($str, $repl, $start); + } + + return utf8_substr_replace($str, $repl, $start, $length); + } + + /** + * UTF-8 aware replacement for ltrim() + * + * Strip whitespace (or other characters) from the beginning of a string + * You only need to use this if you are supplying the charlist + * optional arg and it contains UTF-8 characters. Otherwise ltrim will + * work normally on a UTF-8 string + * + * @param string $str The string to be trimmed + * @param string $charlist The optional charlist of additional characters to trim + * + * @return string The trimmed string + * + * @see http://www.php.net/ltrim + * @since 1.3.0 + */ + public static function ltrim($str, $charlist = false) + { + if (empty($charlist) && $charlist !== false) + { + return $str; + } + + require_once __DIR__ . '/phputf8/trim.php'; + + if ($charlist === false) + { + return utf8_ltrim($str); + } + + return utf8_ltrim($str, $charlist); + } + + /** + * UTF-8 aware replacement for rtrim() + * Strip whitespace (or other characters) from the end of a string + * You only need to use this if you are supplying the charlist + * optional arg and it contains UTF-8 characters. Otherwise rtrim will + * work normally on a UTF-8 string + * + * @param string $str The string to be trimmed + * @param string $charlist The optional charlist of additional characters to trim + * + * @return string The trimmed string + * + * @see http://www.php.net/rtrim + * @since 1.3.0 + */ + public static function rtrim($str, $charlist = false) + { + if (empty($charlist) && $charlist !== false) + { + return $str; + } + + require_once __DIR__ . '/phputf8/trim.php'; + + if ($charlist === false) + { + return utf8_rtrim($str); + } + + return utf8_rtrim($str, $charlist); + } + + /** + * UTF-8 aware replacement for trim() + * Strip whitespace (or other characters) from the beginning and end of a string + * Note: you only need to use this if you are supplying the charlist + * optional arg and it contains UTF-8 characters. Otherwise trim will + * work normally on a UTF-8 string + * + * @param string $str The string to be trimmed + * @param string $charlist The optional charlist of additional characters to trim + * + * @return string The trimmed string + * + * @see http://www.php.net/trim + * @since 1.3.0 + */ + public static function trim($str, $charlist = false) + { + if (empty($charlist) && $charlist !== false) + { + return $str; + } + + require_once __DIR__ . '/phputf8/trim.php'; + + if ($charlist === false) + { + return utf8_trim($str); + } + + return utf8_trim($str, $charlist); + } + + /** + * UTF-8 aware alternative to ucfirst + * Make a string's first character uppercase or all words' first character uppercase + * + * @param string $str String to be processed + * @param string $delimiter The words delimiter (null means do not split the string) + * @param string $newDelimiter The new words delimiter (null means equal to $delimiter) + * + * @return string If $delimiter is null, return the string with first character as upper case (if applicable) + * else consider the string of words separated by the delimiter, apply the ucfirst to each words + * and return the string with the new delimiter + * + * @see http://www.php.net/ucfirst + * @since 1.3.0 + */ + public static function ucfirst($str, $delimiter = null, $newDelimiter = null) + { + require_once __DIR__ . '/phputf8/ucfirst.php'; + + if ($delimiter === null) + { + return utf8_ucfirst($str); + } + + if ($newDelimiter === null) + { + $newDelimiter = $delimiter; + } + + return implode($newDelimiter, array_map('utf8_ucfirst', explode($delimiter, $str))); + } + + /** + * UTF-8 aware alternative to ucwords + * Uppercase the first character of each word in a string + * + * @param string $str String to be processed + * + * @return string String with first char of each word uppercase + * + * @see http://www.php.net/ucwords + * @since 1.3.0 + */ + public static function ucwords($str) + { + require_once __DIR__ . '/phputf8/ucwords.php'; + + return utf8_ucwords($str); + } + + /** + * Transcode a string. + * + * @param string $source The string to transcode. + * @param string $from_encoding The source encoding. + * @param string $to_encoding The target encoding. + * + * @return mixed The transcoded string, or null if the source was not a string. + * + * @link https://bugs.php.net/bug.php?id=48147 + * + * @since 1.3.0 + */ + public static function transcode($source, $from_encoding, $to_encoding) + { + if (is_string($source)) + { + switch (ICONV_IMPL) + { + case 'glibc': + return @iconv($from_encoding, $to_encoding . '//TRANSLIT,IGNORE', $source); + + case 'libiconv': + default: + return iconv($from_encoding, $to_encoding . '//IGNORE//TRANSLIT', $source); + } + } + + return null; + } + + /** + * Tests a string as to whether it's valid UTF-8 and supported by the Unicode standard. + * + * Note: this function has been modified to simple return true or false. + * + * @param string $str UTF-8 encoded string. + * + * @return boolean true if valid + * + * @author + * @see http://hsivonen.iki.fi/php-utf8/ + * @see compliant + * @since 1.3.0 + */ + public static function valid($str) + { + require_once __DIR__ . '/phputf8/utils/validation.php'; + + return utf8_is_valid($str); + } + + /** + * Tests whether a string complies as UTF-8. This will be much + * faster than utf8_is_valid but will pass five and six octet + * UTF-8 sequences, which are not supported by Unicode and + * so cannot be displayed correctly in a browser. In other words + * it is not as strict as utf8_is_valid but it's faster. If you use + * it to validate user input, you place yourself at the risk that + * attackers will be able to inject 5 and 6 byte sequences (which + * may or may not be a significant risk, depending on what you are + * are doing) + * + * @param string $str UTF-8 string to check + * + * @return boolean TRUE if string is valid UTF-8 + * + * @see valid + * @see http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php#54805 + * @since 1.3.0 + */ + public static function compliant($str) + { + require_once __DIR__ . '/phputf8/utils/validation.php'; + + return utf8_compliant($str); + } + + /** + * Converts Unicode sequences to UTF-8 string + * + * @param string $str Unicode string to convert + * + * @return string UTF-8 string + * + * @since 1.3.0 + */ + public static function unicode_to_utf8($str) + { + if (extension_loaded('mbstring')) + { + return preg_replace_callback( + '/\\\\u([0-9a-fA-F]{4})/', + function ($match) + { + return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE'); + }, + $str + ); + } + + return $str; + } + + /** + * Converts Unicode sequences to UTF-16 string + * + * @param string $str Unicode string to convert + * + * @return string UTF-16 string + * + * @since 1.3.0 + */ + public static function unicode_to_utf16($str) + { + if (extension_loaded('mbstring')) + { + return preg_replace_callback( + '/\\\\u([0-9a-fA-F]{4})/', + function ($match) + { + return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UTF-16BE'); + }, + $str + ); + } + + return $str; + } +} diff --git a/libraries/vendor/joomla/utilities/src/ArrayHelper.php b/libraries/vendor/joomla/utilities/src/ArrayHelper.php index ea4e764a63911..dde3f4250b121 100644 --- a/libraries/vendor/joomla/utilities/src/ArrayHelper.php +++ b/libraries/vendor/joomla/utilities/src/ArrayHelper.php @@ -2,13 +2,13 @@ /** * Part of the Joomla Framework Utilities Package * - * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Utilities; -use Joomla\String\String; +use Joomla\String\StringHelper; /** * ArrayHelper is an array utility class for doing all sorts of odds and ends with arrays. @@ -512,11 +512,11 @@ public static function sortObjects(array $a, $k, $direction = 1, $caseSensitive } elseif ($caseSensitive) { - $cmp = String::strcmp($va, $vb, $locale); + $cmp = StringHelper::strcmp($va, $vb, $locale); } else { - $cmp = String::strcasecmp($va, $vb, $locale); + $cmp = StringHelper::strcasecmp($va, $vb, $locale); } if ($cmp > 0) diff --git a/plugins/system/updatenotification/updatenotification.php b/plugins/system/updatenotification/updatenotification.php new file mode 100644 index 0000000000000..3bf0c71654c56 --- /dev/null +++ b/plugins/system/updatenotification/updatenotification.php @@ -0,0 +1,408 @@ +params; + $cache_timeout = $params->get('cachetimeout', 6, 'int'); + $cache_timeout = 3600 * $cache_timeout; + + // Do we need to run? Compare the last run timestamp stored in the plugin's options with the current + // timestamp. If the difference is greater than the cache timeout we shall not execute again. + $now = time(); + $last = (int) $this->params->get('lastrun', 0); + + if (!defined('PLG_SYSTEM_UPDATENOTIFICATION_DEBUG') && (abs($now - $last) < $cache_timeout)) + { + return; + } + + // Update last run status + // If I have the time of the last run, I can update, otherwise insert + $this->params->set('lastrun', $now); + + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->update($db->qn('#__extensions')) + ->set($db->qn('params') . ' = ' . $db->q($this->params->toString('JSON'))) + ->where($db->qn('type') . ' = ' . $db->q('plugin')) + ->where($db->qn('folder') . ' = ' . $db->q('system')) + ->where($db->qn('element') . ' = ' . $db->q('updatenotification')); + + try + { + // Lock the tables to prevent multiple plugin executions causing a race condition + $db->lockTable('#__extensions'); + } + catch (Exception $e) + { + // If we can't lock the tables it's too risk continuing execution + return; + } + + try + { + // Update the plugin parameters + $result = $db->setQuery($query)->execute(); + + $this->clearCacheGroups(array('com_plugins'), array(0, 1)); + } + catch (Exception $exc) + { + // If we failed to execite + $db->unlockTables(); + $result = false; + } + + try + { + // Unlock the tables after writing + $db->unlockTables(); + } + catch (Exception $e) + { + // If we can't lock the tables assume we have somehow failed + $result = false; + } + + // Abort on failure + if (!$result) + { + return; + } + + // This is the extension ID for Joomla! itself + $eid = 700; + + // Get any available updates + $updater = JUpdater::getInstance(); + $results = $updater->findUpdates(array($eid), $cache_timeout); + + // If there are no updates our job is done. We need BOTH this check AND the one below. + if (!$results) + { + return; + } + + // Unfortunately Joomla! MVC doesn't allow us to autoload classes, hence the need for an ugly require_once + require_once JPATH_ADMINISTRATOR . '/components/com_installer/models/update.php'; + + // Get the update model and retrieve the Joomla! core updates + $model = JModelLegacy::getInstance('Update', 'InstallerModel'); + $model->setState('filter.extension_id', $eid); + $updates = $model->getItems(); + + // If there are no updates we don't have to notify anyone about anything. This is NOT a duplicate check. + if (empty($updates)) + { + return; + } + + // Get the available update + $update = array_pop($updates); + + // Check the available version. If it's the same as the installed version we have no updates to notify about. + if (version_compare($update->version, JVERSION, 'eq')) + { + return; + } + + // If we're here, we have updates. First, get a link to the Joomla! Update component. + $baseURL = JURI::base(); + $baseURL = rtrim($baseURL, '/'); + $baseURL .= (substr($baseURL, -13) != 'administrator') ? '/administrator/' : '/'; + $baseURL .= 'index.php?option=com_joomlaupdate'; + $uri = new JUri($baseURL); + + /** + * Some third party security solutions require a secret query parameter to allow log in to the administrator + * back-end of the site. The link generated above will be invalid and could probably block the user out of their + * site, confusing them (they can't understand the third party security solution is not part of Joomla! proper). + * So, we're calling the onBuildAdministratorLoginURL system plugin event to let these third party solutions + * add any necessary secret query parameters to the URL. The plugins are supposed to have a method with the + * signature: + * + * public function onBuildAdministratorLoginURL(JUri &$uri); + * + * The plugins should modify the $uri object directly and return null. + */ + + JEventDispatcher::getInstance()->trigger('onBuildAdministratorLoginURL', array(&$uri)); + + // Let's find out the email addresses to notify + $superUsers = array(); + $specificEmail = $this->params->get('email', ''); + + if (!empty($specificEmail)) + { + $superUsers = $this->getSuperUsers($specificEmail); + } + + if (empty($superUsers)) + { + $superUsers = $this->getSuperUsers(); + } + + if (empty($superUsers)) + { + return; + } + + /* Load the appropriate language. We try to load English (UK), the current user's language and the forced + * language preference, in this order. This ensures that we'll never end up with untranslated strings in the + * update email which would make Joomla! seem bad. So, please, if you don't fully understand what the + * following code does DO NOT TOUCH IT. It makes the difference between a hobbyist CMS and a professional + * solution! */ + $jLanguage = JFactory::getLanguage(); + $jLanguage->load('plg_system_updatenotification', JPATH_ADMINISTRATOR, 'en-GB', true, true); + $jLanguage->load('plg_system_updatenotification', JPATH_ADMINISTRATOR, null, true, false); + + // Then try loading the preferred (forced) language + $forcedLanguage = $this->params->get('language_override', ''); + + if (!empty($forcedLanguage)) + { + $jLanguage->load('plg_system_updatenotification', JPATH_ADMINISTRATOR, $forcedLanguage, true, false); + } + + // Set up the email subject and body + + $email_subject = JText::_('PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_SUBJECT'); + $email_body = JText::_('PLG_SYSTEM_UPDATENOTIFICATION_EMAIL_BODY'); + + // Replace merge codes with their values + $newVersion = $update->version; + + $jVersion = new JVersion; + $currentVersion = $jVersion->getShortVersion(); + + $jConfig = JFactory::getConfig(); + $sitename = $jConfig->get('sitename'); + $mailFrom = $jConfig->get('mailfrom'); + $fromName = $jConfig->get('fromname'); + + $substitutions = array( + '[NEWVERSION]' => $newVersion, + '[CURVERSION]' => $currentVersion, + '[SITENAME]' => $sitename, + '[URL]' => JUri::base(), + '[LINK]' => $uri->toString(), + '\\n' => "\n", + ); + + foreach ($substitutions as $k => $v) + { + $email_subject = str_replace($k, $v, $email_subject); + $email_body = str_replace($k, $v, $email_body); + } + + // Send the emails to the Super Users + foreach ($superUsers as $superUser) + { + $mailer = JFactory::getMailer(); + $mailer->setSender(array($mailFrom, $fromName)); + $mailer->addRecipient($superUser->email); + $mailer->setSubject($email_subject); + $mailer->setBody($email_body); + $mailer->Send(); + } + } + + /** + * Returns the Super Users email information. If you provide a comma separated $email list + * we will check that these emails do belong to Super Users and that they have not blocked + * system emails. + * + * @param null|string $email A list of Super Users to email + * + * @return array The list of Super User emails + */ + private function getSuperUsers($email = null) + { + // Get a reference to the database object + $db = JFactory::getDBO(); + + // Convert the email list to an array + if (!empty($email)) + { + $temp = explode(',', $email); + $emails = array(); + + foreach ($temp as $entry) + { + $entry = trim($entry); + $emails[] = $db->q($entry); + } + + $emails = array_unique($emails); + } + else + { + $emails = array(); + } + + // Get a list of groups which have Super User privileges + $ret = array(); + + try + { + $query = $db->getQuery(true) + ->select($db->qn('rules')) + ->from($db->qn('#__assets')) + ->where($db->qn('parent_id') . ' = ' . $db->q(0)); + $db->setQuery($query, 0, 1); + $rulesJSON = $db->loadResult(); + $rules = json_decode($rulesJSON, true); + + $rawGroups = $rules['core.admin']; + $groups = array(); + + if (empty($rawGroups)) + { + return $ret; + } + + foreach ($rawGroups as $g => $enabled) + { + if ($enabled) + { + $groups[] = $db->q($g); + } + } + + if (empty($groups)) + { + return $ret; + } + } + catch (Exception $exc) + { + return $ret; + } + + // Get the user IDs of users belonging to the SA groups + try + { + $query = $db->getQuery(true) + ->select($db->qn('user_id')) + ->from($db->qn('#__user_usergroup_map')) + ->where($db->qn('group_id') . ' IN(' . implode(',', $groups) . ')'); + $db->setQuery($query); + $rawUserIDs = $db->loadColumn(0); + + if (empty($rawUserIDs)) + { + return $ret; + } + + $userIDs = array(); + + foreach ($rawUserIDs as $id) + { + $userIDs[] = $db->q($id); + } + } + catch (Exception $exc) + { + return $ret; + } + + // Get the user information for the Super Administrator users + try + { + $query = $db->getQuery(true) + ->select( + array( + $db->qn('id'), + $db->qn('username'), + $db->qn('email'), + ) + )->from($db->qn('#__users')) + ->where($db->qn('id') . ' IN(' . implode(',', $userIDs) . ')') + ->where($db->qn('sendEmail') . ' = ' . $db->q('1')); + + if (!empty($emails)) + { + $query->where($db->qn('email') . 'IN(' . implode(',', $emails) . ')'); + } + + $db->setQuery($query); + $ret = $db->loadObjectList(); + } + catch (Exception $exc) + { + return $ret; + } + + return $ret; + } + + /** + * Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp. + * + * @param array $clearGroups The cache groups to clean + * @param array $cacheClients The cache clients (site, admin) to clean + * + * @return void + */ + private function clearCacheGroups(array $clearGroups, array $cacheClients = array(0, 1)) + { + $conf = JFactory::getConfig(); + + foreach ($clearGroups as $group) + { + foreach ($cacheClients as $client_id) + { + try + { + $options = array( + 'defaultgroup' => $group, + 'cachebase' => ($client_id) ? JPATH_ADMINISTRATOR . '/cache' : + $conf->get('cache_path', JPATH_SITE . '/cache') + ); + + $cache = JCache::getInstance('callback', $options); + $cache->clean(); + } + catch (Exception $e) + { + // Ignore it + } + } + } + } +} diff --git a/plugins/system/updatenotification/updatenotification.xml b/plugins/system/updatenotification/updatenotification.xml new file mode 100644 index 0000000000000..faaf3492b8ae4 --- /dev/null +++ b/plugins/system/updatenotification/updatenotification.xml @@ -0,0 +1,34 @@ + + + PLG_SYSTEM_UPDATENOTIFICATION + Joomla! Project + May 2015 + Copyright (C) 2005 - 2015 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.0.0 + PLG_SYSTEM_UPDATENOTIFICATION_DESCRIPTION + + updatenotification.php + + + en-GB.plg_system_updatenotification.ini + en-GB.plg_system_updatenotification.sys.ini + + + +
+ + + + + +
+
+
+
diff --git a/tests/unit/suites/libraries/cms/component/router/JComponentRouterBaseTest.php b/tests/unit/suites/libraries/cms/component/router/JComponentRouterBaseTest.php new file mode 100644 index 0000000000000..051e0d06ddcfd --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/JComponentRouterBaseTest.php @@ -0,0 +1,92 @@ +assertInstanceOf('JComponentRouterInterface', $object); + $this->assertInstanceOf('JComponentRouterBase', $object); + $this->assertEquals($app, $object->app); + $this->assertEquals($app->getMenu(), $object->menu); + $this->assertEquals(null, $object->app->get('value')); + + /** + * Test if the setup works when an app object is handed over + * Especially test if the app objects are different + */ + $app2 = TestMockApplication::create($this); + $object = new JComponentRouterBaseInspector($app2); + $this->assertEquals($app2, $object->app); + //The original $app is not the same object as $app2, thus we did not use JFactory + $this->assertFalse($app === $object->app); + + /** + * Test if the setup works when both an app and menu object is handed over + */ + $menu2 = new stdClass(); + $object = new JComponentRouterBaseInspector($app, $menu2); + $this->assertEquals($app, $object->app); + $this->assertEquals($menu2, $object->menu); + + /** + * Test what happens when no application, but a menu object is handed over + */ + $object = new JComponentRouterBaseInspector(false, $menu); + $this->assertEquals($app, $object->app); + $this->assertEquals($menu, $object->menu); + + JFactory::$language = $app_bkp; + } + + /** + * Test JComponentRouterBase::preprocess + * + * @return void + * + * @since 3.4 + * @covers JComponentRouterBase::preprocess + */ + public function testPreprocess() + { + $app = TestMockApplication::create($this); + $menu = TestMockMenu::create($this); + $object = new JComponentRouterBaseInspector($app, $menu); + + $array = array('option' => 'com_test', 'view' => 'test'); + $this->assertEquals($array, $object->preprocess($array)); + } +} diff --git a/tests/unit/suites/libraries/cms/component/router/JComponentRouterLegacyTest.php b/tests/unit/suites/libraries/cms/component/router/JComponentRouterLegacyTest.php new file mode 100644 index 0000000000000..bf959d20841d1 --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/JComponentRouterLegacyTest.php @@ -0,0 +1,120 @@ +object = new JComponentRouterLegacy('Comtest'); + } + + /** + * Test JComponentRouterLegacy::__construct + * + * @return void + * + * @since 3.4 + * @covers JComponentRouterLegacy::__construct + */ + public function testConstruct() + { + $this->assertInstanceOf('JComponentRouterInterface', $this->object); + $this->assertInstanceOf('JComponentRouterLegacy', $this->object); + } + + /** + * Test JComponentRouterLegacy::preprocess + * + * @return void + * + * @since 3.4 + * @covers JComponentRouterLegacy::preprocess + */ + public function testPreprocess() + { + $this->assertEquals(array(), $this->object->preprocess(array())); + $this->assertEquals( + array('option' => 'com_test', 'view' => 'test'), + $this->object->preprocess(array('option' => 'com_test', 'view' => 'test')) + ); + } + + /** + * Test JComponentRouterLegacy::build + * + * @return void + * + * @since 3.4 + * @covers JComponentRouterLegacy::build + */ + public function testBuild() + { + $array = array(); + $this->assertEquals($array, $this->object->build($array)); + $query = array('option' => 'com_test'); + $segments = array('option-com_test'); + $this->assertEquals($segments, $this->object->build($query)); + $query = array('option' => 'com_test', '42' => 'test-test'); + $segments = array('option-com_test', '42-test-test'); + $this->assertEquals($segments, $this->object->build($query)); + $object = new JComponentRouterLegacy('fake'); + $query = array('option' => 'com_test', '42' => 'test-test'); + $this->assertEquals(array(), $object->build($query)); + } + + /** + * Test JComponentRouterLegacy::parse + * + * @return void + * + * @since 3.4 + * @covers JComponentRouterLegacy::parse + */ + public function testParse() + { + $array = array(); + $this->assertEquals($array, $this->object->parse($array)); + $query = array('option' => 'com_test'); + $segments = array('option-com_test'); + $this->assertEquals($query, $this->object->parse($segments)); + $query = array('option' => 'com_test', '42' => 'test-test'); + $segments = array('option-com_test', '42-test-test'); + $this->assertEquals($query, $this->object->parse($segments)); + $object = new JComponentRouterLegacy('fake'); + $segments = array('option-com_test', '42-test-test'); + $this->assertEquals(array(), $object->parse($segments)); + } +} diff --git a/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php b/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php new file mode 100644 index 0000000000000..0b6c06a2640dc --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php @@ -0,0 +1,350 @@ +getMockCmsApp(); + $this->object = new JComponentRouterViewInspector($app, $app->getMenu()); + } + + /** + * Gets the data set to be loaded into the database during setup + * + * @return PHPUnit_Extensions_Database_DataSet_CsvDataSet + * + * @since 3.2 + */ + protected function getDataSet() + { + $dataSet = new PHPUnit_Extensions_Database_DataSet_CsvDataSet(',', "'", '\\'); + + $dataSet->addTable('jos_categories', JPATH_TEST_DATABASE . '/jos_categories.csv'); + + return $dataSet; + } + + /** + * Tests the registerView() method + * + * @return void + * + * @since 3.5 + * @covers JComponentRouterView::registerView + */ + public function testRegisterView() + { + $views = $this->getComContentViews(); + + foreach ($views as $view) + { + $this->object->registerView($view); + } + + $this->assertEquals($views, $this->object->get('views')); + } + + /** + * Tests the getViews() method + * + * @return void + * + * @since 3.5 + * @covers JComponentRouterView::getViews + */ + public function testGetViews() + { + $views = $this->getComContentViews(); + + foreach ($views as $view) + { + $this->object->registerView($view); + } + + $this->assertEquals($views, $this->object->getViews()); + } + + /** + * Cases for testGetPath + * + * @return array + * + * @since 3.5 + */ + public function casesGetPath() + { + $cases = array(); + // No view, so we don't have a path to return. + $cases[] = array(array('task' => 'edit'), array()); + + // View without any parents and children + $cases[] = array(array('view' => 'form'), array('form' => true)); + + // View without any parents, but with children + $cases[] = array(array('view' => 'categories'), array('categories' => true)); + + // View with parent and children + $qcases[] = array(array('view' => 'category', 'id' => '9'), array('category' => array('9:uncategorised'), 'categories' => true)); + + //View with parent, no children + $cases[] = array(array('view' => 'article', 'id' => '42:question-for-everything', 'catid' => '9'), + array( + 'article' => array('42:question-for-everything'), + 'category' => array('9:uncategorised'), + 'categories' => true + ) + ); + + //View with parent, no children and nested view + $cases[] = array(array('view' => 'article', 'id' => '42:question-for-everything', 'catid' => '20'), + array( + 'article' => array('42:question-for-everything'), + 'category' => array('20:extensions', + '19:joomla', + '14:sample-data-articles' + ), + 'categories' => true + ) + ); + + return $cases; + } + + /** + * Tests the getPath() method + * + * @return void + * + * @dataProvider casesGetPath + * @since 3.5 + * @covers JComponentRouterView::getPath + */ + public function testGetPath($input, $result) + { + // This test requires an application registered to JFactory + $this->saveFactoryState(); + JFactory::$application = $this->object->app; + + $views = $this->getComContentViews(); + $this->object->set('name', 'unittest'); + + foreach ($views as $view) + { + $this->object->registerView($view); + } + + $this->assertEquals($result, $this->object->getPath($input)); + + $this->restoreFactoryState(); + } + + /** + * Tests the getRules() method + * + * @return void + * + * @since 3.5 + * @covers JComponentRouterView::getRules + */ + public function testGetRules() + { + $rule = new TestComponentRouterRule($this->object); + $this->object->attachRule($rule); + $this->assertEquals(array($rule), $this->object->getRules()); + } + + /** + * Tests the attachRules() method + * + * @return void + * + * @since 3.5 + * @covers JComponentRouterView::attachRules + */ + public function testAttachRules() + { + $rule = new TestComponentRouterRule($this->object); + $this->assertEquals(array(), $this->object->getRules()); + $this->object->attachRules(array($rule)); + $this->assertEquals(array($rule), $this->object->getRules()); + } + + /** + * Tests the attachRule() method + * + * @return void + * + * @since 3.5 + * @covers JComponentRouterView::attachRule + */ + public function testAttachRule() + { + $rule = new TestComponentRouterRule($this->object); + $this->assertEquals(array(), $this->object->get('rules')); + $this->object->attachRule($rule); + $this->assertEquals(array($rule), $this->object->get('rules')); + $this->object->attachRule($rule); + $this->assertEquals(array($rule, $rule), $this->object->get('rules')); + } + + /** + * Tests the detachRule() method + * + * @return void + * + * @since 3.5 + * @covers JComponentRouterView::detachRule + */ + public function testDetachRule() + { + $rule = new TestComponentRouterRule($this->object); + $this->object->attachRule($rule); + $this->assertEquals(array($rule), $this->object->get('rules')); + $this->assertTrue($this->object->detachRule($rule)); + $this->assertEquals(array(), $this->object->get('rules')); + $this->assertFalse($this->object->detachRule($rule)); + } + + /** + * Tests the preprocess() method + * + * @return void + * + * @since 3.5 + * @covers JComponentRouterView::preprocess + */ + public function testPreprocess() + { + $rule = new TestComponentRouterRule($this->object); + $this->object->attachRule($rule); + $this->assertEquals(array('key' => 'value', 'testrule' => 'yes'), $this->object->preprocess(array('key' => 'value'))); + } + + /** + * Tests the build() method + * + * @return void + * + * @since 3.5 + * @covers JComponentRouterView::build + */ + public function testBuild() + { + $rule = new TestComponentRouterRule($this->object); + $this->object->attachRule($rule); + $query = array('key' => 'value', 'test' => 'true'); + $this->assertEquals(array('testrule-run'), $this->object->build($query)); + $this->assertEquals(array('key' => 'value'), $query); + } + + /** + * Tests the parse() method + * + * @return void + * + * @since 3.5 + * @covers JComponentRouterView::parse + */ + public function testParse() + { + $rule = new TestComponentRouterRule($this->object); + $this->object->attachRule($rule); + $segments = array('testrun', 'getsdropped'); + $this->assertEquals(array('testparse' => 'run'), $this->object->parse($segments)); + $this->assertEquals(array('testrun'), $segments); + } + + /** + * Tests the getName() method + * + * @return void + * + * @since 3.5 + * @covers JComponentRouterView::getName + */ + public function testGetName() + { + $this->object->set('name', 'test'); + $this->assertEquals('test', $this->object->getName()); + $this->object->set('name', null); + $this->assertEquals('jcomponent', $this->object->getName()); + } + + /** + * Tests the getName() method and if it throws the right Exception + * + * @return void + * + * @since 3.5 + * @expectedException Exception + * @covers JComponentRouterView::getName + */ + public function testGetNameException() + { + $object = new FakeComponentURLCreator($this->object->app, $this->object->menu); + $object->getName(); + } + + /** + * As view testdata, use the view configuration of com_content + * + * @return array|JComponentRouterViewconfiguration + */ + protected function getComContentViews() + { + $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); + $category = new JComponentRouterViewconfiguration('category'); + $category->setKey('id')->setParent($categories)->setNestable()->addLayout('blog'); + $article = new JComponentRouterViewconfiguration('article'); + $article->setKey('id')->setParent($category, 'catid'); + $archive = new JComponentRouterViewconfiguration('archive'); + $featured = new JComponentRouterViewconfiguration('featured'); + $form = new JComponentRouterViewconfiguration('form'); + + return array( + 'categories' => $categories, + 'category' => $category, + 'article' => $article, + 'archive' => $archive, + 'featured' => $featured, + 'form' => $form + ); + } +} diff --git a/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewconfigurationTest.php b/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewconfigurationTest.php new file mode 100644 index 0000000000000..581fc5d5822cc --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewconfigurationTest.php @@ -0,0 +1,205 @@ +object = new JComponentRouterViewconfiguration('test'); + } + + /** + * Test JComponentRouterViewconfiguration::__construct + * + * @return void + * + * @since 3.4 + * @covers JComponentRouterViewconfiguration::__construct + */ + public function testConstruct() + { + $this->assertInstanceOf('JComponentRouterViewconfiguration', $this->object); + $this->assertEquals('test', $this->object->name); + $this->assertEquals(array('test'), $this->object->path); + } + + /** + * Test JComponentRouterViewconfiguration::setName + * + * @return void + * + * @since 3.4 + * @covers JComponentRouterViewconfiguration::setName + */ + public function testSetName() + { + $this->assertEquals('test', $this->object->name); + $this->assertEquals(array('test'), $this->object->path); + $this->assertEquals($this->object, $this->object->setName('name')); + $this->assertEquals('name', $this->object->name); + $this->assertEquals(array('name'), $this->object->path); + $object2 = new JComponentRouterViewconfiguration('parent'); + $this->object->setParent($object2); + $this->assertEquals(array('parent', 'name'), $this->object->path); + $this->object->setName('name2'); + $this->assertEquals(array('parent', 'name2'), $this->object->path); + } + + /** + * Test JComponentRouterViewconfiguration::setViewKey + * + * @return void + * + * @since 3.4 + * @covers JComponentRouterViewconfiguration::setKey + */ + public function testSetKey() + { + $this->assertFalse($this->object->key); + $this->assertEquals($this->object, $this->object->setKey('id')); + $this->assertEquals('id', $this->object->key); + } + + /** + * Test JComponentRouterViewconfiguration::setParent + * + * @return void + * + * @since 3.4 + * @covers JComponentRouterViewconfiguration::setParent + */ + public function testSetParent() + { + $parent = new JComponentRouterViewconfiguration('parent'); + + // View has no parent + $this->assertEquals(false, $this->object->parent); + $this->assertEquals(false, $this->object->parent_key); + $this->assertEquals(array(), $this->object->children); + $this->assertEquals(array(), $this->object->child_keys); + $this->assertEquals(array('test'), $this->object->path); + $this->assertEquals(array(), $parent->children); + $this->assertEquals(array(), $parent->child_keys); + + // Assign View a parent + $this->assertEquals($this->object, $this->object->setParent($parent)); + $this->assertEquals($parent, $this->object->parent); + $this->assertEquals(false, $this->object->parent_key); + $this->assertEquals(array(), $this->object->children); + $this->assertEquals(array($this->object), $parent->children); + $this->assertEquals(array('parent', 'test'), $this->object->path); + $this->assertEquals(array(), $parent->child_keys); + + // Re-assign View a parent, this time with an ID + $parent2 = new JComponentRouterViewconfiguration('category'); + $this->assertEquals($this->object, $this->object->setParent($parent2, 'catid')); + $this->assertEquals($parent2, $this->object->parent); + $this->assertEquals('catid', $this->object->parent_key); + $this->assertEquals(array(), $this->object->children); + $this->assertEquals(array($this->object), $parent2->children); + $this->assertEquals(array('category', 'test'), $this->object->path); + $this->assertEquals(array('catid'), $parent2->child_keys); + // Make sure that the original parent is cleaned up + $this->assertEquals(array(), $parent->children); + $this->assertEquals(array(), $parent->child_keys); + + // Re-assign View a parent, again with an ID + $parent3 = new JComponentRouterViewconfiguration('form'); + $this->assertEquals($this->object, $this->object->setParent($parent3, 'formid')); + $this->assertEquals($parent3, $this->object->parent); + $this->assertEquals('formid', $this->object->parent_key); + $this->assertEquals(array('formid'), $parent3->child_keys); + // Make sure that the original parent is cleaned up + $this->assertEquals(array(), $parent2->children); + $this->assertEquals(array(), $parent2->child_keys); + } + + /** + * Test JComponentRouterViewconfiguration::setNestable + * + * @return void + * + * @since 3.4 + * @covers JComponentRouterViewconfiguration::setNestable + */ + public function testSetNestable() + { + $this->assertFalse($this->object->nestable); + $this->assertEquals($this->object, $this->object->setNestable()); + $this->assertTrue($this->object->nestable); + $this->assertEquals($this->object, $this->object->setNestable(false)); + $this->assertFalse($this->object->nestable); + $this->assertEquals($this->object, $this->object->setNestable(true)); + $this->assertTrue($this->object->nestable); + } + + /** + * Test JComponentRouterViewconfiguration::addLayout + * + * @return void + * + * @since 3.4 + * @covers JComponentRouterViewconfiguration::addLayout + */ + public function testAddLayout() + { + $this->assertEquals(array('default'), $this->object->layouts); + $this->assertEquals($this->object, $this->object->addLayout('form')); + $this->assertEquals(array('default', 'form'), $this->object->layouts); + // Make sure that a layout can only be added once + $this->object->addLayout('form'); + $this->assertEquals(array('default', 'form'), $this->object->layouts); + } + + /** + * Test JComponentRouterViewconfiguration::removeLayout + * + * @return void + * + * @since 3.4 + * @covers JComponentRouterViewconfiguration::removeLayout + */ + public function testRemoveLayout() + { + $this->assertEquals(array('default'), $this->object->layouts); + $this->object->addLayout('form'); + $this->assertEquals($this->object, $this->object->removeLayout('default')); + $this->assertEquals(array(1 => 'form'), $this->object->layouts); + $this->assertEquals($this->object, $this->object->removeLayout('fake')); + $this->assertEquals(array(1 => 'form'), $this->object->layouts); + $this->object->removeLayout('form'); + $this->assertEquals(array(), $this->object->layouts); + } + +} diff --git a/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesMenuTest.php b/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesMenuTest.php new file mode 100644 index 0000000000000..38176227a76d3 --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesMenuTest.php @@ -0,0 +1,237 @@ +getMockCmsApp(); + JFactory::$application = $app; + $router = new JComponentRouterViewInspector($app, $app->getMenu()); + $router->set('name', 'content'); + $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); + $router->registerView($categories); + $category = new JComponentRouterViewconfiguration('category'); + $category->setKey('id')->setParent($categories)->setNestable()->addLayout('blog'); + $router->registerView($category); + $article = new JComponentRouterViewconfiguration('article'); + $article->setKey('id')->setParent($category, 'catid'); + $router->registerView($article); + $archive = new JComponentRouterViewconfiguration('archive'); + $router->registerView($archive); + $featured = new JComponentRouterViewconfiguration('featured'); + $router->registerView($featured); + $form = new JComponentRouterViewconfiguration('form'); + $router->registerView($form); + $router->menu = new MockJComponentRouterRulesMenuMenuObject(); + + $this->object = new JComponentRouterRulesMenuInspector($router); + } + + /** + * Gets the data set to be loaded into the database during setup + * + * @return PHPUnit_Extensions_Database_DataSet_CsvDataSet + * + * @since 3.5 + */ + protected function getDataSet() + { + $dataSet = new PHPUnit_Extensions_Database_DataSet_CsvDataSet(',', "'", '\\'); + + $dataSet->addTable('jos_categories', JPATH_TEST_DATABASE . '/jos_categories.csv'); + $dataSet->addTable('jos_extensions', JPATH_TEST_DATABASE . '/jos_extensions.csv'); + + return $dataSet; + } + + /** + * Tests the __construct() method + * + * @return void + * + * @since 3.5 + */ + public function testConstruct() + { + $this->assertInstanceOf('JComponentRouterRulesMenu', $this->object); + $this->assertInstanceOf('JComponentRouterView', $this->object->get('router')); + $this->assertEquals(array( + '*' => array( + 'featured' => '47', + 'categories' => array(14 => '48'), + 'category' => array (20 => '49')) + ), $this->object->get('lookup')); + } + + /** + * Cases for testPreprocess + * + * @return array + * + * @since 3.5 + */ + public function casesPreprocess() + { + $cases = array(); + + // Check direct link to a simple view + $cases[] = array(array('option' => 'com_content', 'view' => 'featured'), + array('option' => 'com_content', 'view' => 'featured', 'Itemid' => '47')); + + // Check direct link to a simple view with a language + $cases[] = array(array('option' => 'com_content', 'view' => 'featured', 'lang' => 'en-GB'), + array('option' => 'com_content', 'view' => 'featured', 'lang' => 'en-GB', 'Itemid' => '51')); + + // Check direct link to a view with a key + $cases[] = array(array('option' => 'com_content', 'view' => 'categories', 'id' => '14'), + array('option' => 'com_content', 'view' => 'categories', 'id' => '14', 'Itemid' => '48')); + + // Check direct link to a view with a key with a language + $cases[] = array(array('option' => 'com_content', 'view' => 'categories', 'id' => '14', 'lang' => 'en-GB'), + array('option' => 'com_content', 'view' => 'categories', 'id' => '14', 'lang' => 'en-GB', 'Itemid' => '50')); + + // Check indirect link to a nested view with a key + $cases[] = array(array('option' => 'com_content', 'view' => 'category', 'id' => '22'), + array('option' => 'com_content', 'view' => 'category', 'id' => '22', 'Itemid' => '49')); + + // Check indirect link to a nested view with a key and a language + $cases[] = array(array('option' => 'com_content', 'view' => 'category', 'id' => '22', 'lang' => 'en-GB'), + array('option' => 'com_content', 'view' => 'category', 'id' => '22', 'lang' => 'en-GB', 'Itemid' => '49')); + + // Check indirect link to a single view behind a nested view with a key + $cases[] = array(array('option' => 'com_content', 'view' => 'article', 'id' => '42', 'catid' => '22'), + array('option' => 'com_content', 'view' => 'article', 'id' => '42', 'catid' => '22', 'Itemid' => '49')); + + // Check indirect link to a single view behind a nested view with a key and language + $cases[] = array(array('option' => 'com_content', 'view' => 'article', 'id' => '42', 'catid' => '22', 'lang' => 'en-GB'), + array('option' => 'com_content', 'view' => 'article', 'id' => '42', 'catid' => '22', 'lang' => 'en-GB', 'Itemid' => '49')); + + // Check non-existing menu link + $cases[] = array(array('option' => 'com_content', 'view' => 'categories', 'id' => '42'), + array('option' => 'com_content', 'view' => 'categories', 'id' => '42', 'Itemid' => '49')); + + // Check indirect link to a single view behind a nested view with a key and language + $cases[] = array(array('option' => 'com_content', 'view' => 'categories', 'id' => '42', 'lang' => 'en-GB'), + array('option' => 'com_content', 'view' => 'categories', 'id' => '42', 'lang' => 'en-GB', 'Itemid' => '49')); + + // Check if a query with existing Itemid that is not the current active menu-item is not touched + $cases[] = array(array('option' => 'com_content', 'view' => 'categories', 'id' => '42', 'Itemid' => '99'), + array('option' => 'com_content', 'view' => 'categories', 'id' => '42', 'Itemid' => '99')); + + // Check if a query with existing Itemid that is the current active menu-item is correctly searched + $cases[] = array(array('option' => 'com_content', 'view' => 'categories', 'id' => '14', 'Itemid' => '49'), + array('option' => 'com_content', 'view' => 'categories', 'id' => '14', 'Itemid' => '48')); + + return $cases; + } + + /** + * Tests the preprocess() method + * + * @return void + * + * @dataProvider casesPreprocess + * @since 3.5 + */ + public function testPreprocess($input, $result) + { + $this->saveFactoryState(); + + $this->object->preprocess($input); + $this->assertEquals($result, $input); + + $this->restoreFactoryState(); + } + + /** + * Tests the preprocess() method + * + * @return void + * + * @since 3.5 + */ + public function testPreprocessLanguage() + { + $this->saveFactoryState(); + + // Test if the default Itemid is used if everything else fails + $router = $this->object->get('router'); + $router->menu->active = null; + $query = array(); + $this->object->preprocess($query); + $this->assertEquals(array('Itemid' => '47'), $query); + + // Test if the correct default item is used based on the language + $query = array('lang' => 'en-GB'); + $this->object->preprocess($query); + $this->assertEquals(array('lang' => 'en-GB', 'Itemid' => '51'), $query); + + $this->restoreFactoryState(); + } + + /** + * Tests the buildLookup() method + * + * @return void + * + * @since 3.5 + */ + public function testBuildLookup() + { + $this->assertEquals(array( + '*' => array( + 'featured' => '47', + 'categories' => array(14 => '48'), + 'category' => array (20 => '49')) + ), $this->object->get('lookup')); + + $this->object->runBuildLookUp('en-GB'); + $this->assertEquals(array( + '*' => array( + 'featured' => '47', + 'categories' => array(14 => '48'), + 'category' => array (20 => '49')), + 'en-GB' => array( + 'featured' => '51', + 'categories' => array(14 => '50'), + 'category' => array (20 => '49')) + ), $this->object->get('lookup')); + } +} diff --git a/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesNomenuTest.php b/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesNomenuTest.php new file mode 100644 index 0000000000000..029d819fa4893 --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesNomenuTest.php @@ -0,0 +1,163 @@ +getMockCmsApp(); + $router = new JComponentRouterViewInspector($app, $app->getMenu()); + $router->set('name', 'content'); + $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); + $router->registerView($categories); + $category = new JComponentRouterViewconfiguration('category'); + $category->setKey('id')->setParent($categories)->setNestable()->addLayout('blog'); + $router->registerView($category); + $article = new JComponentRouterViewconfiguration('article'); + $article->setKey('id')->setParent($category, 'catid'); + $router->registerView($article); + $archive = new JComponentRouterViewconfiguration('archive'); + $router->registerView($archive); + $featured = new JComponentRouterViewconfiguration('featured'); + $router->registerView($featured); + $form = new JComponentRouterViewconfiguration('form'); + $router->registerView($form); + + $this->object = new JComponentRouterRulesNomenuInspector($router); + } + + /** + * Tests the __construct() method + * + * @return void + * + * @since 3.4 + */ + public function testConstruct() + { + $this->assertInstanceOf('JComponentRouterRulesNomenu', $this->object); + $this->assertInstanceOf('JComponentRouterView', $this->object->get('router')); + } + + /** + * Tests the parse() method + * + * @return void + * + * @since 3.4 + */ + public function testParse() + { + // Check if a false view is properly rejected + $segments = array('falseview'); + $vars = array('option' => 'com_content'); + $this->object->parse($segments, $vars); + $this->assertEquals(array('falseview'), $segments); + $this->assertEquals(array('option' => 'com_content'), $vars); + + // Check if a single view is properly parsed + $segments = array('featured'); + $vars = array('option' => 'com_content'); + $this->object->parse($segments, $vars); + $this->assertEquals(array(), $segments); + $this->assertEquals(array('option' => 'com_content', 'view' => 'featured'), $vars); + + // Check if a view with ID is properly parsed + $segments = array('category', '23-the-question'); + $vars = array('option' => 'com_content'); + $this->object->parse($segments, $vars); + $this->assertEquals(array(), $segments); + $this->assertEquals(array('option' => 'com_content', 'view' => 'category', 'id' => '23:the-question'), $vars); + + // Check if a view that normally has an ID but which is missing is properly parsed + $segments = array('category'); + $vars = array('option' => 'com_content'); + $this->object->parse($segments, $vars); + $this->assertEquals(array(), $segments); + $this->assertEquals(array('option' => 'com_content', 'view' => 'category'), $vars); + + // Test if the rule is properly skipped when a menu item is set + $router = $this->object->get('router'); + $router->menu->expects($this->any()) + ->method('getActive') + ->will($this->returnValue(new stdClass())); + $segments = array('article', '42:the-answer'); + $vars = array('option' => 'com_content'); + $this->object->parse($segments, $vars); + $this->assertEquals(array('article', '42:the-answer'), $segments); + $this->assertEquals(array('option' => 'com_content'), $vars); + } + + /** + * Tests the build() method + * + * @return void + * + * @since 3.4 + */ + public function testBuild() + { + // Test if the rule is properly skipped if an Itemid is set + $query = array('option' => 'com_content', 'view' => 'article', 'id' => '42:the-answer', 'Itemid' => '23'); + $segments = array(); + $this->object->build($query, $segments); + $this->assertEquals(array('option' => 'com_content', 'view' => 'article', 'id' => '42:the-answer', 'Itemid' => '23'), $query); + $this->assertEquals(array(), $segments); + + // Test if a false view is properly not treated + $query = array('option' => 'com_content', 'view' => 'falseview', 'id' => '42:the-answer'); + $segments = array(); + $this->object->build($query, $segments); + $this->assertEquals(array('option' => 'com_content', 'view' => 'falseview', 'id' => '42:the-answer'), $query); + $this->assertEquals(array(), $segments); + + // Test if a single view without identifier is properly build + $query = array('option' => 'com_content', 'view' => 'featured'); + $segments = array(); + $this->object->build($query, $segments); + $this->assertEquals(array('option' => 'com_content'), $query); + $this->assertEquals(array('featured'), $segments); + + // Test if a single view with identifier is properly build + $query = array('option' => 'com_content', 'view' => 'article', 'id' => '42:the-answer'); + $segments = array(); + $this->object->build($query, $segments); + $this->assertEquals(array('option' => 'com_content'), $query); + $this->assertEquals(array('article', '42-the-answer'), $segments); + } +} diff --git a/tests/unit/suites/libraries/cms/component/router/rules/stubs/JComponentRouterRulesMenuInspector.php b/tests/unit/suites/libraries/cms/component/router/rules/stubs/JComponentRouterRulesMenuInspector.php new file mode 100644 index 0000000000000..774114d3ce917 --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/rules/stubs/JComponentRouterRulesMenuInspector.php @@ -0,0 +1,52 @@ +$key; + } + + /** + * Sets an attribute of the object + * + * @param string $key Attributename to return + * @param mixed $value Value to be set + * + * @return void + * + * @since 3.4 + */ + public function set($key, $value) + { + $this->$key = $value; + } + + public function runBuildLookup($language = '*') + { + return $this->buildLookup($language); + } +} \ No newline at end of file diff --git a/tests/unit/suites/libraries/cms/component/router/rules/stubs/JComponentRouterRulesNomenuInspector.php b/tests/unit/suites/libraries/cms/component/router/rules/stubs/JComponentRouterRulesNomenuInspector.php new file mode 100644 index 0000000000000..e6f45d319301b --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/rules/stubs/JComponentRouterRulesNomenuInspector.php @@ -0,0 +1,47 @@ +$key; + } + + /** + * Sets an attribute of the object + * + * @param string $key Attributename to return + * @param mixed $value Value to be set + * + * @return void + * + * @since 3.4 + */ + public function set($key, $value) + { + $this->$key = $value; + } +} \ No newline at end of file diff --git a/tests/unit/suites/libraries/cms/component/router/rules/stubs/MockJComponentRouterRulesMenuMenuObject.php b/tests/unit/suites/libraries/cms/component/router/rules/stubs/MockJComponentRouterRulesMenuMenuObject.php new file mode 100644 index 0000000000000..3b710d4eebce5 --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/rules/stubs/MockJComponentRouterRulesMenuMenuObject.php @@ -0,0 +1,196 @@ +items[47] = (object) array( + 'id' => '47', + 'menutype' => 'testmenu', + 'title' => 'Content Home', + 'alias' => 'content-home', + 'route' => 'content-home', + 'link' => 'index.php?option=com_content&view=featured', + 'type' => 'component', + 'level' => '1', + 'language' => '*', + 'component_id' => '22', + 'component' => 'com_content', + 'parent_id' => '0', + 'query' => array('option' => 'com_content', 'view' => 'featured')); + + $this->items[48] = (object) array( + 'id' => '48', + 'menutype' => 'testmenu', + 'title' => 'Categories View', + 'alias' => 'categories', + 'route' => 'content-home/categories', + 'link' => 'index.php?option=com_content&view=categories&id=14', + 'type' => 'component', + 'level' => '2', + 'language' => '*', + 'component_id' => '22', + 'component' => 'com_content', + 'parent_id' => '47', + 'query' => array('option' => 'com_content', 'view' => 'categories', 'id' => '14')); + + $this->items[49] = (object) array( + 'id' => '49', + 'menutype' => 'testmenu', + 'title' => 'Category View', + 'alias' => 'category-view', + 'route' => 'category-view', + 'link' => 'index.php?option=com_content&view=category&id=20', + 'type' => 'component', + 'level' => '1', + 'language' => '*', + 'component_id' => '22', + 'component' => 'com_content', + 'parent_id' => '47', + 'query' => array('option' => 'com_content', 'view' => 'category', 'id' => '20')); + + $this->items[50] = (object) array( + 'id' => '50', + 'menutype' => 'testmenu', + 'title' => 'Categories View', + 'alias' => 'categories', + 'route' => 'content-home/categories', + 'link' => 'index.php?option=com_content&view=categories&id=14', + 'type' => 'component', + 'level' => '2', + 'language' => 'en-GB', + 'component_id' => '22', + 'component' => 'com_content', + 'parent_id' => '47', + 'query' => array('option' => 'com_content', 'view' => 'categories', 'id' => '14')); + + $this->items[51] = (object) array( + 'id' => '51', + 'menutype' => 'testmenu', + 'title' => 'Content Home', + 'alias' => 'content-home', + 'route' => 'content-home', + 'link' => 'index.php?option=com_content&view=featured', + 'type' => 'component', + 'level' => '1', + 'language' => 'en-GB', + 'component_id' => '22', + 'component' => 'com_content', + 'parent_id' => '0', + 'query' => array('option' => 'com_content', 'view' => 'featured')); + } + + /** + * Gets the menu item set that fits the search array + * + * @param array $attributes Search criteria + * @param array $values Search criteria + * + * @return mixed Menu items + * + * @since 3.4 + */ + public function getItems($attributes, $values) + { + $items = array(); + $attributes = (array) $attributes; + $values = (array) $values; + + foreach ($this->items as $item) + { + $test = true; + + for ($i = 0, $count = count($attributes); $i < $count; $i++) + { + if (is_array($values[$i])) + { + if (!in_array($item->$attributes[$i], $values[$i])) + { + $test = false; + break; + } + } + else + { + if ($item->$attributes[$i] != $values[$i]) + { + $test = false; + break; + } + } + } + + if ($test) + { + $items[] = $item; + } + } + + return $items; + } + + /** + * Return the currently active menuitem + * + * @return object Menuitem + * @since 3.4 + */ + public function getActive() + { + return (isset($this->items[$this->active]) ? $this->items[$this->active] : null); + } + + /** + * Return the default menuitem for the language + * + * @param string $language Language for the default + * + * @return object Menuitem + * @since 3.4 + */ + public function getDefault($language = '*') + { + if ($language == '*') + { + return $this->items[47]; + } + + if ($language == 'en-GB') + { + return $this->items[51]; + } + } +} \ No newline at end of file diff --git a/tests/unit/suites/libraries/cms/component/router/stubs/JCategoriesMock.php b/tests/unit/suites/libraries/cms/component/router/stubs/JCategoriesMock.php new file mode 100644 index 0000000000000..33f3443c56c22 --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/stubs/JCategoriesMock.php @@ -0,0 +1,34 @@ +$key; + } + + public function build(&$query) + { + } + + public function parse(&$segments) + { + + } +} diff --git a/tests/unit/suites/libraries/cms/component/router/stubs/JComponentRouterViewInspector.php b/tests/unit/suites/libraries/cms/component/router/stubs/JComponentRouterViewInspector.php new file mode 100644 index 0000000000000..9e4ddde709b82 --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/stubs/JComponentRouterViewInspector.php @@ -0,0 +1,108 @@ +$key; + } + + /** + * Sets an attribute of the object + * + * @param string $key Attributename to return + * @param mixed $value Value to be set + * + * @return void + * + * @since 3.4 + */ + public function set($key, $value) + { + $this->$key = $value; + } + + /** + * Get content items of the type category + * + * @param int $id ID of the category to load + * + * @return array Categories path identified by $id + * + * @since 3.4 + */ + public function getCategorySegment($id, $query) + { + $category = JCategories::getInstance($this->getName())->get($id); + if ($category) + { + return array_reverse($category->getPath()); + } + + return array(); + } + + /** + * Get content items of the type categories + * + * @param int $id ID of the category to load + * + * @return array Categories path identified by $id + * + * @since 3.4 + */ + public function getCategoriesSegment($id, $query) + { + $category = JCategories::getInstance($this->getName())->get($id); + if ($category) + { + return array_reverse($category->getPath()); + } + + return array(); + } + + /** + * Get content items of the type article + * + * @param int $id ID of the article to load + * + * @return array article identified by $id + * + * @since 3.4 + */ + public function getArticleSegment($id, $query) + { + return array($id); + } +} + +/** + * Mock class to crash JComponentRouterAdvanced::getName + */ +class FakeComponentURLCreator extends JComponentRouterViewInspector +{ +} \ No newline at end of file diff --git a/tests/unit/suites/libraries/cms/component/router/stubs/componentrouter.php b/tests/unit/suites/libraries/cms/component/router/stubs/componentrouter.php new file mode 100644 index 0000000000000..6b13df53e61f1 --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/stubs/componentrouter.php @@ -0,0 +1,45 @@ + $var) + { + $return[] = $key . '-' . $var; + } + + return $return; +} + +/** + * Parse function for a fictitious legacy com_comtest router + * + * @package Joomla.UnitTest + * @subpackage Component + * @since 3.4 + */ +function ComtestParseRoute(&$segments) +{ + $return = array(); + foreach ($segments as $segment) + { + list($key, $var) = explode(':', $segment, 2); + $return[$key] = $var; + } + + return $return; +} diff --git a/tests/unit/suites/libraries/cms/component/router/stubs/componentrouterrule.php b/tests/unit/suites/libraries/cms/component/router/stubs/componentrouterrule.php new file mode 100644 index 0000000000000..7e2cbe40955d3 --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/stubs/componentrouterrule.php @@ -0,0 +1,84 @@ +router = $router; + } + + /** + * Finds the right Itemid for this query + * + * @param array &$query The query array to process + * + * @return void + * + * @since 3.4 + */ + public function preprocess(&$query) + { + $query['testrule'] = 'yes'; + } + + /** + * Parse method + * + * @param array &$segments The URL segments to parse + * @param array &$vars The vars that result from the segments + * + * @return void + * + * @since 3.4 + */ + public function parse(&$segments, &$vars) + { + array_pop($segments); + $vars['testparse'] = 'run'; + } + + /** + * Build method + * + * @param array &$query The vars that should be converted + * @param array &$segments The URL segments to create + * + * @return void + * + * @since 3.4 + */ + public function build(&$query, &$segments) + { + array_pop($query); + $segments[] = 'testrule-run'; + } +} diff --git a/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php b/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php index abbd53eee2a28..2c3610c9e9f9e 100644 --- a/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php +++ b/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php @@ -794,7 +794,7 @@ public function testGetComponentRouter() * Check if a proper router is automatically loaded * by loading the router of com_content */ - $this->assertInstanceOf('ContentRouter', $this->object->getComponentRouter('com_content')); + $this->assertInstanceOf('WrapperRouter', $this->object->getComponentRouter('com_wrapper')); /** * Check if an instance of JComponentRouterLegacy diff --git a/tests/unit/suites/libraries/joomla/registry/JRegistryFormatTest.php b/tests/unit/suites/libraries/joomla/registry/JRegistryFormatTest.php deleted file mode 100644 index 39520edd7c4f7..0000000000000 --- a/tests/unit/suites/libraries/joomla/registry/JRegistryFormatTest.php +++ /dev/null @@ -1,66 +0,0 @@ -assertInstanceOf( - 'JRegistryFormatINI', - $object - ); - - // Test JSON format. - $object = JRegistryFormat::getInstance('JSON'); - $this->assertInstanceOf( - 'JRegistryFormatJSON', - $object - ); - - // Test PHP format. - $object = JRegistryFormat::getInstance('PHP'); - $this->assertInstanceOf( - 'JRegistryFormatPHP', - $object - ); - - // Test XML format. - $object = JRegistryFormat::getInstance('XML'); - $this->assertInstanceOf( - 'JRegistryFormatXML', - $object - ); - - // Test non-existing format. - try - { - $object = JRegistryFormat::getInstance('SQL'); - } - catch (Exception $e) - { - return; - } - $this->fail('JRegistryFormat should throw an exception in case of non-existing formats'); - } -} diff --git a/tests/unit/suites/libraries/joomla/registry/JRegistryTest.php b/tests/unit/suites/libraries/joomla/registry/JRegistryTest.php deleted file mode 100644 index 01e52c2d095c9..0000000000000 --- a/tests/unit/suites/libraries/joomla/registry/JRegistryTest.php +++ /dev/null @@ -1,612 +0,0 @@ - '123', 'b' => '456')); - $a->set('foo', 'bar'); - $b = clone $a; - - $this->assertThat( - serialize($a), - $this->equalTo(serialize($b)) - ); - - $this->assertThat( - $a, - $this->logicalNot($this->identicalTo($b)), - 'Line: ' . __LINE__ . '.' - ); - } - - /** - * Test the JRegistry::__toString method. - * - * @covers JRegistry::__toString - * - * @return void - */ - public function test__toString() - { - $object = new stdClass; - $a = new JRegistry($object); - $a->set('foo', 'bar'); - - // __toString only allows for a JSON value. - $this->assertThat( - (string) $a, - $this->equalTo('{"foo":"bar"}'), - 'Line: ' . __LINE__ . '.' - ); - } - - /** - * Test the JRegistry::jsonSerialize method. - * - * @covers JRegistry::jsonSerialize - * - * @return void - */ - public function testJsonSerialize() - { - if (version_compare(PHP_VERSION, '5.4.0', '<')) - { - $this->markTestSkipped('This test requires PHP 5.4 or newer.'); - } - - $object = new stdClass; - $a = new JRegistry($object); - $a->set('foo', 'bar'); - - // __toString only allows for a JSON value. - $this->assertThat( - json_encode($a), - $this->equalTo('{"foo":"bar"}'), - 'Line: ' . __LINE__ . '.' - ); - } - - /** - * Tests serializing JRegistry objects. - * - * @return void - */ - public function testSerialize() - { - $a = new JRegistry; - $a->set('foo', 'bar'); - - $serialized = serialize($a); - $b = unserialize($serialized); - - // __toString only allows for a JSON value. - $this->assertThat( - $b, - $this->equalTo($a), - 'Line: ' . __LINE__ . '.' - ); - } - - /** - * Test the JRegistry::def method. - * - * @covers JRegistry::def - * - * @return void - */ - public function testDef() - { - $a = new JRegistry; - - $this->assertThat( - $a->def('foo', 'bar'), - $this->equalTo('bar'), - 'Line: ' . __LINE__ . '. def should return default value' - ); - - $this->assertThat( - $a->get('foo'), - $this->equalTo('bar'), - 'Line: ' . __LINE__ . '. default should now be the current value' - ); - } - - /** - * Tet the JRegistry::bindData method. - * - * @covers JRegistry::bindData - * - * @return void - */ - public function testBindData() - { - $a = new JRegistryInspector; - $parent = new stdClass; - - $a->bindData($parent, 'foo'); - $this->assertThat( - $parent->{0}, - $this->equalTo('foo'), - 'Line: ' . __LINE__ . ' The input value should exist in the parent object.' - ); - - $a->bindData($parent, array('foo' => 'bar')); - $this->assertThat( - $parent->{'foo'}, - $this->equalTo('bar'), - 'Line: ' . __LINE__ . ' The input value should exist in the parent object.' - ); - - $a->bindData($parent, array('level1' => array('level2' => 'value2'))); - $this->assertThat( - $parent->{'level1'}->{'level2'}, - $this->equalTo('value2'), - 'Line: ' . __LINE__ . ' The input value should exist in the parent object.' - ); - - $a->bindData($parent, array('intarray' => array(0, 1, 2))); - $this->assertThat( - $parent->{'intarray'}, - $this->equalTo(array(0, 1, 2)), - 'Line: ' . __LINE__ . ' The un-associative array should bind natively.' - ); - } - - /** - * Test the JRegistry::exists method. - * - * @covers JRegistry::exists - * - * @return void - */ - public function testExists() - { - $a = new JRegistry; - $a->set('foo', 'bar1'); - $a->set('config.foo', 'bar2'); - $a->set('deep.level.foo', 'bar3'); - - $this->assertThat( - $a->exists('foo'), - $this->isTrue(), - 'Line: ' . __LINE__ . ' The path should exist, returning true.' - ); - - $this->assertThat( - $a->exists('config.foo'), - $this->isTrue(), - 'Line: ' . __LINE__ . ' The path should exist, returning true.' - ); - - $this->assertThat( - $a->exists('deep.level.foo'), - $this->isTrue(), - 'Line: ' . __LINE__ . ' The path should exist, returning true.' - ); - - $this->assertThat( - $a->exists('deep.level.bar'), - $this->isFalse(), - 'Line: ' . __LINE__ . ' The path should not exist, returning false.' - ); - - $this->assertThat( - $a->exists('bar.foo'), - $this->isFalse(), - 'Line: ' . __LINE__ . ' The path should not exist, returning false.' - ); - } - - /** - * Test the JRegistry::get method - * - * @covers JRegistry::get - * - * @return void - */ - public function testGet() - { - $a = new JRegistry; - $a->set('foo', 'bar'); - $this->assertEquals('bar', $a->get('foo'), 'Line: ' . __LINE__ . ' get method should work.'); - $this->assertNull($a->get('xxx.yyy'), 'Line: ' . __LINE__ . ' get should return null when not found.'); - } - - /** - * Test the JRegistry::getInstance method. - * - * @covers JRegistry::getInstance - * - * @return void - */ - public function testGetInstance() - { - // Test INI format. - $a = JRegistry::getInstance('a'); - $b = JRegistry::getInstance('a'); - $c = JRegistry::getInstance('c'); - - // Check the object type. - $this->assertThat( - $a instanceof JRegistry, - $this->isTrue(), - 'Line: ' . __LINE__ . '.' - ); - - // Check cache handling for same registry id. - $this->assertThat( - $a, - $this->identicalTo($b), - 'Line: ' . __LINE__ . '.' - ); - - // Check cache handling for different registry id. - $this->assertThat( - $a, - $this->logicalNot($this->identicalTo($c)), - 'Line: ' . __LINE__ . '.' - ); - } - - /** - * Test the JRegistry::loadArray method. - * - * @covers JRegistry::loadArray - * - * @return void - */ - public function testLoadArray() - { - $array = array( - 'foo' => 'bar' - ); - $registry = new JRegistry; - $result = $registry->loadArray($array); - - // Result is always true, no error checking in method. - - // Test getting a known value. - $this->assertThat( - $registry->get('foo'), - $this->equalTo('bar'), - 'Line: ' . __LINE__ . '.' - ); - } - - /** - * Test the JRegistry::loadFile method. - * - * @covers JRegistry::loadFile - * - * @return void - */ - public function testLoadFile() - { - $registry = new JRegistry; - - // Result is always true, no error checking in method. - - // JSON. - $result = $registry->loadFile(__DIR__ . '/stubs/jregistry.json'); - - // Test getting a known value. - $this->assertThat( - $registry->get('foo'), - $this->equalTo('bar'), - 'Line: ' . __LINE__ . '.' - ); - - // INI. - $result = $registry->loadFile(__DIR__ . '/stubs/jregistry.ini', 'ini'); - - // Test getting a known value. - $this->assertThat( - $registry->get('foo'), - $this->equalTo('bar'), - 'Line: ' . __LINE__ . '.' - ); - - // INI + section. - $result = $registry->loadFile(__DIR__ . '/stubs/jregistry.ini', 'ini', array('processSections' => true)); - - // Test getting a known value. - $this->assertThat( - $registry->get('section.foo'), - $this->equalTo('bar'), - 'Line: ' . __LINE__ . '.' - ); - - // XML and PHP versions do not support stringToObject. - } - - /** - * Test the JRegistry::loadString() method. - * - * @covers JRegistry::loadString - * - * @return void - */ - public function testLoadString() - { - $registry = new JRegistry; - $result = $registry->loadString('foo="testloadini1"', 'INI'); - - // Test getting a known value. - $this->assertThat( - $registry->get('foo'), - $this->equalTo('testloadini1'), - 'Line: ' . __LINE__ . '.' - ); - - $result = $registry->loadString("[section]\nfoo=\"testloadini2\"", 'INI'); - - // Test getting a known value. - $this->assertThat( - $registry->get('foo'), - $this->equalTo('testloadini2'), - 'Line: ' . __LINE__ . '.' - ); - - $result = $registry->loadString("[section]\nfoo=\"testloadini3\"", 'INI', array('processSections' => true)); - - // Test getting a known value after processing sections. - $this->assertThat( - $registry->get('section.foo'), - $this->equalTo('testloadini3'), - 'Line: ' . __LINE__ . '.' - ); - - $string = '{"foo":"testloadjson"}'; - - $registry = new JRegistry; - $result = $registry->loadString($string); - - // Result is always true, no error checking in method. - - // Test getting a known value. - $this->assertThat( - $registry->get('foo'), - $this->equalTo('testloadjson'), - 'Line: ' . __LINE__ . '.' - ); - - } - - /** - * Test the JRegistry::loadObject method. - * - * @covers JRegistry::loadObject - * - * @return void - */ - public function testLoadObject() - { - $object = new stdClass; - $object->foo = 'testloadobject'; - - $registry = new JRegistry; - $result = $registry->loadObject($object); - - // Result is always true, no error checking in method. - - // Test getting a known value. - $this->assertThat( - $registry->get('foo'), - $this->equalTo('testloadobject'), - 'Line: ' . __LINE__ . '.' - ); - - // Test case from Tracker Issue 22444 - $registry = new JRegistry; - $object = new JObject; - $object2 = new JObject; - $object2->set('test', 'testcase'); - $object->set('test', $object2); - $this->assertInstanceOf( - 'JRegistry', - $registry->loadObject($object), - 'Line: ' . __LINE__ . '. Should load object successfully' - ); - } - - /** - * Test the JRegistry::merge method. - * - * @covers JRegistry::merge - * - * @return void - */ - public function testMerge() - { - $array1 = array( - 'foo' => 'bar', - 'hoo' => 'hum', - 'dum' => array( - 'dee' => 'dum' - ) - ); - - $array2 = array( - 'foo' => 'soap', - 'dum' => 'huh' - ); - $registry1 = new JRegistry; - $registry1->loadArray($array1); - - $registry2 = new JRegistry; - $registry2->loadArray($array2); - - $registry1->merge($registry2); - - // Test getting a known value. - $this->assertThat( - $registry1->get('foo'), - $this->equalTo('soap'), - 'Line: ' . __LINE__ . '.' - ); - - $this->assertThat( - $registry1->get('dum'), - $this->equalTo('huh'), - 'Line: ' . __LINE__ . '.' - ); - - // Test merge with zero and blank value - $json1 = '{"param1":1, "param2":"value2"}'; - $json2 = '{"param1":2, "param2":"", "param3":0, "param4":-1, "param5":1}'; - $a = new JRegistry($json1); - $b = new JRegistry; - $b->loadString($json2, 'JSON'); - $a->merge($b); - - // New param with zero value should show in merged registry - $this->assertEquals(2, $a->get('param1'), '$b value should override $a value'); - $this->assertEquals('value2', $a->get('param2'), '$a value should override blank $b value'); - $this->assertEquals(0, $a->get('param3'), '$b value of 0 should override $a value'); - $this->assertEquals(-1, $a->get('param4'), '$b value of -1 should override $a value'); - $this->assertEquals(1, $a->get('param5'), '$b value of 1 should override $a value'); - - $a = new JRegistry; - $b = new stdClass; - $this->assertFalse($a->merge($b), 'Line: ' . __LINE__ . '. Attempt to merge non JRegistry should return false'); - } - - /** - * Test the JRegistry::set method. - * - * @covers JRegistry::set - * - * @return void - */ - public function testSet() - { - $a = new JRegistry; - $a->set('foo', 'testsetvalue1'); - - $this->assertThat( - $a->set('foo', 'testsetvalue2'), - $this->equalTo('testsetvalue2'), - 'Line: ' . __LINE__ . '.' - ); - } - - /** - * Test the JRegistry::toArray method. - * - * @covers JRegistry::toArray - * - * @return void - */ - public function testToArray() - { - $a = new JRegistry; - $a->set('foo1', 'testtoarray1'); - $a->set('foo2', 'testtoarray2'); - $a->set('config.foo3', 'testtoarray3'); - - $expected = array( - 'foo1' => 'testtoarray1', - 'foo2' => 'testtoarray2', - 'config' => array('foo3' => 'testtoarray3') - ); - - $this->assertThat( - $a->toArray(), - $this->equalTo($expected), - 'Line: ' . __LINE__ . '.' - ); - } - - /** - * Test the JRegistry::toObject method. - * - * @covers JRegistry::toObject - * - * @return void - */ - public function testToObject() - { - $a = new JRegistry; - $a->set('foo1', 'testtoobject1'); - $a->set('foo2', 'testtoobject2'); - $a->set('config.foo3', 'testtoobject3'); - - $expected = new stdClass; - $expected->foo1 = 'testtoobject1'; - $expected->foo2 = 'testtoobject2'; - $expected->config = new StdClass; - $expected->config->foo3 = 'testtoobject3'; - - $this->assertThat( - $a->toObject(), - $this->equalTo($expected), - 'Line: ' . __LINE__ . '.' - ); - } - - /** - * Test the JRegistry::toString method. - * - * @covers JRegistry::toString - * - * @return void - */ - public function testToString() - { - $a = new JRegistry; - $a->set('foo1', 'testtostring1'); - $a->set('foo2', 'testtostring2'); - $a->set('config.foo3', 'testtostring3'); - - $this->assertThat( - trim($a->toString('JSON')), - $this->equalTo( - '{"foo1":"testtostring1","foo2":"testtostring2","config":{"foo3":"testtostring3"}}' - ), - 'Line: ' . __LINE__ . '.' - ); - - $this->assertThat( - trim($a->toString('INI')), - $this->equalTo( - "foo1=\"testtostring1\"\nfoo2=\"testtostring2\"\n\n[config]\nfoo3=\"testtostring3\"" - ), - 'Line: ' . __LINE__ . '.' - ); - } -} diff --git a/tests/unit/suites/libraries/joomla/registry/format/JRegistryFormatIniTest.php b/tests/unit/suites/libraries/joomla/registry/format/JRegistryFormatIniTest.php deleted file mode 100644 index 8590dada8ab56..0000000000000 --- a/tests/unit/suites/libraries/joomla/registry/format/JRegistryFormatIniTest.php +++ /dev/null @@ -1,109 +0,0 @@ -foo = 'bar'; - $object->booleantrue = true; - $object->booleanfalse = false; - $object->numericint = 42; - $object->numericfloat = 3.1415; - $object->section = new stdClass; - $object->section->key = 'value'; - - // Test basic object to string. - $string = $class->objectToString($object); - $this->assertThat( - trim($string), - $this->equalTo("foo=\"bar\"\nbooleantrue=true\nbooleanfalse=false\nnumericint=42\nnumericfloat=3.1415\n\n[section]\nkey=\"value\"") - ); - } - - /** - * Test the JRegistryFormatINI::stringToObject method. - * - * @return void - */ - public function testStringToObject() - { - $class = JRegistryFormat::getInstance('INI'); - - $string2 = "[section]\nfoo=bar"; - - $object1 = new stdClass; - $object1->foo = 'bar'; - - $object2 = new stdClass; - $object2->section = $object1; - - // Test INI format string without sections. - $object = $class->stringToObject($string2, array('processSections' => false)); - $this->assertThat( - $object, - $this->equalTo($object1) - ); - - // Test INI format string with sections. - $object = $class->stringToObject($string2, array('processSections' => true)); - $this->assertThat( - $object, - $this->equalTo($object2) - ); - - // Test empty string - $this->assertThat( - $class->stringToObject(null), - $this->equalTo(new stdClass) - ); - - $string3 = "[section]\nfoo=bar\n;Testcomment\nkey=value\n\n/brokenkey=)brokenvalue"; - $object2->section->key = 'value'; - - $this->assertThat( - $class->stringToObject($string3, array('processSections' => true)), - $this->equalTo($object2) - ); - - $string4 = "boolfalse=false\nbooltrue=true\nkeywithoutvalue\nnumericfloat=3.1415\nnumericint=42\nkey=\"value\""; - $object3 = new stdClass; - $object3->boolfalse = false; - $object3->booltrue = true; - $object3->numericfloat = 3.1415; - $object3->numericint = 42; - $object3->key = 'value'; - - $this->assertThat( - $class->stringToObject($string4), - $this->equalTo($object3) - ); - - // Trigger the cache - Doing this only to achieve 100% code coverage. ;-) - $this->assertThat( - $class->stringToObject($string4), - $this->equalTo($object3) - ); - } -} diff --git a/tests/unit/suites/libraries/joomla/registry/format/JRegistryFormatJsonTest.php b/tests/unit/suites/libraries/joomla/registry/format/JRegistryFormatJsonTest.php deleted file mode 100644 index e2266c99aa80a..0000000000000 --- a/tests/unit/suites/libraries/joomla/registry/format/JRegistryFormatJsonTest.php +++ /dev/null @@ -1,118 +0,0 @@ -foo = 'bar'; - $object->quoted = '"stringwithquotes"'; - $object->booleantrue = true; - $object->booleanfalse = false; - $object->numericint = 42; - $object->numericfloat = 3.1415; - - // The PHP registry format does not support nested objects - $object->section = new stdClass; - $object->section->key = 'value'; - $object->array = array('nestedarray' => array('test1' => 'value1')); - - $string = '{"foo":"bar","quoted":"\"stringwithquotes\"",' . - '"booleantrue":true,"booleanfalse":false,' . - '"numericint":42,"numericfloat":3.1415,' . - '"section":{"key":"value"},' . - '"array":{"nestedarray":{"test1":"value1"}}' . - '}'; - - // Test basic object to string. - $this->assertThat( - $class->objectToString($object, $options), - $this->equalTo($string) - ); - } - - /** - * Test the JRegistryFormatJSON::stringToObject method. - * - * @return void - */ - public function testStringToObject() - { - $class = new JRegistryFormatJSON; - - $string1 = '{"title":"Joomla Framework","author":"Me","params":{"show_title":1,"show_abstract":0,"show_author":1,"categories":[1,2]}}'; - $string2 = "[section]\nfoo=bar"; - - $object1 = new stdClass; - $object1->title = 'Joomla Framework'; - $object1->author = 'Me'; - $object1->params = new stdClass; - $object1->params->show_title = 1; - $object1->params->show_abstract = 0; - $object1->params->show_author = 1; - $object1->params->categories = array(1, 2); - - $object2 = new stdClass; - $object2->section = new stdClass; - $object2->section->foo = 'bar'; - - $object3 = new stdClass; - $object3->foo = 'bar'; - - // Test basic JSON string to object. - $object = $class->stringToObject($string1, array('processSections' => false)); - $this->assertThat( - $object, - $this->equalTo($object1), - 'Line:' . __LINE__ . ' The complex JSON string should convert into the appropriate object.' - ); - - // Test INI format string without sections. - $object = $class->stringToObject($string2, array('processSections' => false)); - $this->assertThat( - $object, - $this->equalTo($object3), - 'Line:' . __LINE__ . ' The INI string should convert into an object without sections.' - ); - - // Test INI format string with sections. - $object = $class->stringToObject($string2, array('processSections' => true)); - $this->assertThat( - $object, - $this->equalTo($object2), - 'Line:' . __LINE__ . ' The INI string should covert into an object with sections.' - ); - - /** - * Test for bad input - * Everything that is not starting with { is handled by - * JRegistryFormatIni, which we test seperately - */ - $this->assertThat( - $class->stringToObject('{key:\'value\''), - $this->equalTo(false) - ); - } -} diff --git a/tests/unit/suites/libraries/joomla/registry/format/JRegistryFormatPhpTest.php b/tests/unit/suites/libraries/joomla/registry/format/JRegistryFormatPhpTest.php deleted file mode 100644 index 77689e0b27392..0000000000000 --- a/tests/unit/suites/libraries/joomla/registry/format/JRegistryFormatPhpTest.php +++ /dev/null @@ -1,71 +0,0 @@ - 'myClass'); - $object = new stdClass; - $object->foo = 'bar'; - $object->quoted = '"stringwithquotes"'; - $object->booleantrue = true; - $object->booleanfalse = false; - $object->numericint = 42; - $object->numericfloat = 3.1415; - - // The PHP registry format does not support nested objects - $object->section = new stdClass; - $object->section->key = 'value'; - $object->array = array('nestedarray' => array('test1' => 'value1')); - - $string = " \"value\");\n" . - "\tpublic \$array = array(\"nestedarray\" => array(\"test1\" => \"value1\"));\n" . - "}\n?>"; - $this->assertThat( - $class->objectToString($object, $options), - $this->equalTo($string) - ); - } - - /** - * Test the JRegistryFormatPHP::stringToObject method. - * - * @return void - */ - public function testStringToObject() - { - $class = JRegistryFormat::getInstance('PHP'); - - // This method is not implemented in the class. The test is to achieve 100% code coverage - $this->assertTrue($class->stringToObject('')); - } -} diff --git a/tests/unit/suites/libraries/joomla/registry/format/JRegistryFormatXmlTest.php b/tests/unit/suites/libraries/joomla/registry/format/JRegistryFormatXmlTest.php deleted file mode 100644 index 6ded6bdee54bb..0000000000000 --- a/tests/unit/suites/libraries/joomla/registry/format/JRegistryFormatXmlTest.php +++ /dev/null @@ -1,103 +0,0 @@ -foo = 'bar'; - $object->quoted = '"stringwithquotes"'; - $object->booleantrue = true; - $object->booleanfalse = false; - $object->numericint = 42; - $object->numericfloat = 3.1415; - $object->section = new stdClass; - $object->section->key = 'value'; - $object->array = array('nestedarray' => array('test1' => 'value1')); - - $string = "\n" . - "bar" . - "\"stringwithquotes\"" . - "1" . - "" . - "42" . - "3.1415" . - "" . - "value" . - "" . - "" . - "" . - "value1" . - "" . - "" . - "\n"; - - // Test basic object to string. - $this->assertXmlStringEqualsXmlString( - $class->objectToString($object, $options), - $string - ); - } - - /** - * Test the JRegistryFormatXML::stringToObject method. - * - * @return void - */ - public function testStringToObject() - { - $class = JRegistryFormat::getInstance('XML'); - $object = new stdClass; - $object->foo = 'bar'; - $object->booleantrue = true; - $object->booleanfalse = false; - $object->numericint = 42; - $object->numericfloat = 3.1415; - $object->section = new stdClass; - $object->section->key = 'value'; - $object->array = array('test1' => 'value1'); - - $string = "\n" . - "bar" . - "1" . - "" . - "42" . - "3.1415" . - "" . - "value" . - "" . - "" . - "value1" . - "" . - "\n"; - - // Test basic object to string. - $this->assertThat( - $class->stringToObject($string), - $this->equalTo($object) - ); - } - -} diff --git a/tests/unit/suites/libraries/joomla/registry/stubs/JRegistryInspector.php b/tests/unit/suites/libraries/joomla/registry/stubs/JRegistryInspector.php deleted file mode 100644 index 7af12476e0ccb..0000000000000 --- a/tests/unit/suites/libraries/joomla/registry/stubs/JRegistryInspector.php +++ /dev/null @@ -1,31 +0,0 @@ -inflector = JStringInflector::getInstance(true); - } - - /** - * Method to test JStringInflector::addRule(). - * - * @return void - * - * @since 12.1 - */ - public function testAddRule() - { - // Case 1 - TestReflection::invoke($this->inflector, 'addRule', '/foo/', 'singular'); - - $rules = TestReflection::getValue($this->inflector, 'rules'); - - $this->assertThat( - in_array('/foo/', $rules['singular']), - $this->isTrue(), - 'Checks if the singular rule was added correctly.' - ); - - // Case 2 - TestReflection::invoke($this->inflector, 'addRule', '/bar/', 'plural'); - - $rules = TestReflection::getValue($this->inflector, 'rules'); - - $this->assertThat( - in_array('/bar/', $rules['plural']), - $this->isTrue(), - 'Checks if the plural rule was added correctly.' - ); - - // Case 3 - TestReflection::invoke($this->inflector, 'addRule', array('/goo/', '/car/'), 'singular'); - - $rules = TestReflection::getValue($this->inflector, 'rules'); - - $this->assertThat( - in_array('/goo/', $rules['singular']), - $this->isTrue(), - 'Checks if an array of rules was added correctly (1).' - ); - - $this->assertThat( - in_array('/car/', $rules['singular']), - $this->isTrue(), - 'Checks if an array of rules was added correctly (2).' - ); - } - - /** - * Method to test JStringInflector::addRule(). - * - * @return void - * - * @since 12.1 - * @expectedException InvalidArgumentException - */ - public function testaddRuleException() - { - TestReflection::invoke($this->inflector, 'addRule', new stdClass, 'singular'); - } - - /** - * Method to test JStringInflector::getCachedPlural(). - * - * @return void - * - * @since 12.1 - */ - public function testGetCachedPlural() - { - // Reset the cache. - TestReflection::setValue($this->inflector, 'cache', array('foo' => 'bar')); - - $this->assertThat( - TestReflection::invoke($this->inflector, 'getCachedPlural', 'bar'), - $this->isFalse(), - 'Checks for an uncached plural.' - ); - - $this->assertThat( - TestReflection::invoke($this->inflector, 'getCachedPlural', 'foo'), - $this->equalTo('bar'), - 'Checks for a cached plural word.' - ); - } - - /** - * Method to test JStringInflector::getCachedSingular(). - * - * @return void - * - * @since 12.1 - */ - public function testGetCachedSingular() - { - // Reset the cache. - TestReflection::setValue($this->inflector, 'cache', array('foo' => 'bar')); - - $this->assertThat( - TestReflection::invoke($this->inflector, 'getCachedSingular', 'foo'), - $this->isFalse(), - 'Checks for an uncached singular.' - ); - - $this->assertThat( - TestReflection::invoke($this->inflector, 'getCachedSingular', 'bar'), - $this->equalTo('foo'), - 'Checks for a cached singular word.' - ); - } - - /** - * Method to test JStringInflector::matchRegexRule(). - * - * @return void - * - * @since 12.1 - */ - public function testMatchRegexRule() - { - $this->assertThat( - TestReflection::invoke($this->inflector, 'matchRegexRule', 'xyz', 'plural'), - $this->equalTo('xyzs'), - 'Checks pluralising against the basic regex.' - ); - - $this->assertThat( - TestReflection::invoke($this->inflector, 'matchRegexRule', 'xyzs', 'singular'), - $this->equalTo('xyz'), - 'Checks singularising against the basic regex.' - ); - - $this->assertThat( - TestReflection::invoke($this->inflector, 'matchRegexRule', 'xyz', 'singular'), - $this->isFalse(), - 'Checks singularising against an unmatched regex.' - ); - } - - /** - * Method to test JStringInflector::setCache(). - * - * @return void - * - * @since 12.1 - */ - public function testSetCache() - { - TestReflection::invoke($this->inflector, 'setCache', 'foo', 'bar'); - - $cache = TestReflection::getValue($this->inflector, 'cache'); - - $this->assertThat( - $cache['foo'], - $this->equalTo('bar'), - 'Checks the cache was set.' - ); - - TestReflection::invoke($this->inflector, 'setCache', 'foo', 'car'); - - $cache = TestReflection::getValue($this->inflector, 'cache'); - - $this->assertThat( - $cache['foo'], - $this->equalTo('car'), - 'Checks an existing value in the cache was reset.' - ); - } - - /** - * Method to test JStringInflector::addCountableRule(). - * - * @return void - * - * @since 12.1 - */ - public function testAddCountableRule() - { - // Add string. - $this->inflector->addCountableRule('foo'); - - $rules = TestReflection::getValue($this->inflector, 'rules'); - - $this->assertThat( - in_array('foo', $rules['countable']), - $this->isTrue(), - 'Checks a countable rule was added.' - ); - - // Add array. - $this->inflector->addCountableRule(array('goo', 'car')); - - $rules = TestReflection::getValue($this->inflector, 'rules'); - - $this->assertThat( - in_array('car', $rules['countable']), - $this->isTrue(), - 'Checks a countable rule was added by array.' - ); - } - - /** - * Method to test JStringInflector::addPluraliseRule(). - * - * @return void - * - * @since 12.1 - */ - public function testAddPluraliseRule() - { - $chain = $this->inflector->addPluraliseRule(array('/foo/', '/bar/')); - - $this->assertThat( - $chain, - $this->identicalTo($this->inflector), - 'Checks chaining.' - ); - - $rules = TestReflection::getValue($this->inflector, 'rules'); - - $this->assertThat( - in_array('/bar/', $rules['plural']), - $this->isTrue(), - 'Checks a pluralisation rule was added.' - ); - } - - /** - * Method to test JStringInflector::addSingulariseRule(). - * - * @return void - * - * @since 12.1 - */ - public function testAddSingulariseRule() - { - $chain = $this->inflector->addSingulariseRule(array('/foo/', '/bar/')); - - $this->assertThat( - $chain, - $this->identicalTo($this->inflector), - 'Checks chaining.' - ); - - $rules = TestReflection::getValue($this->inflector, 'rules'); - - $this->assertThat( - in_array('/bar/', $rules['singular']), - $this->isTrue(), - 'Checks a singularisation rule was added.' - ); - } - - /** - * Method to test JStringInflector::getInstance(). - * - * @return void - * - * @since 12.1 - */ - public function testGetInstance() - { - $this->assertInstanceOf( - 'JStringInflector', - JStringInflector::getInstance(), - 'Check getInstance returns the right class.' - ); - - // Inject an instance an test. - TestReflection::setValue($this->inflector, 'instance', new stdClass); - - $this->assertThat( - JStringInflector::getInstance(), - $this->equalTo(new stdClass), - 'Checks singleton instance is returned.' - ); - - $this->assertInstanceOf( - 'JStringInflector', - JStringInflector::getInstance(true), - 'Check getInstance a fresh object with true argument even though the instance is set to something else.' - ); - } - - /** - * Method to test JStringInflector::isCountable(). - * - * @param string $input A string. - * @param boolean $expected The expected result of the function call. - * - * @return void - * - * @dataProvider seedIsCountable - * @since 12.1 - */ - public function testIsCountable($input, $expected) - { - $this->assertThat( - $this->inflector->isCountable($input), - $this->equalTo($expected) - ); - } - - /** - * Method to test JStringInflector::isPlural(). - * - * @param string $singular The singular form of a word. - * @param string $plural The plural form of a word. - * - * @return void - * - * @dataProvider seedSinglePlural - * @since 12.1 - */ - public function testIsPlural($singular, $plural) - { - $this->assertThat( - $this->inflector->isPlural($plural), - $this->isTrue(), - 'Checks the plural is a plural.' - ); - - if ($singular != $plural) - { - $this->assertThat( - $this->inflector->isPlural($singular), - $this->isFalse(), - 'Checks the singular is not plural.' - ); - } - } - - /** - * Method to test JStringInflector::isSingular(). - * - * @param string $singular The singular form of a word. - * @param string $plural The plural form of a word. - * - * @return void - * - * @dataProvider seedSinglePlural - * @since 12.1 - */ - public function testIsSingular($singular, $plural) - { - $this->assertThat( - $this->inflector->isSingular($singular), - $this->isTrue(), - 'Checks the singular is a singular.' - ); - - if ($singular != $plural) - { - $this->assertThat( - $this->inflector->isSingular($plural), - $this->isFalse(), - 'Checks the plural is not singular.' - ); - } - } - - /** - * Method to test JStringInflector::toPlural(). - * - * @param string $singular The singular form of a word. - * @param string $plural The plural form of a word. - * - * @return void - * - * @dataProvider seedSinglePlural - * @since 12.1 - */ - public function testToPlural($singular, $plural) - { - $this->assertThat( - $this->inflector->toPlural($singular), - $this->equalTo($plural) - ); - } - - /** - * Method to test JStringInflector::toPlural(). - * - * @param string $singular The singular form of a word. - * @param string $plural The plural form of a word. - * - * @return void - * - * @dataProvider seedSinglePlural - * @since 12.1 - */ - public function testToSingular($singular, $plural) - { - $this->assertThat( - $this->inflector->toSingular($plural), - $this->equalTo($singular) - ); - } -} diff --git a/tests/unit/suites/libraries/joomla/string/JStringNormaliseTest.php b/tests/unit/suites/libraries/joomla/string/JStringNormaliseTest.php deleted file mode 100644 index 01c593af9f89f..0000000000000 --- a/tests/unit/suites/libraries/joomla/string/JStringNormaliseTest.php +++ /dev/null @@ -1,315 +0,0 @@ -assertEquals($expected, JStringNormalise::fromCamelcase($input)); - } - - /** - * Method to test JStringNormalise::fromCamelCase(string, true). - * - * @param string $input The input value for the method. - * @param string $expected The expected value from the method. - * - * @return void - * - * @dataProvider getFromCamelCaseData - * @since 11.3 - * @covers JStringNormalise::fromCamelcase - */ - public function testFromCamelCase_grouped($input, $expected) - { - $this->assertEquals($expected, JStringNormalise::fromCamelcase($input, true)); - } - - /** - * Method to test JStringNormalise::toCamelCase(). - * - * @param string $expected The expected value from the method. - * @param string $input The input value for the method. - * - * @return void - * - * @dataProvider seedToCamelCase - * @since 11.3 - * @covers JStringNormalise::toCamelcase - */ - public function testToCamelCase($expected, $input) - { - $this->assertEquals($expected, JStringNormalise::toCamelcase($input)); - } - - /** - * Method to test JStringNormalise::toDashSeparated(). - * - * @param string $expected The expected value from the method. - * @param string $input The input value for the method. - * - * @return void - * - * @dataProvider seedToDashSeparated - * @since 11.3 - * @covers JStringNormalise::toDashSeparated - */ - public function testToDashSeparated($expected, $input) - { - $this->assertEquals($expected, JStringNormalise::toDashSeparated($input)); - } - - /** - * Method to test JStringNormalise::toSpaceSeparated(). - * - * @param string $expected The expected value from the method. - * @param string $input The input value for the method. - * - * @return void - * - * @dataProvider seedToSpaceSeparated - * @since 11.3 - * @covers JStringNormalise::toSpaceSeparated - */ - public function testToSpaceSeparated($expected, $input) - { - $this->assertEquals($expected, JStringNormalise::toSpaceSeparated($input)); - } - - /** - * Method to test JStringNormalise::toUnderscoreSeparated(). - * - * @param string $expected The expected value from the method. - * @param string $input The input value for the method. - * - * @return void - * - * @dataProvider seedToUnderscoreSeparated - * @since 11.3 - * @covers JStringNormalise::toUnderscoreSeparated - */ - public function testToUnderscoreSeparated($expected, $input) - { - $this->assertEquals($expected, JStringNormalise::toUnderscoreSeparated($input)); - } - - /** - * Method to test JStringNormalise::toVariable(). - * - * @param string $expected The expected value from the method. - * @param string $input The input value for the method. - * - * @return void - * - * @dataProvider seedToVariable - * @since 11.3 - * @covers JStringNormalise::toVariable - */ - public function testToVariable($expected, $input) - { - $this->assertEquals($expected, JStringNormalise::toVariable($input)); - } - - /** - * Method to test JStringNormalise::toKey(). - * - * @param string $expected The expected value from the method. - * @param string $input The input value for the method. - * - * @return void - * - * @dataProvider seedToKey - * @since 11.3 - * @covers JStringNormalise::toKey - */ - public function testToKey($expected, $input) - { - $this->assertEquals($expected, JStringNormalise::toKey($input)); - } - - /** - * Method to seed data to testFromCamelCase. - * - * @return array - * - * @since 11.3 - */ - public function seedFromCamelCase() - { - return array( - array('Foo Bar', 'FooBar'), - array('foo Bar', 'fooBar'), - array('Foobar', 'Foobar'), - array('foobar', 'foobar') - ); - } - - /** - * Method to seed data to testToCamelCase. - * - * @return array - * - * @since 11.3 - */ - public function seedToCamelCase() - { - return array( - array('FooBar', 'Foo Bar'), - array('FooBar', 'Foo-Bar'), - array('FooBar', 'Foo_Bar'), - array('FooBar', 'foo bar'), - array('FooBar', 'foo-bar'), - array('FooBar', 'foo_bar'), - ); - } - - /** - * Method to seed data to testToDashSeparated. - * - * @return array - * - * @since 11.3 - */ - public function seedToDashSeparated() - { - return array( - array('Foo-Bar', 'Foo Bar'), - array('Foo-Bar', 'Foo-Bar'), - array('Foo-Bar', 'Foo_Bar'), - array('foo-bar', 'foo bar'), - array('foo-bar', 'foo-bar'), - array('foo-bar', 'foo_bar'), - array('foo-bar', 'foo bar'), - array('foo-bar', 'foo---bar'), - array('foo-bar', 'foo___bar'), - ); - } - - /** - * Method to seed data to testToSpaceSeparated. - * - * @return array - * - * @since 11.3 - */ - public function seedToSpaceSeparated() - { - return array( - array('Foo Bar', 'Foo Bar'), - array('Foo Bar', 'Foo-Bar'), - array('Foo Bar', 'Foo_Bar'), - array('foo bar', 'foo bar'), - array('foo bar', 'foo-bar'), - array('foo bar', 'foo_bar'), - array('foo bar', 'foo bar'), - array('foo bar', 'foo---bar'), - array('foo bar', 'foo___bar'), - ); - } - - /** - * Method to seed data to testToUnderscoreSeparated. - * - * @return array - * - * @since 11.3 - */ - public function seedToUnderscoreSeparated() - { - return array( - array('Foo_Bar', 'Foo Bar'), - array('Foo_Bar', 'Foo-Bar'), - array('Foo_Bar', 'Foo_Bar'), - array('foo_bar', 'foo bar'), - array('foo_bar', 'foo-bar'), - array('foo_bar', 'foo_bar'), - array('foo_bar', 'foo bar'), - array('foo_bar', 'foo---bar'), - array('foo_bar', 'foo___bar'), - ); - } - - /** - * Method to seed data to testToVariable. - * - * @return array - * - * @since 11.3 - */ - public function seedToVariable() - { - return array( - array('myFooBar', 'My Foo Bar'), - array('myFooBar', 'My Foo-Bar'), - array('myFooBar', 'My Foo_Bar'), - array('myFooBar', 'my foo bar'), - array('myFooBar', 'my foo-bar'), - array('myFooBar', 'my foo_bar'), - ); - } - - /** - * Method to seed data to testToKey. - * - * @return array - * - * @since 11.3 - */ - public function seedToKey() - { - return array( - array('foo_bar', 'Foo Bar'), - array('foo_bar', 'Foo-Bar'), - array('foo_bar', 'Foo_Bar'), - array('foo_bar', 'foo bar'), - array('foo_bar', 'foo-bar'), - array('foo_bar', 'foo_bar'), - ); - } -} diff --git a/tests/unit/suites/libraries/joomla/string/JStringPunycodeTest.php b/tests/unit/suites/libraries/joomla/string/JStringPunycodeTest.php deleted file mode 100644 index 70e805027fe22..0000000000000 --- a/tests/unit/suites/libraries/joomla/string/JStringPunycodeTest.php +++ /dev/null @@ -1,163 +0,0 @@ -assertEquals( - JStringPunycode::toPunycode('http://www.джумла-тест.рф'), - 'http://www.xn----7sblgc4ag8bhcd.xn--p1ai', - 'Tests idna_convert encoding a UTF8 url in Cyrillic' - ); - - $this->assertEquals( - JStringPunycode::toPunycode('http://au-gré-de-nos-plumes.fr'), - 'http://xn--au-gr-de-nos-plumes-fzb.fr', - 'Tests idna_convert encoding a UTF8 url in French' - ); - } - - /** - * Tests JStringPunycode::fromPunycode - * - * @return void - * - * @since 3.2 - */ - public function testFromPunycode() - { - $this->assertEquals( - JStringPunycode::fromPunycode('http://www.xn----7sblgc4ag8bhcd.xn--p1ai'), - 'http://www.джумла-тест.рф', - 'Tests idna_convert decoding a UTF8 url in Cyrillic' - ); - - $this->assertEquals( - JStringPunycode::fromPunycode('http://xn--au-gr-de-nos-plumes-fzb.fr'), - 'http://au-gré-de-nos-plumes.fr', - 'Tests idna_convert decoding a UTF8 url in French' - ); - } - - /** - * Tests JStringPunycode::urlToPunycode - * - * @return void - * - * @since 3.2 - */ - public function testUrlToPunycode() - { - $this->assertEquals( - JStringPunycode::urlToPunycode('http://www.джумла-тест.рф'), - 'http://www.xn----7sblgc4ag8bhcd.xn--p1ai', - 'Tests punycode encoding a UTF8 url in Cyrillic' - ); - - $this->assertEquals( - JStringPunycode::urlToPunycode('http://au-gré-de-nos-plumes.fr'), - 'http://xn--au-gr-de-nos-plumes-fzb.fr', - 'Tests punycode encoding a UTF8 url in French' - ); - - $this->assertEquals( - JStringPunycode::urlToPunycode('http://www.джумла-тест.рф#test'), - 'http://www.xn----7sblgc4ag8bhcd.xn--p1ai#test', - 'Tests punycode encoding a UTF8 url in Cyrillic with an anchor (See GitHub #4362)' - ); - } - - /** - * Tests JStringPunycode::urlToUTF8 - * - * @return void - * - * @since 3.2 - */ - public function testUrlToUTF8() - { - $this->assertEquals( - JStringPunycode::urlToUTF8('http://www.xn----7sblgc4ag8bhcd.xn--p1ai'), - 'http://www.джумла-тест.рф', - 'Tests punycode decoding a UTF8 url in Cyrillic' - ); - - $this->assertEquals( - JStringPunycode::urlToUTF8('http://xn--au-gr-de-nos-plumes-fzb.fr'), - 'http://au-gré-de-nos-plumes.fr', - 'Tests punycode decoding a UTF8 url in French' - ); - - $this->assertEquals( - JStringPunycode::urlToUTF8('http://www.xn----7sblgc4ag8bhcd.xn--p1ai#test'), - 'http://www.джумла-тест.рф#test', - 'Tests punycode decoding a UTF8 url in Cyrillic with an anchor (See GitHub #4362)' - ); - } - - /** - * Tests JStringPunycode::emailToPunycode - * - * @return void - * - * @since 3.2 - */ - public function testEmailToPunycode() - { - $this->assertEquals( - JStringPunycode::emailToPunycode('example@джумла-тест.рф'), - 'example@xn----7sblgc4ag8bhcd.xn--p1ai', - 'Tests punycode encoding a UTF8 email in Cyrillic' - ); - - $this->assertEquals( - JStringPunycode::emailToPunycode('example@au-gré-de-nos-plumes.fr'), - 'example@xn--au-gr-de-nos-plumes-fzb.fr', - 'Tests punycode encoding a UTF8 email in French' - ); - } - - /** - * Tests JStringPunycode::emailToUTF8 - * - * @return void - * - * @since 3.2 - */ - public function testEmailToUTF8() - { - $this->assertEquals( - JStringPunycode::emailToUTF8('example@xn----7sblgc4ag8bhcd.xn--p1ai'), - 'example@джумла-тест.рф', - 'Tests punycode decoding a UTF8 email in Cyrillic' - ); - - $this->assertEquals( - JStringPunycode::emailToUTF8('example@xn--au-gr-de-nos-plumes-fzb.fr'), - 'example@au-gré-de-nos-plumes.fr', - 'Tests punycode decoding a UTF8 email in French' - ); - } -} diff --git a/tests/unit/suites/libraries/joomla/string/JStringTest.php b/tests/unit/suites/libraries/joomla/string/JStringTest.php deleted file mode 100644 index 94ca308ac66b6..0000000000000 --- a/tests/unit/suites/libraries/joomla/string/JStringTest.php +++ /dev/null @@ -1,911 +0,0 @@ -assertThat( - JString::increment($string, $style, $number), - $this->equalTo($expected) - ); - } - - // @codingStandardsIgnoreStart - // @todo Arguments with default values must be at the end of the argument list - - /** - * Test... - * - * @param string $haystack @todo - * @param string $needle @todo - * @param integer $offset @todo - * @param string $expect @todo - * - * @return void - * - * @dataProvider getStrposData - * @since 11.2 - * @covers JString::strpos - */ - public function testStrpos($haystack, $needle, $offset = 0, $expect) - { - $actual = JString::strpos($haystack, $needle, $offset); - $this->assertEquals($expect, $actual); - } - - // @codingStandardsIgnoreEnd - - // @codingStandardsIgnoreStart - // @todo Arguments with default values must be at the end of the argument list - - /** - * Test... - * - * @param string $haystack @todo - * @param string $needle @todo - * @param integer $offset @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getStrrposData - * @since 11.2 - * @covers JString::strrpos - */ - public function testStrrpos($haystack, $needle, $offset = 0, $expect) - { - $actual = JString::strrpos($haystack, $needle, $offset); - $this->assertEquals($expect, $actual); - } - - // @codingStandardsIgnoreEnd - - // @codingStandardsIgnoreStart - // @todo Arguments with default values must be at the end of the argument list - - /** - * Test... - * - * @param string $string @todo - * @param string $start @todo - * @param bool|int $length @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getSubstrData - * @since 11.2 - * @covers JString::substr - */ - public function testSubstr($string, $start, $length = false, $expect) - { - $actual = JString::substr($string, $start, $length); - $this->assertEquals($expect, $actual); - } - - // @codingStandardsIgnoreEnd - - /** - * Test... - * - * @param string $string @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getStrtolowerData - * @since 11.2 - * @covers JString::strtolower - */ - public function testStrtolower($string, $expect) - { - $actual = JString::strtolower($string); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $string @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getStrtoupperData - * @since 11.2 - * @covers JString::strtoupper - */ - public function testStrtoupper($string, $expect) - { - $actual = JString::strtoupper($string); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $string @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getStrlenData - * @since 11.2 - * @covers JString::strlen - */ - public function testStrlen($string, $expect) - { - $actual = JString::strlen($string); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $search @todo - * @param string $replace @todo - * @param string $subject @todo - * @param integer $count @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getStr_ireplaceData - * @since 11.2 - * @covers JString::str_ireplace - */ - public function testStr_ireplace($search, $replace, $subject, $count, $expect) - { - $actual = JString::str_ireplace($search, $replace, $subject, $count); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $string @todo - * @param string $split_length @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getStr_splitData - * @since 11.2 - * @covers JString::str_split - */ - public function testStr_split($string, $split_length, $expect) - { - $actual = JString::str_split($string, $split_length); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $string1 @todo - * @param string $string2 @todo - * @param string $locale @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getStrcasecmpData - * @since 11.2 - * @covers JString::strcasecmp - */ - public function testStrcasecmp($string1, $string2, $locale, $expect) - { - // Convert the $locale param to a string if it is an array - if (is_array($locale)) - { - $locale = "'" . implode("', '", $locale) . "'"; - } - - if (substr(php_uname(), 0, 6) == 'Darwin' && $locale != false) - { - $this->markTestSkipped('Darwin bug prevents foreign conversion from working properly'); - } - elseif ($locale != false && !setlocale(LC_COLLATE, $locale)) - { - $this->markTestSkipped("Locale {$locale} is not available."); - } - else - { - $actual = JString::strcasecmp($string1, $string2, $locale); - - if ($actual != 0) - { - $actual = $actual / abs($actual); - } - - $this->assertEquals($expect, $actual); - } - } - - /** - * Test... - * - * @param string $string1 @todo - * @param string $string2 @todo - * @param string $locale @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getStrcmpData - * @since 11.2 - * @covers JString::strcmp - */ - public function testStrcmp($string1, $string2, $locale, $expect) - { - // Convert the $locale param to a string if it is an array - if (is_array($locale)) - { - $locale = "'" . implode("', '", $locale) . "'"; - } - - if (substr(php_uname(), 0, 6) == 'Darwin' && $locale != false) - { - $this->markTestSkipped('Darwin bug prevents foreign conversion from working properly'); - } - elseif ($locale != false && !setlocale(LC_COLLATE, $locale)) - { - // If the locale is not available, we can't have to transcode the string and can't reliably compare it. - $this->markTestSkipped("Locale {$locale} is not available."); - } - else - { - $actual = JString::strcmp($string1, $string2, $locale); - - if ($actual != 0) - { - $actual = $actual / abs($actual); - } - - $this->assertEquals($expect, $actual); - } - } - - /** - * Test... - * - * @param string $haystack @todo - * @param string $needles @todo - * @param integer $start @todo - * @param integer $len @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getStrcspnData - * @since 11.2 - * @covers JString::strcspn - */ - public function testStrcspn($haystack, $needles, $start, $len, $expect) - { - $actual = JString::strcspn($haystack, $needles, $start, $len); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $haystack @todo - * @param string $needle @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getStristrData - * @since 11.2 - * @covers JString::stristr - */ - public function testStristr($haystack, $needle, $expect) - { - $actual = JString::stristr($haystack, $needle); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $string @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getStrrevData - * @since 11.2 - * @covers JString::strrev - */ - public function testStrrev($string, $expect) - { - $actual = JString::strrev($string); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $subject @todo - * @param string $mask @todo - * @param integer $start @todo - * @param integer $length @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getStrspnData - * @since 11.2 - * @covers JString::strspn - */ - public function testStrspn($subject, $mask, $start, $length, $expect) - { - $actual = JString::strspn($subject, $mask, $start, $length); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $string @todo - * @param string $replacement @todo - * @param integer $start @todo - * @param integer $length @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getSubstr_replaceData - * @since 11.2 - * @covers JString::substr_replace - */ - public function testSubstr_replace($string, $replacement, $start, $length, $expect) - { - $actual = JString::substr_replace($string, $replacement, $start, $length); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $string @todo - * @param string $charlist @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getLtrimData - * @since 11.2 - * @covers JString::ltrim - */ - public function testLtrim($string, $charlist, $expect) - { - if ($charlist === null) - { - $actual = JString::ltrim($string); - } - else - { - $actual = JString::ltrim($string, $charlist); - } - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $string @todo - * @param string $charlist @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getRtrimData - * @since 11.2 - * @covers JString::rtrim - */ - public function testRtrim($string, $charlist, $expect) - { - if ($charlist === null) - { - $actual = JString::rtrim($string); - } - else - { - $actual = JString::rtrim($string, $charlist); - } - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $string @todo - * @param string $charlist @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getTrimData - * @since 11.2 - * @covers JString::trim - */ - public function testTrim($string, $charlist, $expect) - { - if ($charlist === null) - { - $actual = JString::trim($string); - } - else - { - $actual = JString::trim($string, $charlist); - } - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $string @todo - * @param string $delimiter @todo - * @param string $newDelimiter @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getUcfirstData - * @since 11.2 - * @covers JString::ucfirst - */ - public function testUcfirst($string, $delimiter, $newDelimiter, $expect) - { - $actual = JString::ucfirst($string, $delimiter, $newDelimiter); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $string @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getUcwordsData - * @since 11.2 - * @covers JString::ucwords - */ - public function testUcwords($string, $expect) - { - $actual = JString::ucwords($string); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $source @todo - * @param string $from_encoding @todo - * @param string $to_encoding @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getTranscodeData - * @since 11.2 - * @covers JString::transcode - */ - public function testTranscode($source, $from_encoding, $to_encoding, $expect) - { - $actual = JString::transcode($source, $from_encoding, $to_encoding); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $string @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getValidData - * @since 11.2 - * @covers JString::valid - */ - public function testValid($string, $expect) - { - $actual = JString::valid($string); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @param string $string @todo - * @param string $expect @todo - * - * @return array - * - * @dataProvider getValidData - * @since 11.2 - * @covers JString::compliant - */ - public function testCompliant($string, $expect) - { - $actual = JString::compliant($string); - $this->assertEquals($expect, $actual); - } - - /** - * Test... - * - * @return array - * - * @since 11.2 - * @covers JString::parse_url - */ - public function testParse_Url() - { - $url = 'http://localhost/joomla_development/j16_trunk/administrator/index.php?option=com_contact&view=contact&layout=edit&id=5'; - $expected = parse_url($url); - $actual = JString::parse_url($url); - $this->assertEquals($expected, $actual, 'Line: ' . __LINE__ . ' Results should be equal'); - - // Test all parts of query - $url = 'https://john:doe@www.google.com:80/folder/page.html#id?var=kay&var2=key&true'; - $expected = parse_url($url); - $actual = JString::parse_url($url); - $this->assertEquals($expected, $actual, 'Line: ' . __LINE__ . ' Results should be equal'); - - // Test special characters in URL - $url = 'http://joomla.org/mytestpath/È'; - $expected = parse_url($url); - - // Fix up path for UTF-8 characters - $expected['path'] = '/mytestpath/È'; - $actual = JString::parse_url($url); - $this->assertEquals($expected, $actual, 'Line: ' . __LINE__ . ' Results should be equal'); - - // Test special characters in URL - $url = 'http://mydomain.com/!*\'();:@&=+$,/?%#[]" \\'; - $expected = parse_url($url); - $actual = JString::parse_url($url); - $this->assertEquals($expected, $actual, 'Line: ' . __LINE__ . ' Results should be equal'); - - // Test url encoding in URL - $url = 'http://mydomain.com/%21%2A%27%28%29%3B%3A%40%26%3D%24%2C%2F%3F%25%23%5B%22%20%5C'; - $expected = parse_url($url); - $actual = JString::parse_url($url); - $this->assertEquals($expected, $actual, 'Line: ' . __LINE__ . ' Results should be equal'); - - // Test a mix of the above - $url = 'http://john:doe@mydomain.com:80/%È21%25È3*%('; - $expected = parse_url($url); - - // Fix up path for UTF-8 characters - $expected['path'] = '/%È21%25È3*%('; - $actual = JString::parse_url($url); - $this->assertEquals($expected, $actual, 'Line: ' . __LINE__ . ' Results should be equal'); - - // Test invalild URL - $url = 'http:///mydomain.com'; - $expected = parse_url($url); - $actual = JString::parse_url($url); - $this->assertEquals($expected, $actual, 'Line: ' . __LINE__ . ' Results should be equal'); - } -} diff --git a/tests/unit/suites/libraries/joomla/string/TestHelpers/JString-helper-dataset.php b/tests/unit/suites/libraries/joomla/string/TestHelpers/JString-helper-dataset.php deleted file mode 100644 index bf12f3d0e4698..0000000000000 --- a/tests/unit/suites/libraries/joomla/string/TestHelpers/JString-helper-dataset.php +++ /dev/null @@ -1,314 +0,0 @@ - array('title', null, 0, 'title (2)'), - 'Second default increment' => array('title(2)', null, 0, 'title(3)'), - 'First dash increment' => array('title', 'dash', 0, 'title-2'), - 'Second dash increment' => array('title-2', 'dash', 0, 'title-3'), - 'Set default increment' => array('title', null, 4, 'title (4)'), - 'Unknown style fallback to default' => array('title', 'foo', 0, 'title (2)'), - ); - - /** - * Tests for JString::strpos. - * - * Each element contains $haystack, $needle, $offset, $expect, - * - * @var array - * @since 11.2 - */ - public static $strposTests = array( - array('missing', 'sing', 0, 3), - array('missing', 'sting', 0, false), - array('missing', 'ing', 0, 4), - array(' объектов на карте с', 'на карте', 0, 10), - array('на карте с', 'на карте', 0, 0), - array('на карте с', 'на каррте', 0, false), - array('на карте с', 'на карте', 2, false), - array('missing', 'sing', false, 3) - ); - - /** - * @var array - * @since 11.2 - */ - public static $strrposTests = array( - array('missing', 'sing', 0, 3), - array('missing', 'sting', 0, false), - array('missing', 'ing', 0, 4), - array(' объектов на карте с', 'на карте', 0, 10), - array('на карте с', 'на карте', 0, 0), - array('на карте с', 'на каррте', 0, false), - array('на карте с', 'карт', 2, 3) - ); - - /** - * @var array - * @since 11.2 - */ - public static $substrTests = array( - array('Mississauga', 4, false, 'issauga'), - array(' объектов на карте с', 10, false, 'на карте с'), - array(' объектов на карте с', 10, 5, 'на ка'), - array(' объектов на карте с', -4, false, 'те с'), - array(' объектов на карте с', 99, false, false) - ); - - /** - * @var array - * @since 11.2 - */ - public static $strtolowerTests = array( - array('Joomla! Rocks', 'joomla! rocks') - ); - - /** - * @var array - * @since 11.2 - */ - public static $strtoupperTests = array( - array('Joomla! Rocks', 'JOOMLA! ROCKS') - ); - - /** - * @var array - * @since 11.2 - */ - public static $strlenTests = array( - array('Joomla! Rocks', 13) - ); - - /** - * @var array - * @since 11.2 - */ - public static $str_ireplaceTests = array( - array('Pig', 'cow', 'the pig jumped', false, 'the cow jumped'), - array('Pig', 'cow', 'the pig jumped', true, 'the cow jumped'), - array('Pig', 'cow', 'the pig jumped over the cow', true, 'the cow jumped over the cow'), - array(array('PIG', 'JUMPED'), array('cow', 'hopped'), 'the pig jumped over the pig', true, 'the cow hopped over the cow'), - array('шил', 'биш', 'Би шил идэй чадна', true, 'Би биш идэй чадна'), - array('/', ':', '/test/slashes/', true, ':test:slashes:'), - ); - - /** - * @var array - * @since 11.2 - */ - public static $str_splitTests = array( - array('string', 1, array('s', 't', 'r', 'i', 'n', 'g')), - array('string', 2, array('st', 'ri', 'ng')), - array('волн', 3, array('вол', 'н')), - array('волн', 1, array('в', 'о', 'л', 'н')) - ); - - /** - * @var array - * @since 11.2 - */ - public static $strcasecmpTests = array( - array('THIS IS STRING1', 'this is string1', false, 0), - array('this is string1', 'this is string2', false, -1), - array('this is string2', 'this is string1', false, 1), - array('бгдпт', 'бгдпт', false, 0), - array('àbc', 'abc', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), 1), - array('àbc', 'bcd', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), - array('é', 'è', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), - array('É', 'é', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), 0), - array('œ', 'p', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), - array('œ', 'n', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), 1), - ); - - /** - * @var array - * @since 11.2 - */ - public static $strcmpTests = array( - array('THIS IS STRING1', 'this is string1', false, -1), - array('this is string1', 'this is string2', false, -1), - array('this is string2', 'this is string1', false, 1), - array('a', 'B', false, 1), - array('A', 'b', false, -1), - array('Àbc', 'abc', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), 1), - array('Àbc', 'bcd', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), - array('É', 'è', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), - array('é', 'È', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), - array('Œ', 'p', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), - array('Œ', 'n', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), 1), - array('œ', 'N', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), 1), - array('œ', 'P', array('fr_FR.utf8', 'fr_FR.UTF-8', 'fr_FR.UTF-8@euro', 'French_Standard', 'french', 'fr_FR', 'fre_FR'), -1), - ); - - /** - * @var array - * @since 11.2 - */ - public static $strcspnTests = array( - array('subject string ', '<>', false, false, 8), - array('Би шил {123} идэй {456} чадна', '}{', null, false, 7), - array('Би шил {123} идэй {456} чадна', '}{', 13, 10, 5) - ); - - /** - * @var array - * @since 11.2 - */ - public static $stristrTests = array( - array('haystack', 'needle', false), - array('before match, after match', 'match', 'match, after match'), - array('Би шил идэй чадна', 'шил', 'шил идэй чадна') - ); - - /** - * @var array - * @since 11.2 - */ - public static $strrevTests = array( - array('abc def', 'fed cba'), - array('Би шил', 'лиш иБ') - ); - - /** - * @var array - * @since 11.2 - */ - public static $strspnTests = array( - array('A321 Main Street', '0123456789', 1, 2, 2), - array('321 Main Street', '0123456789', null, 2, 2), - array('A321 Main Street', '0123456789', null, 10, 0), - array('321 Main Street', '0123456789', null, null, 3), - array('Main Street 321', '0123456789', null, -3, 0), - array('321 Main Street', '0123456789', null, -13, 2), - array('321 Main Street', '0123456789', null, -12, 3), - array('A321 Main Street', '0123456789', 0, null, 0), - array('A321 Main Street', '0123456789', 1, 10, 3), - array('A321 Main Street', '0123456789', 1, null, 3), - array('Би шил идэй чадна', 'Би', null, null, 2), - array('чадна Би шил идэй чадна', 'Би', null, null, 0) - ); - - /** - * @var array - * @since 11.2 - */ - public static $substr_replaceTests = array( - array('321 Main Street', 'Broadway Avenue', 4, null, '321 Broadway Avenue'), - array('321 Main Street', 'Broadway', 4, 4, '321 Broadway Street'), - array('чадна Би шил идэй чадна', '我能吞', 6, null, 'чадна 我能吞'), - array('чадна Би шил идэй чадна', '我能吞', 6, 2, 'чадна 我能吞 шил идэй чадна') - ); - - /** - * Test data for JString::ltrim. - * - * @var array Elements of array($string, $charlist, $expect) - * @since 11.2 - */ - public static $ltrimTests = array( - array(' abc def', null, 'abc def'), - array(' abc def', '', ' abc def'), - array(' Би шил', null, 'Би шил'), - array("\t\n\r\x0BБи шил", null, 'Би шил'), - array("\x0B\t\n\rБи шил", "\t\n\x0B", "\rБи шил"), - array("\x09Би шил\x0A", "\x09\x0A", "Би шил\x0A"), - array('1234abc', '0123456789', 'abc') - ); - - /** - * @var array - * @since 11.2 - */ - public static $rtrimTests = array( - array('abc def ', null, 'abc def'), - array('abc def ', '', 'abc def '), - array('Би шил ', null, 'Би шил'), - array("Би шил\t\n\r\x0B", null, 'Би шил'), - array("Би шил\r\x0B\t\n", "\t\n\x0B", "Би шил\r"), - array("\x09Би шил\x0A", "\x09\x0A", "\x09Би шил"), - array('1234abc', 'abc', '01234') - ); - - /** - * @var array - * @since 11.2 - */ - public static $trimTests = array( - array(' abc def ', null, 'abc def'), - array(' abc def ', '', ' abc def '), - array(' Би шил ', null, 'Би шил'), - array("\t\n\r\x0BБи шил\t\n\r\x0B", null, 'Би шил'), - array("\x0B\t\n\rБи шил\r\x0B\t\n", "\t\n\x0B", "\rБи шил\r"), - array("\x09Би шил\x0A", "\x09\x0A", "Би шил"), - array('1234abc56789', '0123456789', 'abc') - ); - - /** - * @var array - * @since 11.2 - */ - public static $ucfirstTests = array( - array('george', null, null, 'George'), - array('мога', null, null, 'Мога'), - array('ψυχοφθόρα', null, null, 'Ψυχοφθόρα'), - array('dr jekill and mister hyde', ' ', null, 'Dr Jekill And Mister Hyde'), - array('dr jekill and mister hyde', ' ', '_', 'Dr_Jekill_And_Mister_Hyde'), - array('dr jekill and mister hyde', ' ', '', 'DrJekillAndMisterHyde'), - ); - - /** - * @var array - * @since 11.2 - */ - public static $ucwordsTests = array( - array('george washington', 'George Washington'), - array("george\r\nwashington", "George\r\nWashington"), - array('мога', 'Мога'), - array('αβγ δεζ', 'Αβγ Δεζ'), - array('åbc öde', 'Åbc Öde') - ); - - /** - * @var array - * @since 11.2 - */ - public static $transcodeTests = array( - array('Åbc Öde €100', 'UTF-8', 'ISO-8859-1', "\xc5bc \xd6de EUR100"), - array(array('Åbc Öde €100'), 'UTF-8', 'ISO-8859-1', null), - ); - - /** - * @var array - * @since 11.2 - */ - public static $validTests = array( - array('george Мога Ž Ψυχοφθόρα ฉันกินกระจกได้ 我能吞下玻璃而不伤身体 ', true), - array("\xFF ABC", false), - array("0xfffd ABC", true), - array('', true) - ); -}