diff --git a/administrator/components/com_admin/models/sysinfo.php b/administrator/components/com_admin/models/sysinfo.php index 30f538b2fa90b..bcc95712246da 100644 --- a/administrator/components/com_admin/models/sysinfo.php +++ b/administrator/components/com_admin/models/sysinfo.php @@ -96,7 +96,8 @@ public function &getPhpSettings() 'zlib' => extension_loaded('zlib'), 'zip' => function_exists('zip_open') && function_exists('zip_read'), 'mbstring' => extension_loaded('mbstring'), - 'iconv' => function_exists('iconv') + 'iconv' => function_exists('iconv'), + 'max_input_vars' => ini_get('max_input_vars'), ); return $this->php_settings; @@ -142,20 +143,21 @@ public function &getInfo() return $this->info; } - $version = new JVersion; - $platform = new JPlatform; - $db = $this->getDbo(); + $version = new JVersion; + $platform = new JPlatform; + $db = $this->getDbo(); $this->info = array( - 'php' => php_uname(), - 'dbversion' => $db->getVersion(), - 'dbcollation' => $db->getCollation(), - 'phpversion' => phpversion(), - 'server' => isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : getenv('SERVER_SOFTWARE'), - 'sapi_name' => php_sapi_name(), - 'version' => $version->getLongVersion(), - 'platform' => $platform->getLongVersion(), - 'useragent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "" + 'php' => php_uname(), + 'dbversion' => $db->getVersion(), + 'dbcollation' => $db->getCollation(), + 'dbconnectioncollation' => $db->getConnectionCollation(), + 'phpversion' => phpversion(), + 'server' => isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : getenv('SERVER_SOFTWARE'), + 'sapi_name' => php_sapi_name(), + 'version' => $version->getLongVersion(), + 'platform' => $platform->getLongVersion(), + 'useragent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "" ); return $this->info; diff --git a/administrator/components/com_admin/script.php b/administrator/components/com_admin/script.php index 1447c69298621..e226df074dfeb 100644 --- a/administrator/components/com_admin/script.php +++ b/administrator/components/com_admin/script.php @@ -425,7 +425,6 @@ public function deleteUnexistingFiles() '/administrator/components/com_installer/models/fields/group.php', '/administrator/components/com_installer/models/fields/index.html', '/administrator/components/com_installer/models/fields/search.php', - '/administrator/components/com_installer/models/fields/type.php', '/administrator/components/com_installer/models/forms/index.html', '/administrator/components/com_installer/models/forms/manage.xml', '/administrator/components/com_installer/views/install/tmpl/default_form.php', @@ -1334,9 +1333,6 @@ public function deleteUnexistingFiles() // Joomla 3.0 '/administrator/components/com_contact/elements', '/administrator/components/com_content/elements', - '/administrator/components/com_installer/models/fields', - '/administrator/components/com_installer/models/forms', - '/administrator/components/com_modules/models/fields', '/administrator/components/com_newsfeeds/elements', '/administrator/components/com_templates/views/prevuuw/tmpl', '/administrator/components/com_templates/views/prevuuw', diff --git a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-10-30.sql b/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-10-30.sql new file mode 100644 index 0000000000000..a3fbadebb349c --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-10-30.sql @@ -0,0 +1 @@ +UPDATE `#__menu` SET `title` = 'com_contact_contacts' WHERE `id` = 8; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-30.sql b/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-30.sql new file mode 100644 index 0000000000000..ce62b18de2f06 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-30.sql @@ -0,0 +1 @@ +UPDATE "#__menu" SET "title" = 'com_contact_contacts' WHERE "id" = 8; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-10-30.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-10-30.sql new file mode 100644 index 0000000000000..c652a5057f9f1 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-10-30.sql @@ -0,0 +1 @@ +UPDATE [#__menu] SET [title] = 'com_contact_contacts' WHERE [id] = 8; diff --git a/administrator/components/com_admin/views/sysinfo/tmpl/default_phpsettings.php b/administrator/components/com_admin/views/sysinfo/tmpl/default_phpsettings.php index 7e0096c1c59d7..3bfa1f2e5ca2b 100644 --- a/administrator/components/com_admin/views/sysinfo/tmpl/default_phpsettings.php +++ b/administrator/components/com_admin/views/sysinfo/tmpl/default_phpsettings.php @@ -157,6 +157,14 @@ php_settings['iconv']); ?> + + + + + + php_settings['max_input_vars']); ?> + + diff --git a/administrator/components/com_categories/models/categories.php b/administrator/components/com_categories/models/categories.php index a8cf668c93800..be9fdcfbbd5c8 100644 --- a/administrator/components/com_categories/models/categories.php +++ b/administrator/components/com_categories/models/categories.php @@ -281,7 +281,26 @@ protected function getListQuery() } // Group by on Categories for JOIN with component tables to count items - $query->group('a.id'); + $query->group('a.id, + a.title, + a.alias, + a.note, + a.published, + a.access, + a.checked_out, + a.checked_out_time, + a.created_user_id, + a.path, + a.parent_id, + a.level, + a.lft, + a.rgt, + a.language, + l.title, + uc.name, + ag.title, + ua.name' + ); // Load Helper file of the component for which com_categories displays the categories $classname = ucfirst(substr($extension, 4)) . 'Helper'; diff --git a/administrator/components/com_categories/models/fields/modal/category.php b/administrator/components/com_categories/models/fields/modal/category.php index 5b91041c71236..ef0bedac2d039 100644 --- a/administrator/components/com_categories/models/fields/modal/category.php +++ b/administrator/components/com_categories/models/fields/modal/category.php @@ -156,21 +156,21 @@ protected function getInput() . ' title="' . JHtml::tooltipText('COM_CATEGORIES_EDIT_CATEGORY') . '" >' . '' . JText::_('JACTION_EDIT') . ''; - - $html[] = JHtml::_( - 'bootstrap.renderModal', - 'modalCategory-' . $this->id, - array( - 'url' => $link . '&' . JSession::getFormToken() . '=1"', - 'title' => JText::_('COM_CATEGORIES_SELECT_A_CATEGORY'), - 'width' => '800px', - 'height' => '300px', - 'footer' => '' - ) - ); } + $html[] = JHtml::_( + 'bootstrap.renderModal', + 'modalCategory-' . $this->id, + array( + 'url' => $link . '&' . JSession::getFormToken() . '=1"', + 'title' => JText::_('COM_CATEGORIES_SELECT_A_CATEGORY'), + 'width' => '800px', + 'height' => '300px', + 'footer' => '' + ) + ); + // Clear category button if ($allowClear) { diff --git a/administrator/components/com_categories/views/category/tmpl/edit.php b/administrator/components/com_categories/views/category/tmpl/edit.php index f2e3cb1a4612b..55a545af4a8c6 100644 --- a/administrator/components/com_categories/views/category/tmpl/edit.php +++ b/administrator/components/com_categories/views/category/tmpl/edit.php @@ -26,6 +26,7 @@ { if (task == "category.cancel" || document.formvalidator.isValid(document.getElementById("item-form"))) { + jQuery("#permissions-sliders select").attr("disabled", "disabled"); ' . $this->form->getField("description")->save() . ' Joomla.submitform(task, document.getElementById("item-form")); } diff --git a/administrator/components/com_config/controller/application/store.php b/administrator/components/com_config/controller/application/store.php new file mode 100644 index 0000000000000..2e24a49b01996 --- /dev/null +++ b/administrator/components/com_config/controller/application/store.php @@ -0,0 +1,56 @@ +authorise('core.admin')) + { + $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR')); + $this->app->redirect('index.php'); + } + + // Get Post DATA + $permissions = array( + 'component' => $this->input->get->get('comp'), + 'action' => $this->input->get->get('action'), + 'rule' => $this->input->get->get('rule'), + 'value' => $this->input->get->get('value'), + 'title' => $this->input->get->get('title', '', 'RAW') + ); + + if (!(substr($permissions['component'], -6) == '.false')) + { + // Load Permissions from Session and send to Model + $model = new ConfigModelApplication; + $response = $model->storePermissions($permissions); + + echo new JResponseJson(json_encode($response)); + } + else + { + echo new JResponseJson(json_encode(false), 0); + } + } +} diff --git a/administrator/components/com_config/model/application.php b/administrator/components/com_config/model/application.php index b5cc9cda94017..bad62209432ee 100644 --- a/administrator/components/com_config/model/application.php +++ b/administrator/components/com_config/model/application.php @@ -327,4 +327,96 @@ private function writeConfigFile(Registry $config) return true; } + + /** + * Method to store the permission values in the asset table. + * + * This method will get an arrray with permission key value paires and transform it + * into json and update the asset table in the database. + * + * @param string $array Need an Array with Permissions (component, rule, value and title) + * + * @return boolean True on success, false on failure. + * + * @since 3.5 + */ + public function storePermissions($array) + { + + try + { + // Create a new query object. + $query = $this->db->getQuery(true); + $query->select($this->db->quoteName(array('name', 'rules'))) + ->from($this->db->quoteName('#__assets')) + ->where($this->db->quoteName('name') . ' = ' . $this->db->quote($array['component'])); + + $this->db->setQuery($query); + + // Load the results as a list of stdClass objects (see later for more options on retrieving data). + $results = $this->db->loadAssocList(); + + if (empty($results)) + { + $data = array(); + $data[$array['action']] = array(); + $data[$array['action']] = array($array['rule'] => $array['value']); + + $rules = new JAccessRules($data); + $asset = JTable::getInstance('asset'); + $asset->rules = (string) $rules; + $asset->name = (string) $array['component']; + $asset->title = (string) $array['title']; + + if (!$asset->check() || !$asset->store()) + { + JFactory::getApplication()->enqueueMessage(JText::_('SOME_ERROR_CODE'), 'error'); + + return false; + } + + return true; + } + else + { + $temp = json_decode($results[0]['rules'], true); + + if (isset($array['value'])) + { + if (!isset($temp[$array['action']])) + { + $temp[$array['action']] = array(); + } + + if (!isset($temp[$array['action']][$array['rule']])) + { + $temp[$array['action']][$array['rule']] = array($array['rule'] => $array['value']); + } + + $temp[$array['action']][$array['rule']] = intval($array['value']); + } + else + { + unset($temp[$array['action']]); + } + + $temp = json_encode($temp); + $query = $this->db->getQuery(true); + + $query->update($this->db->quoteName('#__assets')) + ->set('rules = ' . $this->db->quote($temp)) + ->where($this->db->quoteName('name') . ' = ' . $this->db->quote($array['component'])); + + $this->db->setQuery($query); + + $result = $this->db->execute(); + + return $result; + } + } + catch (Exception $e) + { + return $e->getMessage(); + } + } } diff --git a/administrator/components/com_config/model/form/application.xml b/administrator/components/com_config/model/form/application.xml index 54c46e2d518bb..e5f03eca612d1 100644 --- a/administrator/components/com_config/model/form/application.xml +++ b/administrator/components/com_config/model/form/application.xml @@ -650,6 +650,18 @@ + + + + + form->getField('articletext')->save() . ' Joomla.submitform(task, document.getElementById("item-form")); } diff --git a/administrator/components/com_media/controllers/file.json.php b/administrator/components/com_media/controllers/file.json.php index 9a5bb546942b3..4ee056f13f180 100644 --- a/administrator/components/com_media/controllers/file.json.php +++ b/administrator/components/com_media/controllers/file.json.php @@ -34,8 +34,9 @@ public function upload() if (!JSession::checkToken('request')) { $response = array( - 'status' => '0', - 'error' => JText::_('JINVALID_TOKEN') + 'status' => '0', + 'message' => JText::_('JINVALID_TOKEN'), + 'error' => JText::_('JINVALID_TOKEN') ); echo json_encode($response); @@ -59,8 +60,9 @@ public function upload() || $_SERVER['CONTENT_LENGTH'] > $mediaHelper->toBytes(ini_get('memory_limit'))) { $response = array( - 'status' => '0', - 'error' => JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE') + 'status' => '0', + 'message' => JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE'), + 'error' => JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE') ); echo json_encode($response); @@ -70,39 +72,41 @@ public function upload() // Set FTP credentials, if given JClientHelper::setCredentialsFromRequest('ftp'); - // Make the filename safe - $file['name'] = JFile::makeSafe($file['name']); - - if (!isset($file['name'])) + if (isset($file['name'])) { - $response = array( - 'status' => '0', - 'error' => JText::_('COM_MEDIA_ERROR_BAD_REQUEST') - ); + // Make the filename safe + $file['name'] = JFile::makeSafe($file['name']); - echo json_encode($response); + // We need a URL safe name + $fileparts = pathinfo(COM_MEDIA_BASE . '/' . $folder . '/' . $file['name']); - return; - } + // Transform filename to punycode + $fileparts['filename'] = JStringPunycode::toPunycode($fileparts['filename']); + $tempExt = (!empty($fileparts['extension'])) ? strtolower($fileparts['extension']) : ''; - // The request is valid - $err = null; + // Transform filename to punycode, then neglect otherthan non-alphanumeric characters & underscores. Also transform extension to lowercase + $safeFileName = preg_replace(array("/[\\s]/", "/[^a-zA-Z0-9_]/"), array("_", ""), $fileparts['filename']) . '.' . $tempExt; - $filepath = JPath::clean(COM_MEDIA_BASE . '/' . $folder . '/' . strtolower($file['name'])); + // Create filepath with safe-filename + $files['final'] = $fileparts['dirname'] . DIRECTORY_SEPARATOR . $safeFileName; + $file['name'] = $safeFileName; - if (!MediaHelper::canUpload($file, $err)) - { - JLog::add('Invalid: ' . $filepath . ': ' . $err, JLog::INFO, 'upload'); + $filepath = JPath::clean($files['final']); - $response = array( - 'status' => '0', - 'error' => JText::_($err) - ); + if (!$mediaHelper->canUpload($file, 'com_media')) + { + JLog::add('Invalid: ' . $filepath, JLog::INFO, 'upload'); - echo json_encode($response); + $response = array( + 'status' => '0', + 'message' => JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE'), + 'error' => JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE') + ); - return; - } + echo json_encode($response); + + return; + } // Trigger the onContentBeforeSave event. JPluginHelper::importPlugin('content'); @@ -111,77 +115,100 @@ public function upload() $object_file->filepath = $filepath; $result = $dispatcher->trigger('onContentBeforeSave', array('com_media.file', &$object_file, true)); - if (in_array(false, $result, true)) - { - // There are some errors in the plugins - JLog::add('Errors before save: ' . $object_file->filepath . ' : ' . implode(', ', $object_file->getErrors()), JLog::INFO, 'upload'); - - $response = array( - 'status' => '0', - 'error' => JText::plural('COM_MEDIA_ERROR_BEFORE_SAVE', count($errors = $object_file->getErrors()), implode('
', $errors)) - ); - - echo json_encode($response); - - return; + if (in_array(false, $result, true)) + { + // There are some errors in the plugins + JLog::add('Errors before save: ' . $object_file->filepath . ' : ' . implode(', ', $object_file->getErrors()), JLog::INFO, 'upload'); + + $response = array( + 'status' => '0', + 'message' => JText::plural('COM_MEDIA_ERROR_BEFORE_SAVE', count($errors = $object_file->getErrors()), implode('
', $errors)), + 'error' => JText::plural('COM_MEDIA_ERROR_BEFORE_SAVE', count($errors = $object_file->getErrors()), implode('
', $errors)) + ); + + echo json_encode($response); + + return; + } + + if (JFile::exists($object_file->filepath)) + { + // File exists + JLog::add('File exists: ' . $object_file->filepath . ' by user_id ' . $user->id, JLog::INFO, 'upload'); + + $response = array( + 'status' => '0', + 'message' => JText::_('COM_MEDIA_ERROR_FILE_EXISTS'), + 'error' => JText::_('COM_MEDIA_ERROR_FILE_EXISTS'), + 'location' => str_replace(JPATH_ROOT, '', $filepath) + ); + + echo json_encode($response); + + return; + } + elseif (!$user->authorise('core.create', 'com_media')) + { + // File does not exist and user is not authorised to create + JLog::add('Create not permitted: ' . $object_file->filepath . ' by user_id ' . $user->id, JLog::INFO, 'upload'); + + $response = array( + 'status' => '0', + 'error' => JText::_('COM_MEDIA_ERROR_CREATE_NOT_PERMITTED'), + 'message' => JText::_('COM_MEDIA_ERROR_CREATE_NOT_PERMITTED') + ); + + echo json_encode($response); + + return; + } + + if (!JFile::upload($object_file->tmp_name, $object_file->filepath)) + { + // Error in upload + JLog::add('Error on upload: ' . $object_file->filepath, JLog::INFO, 'upload'); + + $response = array( + 'status' => '0', + 'message' => JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE'), + 'error' => JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE') + ); + + echo json_encode($response); + + return; + } + else + { + // Trigger the onContentAfterSave event. + $dispatcher->trigger('onContentAfterSave', array('com_media.file', &$object_file, true)); + JLog::add($folder, JLog::INFO, 'upload'); + + $returnUrl = str_replace(JPATH_ROOT, '', $object_file->filepath); + + $response = array( + 'status' => '1', + 'message' => JText::sprintf('COM_MEDIA_UPLOAD_COMPLETE', $returnUrl), + 'error' => JText::sprintf('COM_MEDIA_UPLOAD_COMPLETE', $returnUrl), + 'location' => str_replace('\\', '/', $returnUrl) + ); + + echo json_encode($response); + + return; + } } - - if (JFile::exists($object_file->filepath)) + else { - // File exists - JLog::add('File exists: ' . $object_file->filepath . ' by user_id ' . $user->id, JLog::INFO, 'upload'); - $response = array( - 'status' => '0', - 'error' => JText::_('COM_MEDIA_ERROR_FILE_EXISTS') + 'status' => '0', + 'error' => JText::_('COM_MEDIA_ERROR_BAD_REQUEST'), + 'message' => JText::_('COM_MEDIA_ERROR_BAD_REQUEST') ); echo json_encode($response); return; } - - if (!$user->authorise('core.create', 'com_media')) - { - // File does not exist and user is not authorised to create - JLog::add('Create not permitted: ' . $object_file->filepath . ' by user_id ' . $user->id, JLog::INFO, 'upload'); - - $response = array( - 'status' => '0', - 'error' => JText::_('COM_MEDIA_ERROR_CREATE_NOT_PERMITTED') - ); - - echo json_encode($response); - - return; - } - - if (!JFile::upload($object_file->tmp_name, $object_file->filepath)) - { - // Error in upload - JLog::add('Error on upload: ' . $object_file->filepath, JLog::INFO, 'upload'); - - $response = array( - 'status' => '0', - 'error' => JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE') - ); - - echo json_encode($response); - - return; - } - - // Trigger the onContentAfterSave event. - $dispatcher->trigger('onContentAfterSave', array('com_media.file', &$object_file, true)); - JLog::add($folder, JLog::INFO, 'upload'); - - $response = array( - 'status' => '1', - 'error' => JText::sprintf('COM_MEDIA_UPLOAD_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE))) - ); - - echo json_encode($response); - - return; } } diff --git a/administrator/components/com_menus/helpers/menus.php b/administrator/components/com_menus/helpers/menus.php index d193defcaeb3f..b04b55fcf879f 100644 --- a/administrator/components/com_menus/helpers/menus.php +++ b/administrator/components/com_menus/helpers/menus.php @@ -148,7 +148,17 @@ public static function getMenuLinks($menuType = null, $parentId = 0, $mode = 0, { $db = JFactory::getDbo(); $query = $db->getQuery(true) - ->select('a.id AS value, a.title AS text, a.alias, a.level, a.menutype, a.type, a.published, a.template_style_id, a.checked_out, a.language') + ->select('a.id AS value, + a.title AS text, + a.alias, + a.level, + a.menutype, + a.type, + a.published, + a.template_style_id, + a.checked_out, + a.language, + a.lft') ->from('#__menu AS a') ->join('LEFT', $db->quoteName('#__menu') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt'); @@ -194,9 +204,42 @@ public static function getMenuLinks($menuType = null, $parentId = 0, $mode = 0, $query->where('a.published IN ' . $published); } - $query->where('a.published != -2') - ->group('a.id, a.title, a.alias, a.level, a.menutype, a.type, a.template_style_id, a.checked_out, a.lft') - ->order('a.lft ASC'); + $query->where('a.published != -2'); + + if (JLanguageMultilang::isEnabled()) + { + $query->group( + 'a.id , + a.title , + a.alias, + a.level, + a.menutype, + a.type, + a.published, + a.template_style_id, + a.checked_out, + a.language, + a.lft, + l.title , + l.image'); + } + else + { + $query->group( + 'a.id , + a.title , + a.alias, + a.level, + a.menutype, + a.type, + a.published, + a.template_style_id, + a.checked_out, + a.language, + a.lft'); + } + + $query->order('a.lft ASC'); // Get the options. $db->setQuery($query); diff --git a/administrator/components/com_messages/views/config/tmpl/default.php b/administrator/components/com_messages/views/config/tmpl/default.php index 6bdf386b4f029..ceb7ded41fef3 100644 --- a/administrator/components/com_messages/views/config/tmpl/default.php +++ b/administrator/components/com_messages/views/config/tmpl/default.php @@ -14,9 +14,9 @@ JHtml::_('behavior.formvalidator'); JHtml::_('behavior.keepalive'); -JHtml::_('behavior.modal'); -JFactory::getDocument()->addScriptDeclaration(" +JFactory::getDocument()->addScriptDeclaration( + " Joomla.submitbutton = function(task) { if (task == 'config.cancel' || document.formvalidator.isValid(document.getElementById('config-form'))) @@ -24,49 +24,17 @@ Joomla.submitform(task, document.getElementById('config-form')); } }; -"); + " +); ?> -
+
-
- - -
-
- - + form->renderField('lock'); ?> + form->renderField('mail_on_new'); ?> + form->renderField('auto_purge'); ?> + + + +
diff --git a/administrator/components/com_messages/views/message/tmpl/default.php b/administrator/components/com_messages/views/message/tmpl/default.php index 7d06848920986..656dd70782f6b 100644 --- a/administrator/components/com_messages/views/message/tmpl/default.php +++ b/administrator/components/com_messages/views/message/tmpl/default.php @@ -8,7 +8,8 @@ */ defined('_JEXEC') or die; -JHtml::_('behavior.framework'); + +JHtml::_('behavior.core'); JHtml::_('formbehavior.chosen', 'select'); ?>
diff --git a/administrator/components/com_messages/views/messages/tmpl/default.php b/administrator/components/com_messages/views/messages/tmpl/default.php index 40ac3e5ba5bb4..cb02e86a3d6f6 100644 --- a/administrator/components/com_messages/views/messages/tmpl/default.php +++ b/administrator/components/com_messages/views/messages/tmpl/default.php @@ -19,33 +19,44 @@ $user = JFactory::getUser(); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); -?> +JFactory::getDocument()->addStyleDeclaration( + " + @media (min-width: 768px) { + div.modal { + left: none; + width: 500px; + margin-left: -250px; + } + } + " +); +?> -sidebar)) : ?> + sidebar)) : ?>
sidebar; ?>
- -
- -
- -
- - -
-
- + +
+ +
+ +
+ + +
+
+ +
-
-
+
items)) : ?>
@@ -104,7 +115,6 @@ -
diff --git a/administrator/components/com_messages/views/messages/view.html.php b/administrator/components/com_messages/views/messages/view.html.php index 26d78d364b05d..e3bdcf6be249a 100644 --- a/administrator/components/com_messages/views/messages/view.html.php +++ b/administrator/components/com_messages/views/messages/view.html.php @@ -8,7 +8,6 @@ */ defined('_JEXEC') or die; -JHtml::_('behavior.modal'); /** * View class for a list of messages. @@ -42,7 +41,6 @@ public function display($tpl = null) if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); - return false; } @@ -62,7 +60,6 @@ protected function addToolbar() { $state = $this->get('State'); $canDo = JHelperContent::getActions('com_messages'); - JToolbarHelper::title(JText::_('COM_MESSAGES_MANAGER_MESSAGES'), 'envelope inbox'); if ($canDo->get('core.create')) @@ -78,13 +75,26 @@ protected function addToolbar() } JToolbarHelper::divider(); - $bar = JToolbar::getInstance('toolbar'); - - // Instantiate a new JLayoutFile instance and render the layout - JHtml::_('behavior.modal', 'a.messagesSettings'); - $layout = new JLayoutFile('toolbar.mysettings'); - - $bar->appendButton('Custom', $layout->render(array()), 'upload'); + $bar = JToolBar::getInstance('toolbar'); + $bar->appendButton( + 'Popup', + 'cog', + 'COM_MESSAGES_TOOLBAR_MY_SETTINGS', + 'index.php?option=com_messages&view=config&tmpl=component', + 500, + 250, + 0, + 0, + '', + '', + '' + . '' + ); if ($state->get('filter.state') == -2 && $canDo->get('core.delete')) { diff --git a/administrator/components/com_modules/views/module/tmpl/edit.php b/administrator/components/com_modules/views/module/tmpl/edit.php index 905b13ddbe6c2..5231e07995867 100644 --- a/administrator/components/com_modules/views/module/tmpl/edit.php +++ b/administrator/components/com_modules/views/module/tmpl/edit.php @@ -38,6 +38,9 @@ } $script .= " Joomla.submitform(task, document.getElementById('module-form')); + + jQuery('#permissions-sliders select').attr('disabled', 'disabled'); + if (self != top) { if (parent.viewLevels) diff --git a/administrator/components/com_users/views/debuggroup/tmpl/default.php b/administrator/components/com_users/views/debuggroup/tmpl/default.php index 67c69d077eaa1..ed2cbe42b16c7 100644 --- a/administrator/components/com_users/views/debuggroup/tmpl/default.php +++ b/administrator/components/com_users/views/debuggroup/tmpl/default.php @@ -72,9 +72,9 @@
- - - + + +
@@ -106,9 +106,7 @@ endif; ?> - - - + diff --git a/administrator/components/com_users/views/debuguser/tmpl/default.php b/administrator/components/com_users/views/debuguser/tmpl/default.php index 1f4c228455a32..5588f5b564fe1 100644 --- a/administrator/components/com_users/views/debuguser/tmpl/default.php +++ b/administrator/components/com_users/views/debuguser/tmpl/default.php @@ -71,9 +71,9 @@
- - - + + +
@@ -105,9 +105,7 @@ endif; ?> - - - + diff --git a/administrator/language/en-GB/en-GB.com_admin.ini b/administrator/language/en-GB/en-GB.com_admin.ini index d41769caf7db5..ec969fd3a7618 100644 --- a/administrator/language/en-GB/en-GB.com_admin.ini +++ b/administrator/language/en-GB/en-GB.com_admin.ini @@ -107,6 +107,7 @@ COM_ADMIN_LATEST_VERSION_CHECK="Latest Version Check" COM_ADMIN_LICENSE="License" COM_ADMIN_LOG_DIRECTORY="(Log folder)" COM_ADMIN_MAGIC_QUOTES="Magic Quotes" +COM_ADMIN_MAX_INPUT_VARS="Maximum Input Variables" COM_ADMIN_MBSTRING_ENABLED="Multibyte String (mbstring) Enabled" COM_ADMIN_NA="n/a" COM_ADMIN_OPEN_BASEDIR="Open basedir" diff --git a/administrator/language/en-GB/en-GB.com_config.ini b/administrator/language/en-GB/en-GB.com_config.ini index 234e43971f1ec..8b7b9a31b8a57 100644 --- a/administrator/language/en-GB/en-GB.com_config.ini +++ b/administrator/language/en-GB/en-GB.com_config.ini @@ -168,6 +168,8 @@ COM_CONFIG_FIELD_PROXY_USERNAME_DESC="The username used to access the Proxy serv COM_CONFIG_FIELD_PROXY_USERNAME_LABEL="Proxy Username" COM_CONFIG_FIELD_SECRET_DESC="This is an auto-generated, unique alphanumeric code for every Joomla installation. It is used for security functions." COM_CONFIG_FIELD_SECRET_LABEL="Secret" +COM_CONFIG_FIELD_SEF_ADVANCED_LABEL="Use new URL routing" +COM_CONFIG_FIELD_SEF_ADVANCED_DESC="This uses the new URL routing. This will change your URLs!" COM_CONFIG_FIELD_SEF_REWRITE_DESC="Select to use a server's rewrite engine to catch URLs that meet specific conditions and rewrite them as directed. Available for IIS 7 and Apache.
Apache users only!
Rename htaccess.txt to .htaccess before activating.
IIS 7 users only!
Rename web.config.txt to web.config and install IIS URL Rewrite Module before activating.
" COM_CONFIG_FIELD_SEF_REWRITE_LABEL="Use URL Rewriting" COM_CONFIG_FIELD_SEF_SUFFIX_DESC="If yes, the system will add a suffix to the URL based on the document type." diff --git a/administrator/language/en-GB/en-GB.com_modules.ini b/administrator/language/en-GB/en-GB.com_modules.ini index 15a63af8b625c..c32a699c468a7 100644 --- a/administrator/language/en-GB/en-GB.com_modules.ini +++ b/administrator/language/en-GB/en-GB.com_modules.ini @@ -28,7 +28,7 @@ COM_MODULES_EXTENSION_PUBLISHED_DISABLED="Module disabled and published." COM_MODULES_EXTENSION_PUBLISHED_ENABLED="Module enabled and published." COM_MODULES_EXTENSION_UNPUBLISHED_DISABLED="Module disabled and unpublished." COM_MODULES_EXTENSION_UNPUBLISHED_ENABLED="Module enabled and unpublished." -COM_MODULES_EXTRA_STYLE_DESC="Specify the style for the module or the modules in the possiton selected" +COM_MODULES_EXTRA_STYLE_DESC="Specify the style for the module or the modules in the position selected." COM_MODULES_EXTRA_STYLE_TITLE="Module(s) style" COM_MODULES_FIELD_AUTOMATIC_TITLE_LABEL="Automatic Title" COM_MODULES_FIELD_AUTOMATIC_TITLE_DESC="Set yes if you want an automatic translated title. Its use depends on the Administrator template." diff --git a/administrator/language/en-GB/en-GB.lib_joomla.ini b/administrator/language/en-GB/en-GB.lib_joomla.ini index 5301ad0994980..3fa7ce40818e0 100644 --- a/administrator/language/en-GB/en-GB.lib_joomla.ini +++ b/administrator/language/en-GB/en-GB.lib_joomla.ini @@ -635,6 +635,7 @@ JLIB_RULES_ALLOWED="Allowed" JLIB_RULES_ALLOWED_ADMIN="Allowed (Super User)" JLIB_RULES_CALCULATED_SETTING="Calculated Setting 2" JLIB_RULES_CONFLICT="Conflict" +JLIB_RULES_DATABASE_FAILURE="Failure by storing the data to the database." JLIB_RULES_DENIED="Denied" JLIB_RULES_GROUP="%s" JLIB_RULES_GROUPS="Groups" @@ -644,6 +645,8 @@ JLIB_RULES_NOT_ALLOWED="Not Allowed." JLIB_RULES_NOT_ALLOWED_ADMIN_CONFLICT="Conflict" JLIB_RULES_NOT_ALLOWED_LOCKED="Not Allowed (Locked)" JLIB_RULES_NOT_SET="Not Set" +JLIB_RULES_REQUEST_FAILURE="Failure by sending the data to server." +JLIB_RULES_SAVE_BEFORE_CHANGE_PERMISSIONS="Please save before change permissions." JLIB_RULES_SELECT_ALLOW_DENY_GROUP="Allow or deny %s for users in the %s group." JLIB_RULES_SELECT_SETTING="Select New Setting 1" JLIB_RULES_SETTING_NOTES="1. If you change the setting, it will apply to this and all child groups, components and content. Note that Denied will overrule any inherited setting and also the setting in any child group, component or content. In the case of a setting conflict, Deny will take precedence. Not Set is equivalent to Denied but can be changed in child groups, components and content.
2. If you select a new setting, select Save to refresh the calculated settings." diff --git a/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini b/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini index c1361ace6bf41..33a967877ecc9 100644 --- a/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini +++ b/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini @@ -7,6 +7,7 @@ PLG_EDITORS_TINYMCE="Editor - TinyMCE" PLG_TINY_BUTTON_TOGGLE_EDITOR="Toggle editor" PLG_TINY_ERR_CUSTOMCSSFILENOTPRESENT="The file name %s was entered in the TinyMCE Custom CSS field. This file could not be found in the default template folder. No styles are available." PLG_TINY_ERR_EDITORCSSFILENOTPRESENT="Could not find the file 'editor.css' in the template or templates/system folder. No styles are available." +PLG_TINY_ERR_UNSUPPORTEDBROWSER="Drag and drop image upload is not available for your your browser. Please consider using a fully HTML5 compatible browser" PLG_TINY_FIELD_ADVIMAGE_DESC="Turn on/off a more advanced image dialog." PLG_TINY_FIELD_ADVIMAGE_LABEL="Advanced Image" PLG_TINY_FIELD_ADVLIST_DESC="Turn on/off to enable to set number formats and bullet types in ordered and unordered lists." @@ -27,10 +28,14 @@ PLG_TINY_FIELD_CUSTOMBUTTON_DESC="Add custom button(s)." PLG_TINY_FIELD_CUSTOMBUTTON_LABEL="Custom Button" PLG_TINY_FIELD_CUSTOMPLUGIN_DESC="Add custom plugin(s)." PLG_TINY_FIELD_CUSTOMPLUGIN_LABEL="Custom Plugin" +PLG_TINY_FIELD_CUSTOM_PATH_DESC="Provide a directory for the images to be uploaded. If nothing provided images will be uploaded at /images." +PLG_TINY_FIELD_CUSTOM_PATH_LABEL="Images directory" PLG_TINY_FIELD_DATE_DESC="Show or hide the Insert Date button. Only works in Extended mode." PLG_TINY_FIELD_DATE_LABEL="Insert Date" PLG_TINY_FIELD_DIRECTION_DESC="Choose default text direction." PLG_TINY_FIELD_DIRECTION_LABEL="Text Direction" +PLG_TINY_FIELD_DRAG_DROP_DESC="Enable drag and drop for uploading images" +PLG_TINY_FIELD_DRAG_DROP_LABEL="Images drag&drop" PLG_TINY_FIELD_ELEMENTS_DESC="Allows the addition of specific valid elements to the existing rule set." PLG_TINY_FIELD_ELEMENTS_LABEL="Extended Valid Elements" PLG_TINY_FIELD_ENCODING_DESC="Controls how HTML entities are encoded. Recommended setting is 'raw'. 'named' = used named entity encoding (for example, '<'). 'numeric' = use numeric HTML encoding (for example, '%03c'). raw = Do not encode HTML entities. Note that searching content may not work properly if setting is not 'raw'." diff --git a/administrator/language/en-GB/en-GB.plg_system_cache.ini b/administrator/language/en-GB/en-GB.plg_system_cache.ini index 665a51ab52898..502a97239f2ff 100644 --- a/administrator/language/en-GB/en-GB.plg_system_cache.ini +++ b/administrator/language/en-GB/en-GB.plg_system_cache.ini @@ -5,6 +5,10 @@ PLG_CACHE_FIELD_BROWSERCACHE_DESC="If yes, use mechanism for storing page cache in the browser." PLG_CACHE_FIELD_BROWSERCACHE_LABEL="Use Browser Caching" +PLG_CACHE_FIELD_EXCLUDE_DESC="Specify which URLs you want to exclude from caching, each on a separate line. Regular expressions are supported, eg.
about\-[a-z]+ - will exclude all URLs that contain 'about-', for example 'about-us', 'about-me', 'about-joomla' etc.
\/component\/users\/ - will exclude all URLs that contain /component/users/" +PLG_CACHE_FIELD_EXCLUDE_LABEL="Exclude URLs" +PLG_CACHE_FIELD_EXCLUDE_MENU_ITEMS_DESC="Select which menu items you want to exclude from caching." +PLG_CACHE_FIELD_EXCLUDE_MENU_ITEMS_LABEL="Exclude Menu Items" PLG_CACHE_FIELD_LIFETIME_DESC="Page cache lifetime in minutes." PLG_CACHE_FIELD_LIFETIME_LABEL="Cache Lifetime" PLG_CACHE_XML_DESCRIPTION="Provides page caching." diff --git a/administrator/language/en-GB/en-GB.plg_system_updatenotification.ini b/administrator/language/en-GB/en-GB.plg_system_updatenotification.ini index bca688cb3049c..304a4b920bcfc 100644 --- a/administrator/language/en-GB/en-GB.plg_system_updatenotification.ini +++ b/administrator/language/en-GB/en-GB.plg_system_updatenotification.ini @@ -7,7 +7,7 @@ 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_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 belongs 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" @@ -20,4 +20,4 @@ PLG_SYSTEM_UPDATENOTIFICATION_LANGUAGE_OVERRIDE_NONE="Auto" ; [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 +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.xml b/administrator/language/en-GB/en-GB.xml index f806d8045f255..c8f797f2b1555 100644 --- a/administrator/language/en-GB/en-GB.xml +++ b/administrator/language/en-GB/en-GB.xml @@ -1,7 +1,7 @@ - + English (en-GB) - 3.4.6 + 3.5.0 2013-03-07 Joomla! Project admin@joomla.org diff --git a/administrator/language/en-GB/install.xml b/administrator/language/en-GB/install.xml index 49113eaf842ef..e54c676a29f92 100644 --- a/administrator/language/en-GB/install.xml +++ b/administrator/language/en-GB/install.xml @@ -1,8 +1,8 @@ - + English (United Kingdom) en-GB - 3.4.6 + 3.5.0 2013-03-07 Joomla! Project admin@joomla.org diff --git a/components/com_banners/models/banners.php b/components/com_banners/models/banners.php index 36efbcd78e84d..c888de43397fe 100644 --- a/components/com_banners/models/banners.php +++ b/components/com_banners/models/banners.php @@ -184,7 +184,7 @@ protected function getListQuery() $query->where('a.language in (' . $db->quote(JFactory::getLanguage()->getTag()) . ',' . $db->quote('*') . ')'); } - $query->order('a.sticky DESC,' . ($randomise ? 'RAND()' : 'a.ordering')); + $query->order('a.sticky DESC,' . ($randomise ? $query->Rand() : 'a.ordering')); return $query; } diff --git a/components/com_contact/helpers/legacyrouter.php b/components/com_contact/helpers/legacyrouter.php new file mode 100644 index 0000000000000..29fc98522f1c1 --- /dev/null +++ b/components/com_contact/helpers/legacyrouter.php @@ -0,0 +1,275 @@ +router = $router; + } + + /** + * Preprocess the route for the com_contact component + * + * @param array &$query An array of URL arguments + * + * @return void + * + * @since 3.4 + * @deprecated 4.0 + */ + public function preprocess(&$query) + { + } + + /** + * Build the route for the com_contact component + * + * @param array &$query An array of URL arguments + * @param array &$segments The URL arguments to use to assemble the subsequent URL. + * + * @return void + * + * @since 3.4 + * @deprecated 4.0 + */ + public function build(&$query, &$segments) + { + // Get a menu item based on Itemid or currently active + $params = JComponentHelper::getParams('com_contact'); + $advanced = $params->get('sef_advanced_link', 0); + + if (empty($query['Itemid'])) + { + $menuItem = $this->router->menu->getActive(); + } + else + { + $menuItem = $this->router->menu->getItem($query['Itemid']); + } + + $mView = (empty($menuItem->query['view'])) ? null : $menuItem->query['view']; + $mId = (empty($menuItem->query['id'])) ? null : $menuItem->query['id']; + + if (isset($query['view'])) + { + $view = $query['view']; + + if (empty($query['Itemid']) || empty($menuItem) || $menuItem->component != 'com_contact') + { + $segments[] = $query['view']; + } + + unset($query['view']); + } + + // Are we dealing with a contact that is attached to a menu item? + if (isset($view) && ($mView == $view) and (isset($query['id'])) and ($mId == (int) $query['id'])) + { + unset($query['view']); + unset($query['catid']); + unset($query['id']); + return; + } + + if (isset($view) and ($view == 'category' or $view == 'contact')) + { + if ($mId != (int) $query['id'] || $mView != $view) + { + if ($view == 'contact' && isset($query['catid'])) + { + $catid = $query['catid']; + } + elseif (isset($query['id'])) + { + $catid = $query['id']; + } + + $menuCatid = $mId; + $categories = JCategories::getInstance('Contact'); + $category = $categories->get($catid); + + if ($category) + { + // TODO Throw error that the category either not exists or is unpublished + $path = array_reverse($category->getPath()); + + $array = array(); + + foreach ($path as $id) + { + if ((int) $id == (int) $menuCatid) + { + break; + } + + if ($advanced) + { + list($tmp, $id) = explode(':', $id, 2); + } + + $array[] = $id; + } + + $segments = array_merge($segments, array_reverse($array)); + } + + if ($view == 'contact') + { + if ($advanced) + { + list($tmp, $id) = explode(':', $query['id'], 2); + } + else + { + $id = $query['id']; + } + + $segments[] = $id; + } + } + + unset($query['id']); + unset($query['catid']); + } + + if (isset($query['layout'])) + { + if (!empty($query['Itemid']) && isset($menuItem->query['layout'])) + { + if ($query['layout'] == $menuItem->query['layout']) + { + + unset($query['layout']); + } + } + else + { + if ($query['layout'] == 'default') + { + unset($query['layout']); + } + } + } + + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = str_replace(':', '-', $segments[$i]); + } + } + + /** + * Parse the segments of a URL. + * + * @param array &$segments The segments of the URL to parse. + * @param array &$vars The URL attributes to be used by the application. + * + * @return void + * + * @since 3.4 + * @deprecated 4.0 + */ + public function parse(&$segments, &$vars) + { + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + } + + // Get the active menu item. + $item = $this->router->menu->getActive(); + $params = JComponentHelper::getParams('com_contact'); + $advanced = $params->get('sef_advanced_link', 0); + + // Count route segments + $count = count($segments); + + // Standard routing for newsfeeds. + if (!isset($item)) + { + $vars['view'] = $segments[0]; + $vars['id'] = $segments[$count - 1]; + return; + } + + // From the categories view, we can only jump to a category. + $id = (isset($item->query['id']) && $item->query['id'] > 1) ? $item->query['id'] : 'root'; + + $contactCategory = JCategories::getInstance('Contact')->get($id); + + $categories = ($contactCategory) ? $contactCategory->getChildren() : array(); + $vars['catid'] = $id; + $vars['id'] = $id; + $found = 0; + + foreach ($segments as $segment) + { + $segment = $advanced ? str_replace(':', '-', $segment) : $segment; + + foreach ($categories as $category) + { + if ($category->slug == $segment || $category->alias == $segment) + { + $vars['id'] = $category->id; + $vars['catid'] = $category->id; + $vars['view'] = 'category'; + $categories = $category->getChildren(); + $found = 1; + break; + } + } + + if ($found == 0) + { + if ($advanced) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from('#__contact_details') + ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) + ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); + $db->setQuery($query); + $nid = $db->loadResult(); + } + else + { + $nid = $segment; + } + + $vars['id'] = $nid; + $vars['view'] = 'contact'; + } + + $found = 0; + } + } +} diff --git a/components/com_contact/helpers/route.php b/components/com_contact/helpers/route.php index 1b05389ce7585..497f2bfbd410a 100644 --- a/components/com_contact/helpers/route.php +++ b/components/com_contact/helpers/route.php @@ -19,8 +19,6 @@ */ abstract class ContactHelperRoute { - protected static $lookup; - /** * Get the URL route for a contact from a contact ID, contact category ID and language * @@ -34,35 +32,17 @@ abstract class ContactHelperRoute */ public static function getContactRoute($id, $catid, $language = 0) { - $needles = array( - 'contact' => array((int) $id) - ); - - // Create the link + //Create the link $link = 'index.php?option=com_contact&view=contact&id=' . $id; if ($catid > 1) { - $categories = JCategories::getInstance('Contact'); - $category = $categories->get($catid); - - if ($category) - { - $needles['category'] = array_reverse($category->getPath()); - $needles['categories'] = $needles['category']; - $link .= '&catid=' . $catid; - } + $link .= '&catid=' . $catid; } if ($language && $language != "*" && JLanguageMultilang::isEnabled()) { $link .= '&lang=' . $language; - $needles['language'] = $language; - } - - if ($item = self::_findItem($needles)) - { - $link .= '&Itemid=' . $item; } return $link; @@ -71,8 +51,8 @@ public static function getContactRoute($id, $catid, $language = 0) /** * Get the URL route for a contact category from a contact category ID and language * - * @param mixed $catid The id of the contact's category either an integer id or a instance of JCategoryNode - * @param mixed $language The id of the language being used. + * @param mixed $catid The id of the contact's category either an integer id or a instance of JCategoryNode + * @param mixed $language The id of the language being used. * * @return string The link to the contact * @@ -82,131 +62,28 @@ public static function getCategoryRoute($catid, $language = 0) { if ($catid instanceof JCategoryNode) { - $id = $catid->id; - $category = $catid; + $id = $catid->id; } else { $id = (int) $catid; - $category = JCategories::getInstance('Contact')->get($id); } - if ($id < 1 || !($category instanceof JCategoryNode)) + if ($id < 1) { $link = ''; } else { - $needles = array(); - // Create the link $link = 'index.php?option=com_contact&view=category&id=' . $id; - $catids = array_reverse($category->getPath()); - $needles['category'] = $catids; - $needles['categories'] = $catids; - if ($language && $language != "*" && JLanguageMultilang::isEnabled()) { $link .= '&lang=' . $language; - $needles['language'] = $language; - } - - if ($item = self::_findItem($needles)) - { - $link .= '&Itemid=' . $item; } } return $link; } - - /** - * Find an item ID. - * - * @param array $needles An array of language codes. - * - * @return mixed The ID found or null otherwise. - * - * @since 1.6 - */ - protected static function _findItem($needles = null) - { - $app = JFactory::getApplication(); - $menus = $app->getMenu('site'); - $language = isset($needles['language']) ? $needles['language'] : '*'; - - // Prepare the reverse lookup array. - if (!isset(self::$lookup[$language])) - { - self::$lookup[$language] = array(); - - $component = JComponentHelper::getComponent('com_contact'); - $attributes = array('component_id'); - $values = array($component->id); - - if ($language != '*') - { - $attributes[] = 'language'; - $values[] = array($needles['language'], '*'); - } - - $items = $menus->getItems($attributes, $values); - - foreach ($items as $item) - { - if (isset($item->query) && isset($item->query['view'])) - { - $view = $item->query['view']; - - if (!isset(self::$lookup[$language][$view])) - { - self::$lookup[$language][$view] = array(); - } - - if (isset($item->query['id'])) - { - /** - * Here it will become a bit tricky - * language != * can override existing entries - * language == * cannot override existing entries - */ - if (!isset(self::$lookup[$language][$view][$item->query['id']]) || $item->language != '*') - { - self::$lookup[$language][$view][$item->query['id']] = $item->id; - } - } - } - } - } - - if ($needles) - { - foreach ($needles as $view => $ids) - { - if (isset(self::$lookup[$language][$view])) - { - foreach ($ids as $id) - { - if (isset(self::$lookup[$language][$view][(int) $id])) - { - return self::$lookup[$language][$view][(int) $id]; - } - } - } - } - } - - // Check if the active menuitem matches the requested language - $active = $menus->getActive(); - if ($active && ($language == '*' || in_array($active->language, array('*', $language)) || !JLanguageMultilang::isEnabled())) - { - return $active->id; - } - - // If not found, return language specific home link - $default = $menus->getDefault($language); - - return !empty($default->id) ? $default->id : null; - } } diff --git a/components/com_contact/router.php b/components/com_contact/router.php index 94d6ffefe3fa3..579a2d5f4aeb4 100644 --- a/components/com_contact/router.php +++ b/components/com_contact/router.php @@ -14,236 +14,132 @@ * * @since 3.3 */ -class ContactRouter extends JComponentRouterBase +class ContactRouter extends JComponentRouterView { - /** - * Build the route for the com_contact component - * - * @param array &$query An array of URL arguments - * - * @return array The URL arguments to use to assemble the subsequent URL. - * - * @since 3.3 - */ - public function build(&$query) + function __construct($app = null, $menu = null) { - $segments = array(); - - // Get a menu item based on Itemid or currently active - $params = JComponentHelper::getParams('com_contact'); - $advanced = $params->get('sef_advanced_link', 0); - - if (empty($query['Itemid'])) + $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); + $this->registerView($categories); + $category = new JComponentRouterViewconfiguration('category'); + $category->setKey('id')->setParent($categories, 'catid')->setNestable(); + $this->registerView($category); + $contact = new JComponentRouterViewconfiguration('contact'); + $contact->setKey('id')->setParent($category, 'catid'); + $this->registerView($contact); + $this->registerView(new JComponentRouterViewconfiguration('featured')); + + parent::__construct($app, $menu); + + $this->attachRule(new JComponentRouterRulesMenu($this)); + + if ($this->app->get('sef_advanced', 0)) { - $menuItem = $this->menu->getActive(); + $this->attachRule(new JComponentRouterRulesStandard($this)); } else { - $menuItem = $this->menu->getItem($query['Itemid']); + require_once JPATH_SITE . '/components/com_contact/helpers/legacyrouter.php'; + $this->attachRule(new ContactRouterRulesLegacy($this)); } - - $mView = (empty($menuItem->query['view'])) ? null : $menuItem->query['view']; - $mId = (empty($menuItem->query['id'])) ? null : $menuItem->query['id']; - - if (isset($query['view'])) - { - $view = $query['view']; - - if (empty($query['Itemid']) || empty($menuItem) || $menuItem->component != 'com_contact') - { - $segments[] = $query['view']; - } - - unset($query['view']); - } - - // Are we dealing with a contact that is attached to a menu item? - if (isset($view) && ($mView == $view) and (isset($query['id'])) and ($mId == (int) $query['id'])) - { - unset($query['view']); - unset($query['catid']); - unset($query['id']); - return $segments; - } - - if (isset($view) and ($view == 'category' or $view == 'contact')) - { - if ($mId != (int) $query['id'] || $mView != $view) - { - if ($view == 'contact' && isset($query['catid'])) - { - $catid = $query['catid']; - } - elseif (isset($query['id'])) - { - $catid = $query['id']; - } - - $menuCatid = $mId; - $categories = JCategories::getInstance('Contact'); - $category = $categories->get($catid); - - if ($category) - { - // TODO Throw error that the category either not exists or is unpublished - $path = array_reverse($category->getPath()); - - $array = array(); - - foreach ($path as $id) - { - if ((int) $id == (int) $menuCatid) - { - break; - } - - if ($advanced) - { - list($tmp, $id) = explode(':', $id, 2); - } - - $array[] = $id; - } - - $segments = array_merge($segments, array_reverse($array)); - } - - if ($view == 'contact') - { - if ($advanced) - { - list($tmp, $id) = explode(':', $query['id'], 2); - } - else - { - $id = $query['id']; - } - - $segments[] = $id; - } - } - - unset($query['id']); - unset($query['catid']); - } - - if (isset($query['layout'])) - { - if (!empty($query['Itemid']) && isset($menuItem->query['layout'])) - { - if ($query['layout'] == $menuItem->query['layout']) - { - - unset($query['layout']); - } - } - else - { - if ($query['layout'] == 'default') - { - unset($query['layout']); - } - } - } - - $total = count($segments); - - for ($i = 0; $i < $total; $i++) - { - $segments[$i] = str_replace(':', '-', $segments[$i]); - } - - return $segments; } /** - * Parse the segments of a URL. + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is build right now * - * @param array &$segments The segments of the URL to parse. - * - * @return array The URL attributes to be used by the application. - * - * @since 3.3 + * @return array|string The segments of this item */ - public function parse(&$segments) + public function getCategorySegment($id, $query) { - $total = count($segments); - $vars = array(); - - for ($i = 0; $i < $total; $i++) - { - $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); - } - - // Get the active menu item. - $item = $this->menu->getActive(); - $params = JComponentHelper::getParams('com_contact'); - $advanced = $params->get('sef_advanced_link', 0); + $category = JCategories::getInstance($this->getName())->get($id); - // Count route segments - $count = count($segments); - - // Standard routing for newsfeeds. - if (!isset($item)) + if ($category) { - $vars['view'] = $segments[0]; - $vars['id'] = $segments[$count - 1]; - return $vars; + return array_reverse($category->getPath()); } - // From the categories view, we can only jump to a category. - $id = (isset($item->query['id']) && $item->query['id'] > 1) ? $item->query['id'] : 'root'; + return array(); + } - $contactCategory = JCategories::getInstance('Contact')->get($id); + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is build right now + * + * @return array|string The segments of this item + */ + public function getCategoriesSegment($id, $query) + { + return $this->getCategorySegment($id, $query); + } - $categories = ($contactCategory) ? $contactCategory->getChildren() : array(); - $vars['catid'] = $id; - $vars['id'] = $id; - $found = 0; + /** + * Method to get the segment(s) for a contact + * + * @param string $id ID of the contact to retrieve the segments for + * @param array $query The request that is build right now + * + * @return array|string The segments of this item + */ + public function getContactSegment($id, $query) + { + return array($id); + } - foreach ($segments as $segment) + /** + * Method to get the id for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return array|int The id of this item + */ + public function getCategoryId($segment, $query) + { + if (isset($query['id'])) { - $segment = $advanced ? str_replace(':', '-', $segment) : $segment; + $category = JCategories::getInstance($this->getName())->get($query['id']); - foreach ($categories as $category) + foreach ($category->getChildren() as $child) { - if ($category->slug == $segment || $category->alias == $segment) + if ($child->id == (int) $segment) { - $vars['id'] = $category->id; - $vars['catid'] = $category->id; - $vars['view'] = 'category'; - $categories = $category->getChildren(); - $found = 1; - break; + return $child->id; } } + } - if ($found == 0) - { - if ($advanced) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('id')) - ->from('#__contact_details') - ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) - ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); - $db->setQuery($query); - $nid = $db->loadResult(); - } - else - { - $nid = $segment; - } - - $vars['id'] = $nid; - $vars['view'] = 'contact'; - } + return false; + } - $found = 0; - } + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is parsed right now + * + * @return array|int The segments of this item + */ + public function getCategoriesId($segment, $query) + { + return $this->getCategoryId($segment, $query); + } - return $vars; + /** + * Method to get the segment(s) for a contact + * + * @param string $segment Segment of the contact to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return array|int The segments of this item + */ + public function getContactId($segment, $query) + { + return (int) $segment; } } @@ -261,7 +157,8 @@ public function parse(&$segments) */ function ContactBuildRoute(&$query) { - $router = new ContactRouter; + $app = JFactory::getApplication(); + $router = new ContactRouter($app, $app->getMenu()); return $router->build($query); } @@ -280,7 +177,8 @@ function ContactBuildRoute(&$query) */ function ContactParseRoute($segments) { - $router = new ContactRouter; + $app = JFactory::getApplication(); + $router = new ContactRouter($app, $app->getMenu()); return $router->parse($segments); } diff --git a/components/com_content/helpers/legacyrouter.php b/components/com_content/helpers/legacyrouter.php new file mode 100644 index 0000000000000..ed3cac432ce98 --- /dev/null +++ b/components/com_content/helpers/legacyrouter.php @@ -0,0 +1,479 @@ +router = $router; + } + + /** + * Preprocess the route for the com_content component + * + * @param array &$query An array of URL arguments + * + * @return void + * + * @since 3.4 + * @deprecated 4.0 + */ + public function preprocess(&$query) + { + } + + /** + * Build the route for the com_content component + * + * @param array &$query An array of URL arguments + * @param array &$segments The URL arguments to use to assemble the subsequent URL. + * + * @return void + * + * @since 3.4 + * @deprecated 4.0 + */ + public function build(&$query, &$segments) + { + // Get a menu item based on Itemid or currently active + $params = JComponentHelper::getParams('com_content'); + $advanced = $params->get('sef_advanced_link', 0); + + // We need a menu item. Either the one specified in the query, or the current active one if none specified + if (empty($query['Itemid'])) + { + $menuItem = $this->router->menu->getActive(); + $menuItemGiven = false; + } + else + { + $menuItem = $this->router->menu->getItem($query['Itemid']); + $menuItemGiven = true; + } + + // Check again + if ($menuItemGiven && isset($menuItem) && $menuItem->component != 'com_content') + { + $menuItemGiven = false; + unset($query['Itemid']); + } + + if (isset($query['view'])) + { + $view = $query['view']; + } + else + { + // We need to have a view in the query or it is an invalid URL + return; + } + + // Are we dealing with an article or category that is attached to a menu item? + if (($menuItem instanceof stdClass) + && $menuItem->query['view'] == $query['view'] + && isset($query['id']) + && $menuItem->query['id'] == (int) $query['id']) + { + unset($query['view']); + + if (isset($query['catid'])) + { + unset($query['catid']); + } + + if (isset($query['layout'])) + { + unset($query['layout']); + } + + unset($query['id']); + + return; + } + + if ($view == 'category' || $view == 'article') + { + if (!$menuItemGiven) + { + $segments[] = $view; + } + + unset($query['view']); + + if ($view == 'article') + { + if (isset($query['id']) && isset($query['catid']) && $query['catid']) + { + $catid = $query['catid']; + + // Make sure we have the id and the alias + if (strpos($query['id'], ':') === false) + { + $db = JFactory::getDbo(); + $dbQuery = $db->getQuery(true) + ->select('alias') + ->from('#__content') + ->where('id=' . (int) $query['id']); + $db->setQuery($dbQuery); + $alias = $db->loadResult(); + $query['id'] = $query['id'] . ':' . $alias; + } + } + else + { + // We should have these two set for this view. If we don't, it is an error + return; + } + } + else + { + if (isset($query['id'])) + { + $catid = $query['id']; + } + else + { + // We should have id set for this view. If we don't, it is an error + return; + } + } + + if ($menuItemGiven && isset($menuItem->query['id'])) + { + $mCatid = $menuItem->query['id']; + } + else + { + $mCatid = 0; + } + + $categories = JCategories::getInstance('Content'); + $category = $categories->get($catid); + + if (!$category) + { + // We couldn't find the category we were given. Bail. + return; + } + + $path = array_reverse($category->getPath()); + + $array = array(); + + foreach ($path as $id) + { + if ((int) $id == (int) $mCatid) + { + break; + } + + list($tmp, $id) = explode(':', $id, 2); + + $array[] = $id; + } + + $array = array_reverse($array); + + if (!$advanced && count($array)) + { + $array[0] = (int) $catid . ':' . $array[0]; + } + + $segments = array_merge($segments, $array); + + if ($view == 'article') + { + if ($advanced) + { + list($tmp, $id) = explode(':', $query['id'], 2); + } + else + { + $id = $query['id']; + } + + $segments[] = $id; + } + + unset($query['id']); + unset($query['catid']); + } + + if ($view == 'archive') + { + if (!$menuItemGiven) + { + $segments[] = $view; + unset($query['view']); + } + + if (isset($query['year'])) + { + if ($menuItemGiven) + { + $segments[] = $query['year']; + unset($query['year']); + } + } + + if (isset($query['year']) && isset($query['month'])) + { + if ($menuItemGiven) + { + $segments[] = $query['month']; + unset($query['month']); + } + } + } + + if ($view == 'featured') + { + if (!$menuItemGiven) + { + $segments[] = $view; + } + + unset($query['view']); + } + + /* + * If the layout is specified and it is the same as the layout in the menu item, we + * unset it so it doesn't go into the query string. + */ + if (isset($query['layout'])) + { + if ($menuItemGiven && isset($menuItem->query['layout'])) + { + if ($query['layout'] == $menuItem->query['layout']) + { + unset($query['layout']); + } + } + else + { + if ($query['layout'] == 'default') + { + unset($query['layout']); + } + } + } + + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = str_replace(':', '-', $segments[$i]); + } + } + + /** + * Parse the segments of a URL. + * + * @param array &$segments The segments of the URL to parse. + * @param array &$vars The URL attributes to be used by the application. + * + * @return void + * + * @since 3.4 + * @deprecated 4.0 + */ + public function parse(&$segments, &$vars) + { + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + } + + // Get the active menu item. + $item = $this->router->menu->getActive(); + $params = JComponentHelper::getParams('com_content'); + $advanced = $params->get('sef_advanced_link', 0); + $db = JFactory::getDbo(); + + // Count route segments + $count = count($segments); + + /* + * Standard routing for articles. If we don't pick up an Itemid then we get the view from the segments + * the first segment is the view and the last segment is the id of the article or category. + */ + if (!isset($item)) + { + $vars['view'] = $segments[0]; + $vars['id'] = $segments[$count - 1]; + + return; + } + + /* + * If there is only one segment, then it points to either an article or a category. + * We test it first to see if it is a category. If the id and alias match a category, + * then we assume it is a category. If they don't we assume it is an article + */ + if ($count == 1) + { + // We check to see if an alias is given. If not, we assume it is an article + if (strpos($segments[0], ':') === false) + { + $vars['view'] = 'article'; + $vars['id'] = (int) $segments[0]; + + return; + } + + list($id, $alias) = explode(':', $segments[0], 2); + + // First we check if it is a category + $category = JCategories::getInstance('Content')->get($id); + + if ($category && $category->alias == $alias) + { + $vars['view'] = 'category'; + $vars['id'] = $id; + + return; + } + else + { + $query = $db->getQuery(true) + ->select($db->quoteName(array('alias', 'catid'))) + ->from($db->quoteName('#__content')) + ->where($db->quoteName('id') . ' = ' . (int) $id); + $db->setQuery($query); + $article = $db->loadObject(); + + if ($article) + { + if ($article->alias == $alias) + { + $vars['view'] = 'article'; + $vars['catid'] = (int) $article->catid; + $vars['id'] = (int) $id; + + return; + } + } + } + } + + /* + * If there was more than one segment, then we can determine where the URL points to + * because the first segment will have the target category id prepended to it. If the + * last segment has a number prepended, it is an article, otherwise, it is a category. + */ + if (!$advanced) + { + $cat_id = (int) $segments[0]; + + $article_id = (int) $segments[$count - 1]; + + if ($article_id > 0) + { + $vars['view'] = 'article'; + $vars['catid'] = $cat_id; + $vars['id'] = $article_id; + } + else + { + $vars['view'] = 'category'; + $vars['id'] = $cat_id; + } + + return; + } + + // We get the category id from the menu item and search from there + $id = $item->query['id']; + $category = JCategories::getInstance('Content')->get($id); + + if (!$category) + { + JError::raiseError(404, JText::_('COM_CONTENT_ERROR_PARENT_CATEGORY_NOT_FOUND')); + + return; + } + + $categories = $category->getChildren(); + $vars['catid'] = $id; + $vars['id'] = $id; + $found = 0; + + foreach ($segments as $segment) + { + $segment = str_replace(':', '-', $segment); + + foreach ($categories as $category) + { + if ($category->alias == $segment) + { + $vars['id'] = $category->id; + $vars['catid'] = $category->id; + $vars['view'] = 'category'; + $categories = $category->getChildren(); + $found = 1; + break; + } + } + + if ($found == 0) + { + if ($advanced) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from('#__content') + ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) + ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); + $db->setQuery($query); + $cid = $db->loadResult(); + } + else + { + $cid = $segment; + } + + $vars['id'] = $cid; + + if ($item->query['view'] == 'archive' && $count != 1) + { + $vars['year'] = $count >= 2 ? $segments[$count - 2] : null; + $vars['month'] = $segments[$count - 1]; + $vars['view'] = 'archive'; + } + else + { + $vars['view'] = 'article'; + } + } + + $found = 0; + } + } +} diff --git a/components/com_content/helpers/route.php b/components/com_content/helpers/route.php index 357b6f954cdd0..1b790ec487145 100644 --- a/components/com_content/helpers/route.php +++ b/components/com_content/helpers/route.php @@ -16,8 +16,6 @@ */ abstract class ContentHelperRoute { - protected static $lookup = array(); - /** * Get the article route. * @@ -31,35 +29,17 @@ abstract class ContentHelperRoute */ public static function getArticleRoute($id, $catid = 0, $language = 0) { - $needles = array( - 'article' => array((int) $id) - ); - // Create the link $link = 'index.php?option=com_content&view=article&id=' . $id; if ((int) $catid > 1) { - $categories = JCategories::getInstance('Content'); - $category = $categories->get((int) $catid); - - if ($category) - { - $needles['category'] = array_reverse($category->getPath()); - $needles['categories'] = $needles['category']; - $link .= '&catid=' . $catid; - } + $link .= '&catid=' . $catid; } if ($language && $language != "*" && JLanguageMultilang::isEnabled()) { $link .= '&lang=' . $language; - $needles['language'] = $language; - } - - if ($item = self::_findItem($needles)) - { - $link .= '&Itemid=' . $item; } return $link; @@ -79,36 +59,24 @@ public static function getCategoryRoute($catid, $language = 0) { if ($catid instanceof JCategoryNode) { - $id = $catid->id; - $category = $catid; + $id = $catid->id; } else { - $id = (int) $catid; - $category = JCategories::getInstance('Content')->get($id); + $id = (int) $catid; } - if ($id < 1 || !($category instanceof JCategoryNode)) + if ($id < 1) { $link = ''; } else { - $needles = array(); - $link = 'index.php?option=com_content&view=category&id=' . $id; - $catids = array_reverse($category->getPath()); - $needles['category'] = $catids; - $needles['categories'] = $catids; + $link = 'index.php?option=com_content&view=category&id=' . $id; if ($language && $language != "*" && JLanguageMultilang::isEnabled()) { $link .= '&lang=' . $language; - $needles['language'] = $language; - } - - if ($item = self::_findItem($needles)) - { - $link .= '&Itemid=' . $item; } } @@ -126,109 +94,6 @@ public static function getCategoryRoute($catid, $language = 0) */ public static function getFormRoute($id) { - // Create the link - if ($id) - { - $link = 'index.php?option=com_content&task=article.edit&a_id=' . $id; - } - else - { - $link = 'index.php?option=com_content&task=article.edit&a_id=0'; - } - - return $link; - } - - /** - * Find an item ID. - * - * @param array $needles An array of language codes. - * - * @return mixed The ID found or null otherwise. - * - * @since 1.5 - */ - protected static function _findItem($needles = null) - { - $app = JFactory::getApplication(); - $menus = $app->getMenu('site'); - $language = isset($needles['language']) ? $needles['language'] : '*'; - - // Prepare the reverse lookup array. - if (!isset(self::$lookup[$language])) - { - self::$lookup[$language] = array(); - - $component = JComponentHelper::getComponent('com_content'); - - $attributes = array('component_id'); - $values = array($component->id); - - if ($language != '*') - { - $attributes[] = 'language'; - $values[] = array($needles['language'], '*'); - } - - $items = $menus->getItems($attributes, $values); - - foreach ($items as $item) - { - if (isset($item->query) && isset($item->query['view'])) - { - $view = $item->query['view']; - - if (!isset(self::$lookup[$language][$view])) - { - self::$lookup[$language][$view] = array(); - } - - if (isset($item->query['id'])) - { - /** - * Here it will become a bit tricky - * language != * can override existing entries - * language == * cannot override existing entries - */ - if (!isset(self::$lookup[$language][$view][$item->query['id']]) || $item->language != '*') - { - self::$lookup[$language][$view][$item->query['id']] = $item->id; - } - } - } - } - } - - if ($needles) - { - foreach ($needles as $view => $ids) - { - if (isset(self::$lookup[$language][$view])) - { - foreach ($ids as $id) - { - if (isset(self::$lookup[$language][$view][(int) $id])) - { - return self::$lookup[$language][$view][(int) $id]; - } - } - } - } - } - - // Check if the active menuitem matches the requested language - $active = $menus->getActive(); - - if ($active - && $active->component == 'com_content' - && ($language == '*' || in_array($active->language, array('*', $language)) || !JLanguageMultilang::isEnabled())) - { - return $active->id; - } - - // If not found, return language specific home link - $default = $menus->getDefault($language); - - return !empty($default->id) ? $default->id : null; + return 'index.php?option=com_content&task=article.edit&a_id=' . (int) $id; } } diff --git a/components/com_content/router.php b/components/com_content/router.php index 322be214620f9..8d1886442a1ce 100644 --- a/components/com_content/router.php +++ b/components/com_content/router.php @@ -10,455 +10,138 @@ defined('_JEXEC') or die; /** - * Routing class from com_content + * Routing class of com_content * * @since 3.3 */ -class ContentRouter extends JComponentRouterBase +class ContentRouter extends JComponentRouterView { - /** - * Build the route for the com_content component - * - * @param array &$query An array of URL arguments - * - * @return array The URL arguments to use to assemble the subsequent URL. - * - * @since 3.3 - */ - public function build(&$query) + function __construct($app = null, $menu = null) { - $segments = array(); - - // Get a menu item based on Itemid or currently active - $params = JComponentHelper::getParams('com_content'); - $advanced = $params->get('sef_advanced_link', 0); + $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); + $this->registerView($categories); + $category = new JComponentRouterViewconfiguration('category'); + $category->setKey('id')->setParent($categories, 'catid')->setNestable()->addLayout('blog'); + $this->registerView($category); + $article = new JComponentRouterViewconfiguration('article'); + $article->setKey('id')->setParent($category, 'catid'); + $this->registerView($article); + $this->registerView(new JComponentRouterViewconfiguration('archive')); + $this->registerView(new JComponentRouterViewconfiguration('featured')); + $this->registerView(new JComponentRouterViewconfiguration('form')); - // We need a menu item. Either the one specified in the query, or the current active one if none specified - if (empty($query['Itemid'])) - { - $menuItem = $this->menu->getActive(); - $menuItemGiven = false; - } - else - { - $menuItem = $this->menu->getItem($query['Itemid']); - $menuItemGiven = true; - } + parent::__construct($app, $menu); - // Check again - if ($menuItemGiven && isset($menuItem) && $menuItem->component != 'com_content') - { - $menuItemGiven = false; - unset($query['Itemid']); - } + $this->attachRule(new JComponentRouterRulesMenu($this)); - if (isset($query['view'])) + if ($this->app->get('sef_advanced', 0)) { - $view = $query['view']; + $this->attachRule(new JComponentRouterRulesStandard($this)); } else { - // We need to have a view in the query or it is an invalid URL - return $segments; - } - - // Are we dealing with an article or category that is attached to a menu item? - if (($menuItem instanceof stdClass) - && $menuItem->query['view'] == $query['view'] - && isset($query['id']) - && $menuItem->query['id'] == (int) $query['id']) - { - unset($query['view']); - - if (isset($query['catid'])) - { - unset($query['catid']); - } - - if (isset($query['layout'])) - { - unset($query['layout']); - } - - unset($query['id']); - - return $segments; - } - - if ($view == 'category' || $view == 'article') - { - if (!$menuItemGiven) - { - $segments[] = $view; - } - - unset($query['view']); - - if ($view == 'article') - { - if (isset($query['id']) && isset($query['catid']) && $query['catid']) - { - $catid = $query['catid']; - - // Make sure we have the id and the alias - if (strpos($query['id'], ':') === false) - { - $db = JFactory::getDbo(); - $dbQuery = $db->getQuery(true) - ->select('alias') - ->from('#__content') - ->where('id=' . (int) $query['id']); - $db->setQuery($dbQuery); - $alias = $db->loadResult(); - $query['id'] = $query['id'] . ':' . $alias; - } - } - else - { - // We should have these two set for this view. If we don't, it is an error - return $segments; - } - } - else - { - if (isset($query['id'])) - { - $catid = $query['id']; - } - else - { - // We should have id set for this view. If we don't, it is an error - return $segments; - } - } - - if ($menuItemGiven && isset($menuItem->query['id'])) - { - $mCatid = $menuItem->query['id']; - } - else - { - $mCatid = 0; - } - - $categories = JCategories::getInstance('Content'); - $category = $categories->get($catid); - - if (!$category) - { - // We couldn't find the category we were given. Bail. - return $segments; - } - - $path = array_reverse($category->getPath()); - - $array = array(); - - foreach ($path as $id) - { - if ((int) $id == (int) $mCatid) - { - break; - } - - list($tmp, $id) = explode(':', $id, 2); - - $array[] = $id; - } - - $array = array_reverse($array); - - if (!$advanced && count($array)) - { - $array[0] = (int) $catid . ':' . $array[0]; - } - - $segments = array_merge($segments, $array); - - if ($view == 'article') - { - if ($advanced) - { - list($tmp, $id) = explode(':', $query['id'], 2); - } - else - { - $id = $query['id']; - } - - $segments[] = $id; - } - - unset($query['id']); - unset($query['catid']); - } - - if ($view == 'archive') - { - if (!$menuItemGiven || $menuItem->query['view'] != 'archive') - { - // Did not work without removing Itemid - if (isset($menuItem)) - { - unset($query['Itemid']); - } - - $segments[] = $view; - } - - unset($query['view']); - - if (isset($query['year'])) - { - $segments[] = $query['year']; - unset($query['year']); - } - - if (isset($query['month'])) - { - $segments[] = $query['month']; - unset($query['month']); - } + require_once JPATH_SITE . '/components/com_content/helpers/legacyrouter.php'; + $this->attachRule(new ContentRouterRulesLegacy($this)); } - - if ($view == 'featured') - { - if (!$menuItemGiven) - { - $segments[] = $view; - } - - unset($query['view']); - } - - /* - * If the layout is specified and it is the same as the layout in the menu item, we - * unset it so it doesn't go into the query string. - */ - if (isset($query['layout'])) - { - if ($menuItemGiven && isset($menuItem->query['layout'])) - { - if ($query['layout'] == $menuItem->query['layout']) - { - unset($query['layout']); - } - } - else - { - if ($query['layout'] == 'default') - { - unset($query['layout']); - } - } - } - - $total = count($segments); - - for ($i = 0; $i < $total; $i++) - { - $segments[$i] = str_replace(':', '-', $segments[$i]); - } - - return $segments; } /** - * Parse the segments of a URL. - * - * @param array &$segments The segments of the URL to parse. + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is build right now * - * @return array The URL attributes to be used by the application. - * - * @since 3.3 + * @return array|string The segments of this item */ - public function parse(&$segments) + public function getCategorySegment($id, $query) { - $total = count($segments); - $vars = array(); + $category = JCategories::getInstance($this->getName())->get($id); - for ($i = 0; $i < $total; $i++) + if ($category) { - $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + return array_reverse($category->getPath()); } - // Get the active menu item. - $item = $this->menu->getActive(); - $params = JComponentHelper::getParams('com_content'); - $advanced = $params->get('sef_advanced_link', 0); - $db = JFactory::getDbo(); - - // Count route segments - $count = count($segments); - - /* - * Standard routing for articles. If we don't pick up an Itemid then we get the view from the segments - * the first segment is the view and the last segment is the id of the article or category. - */ - if (!isset($item)) - { - $vars['view'] = $segments[0]; + return array(); + } - // Called if no menu item created - if ($vars['view'] == 'archive') - { - $vars['year'] = $count >= 2 ? $segments[$count - 2] : null; - $vars['month'] = $segments[$count - 1]; - } - else - { - $vars['id'] = $segments[$count - 1]; - } + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is build right now + * + * @return array|string The segments of this item + */ + public function getCategoriesSegment($id, $query) + { + return $this->getCategorySegment($id, $query); + } - return $vars; - } + /** + * Method to get the segment(s) for an article + * + * @param string $id ID of the article to retrieve the segments for + * @param array $query The request that is build right now + * + * @return array|string The segments of this item + */ + public function getArticleSegment($id, $query) + { + return array($id); + } - // First handle archive view - if ($item->query['view'] == 'archive') + /** + * Method to get the id for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return array|int The id of this item + */ + public function getCategoryId($segment, $query) + { + if (isset($query['id'])) { - $vars['year'] = $count >= 2 ? $segments[$count - 2] : null; - $vars['month'] = $segments[$count - 1]; - $vars['view'] = 'archive'; + $category = JCategories::getInstance($this->getName())->get($query['id']); - return $vars; - } - - /* - * If there is only one segment, then it points to either an article or a category. - * We test it first to see if it is a category. If the id and alias match a category, - * then we assume it is a category. If they don't we assume it is an article - */ - if ($count == 1) - { - // We check to see if an alias is given. If not, we assume it is an article - if (strpos($segments[0], ':') === false) + foreach ($category->getChildren() as $child) { - $vars['view'] = 'article'; - $vars['id'] = (int) $segments[0]; - - return $vars; - } - - list($id, $alias) = explode(':', $segments[0], 2); - - // First we check if it is a category - $category = JCategories::getInstance('Content')->get($id); - - if ($category && $category->alias == $alias) - { - $vars['view'] = 'category'; - $vars['id'] = $id; - - return $vars; - } - else - { - $query = $db->getQuery(true) - ->select($db->quoteName(array('alias', 'catid'))) - ->from($db->quoteName('#__content')) - ->where($db->quoteName('id') . ' = ' . (int) $id); - $db->setQuery($query); - $article = $db->loadObject(); - - if ($article) + if ($child->id == (int) $segment) { - if ($article->alias == $alias) - { - $vars['view'] = 'article'; - $vars['catid'] = (int) $article->catid; - $vars['id'] = (int) $id; - - return $vars; - } + return $child->id; } } } - /* - * If there was more than one segment, then we can determine where the URL points to - * because the first segment will have the target category id prepended to it. If the - * last segment has a number prepended, it is an article, otherwise, it is a category. - */ - if (!$advanced) - { - $cat_id = (int) $segments[0]; - - $article_id = (int) $segments[$count - 1]; - - if ($article_id > 0) - { - $vars['view'] = 'article'; - $vars['catid'] = $cat_id; - $vars['id'] = $article_id; - } - else - { - $vars['view'] = 'category'; - $vars['id'] = $cat_id; - } - - return $vars; - } - - // We get the category id from the menu item and search from there - $id = $item->query['id']; - $category = JCategories::getInstance('Content')->get($id); - - if (!$category) - { - JError::raiseError(404, JText::_('COM_CONTENT_ERROR_PARENT_CATEGORY_NOT_FOUND')); - - return $vars; - } - - $categories = $category->getChildren(); - $vars['catid'] = $id; - $vars['id'] = $id; - $found = 0; - - foreach ($segments as $segment) - { - $segment = str_replace(':', '-', $segment); - - foreach ($categories as $category) - { - if ($category->alias == $segment) - { - $vars['id'] = $category->id; - $vars['catid'] = $category->id; - $vars['view'] = 'category'; - $categories = $category->getChildren(); - $found = 1; - break; - } - } - - if ($found == 0) - { - if ($advanced) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('id')) - ->from('#__content') - ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) - ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); - $db->setQuery($query); - $cid = $db->loadResult(); - } - else - { - $cid = $segment; - } - - $vars['id'] = $cid; - $vars['view'] = 'article'; - } + return false; + } - $found = 0; - } + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is parsed right now + * + * @return array|int The segments of this item + */ + public function getCategoriesId($segment, $query) + { + return $this->getCategoryId($segment, $query); + } - return $vars; + /** + * Method to get the segment(s) for an article + * + * @param string $segment Segment of the article to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return array|int The segments of this item + */ + public function getArticleId($segment, $query) + { + return (int) $segment; } } @@ -476,7 +159,8 @@ public function parse(&$segments) */ function contentBuildRoute(&$query) { - $router = new ContentRouter; + $app = JFactory::getApplication(); + $router = new ContentRouter($app, $app->getMenu()); return $router->build($query); } @@ -496,7 +180,8 @@ function contentBuildRoute(&$query) */ function contentParseRoute($segments) { - $router = new ContentRouter; + $app = JFactory::getApplication(); + $router = new ContentRouter($app, $app->getMenu()); return $router->parse($segments); } diff --git a/components/com_newsfeeds/helpers/legacyrouter.php b/components/com_newsfeeds/helpers/legacyrouter.php new file mode 100644 index 0000000000000..446e98e449c16 --- /dev/null +++ b/components/com_newsfeeds/helpers/legacyrouter.php @@ -0,0 +1,273 @@ +router = $router; + } + + /** + * Preprocess the route for the com_newsfeeds component + * + * @param array &$query An array of URL arguments + * + * @return void + * + * @since 3.4 + * @deprecated 4.0 + */ + public function preprocess(&$query) + { + } + + /** + * Build the route for the com_newsfeeds component + * + * @param array &$query An array of URL arguments + * @param array &$segments The URL arguments to use to assemble the subsequent URL. + * + * @return void + * + * @since 3.4 + * @deprecated 4.0 + */ + public function build(&$query, &$segments) + { + // Get a menu item based on Itemid or currently active + $params = JComponentHelper::getParams('com_newsfeeds'); + $advanced = $params->get('sef_advanced_link', 0); + + if (empty($query['Itemid'])) + { + $menuItem = $this->router->menu->getActive(); + } + else + { + $menuItem = $this->router->menu->getItem($query['Itemid']); + } + + $mView = (empty($menuItem->query['view'])) ? null : $menuItem->query['view']; + $mId = (empty($menuItem->query['id'])) ? null : $menuItem->query['id']; + + if (isset($query['view'])) + { + $view = $query['view']; + + if (empty($query['Itemid']) || empty($menuItem) || $menuItem->component != 'com_newsfeeds') + { + $segments[] = $query['view']; + } + + unset($query['view']); + } + + // Are we dealing with an newsfeed that is attached to a menu item? + if (isset($query['view']) && ($mView == $query['view']) and (isset($query['id'])) and ($mId == (int) $query['id'])) + { + unset($query['view']); + unset($query['catid']); + unset($query['id']); + + return; + } + + if (isset($view) and ($view == 'category' or $view == 'newsfeed')) + { + if ($mId != (int) $query['id'] || $mView != $view) + { + if ($view == 'newsfeed' && isset($query['catid'])) + { + $catid = $query['catid']; + } + elseif (isset($query['id'])) + { + $catid = $query['id']; + } + + $menuCatid = $mId; + $categories = JCategories::getInstance('Newsfeeds'); + $category = $categories->get($catid); + + if ($category) + { + $path = $category->getPath(); + $path = array_reverse($path); + + $array = array(); + + foreach ($path as $id) + { + if ((int) $id == (int) $menuCatid) + { + break; + } + + if ($advanced) + { + list($tmp, $id) = explode(':', $id, 2); + } + + $array[] = $id; + } + + $segments = array_merge($segments, array_reverse($array)); + } + + if ($view == 'newsfeed') + { + if ($advanced) + { + list($tmp, $id) = explode(':', $query['id'], 2); + } + else + { + $id = $query['id']; + } + + $segments[] = $id; + } + } + + unset($query['id']); + unset($query['catid']); + } + + if (isset($query['layout'])) + { + if (!empty($query['Itemid']) && isset($menuItem->query['layout'])) + { + if ($query['layout'] == $menuItem->query['layout']) + { + unset($query['layout']); + } + } + else + { + if ($query['layout'] == 'default') + { + unset($query['layout']); + } + } + } + + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = str_replace(':', '-', $segments[$i]); + } + } + + /** + * Parse the segments of a URL. + * + * @param array &$segments The segments of the URL to parse. + * @param array &$vars The URL attributes to be used by the application. + * + * @return void + * + * @since 3.4 + * @deprecated 4.0 + */ + public function parse(&$segments, &$vars) + { + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + } + + // Get the active menu item. + $item = $this->router->menu->getActive(); + $params = JComponentHelper::getParams('com_newsfeeds'); + $advanced = $params->get('sef_advanced_link', 0); + + // Count route segments + $count = count($segments); + + // Standard routing for newsfeeds. + if (!isset($item)) + { + $vars['view'] = $segments[0]; + $vars['id'] = $segments[$count - 1]; + + return; + } + + // From the categories view, we can only jump to a category. + $id = (isset($item->query['id']) && $item->query['id'] > 1) ? $item->query['id'] : 'root'; + $categories = JCategories::getInstance('Newsfeeds')->get($id)->getChildren(); + $vars['catid'] = $id; + $vars['id'] = $id; + $found = 0; + + foreach ($segments as $segment) + { + $segment = $advanced ? str_replace(':', '-', $segment) : $segment; + + foreach ($categories as $category) + { + if ($category->slug == $segment || $category->alias == $segment) + { + $vars['id'] = $category->id; + $vars['catid'] = $category->id; + $vars['view'] = 'category'; + $categories = $category->getChildren(); + $found = 1; + break; + } + } + + if ($found == 0) + { + if ($advanced) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from('#__newsfeeds') + ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) + ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); + $db->setQuery($query); + $nid = $db->loadResult(); + } + else + { + $nid = $segment; + } + + $vars['id'] = $nid; + $vars['view'] = 'newsfeed'; + } + + $found = 0; + } + } +} diff --git a/components/com_newsfeeds/helpers/route.php b/components/com_newsfeeds/helpers/route.php index 0ee6df13e9f0e..d78da59241702 100644 --- a/components/com_newsfeeds/helpers/route.php +++ b/components/com_newsfeeds/helpers/route.php @@ -16,8 +16,6 @@ */ abstract class NewsfeedsHelperRoute { - protected static $lookup; - /** * getNewsfeedRoute * @@ -29,36 +27,17 @@ abstract class NewsfeedsHelperRoute */ public static function getNewsfeedRoute($id, $catid, $language = 0) { - $needles = array( - 'newsfeed' => array((int) $id) - ); - // Create the link $link = 'index.php?option=com_newsfeeds&view=newsfeed&id=' . $id; if ((int) $catid > 1) { - $categories = JCategories::getInstance('Newsfeeds'); - $category = $categories->get((int) $catid); - - if ($category) - { - // TODO Throw error that the category either not exists or is unpublished - $needles['category'] = array_reverse($category->getPath()); - $needles['categories'] = $needles['category']; - $link .= '&catid=' . $catid; - } + $link .= '&catid=' . $catid; } if ($language && $language != "*" && JLanguageMultilang::isEnabled()) { $link .= '&lang=' . $language; - $needles['language'] = $language; - } - - if ($item = self::_findItem($needles)) - { - $link .= '&Itemid=' . $item; } return $link; @@ -77,130 +56,27 @@ public static function getCategoryRoute($catid, $language = 0) if ($catid instanceof JCategoryNode) { $id = $catid->id; - $category = $catid; } else { $id = (int) $catid; - $category = JCategories::getInstance('Newsfeeds')->get($id); } - if ($id < 1 || !($category instanceof JCategoryNode)) + if ($id < 1) { $link = ''; } else { - $needles = array(); - // Create the link $link = 'index.php?option=com_newsfeeds&view=category&id=' . $id; - $catids = array_reverse($category->getPath()); - $needles['category'] = $catids; - $needles['categories'] = $catids; - if ($language && $language != "*" && JLanguageMultilang::isEnabled()) { $link .= '&lang=' . $language; - $needles['language'] = $language; - } - - if ($item = self::_findItem($needles)) - { - $link .= '&Itemid=' . $item; } } return $link; } - - /** - * finditem - * - * @param null $needles what we are searching for - * - * @return int menu itemid - * - * @throws Exception - */ - protected static function _findItem($needles = null) - { - $app = JFactory::getApplication(); - $menus = $app->getMenu('site'); - $language = isset($needles['language']) ? $needles['language'] : '*'; - - // Prepare the reverse lookup array. - if (!isset(self::$lookup[$language])) - { - self::$lookup[$language] = array(); - - $component = JComponentHelper::getComponent('com_newsfeeds'); - - $attributes = array('component_id'); - $values = array($component->id); - - if ($language != '*') - { - $attributes[] = 'language'; - $values[] = array($needles['language'], '*'); - } - - $items = $menus->getItems($attributes, $values); - - foreach ($items as $item) - { - if (isset($item->query) && isset($item->query['view'])) - { - $view = $item->query['view']; - - if (!isset(self::$lookup[$language][$view])) - { - self::$lookup[$language][$view] = array(); - } - - if (isset($item->query['id'])) - { - /* Here it will become a bit tricky - language != * can override existing entries - language == * cannot override existing entries */ - if (!isset(self::$lookup[$language][$view][$item->query['id']]) || $item->language != '*') - { - self::$lookup[$language][$view][$item->query['id']] = $item->id; - } - } - } - } - } - - if ($needles) - { - foreach ($needles as $view => $ids) - { - if (isset(self::$lookup[$language][$view])) - { - foreach ($ids as $id) - { - if (isset(self::$lookup[$language][$view][(int) $id])) - { - return self::$lookup[$language][$view][(int) $id]; - } - } - } - } - } - - // Check if the active menuitem matches the requested language - $active = $menus->getActive(); - - if ($active && ($language == '*' || in_array($active->language, array('*', $language)) || !JLanguageMultilang::isEnabled())) - { - return $active->id; - } - - // If not found, return language specific home link - $default = $menus->getDefault($language); - - return !empty($default->id) ? $default->id : null; - } } diff --git a/components/com_newsfeeds/router.php b/components/com_newsfeeds/router.php index 2377d32c013e5..c45679904102f 100644 --- a/components/com_newsfeeds/router.php +++ b/components/com_newsfeeds/router.php @@ -14,235 +14,130 @@ * * @since 3.3 */ -class NewsfeedsRouter extends JComponentRouterBase +class NewsfeedsRouter extends JComponentRouterView { - /** - * Build the route for the com_newsfeeds component - * - * @param array &$query An array of URL arguments - * - * @return array The URL arguments to use to assemble the subsequent URL. - * - * @since 3.3 - */ - public function build(&$query) + function __construct($app = null, $menu = null) { - $segments = array(); + $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); + $this->registerView($categories); + $category = new JComponentRouterViewconfiguration('category'); + $category->setKey('id')->setParent($categories, 'catid')->setNestable(); + $this->registerView($category); + $newsfeed = new JComponentRouterViewconfiguration('newsfeed'); + $newsfeed->setKey('id')->setParent($category, 'catid'); + $this->registerView($newsfeed); - // Get a menu item based on Itemid or currently active - $params = JComponentHelper::getParams('com_newsfeeds'); - $advanced = $params->get('sef_advanced_link', 0); + parent::__construct($app, $menu); - if (empty($query['Itemid'])) - { - $menuItem = $this->menu->getActive(); - } - else - { - $menuItem = $this->menu->getItem($query['Itemid']); - } + $this->attachRule(new JComponentRouterRulesMenu($this)); - $mView = (empty($menuItem->query['view'])) ? null : $menuItem->query['view']; - $mId = (empty($menuItem->query['id'])) ? null : $menuItem->query['id']; - - if (isset($query['view'])) + if ($this->app->get('sef_advanced', 0)) { - $view = $query['view']; - - if (empty($query['Itemid']) || empty($menuItem) || $menuItem->component != 'com_newsfeeds') - { - $segments[] = $query['view']; - } - - unset($query['view']); - } - - // Are we dealing with an newsfeed that is attached to a menu item? - if (isset($query['view']) && ($mView == $query['view']) and (isset($query['id'])) and ($mId == (int) $query['id'])) - { - unset($query['view']); - unset($query['catid']); - unset($query['id']); - - return $segments; + $this->attachRule(new JComponentRouterRulesStandard($this)); } - - if (isset($view) and ($view == 'category' or $view == 'newsfeed')) - { - if ($mId != (int) $query['id'] || $mView != $view) - { - if ($view == 'newsfeed' && isset($query['catid'])) - { - $catid = $query['catid']; - } - elseif (isset($query['id'])) - { - $catid = $query['id']; - } - - $menuCatid = $mId; - $categories = JCategories::getInstance('Newsfeeds'); - $category = $categories->get($catid); - - if ($category) - { - $path = $category->getPath(); - $path = array_reverse($path); - - $array = array(); - - foreach ($path as $id) - { - if ((int) $id == (int) $menuCatid) - { - break; - } - - if ($advanced) - { - list($tmp, $id) = explode(':', $id, 2); - } - - $array[] = $id; - } - - $segments = array_merge($segments, array_reverse($array)); - } - - if ($view == 'newsfeed') - { - if ($advanced) - { - list($tmp, $id) = explode(':', $query['id'], 2); - } - else - { - $id = $query['id']; - } - - $segments[] = $id; - } - } - - unset($query['id']); - unset($query['catid']); - } - - if (isset($query['layout'])) - { - if (!empty($query['Itemid']) && isset($menuItem->query['layout'])) - { - if ($query['layout'] == $menuItem->query['layout']) - { - unset($query['layout']); - } - } - else - { - if ($query['layout'] == 'default') - { - unset($query['layout']); - } - } - } - - $total = count($segments); - - for ($i = 0; $i < $total; $i++) + else { - $segments[$i] = str_replace(':', '-', $segments[$i]); + require_once JPATH_SITE . '/components/com_newsfeeds/helpers/legacyrouter.php'; + $this->attachRule(new NewsfeedsRouterRulesLegacy($this)); } - - return $segments; } /** - * Parse the segments of a URL. - * - * @param array &$segments The segments of the URL to parse. + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is build right now * - * @return array The URL attributes to be used by the application. - * - * @since 3.3 + * @return array|string The segments of this item */ - public function parse(&$segments) + public function getCategorySegment($id, $query) { - $total = count($segments); - $vars = array(); - - for ($i = 0; $i < $total; $i++) + $category = JCategories::getInstance($this->getName())->get($id); + if ($category) { - $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + return array_reverse($category->getPath()); } - // Get the active menu item. - $item = $this->menu->getActive(); - $params = JComponentHelper::getParams('com_newsfeeds'); - $advanced = $params->get('sef_advanced_link', 0); - - // Count route segments - $count = count($segments); - - // Standard routing for newsfeeds. - if (!isset($item)) - { - $vars['view'] = $segments[0]; - $vars['id'] = $segments[$count - 1]; + return array(); + } - return $vars; - } + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is build right now + * + * @return array|string The segments of this item + */ + public function getCategoriesSegment($id, $query) + { + return $this->getCategorySegment($id, $query); + } - // From the categories view, we can only jump to a category. - $id = (isset($item->query['id']) && $item->query['id'] > 1) ? $item->query['id'] : 'root'; - $categories = JCategories::getInstance('Newsfeeds')->get($id)->getChildren(); - $vars['catid'] = $id; - $vars['id'] = $id; - $found = 0; + /** + * Method to get the segment(s) for a newsfeed + * + * @param string $id ID of the newsfeed to retrieve the segments for + * @param array $query The request that is build right now + * + * @return array|string The segments of this item + */ + public function getNewsfeedSegment($id, $query) + { + return array($id); + } - foreach ($segments as $segment) + /** + * Method to get the id for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return array|int The id of this item + */ + public function getCategoryId($segment, $query) + { + if (isset($query['id'])) { - $segment = $advanced ? str_replace(':', '-', $segment) : $segment; + $category = JCategories::getInstance($this->getName())->get($query['id']); - foreach ($categories as $category) + foreach ($category->getChildren() as $child) { - if ($category->slug == $segment || $category->alias == $segment) + if ($child->id == (int) $segment) { - $vars['id'] = $category->id; - $vars['catid'] = $category->id; - $vars['view'] = 'category'; - $categories = $category->getChildren(); - $found = 1; - - break; + return $child->id; } } + } - if ($found == 0) - { - if ($advanced) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('id')) - ->from('#__newsfeeds') - ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) - ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); - $db->setQuery($query); - $nid = $db->loadResult(); - } - else - { - $nid = $segment; - } - - $vars['id'] = $nid; - $vars['view'] = 'newsfeed'; - } + return false; + } - $found = 0; - } + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is parsed right now + * + * @return array|int The segments of this item + */ + public function getCategoriesId($segment, $query) + { + return $this->getCategoryId($segment, $query); + } - return $vars; + /** + * Method to get the segment(s) for a newsfeed + * + * @param string $segment Segment of the newsfeed to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return array|int The segments of this item + */ + public function getNewsfeedId($segment, $query) + { + return (int) $segment; } } @@ -260,7 +155,8 @@ public function parse(&$segments) */ function newsfeedsBuildRoute(&$query) { - $router = new NewsfeedsRouter; + $app = JFactory::getApplication(); + $router = new NewsfeedsRouter($app, $app->getMenu()); return $router->build($query); } @@ -276,7 +172,8 @@ function newsfeedsBuildRoute(&$query) */ function newsfeedsParseRoute($segments) { - $router = new NewsfeedsRouter; + $app = JFactory::getApplication(); + $router = new NewsfeedsRouter($app, $app->getMenu()); return $router->parse($segments); } diff --git a/components/com_tags/models/tag.php b/components/com_tags/models/tag.php index 63ca9afdba10d..e18a8a7448936 100644 --- a/components/com_tags/models/tag.php +++ b/components/com_tags/models/tag.php @@ -324,6 +324,11 @@ public function hit($pk = 0) $table = JTable::getInstance('Tag', 'TagsTable'); $table->load($pk); $table->hit($pk); + + if (!$table->hasPrimaryKey()) + { + JError::raiseError(404, JText::_('COM_TAGS_TAG_NOT_FOUND')); + } } return true; diff --git a/components/com_tags/views/tags/tmpl/default_items.php b/components/com_tags/views/tags/tmpl/default_items.php index 6264606130370..8a1f25b875e03 100644 --- a/components/com_tags/views/tags/tmpl/default_items.php +++ b/components/com_tags/views/tags/tmpl/default_items.php @@ -43,96 +43,96 @@ params->get('filter_field') || $this->params->get('show_pagination_limit')) : ?> -
- params->get('filter_field')) : ?> -
- - -
- - params->get('show_pagination_limit')) : ?> -
- - pagination->getLimitBox(); ?> -
- +
+ params->get('filter_field')) : ?> +
+ + +
+ + params->get('show_pagination_limit')) : ?> +
+ + pagination->getLimitBox(); ?> +
+ - - - - -
-
+ + + + +
+
-items == false || $n == 0) : ?> -

- - items as $i => $item) : ?> - -
    - - access)) && in_array($item->access, $this->user->getAuthorisedViewLevels())) : ?> -
  • -

    - - escape($item->title); ?> - -

    + items == false || $n == 0) : ?> +

    + + items as $i => $item) : ?> + +
      + + access)) && in_array($item->access, $this->user->getAuthorisedViewLevels())) : ?> +
    • +

      + + escape($item->title); ?> + +

      - params->get('all_tags_show_tag_image') && !empty($item->images)) : ?> - images); ?> - + params->get('all_tags_show_tag_image') && !empty($item->images)) : ?> + images); ?> + image_intro)): ?> float_intro)) ? $this->params->get('float_intro') : $images->float_intro; ?>
      image_intro_caption) : ?> - image_intro_caption) . '"'; ?> - - src="image_intro; ?>" alt="image_fulltext_alt); ?>"/> + image_intro_caption) : ?> + image_intro_caption) . '"'; ?> + + src="image_intro; ?>" alt="image_fulltext_alt); ?>"/>
      - -
      - params->get('all_tags_show_tag_description', 1)) : ?> - + +
      + params->get('all_tags_show_tag_description', 1)) : ?> + description, $this->params->get('tag_list_item_maximum_characters')); ?> - - params->get('all_tags_show_tag_hits')) : ?> - + + params->get('all_tags_show_tag_hits')) : ?> + hits); ?> - -
      -
    • + +
+ - - - + + + - - + + - -items)) : ?> + + items)) : ?> params->def('show_pagination', 2) == 1 || ($this->params->get('show_pagination') == 2)) && ($this->pagination->pagesTotal > 1)) : ?> - diff --git a/components/com_users/controllers/remind.php b/components/com_users/controllers/remind.php index ac440ad6bda92..6fc24600f3217 100644 --- a/components/com_users/controllers/remind.php +++ b/components/com_users/controllers/remind.php @@ -34,34 +34,24 @@ public function remind() $data = $this->input->post->get('jform', array(), 'array'); // Submit the password reset request. - $return = $model->processRemindRequest($data); + $return = $model->processRemindRequest($data); // Check for a hard error. if ($return == false) { // The request failed. - // Get the route to the next page. - $itemid = UsersHelperRoute::getRemindRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=remind' . $itemid; - // Go back to the request form. $message = JText::sprintf('COM_USERS_REMIND_REQUEST_FAILED', $model->getError()); - $this->setRedirect(JRoute::_($route, false), $message, 'notice'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=remind', false), $message, 'notice'); return false; } else { // The request succeeded. - // Get the route to the next page. - $itemid = UsersHelperRoute::getRemindRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=login' . $itemid; - // Proceed to step two. $message = JText::_('COM_USERS_REMIND_REQUEST_SUCCESS'); - $this->setRedirect(JRoute::_($route, false), $message); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false), $message); return true; } diff --git a/components/com_users/controllers/reset.php b/components/com_users/controllers/reset.php index a2ab90dd02d2b..74cdc88c32359 100644 --- a/components/com_users/controllers/reset.php +++ b/components/com_users/controllers/reset.php @@ -35,7 +35,7 @@ public function request() $data = $this->input->post->get('jform', array(), 'array'); // Submit the password reset request. - $return = $model->processResetRequest($data); + $return = $model->processResetRequest($data); // Check for a hard error. if ($return instanceof Exception) @@ -50,40 +50,25 @@ public function request() $message = JText::_('COM_USERS_RESET_REQUEST_ERROR'); } - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset' . $itemid; - // Go back to the request form. - $this->setRedirect(JRoute::_($route, false), $message, 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset', false), $message, 'error'); return false; } elseif ($return === false) { // The request failed. - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset' . $itemid; - // Go back to the request form. $message = JText::sprintf('COM_USERS_RESET_REQUEST_FAILED', $model->getError()); - $this->setRedirect(JRoute::_($route, false), $message, 'notice'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset', false), $message, 'notice'); return false; } else { // The request succeeded. - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset&layout=confirm' . $itemid; - // Proceed to step two. - $this->setRedirect(JRoute::_($route, false)); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=confirm', false)); return true; } @@ -107,7 +92,7 @@ public function confirm() $data = $this->input->get('jform', array(), 'array'); // Confirm the password reset request. - $return = $model->processResetConfirm($data); + $return = $model->processResetConfirm($data); // Check for a hard error. if ($return instanceof Exception) @@ -122,40 +107,25 @@ public function confirm() $message = JText::_('COM_USERS_RESET_CONFIRM_ERROR'); } - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset&layout=confirm' . $itemid; - // Go back to the confirm form. - $this->setRedirect(JRoute::_($route, false), $message, 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=confirm', false), $message, 'error'); return false; } elseif ($return === false) { // Confirm failed. - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset&layout=confirm' . $itemid; - // Go back to the confirm form. $message = JText::sprintf('COM_USERS_RESET_CONFIRM_FAILED', $model->getError()); - $this->setRedirect(JRoute::_($route, false), $message, 'notice'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=confirm', false), $message, 'notice'); return false; } else { // Confirm succeeded. - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset&layout=complete' . $itemid; - // Proceed to step three. - $this->setRedirect(JRoute::_($route, false)); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=complete', false)); return true; } @@ -178,7 +148,7 @@ public function complete() $data = $this->input->post->get('jform', array(), 'array'); // Complete the password reset request. - $return = $model->processResetComplete($data); + $return = $model->processResetComplete($data); // Check for a hard error. if ($return instanceof Exception) @@ -193,41 +163,26 @@ public function complete() $message = JText::_('COM_USERS_RESET_COMPLETE_ERROR'); } - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset&layout=complete' . $itemid; - // Go back to the complete form. - $this->setRedirect(JRoute::_($route, false), $message, 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=complete', false), $message, 'error'); return false; } elseif ($return === false) { // Complete failed. - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset&layout=complete' . $itemid; - // Go back to the complete form. $message = JText::sprintf('COM_USERS_RESET_COMPLETE_FAILED', $model->getError()); - $this->setRedirect(JRoute::_($route, false), $message, 'notice'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=complete', false), $message, 'notice'); return false; } else { // Complete succeeded. - // Get the route to the next page. - $itemid = UsersHelperRoute::getLoginRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=login' . $itemid; - // Proceed to the login form. $message = JText::_('COM_USERS_RESET_COMPLETE_SUCCESS'); - $this->setRedirect(JRoute::_($route, false), $message); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false), $message); return true; } diff --git a/components/com_users/controllers/user.php b/components/com_users/controllers/user.php index 7acce2f746a61..5188abe0160e6 100644 --- a/components/com_users/controllers/user.php +++ b/components/com_users/controllers/user.php @@ -68,24 +68,22 @@ public function login() $credentials['secretkey'] = $data['secretkey']; // Perform the log in. - if (true === $app->login($credentials, $options)) - { - // Success - if ($options['remember'] == true) - { - $app->setUserState('rememberLogin', true); - } - - $app->setUserState('users.login.form.data', array()); - $app->redirect(JRoute::_($app->getUserState('users.login.form.return'), false)); - } - else + if (true !== $app->login($credentials, $options)) { // Login failed ! $data['remember'] = (int) $options['remember']; $app->setUserState('users.login.form.data', $data); $app->redirect(JRoute::_('index.php?option=com_users&view=login', false)); } + + // Success + if ($options['remember'] == true) + { + $app->setUserState('rememberLogin', true); + } + + $app->setUserState('users.login.form.data', array()); + $app->redirect(JRoute::_($app->getUserState('users.login.form.return'), false)); } /** @@ -107,24 +105,22 @@ public function logout() $method = $input->getMethod(); // Check if the log out succeeded. - if (!($error instanceof Exception)) + if ($error instanceof Exception) { - // Get the return url from the request and validate that it is internal. - $return = $input->$method->get('return', '', 'BASE64'); - $return = base64_decode($return); + $app->redirect(JRoute::_('index.php?option=com_users&view=login', false)); + } - if (!JUri::isInternal($return)) - { - $return = ''; - } + // Get the return url from the request and validate that it is internal. + $return = $input->$method->get('return', '', 'BASE64'); + $return = base64_decode($return); - // Redirect the user. - $app->redirect(JRoute::_($return, false)); - } - else + if (!JUri::isInternal($return)) { - $app->redirect(JRoute::_('index.php?option=com_users&view=login', false)); + $return = ''; } + + // Redirect the user. + $app->redirect(JRoute::_($return, false)); } /** @@ -189,11 +185,11 @@ public function register() if ($errors[$i] instanceof Exception) { $app->enqueueMessage($errors[$i]->getMessage(), 'notice'); + + continue; } - else - { - $app->enqueueMessage($errors[$i], 'notice'); - } + + $app->enqueueMessage($errors[$i], 'notice'); } // Save the data in the session. @@ -250,14 +246,9 @@ public function remind() if ($return instanceof Exception) { // Get the error message to display. - if ($app->get('error_reporting')) - { - $message = $return->getMessage(); - } - else - { - $message = JText::_('COM_USERS_REMIND_REQUEST_ERROR'); - } + $message = $app->get('error_reporting') + ? $return->getMessage() + : JText::_('COM_USERS_REMIND_REQUEST_ERROR'); // Get the route to the next page. $itemid = UsersHelperRoute::getRemindRoute(); @@ -269,7 +260,8 @@ public function remind() return false; } - elseif ($return === false) + + if ($return === false) { // Complete failed. // Get the route to the next page. @@ -283,20 +275,18 @@ public function remind() return false; } - else - { - // Complete succeeded. - // Get the route to the next page. - $itemid = UsersHelperRoute::getLoginRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=login' . $itemid; - // Proceed to the login form. - $message = JText::_('COM_USERS_REMIND_REQUEST_SUCCESS'); - $this->setRedirect(JRoute::_($route, false), $message); + // Complete succeeded. + // Get the route to the next page. + $itemid = UsersHelperRoute::getLoginRoute(); + $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; + $route = 'index.php?option=com_users&view=login' . $itemid; - return true; - } + // Proceed to the login form. + $message = JText::_('COM_USERS_REMIND_REQUEST_SUCCESS'); + $this->setRedirect(JRoute::_($route, false), $message); + + return true; } /** diff --git a/components/com_users/helpers/legacyrouter.php b/components/com_users/helpers/legacyrouter.php new file mode 100644 index 0000000000000..d2e922fff7776 --- /dev/null +++ b/components/com_users/helpers/legacyrouter.php @@ -0,0 +1,296 @@ +router = $router; + } + + /** + * Preprocess the route for the com_users component + * + * @param array &$query An array of URL arguments + * + * @return void + * + * @since 3.4 + * @deprecated 4.0 + */ + public function preprocess(&$query) + { + } + + /** + * Build the route for the com_users component + * + * @param array &$query An array of URL arguments + * @param array &$segments The URL arguments to use to assemble the subsequent URL. + * + * @return void + * + * @since 3.4 + * @deprecated 4.0 + */ + public function build(&$query, &$segments) + { + // Declare static variables. + static $items; + static $default; + static $registration; + static $profile; + static $login; + static $remind; + static $resend; + static $reset; + + // Get the relevant menu items if not loaded. + if (empty($items)) + { + // Get all relevant menu items. + $items = $this->router->menu->getItems('component', 'com_users'); + + // Build an array of serialized query strings to menu item id mappings. + for ($i = 0, $n = count($items); $i < $n; $i++) + { + // Check to see if we have found the resend menu item. + if (empty($resend) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'resend')) + { + $resend = $items[$i]->id; + } + + // Check to see if we have found the reset menu item. + if (empty($reset) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'reset')) + { + $reset = $items[$i]->id; + } + + // Check to see if we have found the remind menu item. + if (empty($remind) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'remind')) + { + $remind = $items[$i]->id; + } + + // Check to see if we have found the login menu item. + if (empty($login) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'login')) + { + $login = $items[$i]->id; + } + + // Check to see if we have found the registration menu item. + if (empty($registration) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'registration')) + { + $registration = $items[$i]->id; + } + + // Check to see if we have found the profile menu item. + if (empty($profile) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'profile')) + { + $profile = $items[$i]->id; + } + } + + // Set the default menu item to use for com_users if possible. + if ($profile) + { + $default = $profile; + } + elseif ($registration) + { + $default = $registration; + } + elseif ($login) + { + $default = $login; + } + } + + if (!empty($query['view'])) + { + switch ($query['view']) + { + case 'reset': + if ($query['Itemid'] = $reset) + { + unset ($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + case 'resend': + if ($query['Itemid'] = $resend) + { + unset ($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + case 'remind': + if ($query['Itemid'] = $remind) + { + unset ($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + case 'login': + if ($query['Itemid'] = $login) + { + unset ($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + case 'registration': + if ($query['Itemid'] = $registration) + { + unset ($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + default: + case 'profile': + if (!empty($query['view'])) + { + $segments[] = $query['view']; + } + + unset ($query['view']); + + if ($query['Itemid'] = $profile) + { + unset ($query['view']); + } + else + { + $query['Itemid'] = $default; + } + + // Only append the user id if not "me". + $user = JFactory::getUser(); + + if (!empty($query['user_id']) && ($query['user_id'] != $user->id)) + { + $segments[] = $query['user_id']; + } + + unset ($query['user_id']); + + break; + } + } + + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = str_replace(':', '-', $segments[$i]); + } + } + + /** + * Parse the segments of a URL. + * + * @param array &$segments The segments of the URL to parse. + * @param array &$vars The URL attributes to be used by the application. + * + * @return void + * + * @since 3.4 + * @deprecated 4.0 + */ + public function parse(&$segments, &$vars) + { + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + } + + // Only run routine if there are segments to parse. + if (count($segments) < 1) + { + return; + } + + // Get the package from the route segments. + $userId = array_pop($segments); + + if (!is_numeric($userId)) + { + $vars['view'] = 'profile'; + + return; + } + + if (is_numeric($userId)) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from($db->quoteName('#__users')) + ->where($db->quoteName('id') . ' = ' . (int) $userId); + $db->setQuery($query); + $userId = $db->loadResult(); + } + + // Set the package id if present. + if ($userId) + { + // Set the package id. + $vars['user_id'] = (int) $userId; + + // Set the view to package if not already set. + if (empty($vars['view'])) + { + $vars['view'] = 'profile'; + } + } + else + { + JError::raiseError(404, JText::_('JGLOBAL_RESOURCE_NOT_FOUND')); + } + } +} diff --git a/components/com_users/helpers/route.php b/components/com_users/helpers/route.php index 9e75df63c16cb..0369d97274157 100644 --- a/components/com_users/helpers/route.php +++ b/components/com_users/helpers/route.php @@ -13,6 +13,7 @@ * Users Route Helper * * @since 1.6 + * @deprecated 4.0 */ class UsersHelperRoute { @@ -22,6 +23,7 @@ class UsersHelperRoute * @return array An array of menu items. * * @since 1.6 + * @deprecated 4.0 */ public static function &getItems() { @@ -51,7 +53,7 @@ public static function &getItems() * @return mixed Integer menu id on success, null on failure. * * @since 1.6 - * @static + * @deprecated 4.0 */ public static function getLoginRoute() { @@ -78,6 +80,7 @@ public static function getLoginRoute() * @return mixed Integer menu id on success, null on failure. * * @since 1.6 + * @deprecated 4.0 */ public static function getProfileRoute() { @@ -106,6 +109,7 @@ public static function getProfileRoute() * @return mixed Integer menu id on success, null on failure. * * @since 1.6 + * @deprecated 4.0 */ public static function getRegistrationRoute() { @@ -132,6 +136,7 @@ public static function getRegistrationRoute() * @return mixed Integer menu id on success, null on failure. * * @since 1.6 + * @deprecated 4.0 */ public static function getRemindRoute() { @@ -158,6 +163,7 @@ public static function getRemindRoute() * @return mixed Integer menu id on success, null on failure. * * @since 1.6 + * @deprecated 4.0 */ public static function getResendRoute() { @@ -184,6 +190,7 @@ public static function getResendRoute() * @return mixed Integer menu id on success, null on failure. * * @since 1.6 + * @deprecated 4.0 */ public static function getResetRoute() { diff --git a/components/com_users/models/remind.php b/components/com_users/models/remind.php index e34e83f1c5461..7b6f84c457731 100644 --- a/components/com_users/models/remind.php +++ b/components/com_users/models/remind.php @@ -158,9 +158,7 @@ public function processRemindRequest($data) $config = JFactory::getConfig(); // Assemble the login link. - $itemid = UsersHelperRoute::getLoginRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $link = 'index.php?option=com_users&view=login' . $itemid; + $link = 'index.php?option=com_users&view=login'; $mode = $config->get('force_ssl', 0) == 2 ? 1 : (-1); // Put together the email template data. diff --git a/components/com_users/models/reset.php b/components/com_users/models/reset.php index 349a2e94e8d68..c71dac3dcafa3 100644 --- a/components/com_users/models/reset.php +++ b/components/com_users/models/reset.php @@ -453,9 +453,7 @@ public function processResetRequest($data) // Assemble the password reset confirmation link. $mode = $config->get('force_ssl', 0) == 2 ? 1 : (-1); - $itemid = UsersHelperRoute::getLoginRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $link = 'index.php?option=com_users&view=reset&layout=confirm&token=' . $token . $itemid; + $link = 'index.php?option=com_users&view=reset&layout=confirm&token=' . $token; // Put together the email template data. $data = $user->getProperties(); diff --git a/components/com_users/router.php b/components/com_users/router.php index 7b55b409f146c..9febfd437e57a 100644 --- a/components/com_users/router.php +++ b/components/com_users/router.php @@ -14,257 +14,29 @@ * * @since 3.2 */ -class UsersRouter extends JComponentRouterBase +class UsersRouter extends JComponentRouterView { - /** - * Build the route for the com_users component - * - * @param array &$query An array of URL arguments - * - * @return array The URL arguments to use to assemble the subsequent URL. - * - * @since 3.3 - */ - public function build(&$query) + function __construct($app = null, $menu = null) { - // Declare static variables. - static $items; - static $default; - static $registration; - static $profile; - static $login; - static $remind; - static $resend; - static $reset; + $this->registerView(new JComponentRouterViewconfiguration('login')); + $this->registerView(new JComponentRouterViewconfiguration('profile')); + $this->registerView(new JComponentRouterViewconfiguration('registration')); + $this->registerView(new JComponentRouterViewconfiguration('remind')); + $this->registerView(new JComponentRouterViewconfiguration('reset')); - $segments = array(); + parent::__construct($app, $menu); - // Get the relevant menu items if not loaded. - if (empty($items)) - { - // Get all relevant menu items. - $items = $this->menu->getItems('component', 'com_users'); - - // Build an array of serialized query strings to menu item id mappings. - for ($i = 0, $n = count($items); $i < $n; $i++) - { - // Check to see if we have found the resend menu item. - if (empty($resend) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'resend')) - { - $resend = $items[$i]->id; - } - - // Check to see if we have found the reset menu item. - if (empty($reset) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'reset')) - { - $reset = $items[$i]->id; - } - - // Check to see if we have found the remind menu item. - if (empty($remind) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'remind')) - { - $remind = $items[$i]->id; - } - - // Check to see if we have found the login menu item. - if (empty($login) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'login')) - { - $login = $items[$i]->id; - } - - // Check to see if we have found the registration menu item. - if (empty($registration) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'registration')) - { - $registration = $items[$i]->id; - } - - // Check to see if we have found the profile menu item. - if (empty($profile) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'profile')) - { - $profile = $items[$i]->id; - } - } - - // Set the default menu item to use for com_users if possible. - if ($profile) - { - $default = $profile; - } - elseif ($registration) - { - $default = $registration; - } - elseif ($login) - { - $default = $login; - } - } - - if (!empty($query['view'])) - { - switch ($query['view']) - { - case 'reset': - if ($query['Itemid'] = $reset) - { - unset ($query['view']); - } - else - { - $query['Itemid'] = $default; - } - break; - - case 'resend': - if ($query['Itemid'] = $resend) - { - unset ($query['view']); - } - else - { - $query['Itemid'] = $default; - } - break; - - case 'remind': - if ($query['Itemid'] = $remind) - { - unset ($query['view']); - } - else - { - $query['Itemid'] = $default; - } - break; - - case 'login': - if ($query['Itemid'] = $login) - { - unset ($query['view']); - } - else - { - $query['Itemid'] = $default; - } - break; - - case 'registration': - if ($query['Itemid'] = $registration) - { - unset ($query['view']); - } - else - { - $query['Itemid'] = $default; - } - break; - - default: - case 'profile': - if (!empty($query['view'])) - { - $segments[] = $query['view']; - } - - unset ($query['view']); - - if ($query['Itemid'] = $profile) - { - unset ($query['view']); - } - else - { - $query['Itemid'] = $default; - } - - // Only append the user id if not "me". - $user = JFactory::getUser(); - - if (!empty($query['user_id']) && ($query['user_id'] != $user->id)) - { - $segments[] = $query['user_id']; - } - - unset ($query['user_id']); - - break; - } - } - - $total = count($segments); + $this->attachRule(new JComponentRouterRulesMenu($this)); - for ($i = 0; $i < $total; $i++) + if ($this->app->get('sef_advanced', 0)) { - $segments[$i] = str_replace(':', '-', $segments[$i]); - } - - return $segments; - } - - /** - * Parse the segments of a URL. - * - * @param array &$segments The segments of the URL to parse. - * - * @return array The URL attributes to be used by the application. - * - * @since 3.3 - */ - public function parse(&$segments) - { - $total = count($segments); - $vars = array(); - - for ($i = 0; $i < $total; $i++) - { - $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); - } - - // Only run routine if there are segments to parse. - if (count($segments) < 1) - { - return; - } - - // Get the package from the route segments. - $userId = array_pop($segments); - - if (!is_numeric($userId)) - { - $vars['view'] = 'profile'; - - return $vars; - } - - if (is_numeric($userId)) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('id')) - ->from($db->quoteName('#__users')) - ->where($db->quoteName('id') . ' = ' . (int) $userId); - $db->setQuery($query); - $userId = $db->loadResult(); - } - - // Set the package id if present. - if ($userId) - { - // Set the package id. - $vars['user_id'] = (int) $userId; - - // Set the view to package if not already set. - if (empty($vars['view'])) - { - $vars['view'] = 'profile'; - } + $this->attachRule(new JComponentRouterRulesStandard($this)); } else { - JError::raiseError(404, JText::_('JGLOBAL_RESOURCE_NOT_FOUND')); + require_once JPATH_SITE . '/components/com_users/helpers/legacyrouter.php'; + $this->attachRule(new UsersRouterRulesLegacy($this)); } - - return $vars; } } @@ -282,7 +54,8 @@ public function parse(&$segments) */ function usersBuildRoute(&$query) { - $router = new UsersRouter; + $app = JFactory::getApplication(); + $router = new UsersRouter($app, $app->getMenu()); return $router->build($query); } @@ -298,7 +71,8 @@ function usersBuildRoute(&$query) */ function usersParseRoute($segments) { - $router = new UsersRouter; + $app = JFactory::getApplication(); + $router = new UsersRouter($app, $app->getMenu()); return $router->parse($segments); } diff --git a/installation/controller/setdefaultlanguage.php b/installation/controller/setdefaultlanguage.php index 4de1631f051ca..8ebca39318381 100644 --- a/installation/controller/setdefaultlanguage.php +++ b/installation/controller/setdefaultlanguage.php @@ -163,25 +163,30 @@ public function execute() $error = true; } - if (!$error) - { - $tableCategory = $model->addCategory($siteLang); + $installContent = (int) $data['installLocalisedContent']; - if ($tableCategory === false) + if ($installContent) + { + if (!$error) { - $app->enqueueMessage(JText::sprintf('INSTL_DEFAULTLANGUAGE_COULD_NOT_CREATE_CATEGORY', $frontend_lang)); - $error = true; - } - } + $tableCategory = $model->addCategory($siteLang); - if (!$error) - { - $categoryId = $tableCategory->id; + if ($tableCategory === false) + { + $app->enqueueMessage(JText::sprintf('INSTL_DEFAULTLANGUAGE_COULD_NOT_CREATE_CATEGORY', $frontend_lang)); + $error = true; + } + } - if (!$model->addArticle($siteLang, $categoryId)) + if (!$error) { - $app->enqueueMessage(JText::sprintf('INSTL_DEFAULTLANGUAGE_COULD_NOT_CREATE_ARTICLE', $frontend_lang)); - $error = true; + $categoryId = $tableCategory->id; + + if (!$model->addArticle($siteLang, $categoryId)) + { + $app->enqueueMessage(JText::sprintf('INSTL_DEFAULTLANGUAGE_COULD_NOT_CREATE_ARTICLE', $frontend_lang)); + $error = true; + } } } } diff --git a/installation/language/tk-TM/tk-TM.ini b/installation/language/tk-TM/tk-TM.ini new file mode 100644 index 0000000000000..92b2cdc7586ef --- /dev/null +++ b/installation/language/tk-TM/tk-TM.ini @@ -0,0 +1,321 @@ +; Joomla! Project +; Copyright (C) 2005 - 2015 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +;Stepbar +INSTL_STEP_COMPLETE_LABEL="Tamamla" +INSTL_STEP_DATABASE_LABEL="Maglumat Bazasy" +INSTL_STEP_DEFAULTLANGUAGE_LABEL="Bellenilen Dili Saýlaň" +INSTL_STEP_FTP_LABEL="FTP Sazlama" +INSTL_STEP_LANGUAGES_LABEL="Dilleri Gurnamak" +INSTL_STEP_SITE_LABEL="Saýtyň Sazlamalary" +INSTL_STEP_SUMMARY_LABEL="Umumy syn" + +;Language view +INSTL_SELECT_LANGUAGE_TITLE="Dil Saýlaň" +INSTL_WARNJAVASCRIPT="Duýduryş! Joomla!-nyň dogry gurnamagy üçin JavaScript açyk bolmaly." +INSTL_WARNJSON="Joomla-nyň dogry gurnamagy PHP-de JSON açyk bolmaly." + +;Preinstall view +INSTL_PRECHECK_TITLE="Gurnamadan Öňürti Barlag" +INSTL_PRECHECK_DESC="Eger şu görkezilen elementler goldanmaýar bolsa(Ýokşeklinde bellenen) bir şekilde düzetmegiňizi haýyş edýäris.
Aşakdaky talaplar ýerine ýetirilmedikçe siz Joomla!-ny gurnap bilmersiňiz." +INSTL_PRECHECK_RECOMMENDED_SETTINGS_TITLE="Maslahat berlen sazlamalar:" +INSTL_PRECHECK_RECOMMENDED_SETTINGS_DESC="Şu maslahat edilen sazlamalar PHP-nyň dogry Joomla bilen işleýişini kepillik edýär.
Ýöne, Joomla! muňa garamazdan maslahat edilen sazlamalrda kiçi näsazlyklar bilenem işlär." +INSTL_PRECHECK_DIRECTIVE="Direktiwa" +INSTL_PRECHECK_RECOMMENDED="Maslahat berlen" +INSTL_PRECHECK_ACTUAL="Hakykysy" + +; Database view +INSTL_DATABASE="Bazanyň Sazlamasy" +INSTL_DATABASE_HOST_DESC="Bu köplenç "localhost"." +INSTL_DATABASE_HOST_LABEL="Hyzmat Nokadynyň Ady" +INSTL_DATABASE_NAME_DESC="Käbir hyzmat nokatlary saýt başyna belli bir baza rugsat berýär. Şol ýagdaýda Joomla! web sahypalary üçin bazada aýratyn tablitsa prefikdlerini ulanyň." +INSTL_DATABASE_NAME_LABEL="Bazanyň Ady" +INSTL_DATABASE_NO_SCHEMA="Şu baza görnüşi üçin hiç hili shema tapylmady. " +INSTL_DATABASE_OLD_PROCESS_DESC="Öňki Joomla!-dan galan ähli ätiýaç tablitsalaryň nusgalary täzelener." +INSTL_DATABASE_OLD_PROCESS_LABEL="Köne Baza Prosessi" +INSTL_DATABASE_PASSWORD_DESC="Web sahypanyň howupsyzlygy üçin bazada parol ulanmak hökman zerurdyr." +INSTL_DATABASE_PASSWORD_LABEL="Parol" +INSTL_DATABASE_PREFIX_DESC="Tablitsa üçin prefiks saýlaň ýa-da tötänleýin meýdana getirilen prefiksi ulanyň. Iň gowysy, üç we dört alfanumeriki simwol we aşakdan çyzgy HÖKMAN ulanylmalydyr. Saýlanan prefiks başga tablitslarda ulanyşda bolmaly däldir." +INSTL_DATABASE_PREFIX_LABEL="Tablitsanyň Prefiksleri" +INSTL_DATABASE_PREFIX_MSG="Tablitsanyň prefiksi harp bilen başlap yzy alfanumeriki simwollar bilen we aşakdan çyzgy gelmelidir" +INSTL_DATABASE_TYPE_DESC="Bu ähtimal "MySQLi"." +INSTL_DATABASE_TYPE_LABEL="Bazanyň Görnüşi" +INSTL_DATABASE_USER_DESC=""root" bolmaly ýada hyzmat ediş nokadyňyz tarapyndan berilen ulanyjy ady." +INSTL_DATABASE_USER_LABEL="Ulanyjy ady" + +;FTP view +INSTL_AUTOFIND_FTP_PATH="FTP-niň awto- gözbaş gözlegi" +INSTL_FTP="FTP Sazlama" +INSTL_FTP_DESC="

Käbir serwerlerde gurnamany dogry tamamlamak üçin FTP güwenamaňyzy subut etmeli. Eger sizde güwenamany tamamlamakda kynçylyk dörän bolsa hyzmat nokadyňyzy takyklamak üçin barlap görüň.

Howupsyzlyk sebäpli iň gowusy tutuş saýta däl diňe Joomla! gurnamasy üçin rugsatly aýratyn FTP ulanyjy hasabyny açyň. Siziň hyzmat nokadyňyz şu mesele boýunça size kömek eder.

Ýatladma: Eger siz Windows Operasýon Ulgamyna gurnaýan bolsaňyz FTP funksýasy hökmandäl.

" +INSTL_FTP_ENABLE_LABEL="FTP -ni Aç" +INSTL_FTP_HOST_LABEL="FTP Hyzmat Nokady" +INSTL_FTP_PASSWORD_LABEL="FTP Paroly" +INSTL_FTP_PORT_LABEL="FTP Porty" +INSTL_FTP_ROOT_LABEL="FTP Gözbaşy" +INSTL_FTP_SAVE_LABEL="FTP Paroluny Sakla" +INSTL_FTP_TITLE="FTP Sazlama (Islege görä -Ulanyjylaryň köpsi bu ädimi böküp geçip biler - Böküp geçmek üçin Indiki düwmesine basyň)" +INSTL_FTP_USER_LABEL="FTP Ulanyjy Ady" +INSTL_VERIFY_FTP_SETTINGS="FTP Sazlamalaryny Takyklaň" +INSTL_FTP_SETTINGS_CORRECT="Sazlamalar dogry" +INSTL_FTP_USER_DESC="Duýduryş! Maslahat berleni boş goýmak we her faýl geçiriminde FTP degişli ulanyjy adyňyzy täzeden girmek." +INSTL_FTP_PASSWORD_DESC="Duýduryş! Maslahat berleni boş goýmak we her faýl geçiriminde FTP degişli paroluňyzy täzeden girmek." + +;Site View +INSTL_SITE="Esasy Sazlama" +INSTL_ADMIN_EMAIL_LABEL="Adminiň Emaili" +INSTL_ADMIN_EMAIL_DESC="Email salgysyny giriň. Bu email salgysy web sahypanyň Super Ulanyjynyň email salgysy bolar." +INSTL_ADMIN_PASSWORD_LABEL="Admin Paroly" +INSTL_ADMIN_PASSWORD_DESC="Super Ulanyjy üçin parol giriň we aşakdaky meýdançada paroly gaýtalaň." +INSTL_ADMIN_PASSWORD2_LABEL="Admin Parolyny Gaýtalaň" +INSTL_ADMIN_USER_LABEL="Admin Ulanyjy Ady" +INSTL_ADMIN_USER_DESC="Super Ulanyjy hasaby üçin ulanyjy adyny belläň." +INSTL_SITE_NAME_LABEL="Web Sahypanyň Ady" +INSTL_SITE_NAME_DESC="Joomla! Web sahypanyň adyny giriň." +INSTL_SITE_METADESC_LABEL="Düşündiriş" +INSTL_SITE_METADESC_TITLE_LABEL="Web sahypa barada umumy düşündiriş giriň. Bu düşündiriş gözleg enjamlary üçindir. Köplenç 20 söz ýeterli bolýa." +INSTL_SITE_OFFLINE_LABEL="Web Sahypa Ulgamyň Daşynda" +INSTL_SITE_OFFLINE_TITLE_LABEL="Gurnama tamamlanan soň web sahypany ulgamyň daşynda belle. Web sahypa soň Global Sazlama üsti bilen ulgamyň içinde belläp bilersiňiz." +INSTL_SITE_INSTALL_SAMPLE_LABEL="Nusgalyk Maglumatlary Gurna" +INSTL_SITE_INSTALL_SAMPLE_DESC="Täze başlanlara nusgalyk maglumatlary gurnamak berk baslahat berilýär.
Bu Jooml!-nyň gurnama bukjasyndaky içindäki nusgalyk mazmuny goýar." +INSTL_SITE_INSTALL_SAMPLE_NONE="Hiç zat( Ýönekeý köp-dilli web sahylar döretmek üçin gerek)" +INSTL_SAMPLE_BLOG_SET="Blog English (GB) Nusgalyk Maglumat" +INSTL_SAMPLE_BROCHURE_SET="Brochure English (GB) Nusgalyk Maglumat" +INSTL_SAMPLE_DATA_SET="Default English (GB) Nusgalyk Maglumat" +INSTL_SAMPLE_LEARN_SET="Learn Joomla English (GB) Nusgalyk Maglumat" +INSTL_SAMPLE_TESTING_SET="Test English (GB) Nusgalyk Maglumat" +INSTL_SITE_INSTALL_SAMPLE_NONE_DESC="Joomla-ny kontentsiz diňe bir menýu we giriş formy bilen gurnar." +INSTL_SAMPLE_BLOG_SET_DESC="Joomla-ny azyjyk makala we blog-a degişli Köne postlar, Köp okalan postlar ýaly modullary gurnar." +INSTL_SAMPLE_BROCHURE_SET_DESC="Joomla-ny azyjyk sahypalar(Baş menýu, Biz barada, Habarlar we Habarlaşma ) bilen gurnar." +INSTL_SAMPLE_DATA_SET_DESC="Joomla-ny ýeke sahypa we Iň Täze Makalalar, Giriş Formy ýaly modullary gurnar." +INSTL_SAMPLE_LEARN_SET_DESC="Joomla -nyň işleýişini tanatma üçin edilen mysal berlen makalalary gurnar." +INSTL_SAMPLE_TESTING_SET_DESC="Joomla-nyň içinde näme bar bolsa ähli menýu we elementler bilen gurnar." + +;Summary view +INSTL_FINALISATION="Tamamlama" +INSTL_SUMMARY_INSTALL="Gurna" +INSTL_SUMMARY_EMAIL_LABEL="Email Sazlama" +INSTL_SUMMARY_EMAIL_PASSWORDS_LABEL="Paroly emailde ugrat" +INSTL_SUMMARY_EMAIL_PASSWORDS_DESC="Duýduruş! Maslahat berlileni email arkaly parol ugratmak ýada saklamak bolanok." +INSTL_SUMMARY_EMAIL_DESC="Sazlama barada maglumatlary %s email salgyma gurnama gutaran soň ugrat." + +;Installing view +INSTL_INSTALLING="Gurnalýar ..." +INSTL_INSTALLING_DATABASE_BACKUP="Köne bazanyň tablitsalary ätiýaç nusgasy alynýar" +INSTL_INSTALLING_DATABASE_REMOVE="Köne bazanyň tablitsalaryny pozulýar" +INSTL_INSTALLING_DATABASE="Bazanyň tablitsalary döredilýär" +INSTL_INSTALLING_SAMPLE="Nusgalyk maglumatlar gurnalýar" +INSTL_INSTALLING_CONFIG="Sazlama faýly döredilýär" +INSTL_INSTALLING_EMAIL="%s email ugradylýar" + +;Email +INSTL_EMAIL_SUBJECT="Sazlamanyň Maglumatlary: %s" +INSTL_EMAIL_HEADING="Aşakda siz täze gurnalan Joomla! web sahypasynyň sazlamalaryny tapyp bilersiňiz:" +INSTL_EMAIL_NOT_SENT="Email ugradylyp bilinmedi." + +;Complete view +INSTL_COMPLETE_ADMINISTRATION_LOGIN_DETAILS="Administratsýanyň Giriş Maglumatlary" +; The word 'installation' should not be translated as it is a physical folder. +INSTL_COMPLETE_ERROR_FOLDER_ALREADY_REMOVED="Gurnama bukjasy 'installation' eýýäm pozulypdyr." +; The word 'installation' should not be translated as it is a physical folder. +INSTL_COMPLETE_ERROR_FOLDER_DELETE="Gurnama bukjasy 'installation' pozulup bilinmeýär. El bilen bukjany pozmany haýyş edýäris." +; The word 'installation' should not be translated as it is a physical folder. +INSTL_COMPLETE_FOLDER_REMOVED="Gurnama bukjasy 'installation' şowly pozuldy." +INSTL_COMPLETE_LANGUAGE_1="Joomla! siziň diliňizde ýa-da ýönekeý köp-dilli web saýt döretmek üçin" +; The word 'installation' should not be translated as it is a physical folder. +INSTL_COMPLETE_LANGUAGE_DESC="Gurnama bukjasyny 'installation' pozmanka siz artykmaçdan dil hem gurnap bilersiňiz. Eger Joomla! programmasyna dil gurnajak bolsaňyz degişli düwmäni basyň." +INSTL_COMPLETE_LANGUAGE_DESC2="Ýatladma: täze dil gurnamalaryny indirmek üçin Joomla! internet gerek bolar.
Käbir serwerleriň sazlamalary Joomla! täze dili gurnama üçin rugsat bermeýär. Eger sizde şeýle ýagdaý bar bolsa gynanmaň soňrak Joomla! Administrator arkaly gurnap bilersiňiz." +; The word 'installation' should not be translated as it is a physical folder. +INSTL_COMPLETE_REMOVE_FOLDER="Gurnama bukjasy 'installation' ýok et" +; The word 'installation' should not be translated as it is a physical folder. +INSTL_COMPLETE_REMOVE_INSTALLATION="GURNAMA BUKJASYNY 'INSTALLATION' DÜÝBÜNDEN ÝOK ETMELIDIGIŇIZI ÝATDA SAKLAMAGYŇYZY HAÝYŞ EDÝÄRIS.
Gurnama bukjasy ýok edilen soň mundan soňky nokada geçip bilersiňiz. Bu Joomla!-nyň howupsyzlyk funksiýasydyr." +INSTL_COMPLETE_TITLE="Gutlaýarys! Joomla! indi gurnalandyr." +INSTL_COMPLETE_INSTALL_LANGUAGES="Artykmaç ädimler: Dilleri gurna" + +;Languages view +INSTL_LANGUAGES="Dil bukjalaryny gurna" +INSTL_LANGUAGES_COLUMN_HEADER_LANGUAGE="Dil" +INSTL_LANGUAGES_COLUMN_HEADER_VERSION="Wersiýa" +INSTL_LANGUAGES_DESC="Joomla interfeýsi birnäçe dilde elýeterlidir. Siziň isleýän dilleriňizi saýlap we Soňky düwmesine basyp gurnamany başladyň.
Ýatladma: bu iş 10 sekund ýaly her dili indirmek üçin wagt alar. Gijikmesiz bolmasyny arzuw edýän bolsaňyz 3 dilden kän ýüklemäň." +INSTL_LANGUAGES_MESSAGE_PLEASE_WAIT="Bu iş tamamlamasy üçin dil başyna 10 sekund ýaly dowam eder
Dilleri indirip gurnaýança garaşmagyňyzy haýyş edýäris..." +INSTL_LANGUAGES_MORE_LANGUAGES="Eger başgada dil gurnamak isleýän bolsaňyz 'Öňki' düwmesini basyň." +INSTL_LANGUAGES_NO_LANGUAGE_SELECTED="Gurnama üçin hiç hili dil saýlanylmady. Eger başgada dil gurnamak isleýän bolsaňyz 'Öňki' düwmesini basyp, isleýän diliňizi spisokdan saýlaň." +INSTL_LANGUAGES_WARNING_NO_INTERNET="Joomla! dil serwerine baglanyp bilmedi. Gurnama prosesini tamamlamagyňyzy haýyş edýäris." +INSTL_LANGUAGES_WARNING_NO_INTERNET2="Ýatladma: Dilleri soň Joomla! Administrator girişi arkaly hem gurnap bilersiňiz" +INSTL_LANGUAGES_WARNING_BACK_BUTTON="Gurnamanyň soňky ädimine git" + +;Default language view +INSTL_DEFAULTLANGUAGE_ACTIVATE_MULTILANGUAGE="Köp-dilli funksýany aktiwleşdir" +INSTL_DEFAULTLANGUAGE_ACTIVATE_MULTILANGUAGE_DESC="Eger aktiw bolanda Joomla sahypaňyz gurnalan dilde ýerli dildäki menýular bilen hyzmat berer." +INSTL_DEFAULTLANGUAGE_ACTIVATE_LANGUAGE_CODE_PLUGIN="Dil kody plaginini işlet" +INSTL_DEFAULTLANGUAGE_ACTIVATE_LANGUAGE_CODE_PLUGIN_DESC="Eger açyk bolsa, dil kody plagini dil kodyny üýtgetmäne HTML dokumentini SEO-ny gowylaşdyrmana kömek eder." +INSTL_DEFAULTLANGUAGE_ADMINISTRATOR="Bellenilen Administrator dili" +INSTL_DEFAULTLANGUAGE_ADMIN_COULDNT_SET_DEFAULT="Joomla bellenilen dil hökmünde bellap bilmedi. Iňňlis dili bellenilen Administrator dili hökmünde belleniler." +INSTL_DEFAULTLANGUAGE_ADMIN_SET_DEFAULT="Joomla %s ADMINISTRATOR dili hökmünde belledi." +INSTL_DEFAULTLANGUAGE_COLUMN_HEADER_SELECT="Saýlaň" +INSTL_DEFAULTLANGUAGE_COLUMN_HEADER_LANGUAGE="Dil" +INSTL_DEFAULTLANGUAGE_COLUMN_HEADER_TAG="Bellik" +INSTL_DEFAULTLANGUAGE_COULD_NOT_CREATE_CONTENT_LANGUAGE="Joomla awtomatiki usully %s mazmun dilini döredilip bilinmedi" +INSTL_DEFAULTLANGUAGE_COULD_NOT_CREATE_MENU="Joomla awtomatiki usully menýu %s döredip bilmedi" +INSTL_DEFAULTLANGUAGE_COULD_NOT_CREATE_MENU_ITEM="Joomla awtomatiki usully baş menýu elementini %s döredip bilmedi" +INSTL_DEFAULTLANGUAGE_COULD_NOT_CREATE_MENU_MODULE="Joomla awtomatiki usully menýu moduluny %s döredip bilmedi" +INSTL_DEFAULTLANGUAGE_COULD_NOT_CREATE_CATEGORY="Joomla awtomatiki usully mazmun kategorýalaryny %s döredip bilmedi" +INSTL_DEFAULTLANGUAGE_COULD_NOT_CREATE_ARTICLE="Joomla awtomatiki usully ýerli makalany %s döredip bilmedi" +INSTL_DEFAULTLANGUAGE_COULD_NOT_ENABLE_MODULESWHITCHER_LANGUAGECODE="Joomla awtomatiki usully dil pereklýuçatel moduluny %s çap edip bilmedi" +INSTL_DEFAULTLANGUAGE_COULD_NOT_ENABLE_PLG_LANGUAGECODE="Joomla awtomatiki usully Dil Kode Plaginini %s işledip bilmedi" +INSTL_DEFAULTLANGUAGE_COULD_NOT_ENABLE_PLG_LANGUAGEFILTER="Joomla awtomatiki usully Dil Filter Plaginini %s işledip bilmedi" +INSTL_DEFAULTLANGUAGE_COULD_NOT_INSTALL_LANGUAGE="Joomla dili %s gurnap bilmedi" +INSTL_DEFAULTLANGUAGE_COULD_NOT_PUBLISH_MOD_MULTILANGSTATUS="Joomla awtomatiki usully dil ýagdaý moduluny %s çap edip bilmedi" +INSTL_DEFAULTLANGUAGE_COULD_NOT_UNPUBLISH_MOD_DEFAULTMENU="Joomla awtomatiki usully menýu moduluny %s çapdan aýyryp bilmedi" +INSTL_DEFAULTLANGUAGE_DESC="Joomla saýlanan dilleri gurnady. Joomla Administrator üçin islendik diliňizi saýlamaňyzy haýyş edýäris" +INSTL_DEFAULTLANGUAGE_DESC_FRONTEND="Joomla saýlanan dilleri gurnady. Joomla web sahypalary üçin islendik diliňizi saýlamaňyzy haýyş edýäris" +INSTL_DEFAULTLANGUAGE_FRONTEND="Bellenilen Saýtyň dili" +INSTL_DEFAULTLANGUAGE_FRONTEND_COULDNT_SET_DEFAULT="Joomla dili bellenilen dil hökmünde belläp bilmedi. Iňňlis dili bellenilen dil hökmünde Web Sahyplar üçin belleniler." +INSTL_DEFAULTLANGUAGE_FRONTEND_SET_DEFAULT="Joomla saýtyň dilini %s belledi." +INSTL_DEFAULTLANGUAGE_INSTALL_LOCALISED_CONTENT="Ýerli edilen mazmuny gurna" +INSTL_DEFAULTLANGUAGE_INSTALL_LOCALISED_CONTENT_DESC="Eger aktiw bolanda, Joomla awtomatiki usully her kategorýa üçin aýratyn boş bir mazmun dörediler." +INSTL_DEFAULTLANGUAGE_MULTILANGUAGE_TITLE="Köp-dilli" +INSTL_DEFAULTLANGUAGE_MULTILANGUAGE_DESC="Bu bölüm size awtomatiki usully Joomla!-nyň köp-dilli funksýasyny aktiwleşdirer." +INSTL_DEFAULTLANGUAGE_TRY_LATER="Siz Joomla! Administrator arkaly hem soň gurnap bilersiňiz" + +; IMPORTANT NOTE FOR TRANSLATORS: Do not literally translate this line, instead add the localised name of the language. For example Spanish will be Español +INSTL_DEFAULTLANGUAGE_NATIVE_LANGUAGE_NAME="Türkmençe (TK)" + +;Database Model +INSTL_DATABASE_COULD_NOT_CONNECT="Baza baglanyp bilmedi. Baglaýyjyň gaýtaran nomeri: %s" +INSTL_DATABASE_COULD_NOT_CREATE_DATABASE="Gurnaýyjy görkezilen baza baglanyp bilmedi we baza döredip bilmedi. Sazlamalary takyklamagyňyzy ýa-da el bilen özüňiz bazany döretmegiňizi haýyş edýäris." +INSTL_DATABASE_COULD_NOT_REFRESH_MANIFEST_CACHE="Uzaltma manifesti käşini täzeläp bilmedi: %s" +INSTL_DATABASE_EMPTY_NAME="" +INSTL_DATABASE_ERROR_BACKINGUP="Bazanyň ätiýaçlyk nusgasyny almada bir näçe näsazlyk çykdy." +INSTL_DATABASE_ERROR_CREATE="Baza %s döredilýärka näsazlyk çykdy.
Ulanyjynyň ýeterli hak-hukugy bolmany üçin bolup biler. Gerek bolan bazanyň aýratyn Joomla! gurmazdan öň gurulmaly." +INSTL_DATABASE_ERROR_DELETE="Bazany öçürmede bir näçe näsazlyk çykdy." +INSTL_DATABASE_FIELD_VALUE_REMOVE="Aýyr" +INSTL_DATABASE_FIELD_VALUE_BACKUP="Ätiýaç Nusga" +INSTL_DATABASE_FIX_TOO_LONG="MySQL tablitsaň prefiks ady köpünden 15 harp bolmaly." +INSTL_DATABASE_INVALID_DB_DETAILS="Berlen bazanyň maglumatlary dogry däl ýa-da boş goýulan." +INSTL_DATABASE_INVALID_MYSQL_VERSION="Gurnamany dowam etmek üçin size MySQL 5.0.4 ýa-da ýokry wersýalary gerek. Siziň wersýaňyz: %s" +INSTL_DATABASE_INVALID_MYSQLI_VERSION="Gurnamany dowam etmek üçin size MySQL 5.0.4 ýa-da ýokry wersýalary gerek. Siziň wersýaňyz: %s" +INSTL_DATABASE_INVALID_PDOMYSQL_VERSION="Gurnamany dowam etmek üçin size MySQL 5.0.4 ýa-da ýokry wersýalary gerek. Siziň wersýaňyz: %s" +INSTL_DATABASE_INVALID_POSTGRESQL_VERSION="Gurnamany dowam etmek üçin size PostgreSQL 8.3.18 ýa-da ýokry wersýalary gerek. Siziň wersýaňyz: %s" +INSTL_DATABASE_INVALID_SQLSRV_VERSION="Gurnamany dowam etmek üçin size SQL Server 2008 R2 (10.50.1600.1) ýa-da ýokry wersýalary gerek. Siziň wersýaňyz: %s" +INSTL_DATABASE_INVALID_SQLZURE_VERSION="Gurnamany dowam etmek üçin size SQL Server 2008 R2 (10.50.1600.1) ýa-da ýokry wersýalary gerek. Siziň wersýaňyz: %s" +INSTL_DATABASE_INVALID_TYPE="Bazanyň görnüşini saýlaň" +INSTL_DATABASE_NAME_TOO_LONG="MySQL bazasynyň ady köpünden 64 harp bolmaly." +INSTL_DATABASE_INVALID_NAME="MySQL-yň 5.1.6 we ondan öňki wersýalaryndaky atlarda "special" bolmaly däl. Siziň wersýaňyz: %s" +INSTL_DATABASE_NAME_INVALID_SPACES="MySQL bazasynyň atlarynda we tablitsa atlarynda boş ýer(probel) bolmaly däl." +INSTL_DATABASE_NAME_INVALID_CHAR="Hiç hili MySQL-de NULL ASCII(0x00) içinde bolup bilmez." +INSTL_DATABASE_FILE_DOES_NOT_EXIST="Faýl %s ýok" + +;controllers +INSTL_COOKIES_NOT_ENABLED="Kukiler siziň brawzerde açyk däl ýaly. Siz programmany şu funksýasyz gurnap bilmersiňiz. Mundan başgada serwerdede session.save_path näsazlyk bolup biler. Eger bu mesele bolsa hosting beriji bilen habarlaşyp bu näsazlygy düzediň." +INSTL_HEADER_ERROR="Näsazlyk" + +;Helpers +INSTL_PAGE_TITLE="Joomla! Web Gurnaýjy" + +;Configuration model +INSTL_ERROR_CONNECT_DB="Baza baglanyp bilmedi. Baglaýyjyň gaýtaran nomeri: %s" +INSTL_STD_OFFLINE_MSG="Bu saýtda abatlaýyş işleri geçirilýär.
Soňrak zyýarat etmegiňizi haýyş edýäris." + +;FTP model +INSTL_FTP_INVALIDROOT="Görkezilen FTP bukjasy Joomla!-nyň gurnama bukjasy däl" +INSTL_FTP_NOCONNECT="FTP serwere baglanyp bilmedi" +INSTL_FTP_NODELE=""DELE" funksýasy şowsuz boldy." +INSTL_FTP_NODIRECTORYLISTING="FTP serwerden bujlaryň spisogyny alyp bilmedi." +INSTL_FTP_NOLIST=""LIST" funksýasy şowsuz boldy." +INSTL_FTP_NOLOGIN="FTP serwere girip bilmedi." +INSTL_FTP_NOMKD=""MKD" funksýasy şowsuz boldy." +INSTL_FTP_NONLST=""NLST" funksýasy şowsuz boldy." +INSTL_FTP_NOPWD=""PWD" funksýasy şowsuz boldy." +INSTL_FTP_NORETR=""RETR" funksýasy şowsuz boldy." +INSTL_FTP_NORMD=""RMD" funksýasy şowsuz boldy." +INSTL_FTP_NOROOT="Görkezilen FTP bukjasyna girip bilmedi." +INSTL_FTP_NOSTOR=""STOR" funksýasy şowsuz boldy." +INSTL_FTP_NOSYST=""SYST" funksýasy şowsuz boldy." +INSTL_FTP_UNABLE_DETECT_ROOT_FOLDER="Awtomatiki usully FTP-nyň gözbaşy bukjasyny tapyp bilmedi." + +;others +INSTL_CONFPROBLEM="Siziň sazlama faýlyňyz ýa-da bukjaňyz ýazylmana açyk däl. Siz görkezilen kody el bilen girip ýüklemeli bolarsyňyz. Tekst meýdançadaky tekst saýlap kopýalaň we taze tekst faýlynyň içine ýerleşdiriň. Tekst faýlyna 'configuration.php' adyny beriň we saýt gözbaşy bukjasyna ýükläň." +INSTL_DATABASE_SUPPORT="Bazanyň Goldawy:" +INSTL_DISPLAY_ERRORS="Näsazlyklary Görkez" +INSTL_ERROR_DB="Bazany ýerleşdirýärka käbir näsazlyklar çykdy: %s" +INSTL_ERROR_INITIALISE_SCHEMA="Bazanyň shemasyny başladyp bolmady" +INSTL_FILE_UPLOADS="Faýl Ýüklemeler" +INSTL_GNU_GPL_LICENSE="GNU Umumy Lisenziýa" +INSTL_JSON_SUPPORT_AVAILABLE="JSON Goldawy" +INSTL_MAGIC_QUOTES_GPC="Magic Quotes GPC Öçür" +INSTL_MAGIC_QUOTES_RUNTIME="Magic Quotes Işleýişi" +INSTL_MB_LANGUAGE_IS_DEFAULT="MB Dili Bllenilen" +INSTL_MB_STRING_OVERLOAD_OFF="MB String Artykmaç Ýükleme Öçük" +INSTL_NOTICEMBLANGNOTDEFAULT="PHP mbstring funksýasy bitarap bellenildi. Bu funksýa ýerlikleýin .htaccess faýlynyň içinde php_value mbstring.language neutral kodyny ýazyp hem bellap bilersiňiz." +INSTL_NOTICEMBSTRINGOVERLOAD="PHP mbstring funksýasy artykmaç ýükleme bellenildi. Bu funksýa ýerlikleýin .htaccess faýlynyň içinde php_value mbstring.func_overload 0 kodyny ýazyp hem belläp bilersiňiz." +INSTL_NOTICEYOUCANSTILLINSTALL="
Siz soňunda sazlamary görensoň gurnamany dowam edip bilersiňiz. Siz eliňiz bilen kody ýüklemeli bolarsyňyz. Tekst meýdançasyna basyp kodlary saýlap täze tekst faýlyň içine ýerleşdiriň. Faýlyň adyna 'configuration.php' goýup saýtyň gözbaş bukjasyna ýükläň." +INSTL_OUTPUT_BUFFERING="Netijäniň Buforizatsýasy" +INSTL_PARSE_INI_FILE_AVAILABLE="INI Parser Goldawy" +INSTL_PHP_VERSION="PHP Wersiýa" +INSTL_PHP_VERSION_NEWER="PHP Wersiýa >= %s" +INSTL_REGISTER_GLOBALS="Globallar Registratsýasyny Öçür" +INSTL_SAFE_MODE="Howupsyz Usul" +INSTL_SESSION_AUTO_START="Sessiýany Awtomatiki Başla" +INSTL_WRITABLE="%s Ýazylmaga açyk" +INSTL_XML_SUPPORT="XML Goldawy" +INSTL_ZIP_SUPPORT_AVAILABLE="Ýerli ZIP goldawy" +INSTL_ZLIB_COMPRESSION_SUPPORT="Zlib Kiçeltme Goldawy" +INSTL_PROCESS_BUSY="Proses ugrunda. Garaşmagyňyzy haýyş edýäris ..." + +;Global strings +JADMINISTRATOR="Administrator" +JCHECK_AGAIN="Täzeden Barla" +JERROR="Näsazlyk" +JEMAIL="E-mail" +JGLOBAL_ISFREESOFTWARE="%s %s boýunça giňden ýaýradylýan erkin programma." +JGLOBAL_LANGUAGE_VERSION_NOT_PLATFORM="Dil bukjasy Joomla!-nyň su wersiýasyna gabat gelenok. Käbir setirler kem bolup biler." +JGLOBAL_SELECT_AN_OPTION="Opsiýa Saýlaň" +JGLOBAL_SELECT_NO_RESULTS_MATCH="Hiç hili netijä deň gelmedi" +JGLOBAL_SELECT_SOME_OPTIONS="Bir näçe opsiýa saýlaň" +JINVALID_TOKEN="Iň soňky haýyşyňyz kabul edilmedi sebäbi howupsyzlyk žetony dogry däl. Sahypany täzeläp täzeden sahypa girmäni haýyş edýäris." +JNEXT="Soňky" +JNO="Ýok" +JNOTICE="Bildiriş" +JOFF="Ýapyk" +JON="Açyk" +JPREVIOUS="Öňki" +JSITE="Saýt" +JUSERNAME="Ulanyjy ady" +JYES="Howa" + +; Framework strings necessary when no lang pack is available +JLIB_DATABASE_ERROR_CONNECT_MYSQL="MySQL-e baglanyp bilmedi." +JLIB_DATABASE_ERROR_DATABASE="Bazada ýalňyşlyk ýüze çykdy." +JLIB_DATABASE_ERROR_LOAD_DATABASE_DRIVER="Bazanyň Draýwerini ýükleme başarnyksyz geçdi: %s" +JLIB_ENVIRONMENT_SESSION_EXPIRED="Siziň sessýaňyz gutardy, sahypany täzeden ýüklemäni haýyş edýäris." +JLIB_FILESYSTEM_ERROR_COPY_FAILED="Kopýalama başarnyksyz geçdi." +JLIB_FILESYSTEM_ERROR_PATH_IS_NOT_A_FOLDER_FILES="JFolder: :files: Berlen ýol bukjanyň ýoly däl. Ýol: %s" +JLIB_FORM_FIELD_INVALID="Ýalňyş meýdan: " +JLIB_FORM_VALIDATE_FIELD_INVALID="Ýalňyş meýdan: %s" +JLIB_FORM_VALIDATE_FIELD_REQUIRED="Gerekli meýdan: %s" +JLIB_INSTALLER_ERROR_FAIL_COPY_FILE="JInstaller: :Gurna: Faýly kopýalama başarnyksyz geçdi %1$s dan %2$s." +JLIB_INSTALLER_NOT_ERROR="Eger TinyMCE baglanyşykly näsazlyklar ýüze çyksa dil(leriň) gurnamasynda hiç hili täsiri ýokdyr. Käbir dil bukjalary Joomla! 3.2.0-dan öňkiler aýratyn dil faýlaryny gurnar. Mundan soňky diller içinde ýerleşýär we mundan soň gurnamak gerekdirmeýär." +JLIB_UTIL_ERROR_CONNECT_DATABASE="JDatabase: :getInstance: Baza baglanyp bilmedi
joomla.library: %1$s - %2$s" + +; Strings for the language debugger +JDEBUG_LANGUAGE_FILES_IN_ERROR="Dil faýlar derňewinde näsazlyk çykdy" +JDEBUG_LANGUAGE_UNTRANSLATED_STRING="Terjime edilmedik setirler" +JNONE="Hiç zat" + +; Necessary for errors +ADMIN_EMAIL="Administratoryň Emaily" +ADMIN_PASSWORD="Administrator Paroly" +ADMIN_PASSWORD2="Admin Parolyny Tassyklaň" +SITE_NAME="Web Sahypanyň Ady" + +; Database types (allows for a more descriptive label than the internal name) +MYSQL="MySQL" +MYSQLI="MySQLi" +ORACLE="Oracle" +PDOMYSQL="MySQL (PDO)" +POSTGRESQL="PostgreSQL" +SQLAZURE="Microsoft SQL Azure" +SQLITE="SQLite" +SQLSRV="Microsoft SQL Serwer" diff --git a/installation/language/tk-TM/tk-TM.xml b/installation/language/tk-TM/tk-TM.xml new file mode 100644 index 0000000000000..af9adf12495de --- /dev/null +++ b/installation/language/tk-TM/tk-TM.xml @@ -0,0 +1,21 @@ + + + Turkmen + 3.4.4 + August 2015 + Shohrat Permanov + Copyright (C) 2005 - 2015 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + + + tk-TM.ini + + + Türkmençe (Türkmenistan) + tk-TM + 0 + + + \ No newline at end of file diff --git a/installation/sql/mysql/joomla.sql b/installation/sql/mysql/joomla.sql index 45be543507871..153f83c78d14e 100644 --- a/installation/sql/mysql/joomla.sql +++ b/installation/sql/mysql/joomla.sql @@ -1258,7 +1258,7 @@ INSERT INTO `#__menu` (`id`, `menutype`, `title`, `alias`, `note`, `path`, `link (5, 'menu', 'com_banners_clients', 'Clients', '', 'Banners/Clients', 'index.php?option=com_banners&view=clients', 'component', 0, 2, 2, 4, 0, '0000-00-00 00:00:00', 0, 0, 'class:banners-clients', 0, '', 6, 7, 0, '*', 1), (6, 'menu', 'com_banners_tracks', 'Tracks', '', 'Banners/Tracks', 'index.php?option=com_banners&view=tracks', 'component', 0, 2, 2, 4, 0, '0000-00-00 00:00:00', 0, 0, 'class:banners-tracks', 0, '', 8, 9, 0, '*', 1), (7, 'menu', 'com_contact', 'Contacts', '', 'Contacts', 'index.php?option=com_contact', 'component', 0, 1, 1, 8, 0, '0000-00-00 00:00:00', 0, 0, 'class:contact', 0, '', 11, 16, 0, '*', 1), -(8, 'menu', 'com_contact', 'Contacts', '', 'Contacts/Contacts', 'index.php?option=com_contact', 'component', 0, 7, 2, 8, 0, '0000-00-00 00:00:00', 0, 0, 'class:contact', 0, '', 12, 13, 0, '*', 1), +(8, 'menu', 'com_contact_contacts', 'Contacts', '', 'Contacts/Contacts', 'index.php?option=com_contact', 'component', 0, 7, 2, 8, 0, '0000-00-00 00:00:00', 0, 0, 'class:contact', 0, '', 12, 13, 0, '*', 1), (9, 'menu', 'com_contact_categories', 'Categories', '', 'Contacts/Categories', 'index.php?option=com_categories&extension=com_contact', 'component', 0, 7, 2, 6, 0, '0000-00-00 00:00:00', 0, 0, 'class:contact-cat', 0, '', 14, 15, 0, '*', 1), (10, 'menu', 'com_messages', 'Messaging', '', 'Messaging', 'index.php?option=com_messages', 'component', 0, 1, 1, 15, 0, '0000-00-00 00:00:00', 0, 0, 'class:messages', 0, '', 17, 22, 0, '*', 1), (11, 'menu', 'com_messages_add', 'New Private Message', '', 'Messaging/New Private Message', 'index.php?option=com_messages&task=message.add', 'component', 0, 10, 2, 15, 0, '0000-00-00 00:00:00', 0, 0, 'class:messages-add', 0, '', 18, 19, 0, '*', 1), diff --git a/installation/sql/postgresql/joomla.sql b/installation/sql/postgresql/joomla.sql index db9977c188c14..2adb2ed17f1e2 100644 --- a/installation/sql/postgresql/joomla.sql +++ b/installation/sql/postgresql/joomla.sql @@ -608,7 +608,7 @@ INSERT INTO "#__extensions" ("extension_id", "name", "type", "element", "folder" (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), -(452, 'plg_system_updatenotification', 'plugin', 'updatenotification', 'system', 0, 1, 1, 0, '', '', '', '', 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), (453, 'plg_editors-xtd_module', 'plugin', 'module', 'editors-xtd', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); -- Templates @@ -1209,7 +1209,7 @@ INSERT INTO "#__menu" ("id", "menutype", "title", "alias", "note", "path", "link (5, 'menu', 'com_banners_clients', 'Clients', '', 'Banners/Clients', 'index.php?option=com_banners&view=clients', 'component', 0, 2, 2, 4, 0, '1970-01-01 00:00:00', 0, 0, 'class:banners-clients', 0, '', 6, 7, 0, '*', 1), (6, 'menu', 'com_banners_tracks', 'Tracks', '', 'Banners/Tracks', 'index.php?option=com_banners&view=tracks', 'component', 0, 2, 2, 4, 0, '1970-01-01 00:00:00', 0, 0, 'class:banners-tracks', 0, '', 8, 9, 0, '*', 1), (7, 'menu', 'com_contact', 'Contacts', '', 'Contacts', 'index.php?option=com_contact', 'component', 0, 1, 1, 8, 0, '1970-01-01 00:00:00', 0, 0, 'class:contact', 0, '', 11, 16, 0, '*', 1), -(8, 'menu', 'com_contact', 'Contacts', '', 'Contacts/Contacts', 'index.php?option=com_contact', 'component', 0, 7, 2, 8, 0, '1970-01-01 00:00:00', 0, 0, 'class:contact', 0, '', 12, 13, 0, '*', 1), +(8, 'menu', 'com_contact_contacts', 'Contacts', '', 'Contacts/Contacts', 'index.php?option=com_contact', 'component', 0, 7, 2, 8, 0, '1970-01-01 00:00:00', 0, 0, 'class:contact', 0, '', 12, 13, 0, '*', 1), (9, 'menu', 'com_contact_categories', 'Categories', '', 'Contacts/Categories', 'index.php?option=com_categories&extension=com_contact', 'component', 0, 7, 2, 6, 0, '1970-01-01 00:00:00', 0, 0, 'class:contact-cat', 0, '', 14, 15, 0, '*', 1), (10, 'menu', 'com_messages', 'Messaging', '', 'Messaging', 'index.php?option=com_messages', 'component', 0, 1, 1, 15, 0, '1970-01-01 00:00:00', 0, 0, 'class:messages', 0, '', 17, 22, 0, '*', 1), (11, 'menu', 'com_messages_add', 'New Private Message', '', 'Messaging/New Private Message', 'index.php?option=com_messages&task=message.add', 'component', 0, 10, 2, 15, 0, '1970-01-01 00:00:00', 0, 0, 'class:messages-add', 0, '', 18, 19, 0, '*', 1), diff --git a/installation/sql/sqlazure/joomla.sql b/installation/sql/sqlazure/joomla.sql index 9fbc489f35330..c53304ceaace7 100644 --- a/installation/sql/sqlazure/joomla.sql +++ b/installation/sql/sqlazure/joomla.sql @@ -997,7 +997,7 @@ SELECT 450, 'plg_twofactorauth_yubikey', 'plugin', 'yubikey', 'twofactorauth', 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 UNION ALL -SELECT 452, 'plg_system_updatenotification', 'plugin', 'updatenotification', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0; +SELECT 452, 'plg_system_updatenotification', 'plugin', 'updatenotification', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 UNION ALL SELECT 453, 'plg_editors-xtd_module', 'plugin', 'module', 'editors-xtd', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0; @@ -1987,7 +1987,7 @@ SELECT 6, 'menu', 'com_banners_tracks', 'Tracks', '', 'Banners/Tracks', 'index.p UNION ALL SELECT 7, 'menu', 'com_contact', 'Contacts', '', 'Contacts', 'index.php?option=com_contact', 'component', 0, 1, 1, 8, 0, '1900-01-01 00:00:00', 0, 0, 'class:contact', 0, '', 11, 16, 0, '*', 1 UNION ALL -SELECT 8, 'menu', 'com_contact', 'Contacts', '', 'Contacts/Contacts', 'index.php?option=com_contact', 'component', 0, 7, 2, 8, 0, '1900-01-01 00:00:00', 0, 0, 'class:contact', 0, '', 12, 13, 0, '*', 1 +SELECT 8, 'menu', 'com_contact_contacts', 'Contacts', '', 'Contacts/Contacts', 'index.php?option=com_contact', 'component', 0, 7, 2, 8, 0, '1900-01-01 00:00:00', 0, 0, 'class:contact', 0, '', 12, 13, 0, '*', 1 UNION ALL SELECT 9, 'menu', 'com_contact_categories', 'Categories', '', 'Contacts/Categories', 'index.php?option=com_categories&extension=com_contact', 'component', 0, 7, 2, 6, 0, '1900-01-01 00:00:00', 0, 0, 'class:contact-cat', 0, '', 14, 15, 0, '*', 1 UNION ALL diff --git a/language/en-GB/en-GB.com_tags.ini b/language/en-GB/en-GB.com_tags.ini index ffde34f5d6336..8e47ed32816c0 100644 --- a/language/en-GB/en-GB.com_tags.ini +++ b/language/en-GB/en-GB.com_tags.ini @@ -9,4 +9,5 @@ COM_TAGS_MODIFIED_DATE="Modified Date" COM_TAGS_NO_ITEMS="No matching items were found." COM_TAGS_NO_TAGS="There are no tags." COM_TAGS_PUBLISHED_DATE="Published Date" +COM_TAGS_TAG_NOT_FOUND="Tag not found." COM_TAGS_TITLE_FILTER_LABEL="Enter Part of Title" \ No newline at end of file diff --git a/language/en-GB/en-GB.lib_joomla.ini b/language/en-GB/en-GB.lib_joomla.ini index 5301ad0994980..3fa7ce40818e0 100644 --- a/language/en-GB/en-GB.lib_joomla.ini +++ b/language/en-GB/en-GB.lib_joomla.ini @@ -635,6 +635,7 @@ JLIB_RULES_ALLOWED="Allowed" JLIB_RULES_ALLOWED_ADMIN="Allowed (Super User)" JLIB_RULES_CALCULATED_SETTING="Calculated Setting 2" JLIB_RULES_CONFLICT="Conflict" +JLIB_RULES_DATABASE_FAILURE="Failure by storing the data to the database." JLIB_RULES_DENIED="Denied" JLIB_RULES_GROUP="%s" JLIB_RULES_GROUPS="Groups" @@ -644,6 +645,8 @@ JLIB_RULES_NOT_ALLOWED="Not Allowed." JLIB_RULES_NOT_ALLOWED_ADMIN_CONFLICT="Conflict" JLIB_RULES_NOT_ALLOWED_LOCKED="Not Allowed (Locked)" JLIB_RULES_NOT_SET="Not Set" +JLIB_RULES_REQUEST_FAILURE="Failure by sending the data to server." +JLIB_RULES_SAVE_BEFORE_CHANGE_PERMISSIONS="Please save before change permissions." JLIB_RULES_SELECT_ALLOW_DENY_GROUP="Allow or deny %s for users in the %s group." JLIB_RULES_SELECT_SETTING="Select New Setting 1" JLIB_RULES_SETTING_NOTES="1. If you change the setting, it will apply to this and all child groups, components and content. Note that Denied will overrule any inherited setting and also the setting in any child group, component or content. In the case of a setting conflict, Deny will take precedence. Not Set is equivalent to Denied but can be changed in child groups, components and content.
2. If you select a new setting, select Save to refresh the calculated settings." diff --git a/language/en-GB/en-GB.xml b/language/en-GB/en-GB.xml index 2750ff289c614..ecdf13bc1692c 100644 --- a/language/en-GB/en-GB.xml +++ b/language/en-GB/en-GB.xml @@ -1,7 +1,7 @@ - + English (en-GB) - 3.4.6 + 3.5.0 2013-03-07 Joomla! Project admin@joomla.org diff --git a/language/en-GB/install.xml b/language/en-GB/install.xml index 470747b847dc3..8351782860e4d 100644 --- a/language/en-GB/install.xml +++ b/language/en-GB/install.xml @@ -1,8 +1,8 @@ - + English (United Kingdom) en-GB - 3.4.6 + 3.5.0 2013-03-07 Joomla! Project admin@joomla.org diff --git a/libraries/cms/application/cms.php b/libraries/cms/application/cms.php index 6c957aeb38327..b6e8c006450b0 100644 --- a/libraries/cms/application/cms.php +++ b/libraries/cms/application/cms.php @@ -233,10 +233,15 @@ public function enqueueMessage($msg, $type = 'message') } // For empty queue, if messages exists in the session, enqueue them first. - $this->getMessageQueue(); + $messages = $this->getMessageQueue(); - // Enqueue the message. - $this->_messageQueue[] = array('message' => $msg, 'type' => strtolower($type)); + $message = array('message' => $msg, 'type' => strtolower($type)); + + if (!in_array($message, $this->_messageQueue)) + { + // Enqueue the message. + $this->_messageQueue[] = $message; + } } /** diff --git a/libraries/cms/component/router/rules/menu.php b/libraries/cms/component/router/rules/menu.php new file mode 100644 index 0000000000000..793d7ccbe6a81 --- /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']) && $this->router->menu->getActive() && $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[$views[$view]->key]] = $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/rules/standard.php b/libraries/cms/component/router/rules/standard.php new file mode 100644 index 0000000000000..4f9768ca60459 --- /dev/null +++ b/libraries/cms/component/router/rules/standard.php @@ -0,0 +1,271 @@ +router = $router; + } + + /** + * Dummymethod to fullfill the interface requirements + * + * @param array &$query The query array to process + * + * @return void + * + * @since 3.4 + */ + public function preprocess(&$query) + { + } + + /** + * Parse the 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) + { + // Get the views and the currently active query vars + $views = $this->router->getViews(); + $active = $this->router->menu->getActive(); + $vars = array_merge($active->query, $vars); + + // We don't have a view or its not a view of this component! We stop here + if (!isset($vars['view']) || !isset($views[$vars['view']])) + { + return; + } + + // Copy the segments, so that we can iterate over all of them and at the same time modify the original segments + $temp_segments = $segments; + + // Iterate over the segments as long as a segment fits + foreach ($temp_segments as $segment) + { + // Our current view is nestable. We need to check first if the segment fits to that + if ($views[$vars['view']]->nestable) + { + if (is_callable(array($this->router, 'get' . ucfirst($views[$vars['view']]->name) . 'Id'))) + { + $key = call_user_func_array(array($this->router, 'get' . ucfirst($views[$vars['view']]->name) . 'Id'), array($segment, $vars)); + + // Did we get a proper key? If not, we need to look in the child-views + if ($key) + { + $vars[$views[$vars['view']]->key] = $key; + array_shift($segments); + continue; + } + } + else + { + // The router is not complete. The getKey() method is missing. + return; + } + } + + // Lets find the right view that belongs to this segment + $found = false; + foreach ($views[$vars['view']]->children as $view) + { + if (!$view->key) + { + if ($view->name == $segment) + { + // The segment is a view name + $parent = $views[$vars['view']]; + $vars['view'] = $view->name; + $found = true; + + if ($view->parent_key && isset($vars[$parent->key])) + { + $parent_key = $vars[$parent->key]; + unset($vars[$parent->key]); + $vars[$view->parent_key] = $parent_key; + } + + break; + } + } + else + { + if (is_callable(array($this->router, 'get' . ucfirst($view->name) . 'Id'))) + { + // Hand the data over to the router specific method and see if there is a content item that fits + $key = call_user_func_array(array($this->router, 'get' . ucfirst($view->name) . 'Id'), array($segment, $vars)); + + if ($key) + { + // Found the right view and the right item + $parent = $views[$vars['view']]; + $vars['view'] = $view->name; + $found = true; + + if ($view->parent_key && isset($vars[$parent->key])) + { + $parent_key = $vars[$parent->key]; + unset($vars[$parent->key]); + $vars[$view->parent_key] = $parent_key; + } + + $vars[$view->key] = $key; + + break; + } + } + } + } + + if (!$found) + { + return; + } + else + { + array_shift($segments); + } + } + } + + /** + * Build a standard 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) + { + // Get the menu item belonging to the Itemid that has been found + $item = $this->router->menu->getItem($query['Itemid']); + + if (!isset($query['view'])) + { + return; + } + + // Get all views for this component + $views = $this->router->getViews(); + + // Return directly when the URL of the Itemid is identical with the URL to build + if (isset($item->query['view']) && $item->query['view'] == $query['view']) + { + $view = $views[$query['view']]; + if (isset($item->query[$view->key]) && $item->query[$view->key] == (int) $query[$view->key]) + { + unset($query[$view->key]); + while ($view) + { + unset($query[$view->parent_key]); + $view = $view->parent; + } + unset($query['view']); + unset($query['layout']); + return; + } + } + + // Get the path from the view of the current URL and parse it to the menu item + $path = array_reverse($this->router->getPath($query)); + $found = false; + $found2 = false; + for ($i = 0, $j = count($path); $i < $j; $i++) + { + reset($path); + $view = key($path); + if ($found) + { + $ids = array_shift($path); + if ($views[$view]->nestable) + { + foreach (array_reverse($ids) as $id) + { + if ($found2) + { + $segments[] = str_replace(':', '-', $id); + } + else + { + if ((int) $item->query[$views[$view]->key] == (int) $id) + { + $found2 = true; + } + } + } + } + else + { + if (is_bool($ids)) + { + $segments[] = $views[$view]->name; + } + else + { + $segments[] = str_replace(':', '-', $ids[0]); + } + } + } + else + { + if ($item->query['view'] != $view) + { + array_shift($path); + } + else + { + if (!$views[$view]->nestable) + { + array_shift($path); + } + else + { + $i--; + $found2 = false; + } + $found = true; + } + } + unset($query[$views[$view]->parent_key]); + } + unset($query['layout']); + 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 index 73486e681ac62..d7a894e3df435 100644 --- a/libraries/cms/component/router/view.php +++ b/libraries/cms/component/router/view.php @@ -115,6 +115,10 @@ public function getPath($query) { $result[$view->name] = call_user_func_array(array($this, 'get' . ucfirst($view->name) . 'Segment'), array($query[$key], $query)); } + elseif ($view->key && isset($query[$view->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[$view->key], $query)); + } else { $result[$view->name] = true; @@ -229,6 +233,7 @@ public function build(&$query) { $rule->build($query, $segments); } + return $segments; } diff --git a/libraries/cms/html/formbehavior.php b/libraries/cms/html/formbehavior.php index 48f86a69b8d71..26dd5aae0a58d 100644 --- a/libraries/cms/html/formbehavior.php +++ b/libraries/cms/html/formbehavior.php @@ -131,6 +131,7 @@ public static function ajaxchosen(Registry $options, $debug = null) static::chosen($selector, $debug); $displayData = array( + 'url' => $url, 'debug' => $debug, 'options' => $options, 'selector' => $selector, diff --git a/libraries/cms/html/rules.php b/libraries/cms/html/rules.php index 0865050c1f9b9..780e615cf4534 100644 --- a/libraries/cms/html/rules.php +++ b/libraries/cms/html/rules.php @@ -9,10 +9,13 @@ defined('JPATH_PLATFORM') or die; +JLog::add('JHtmlRules is deprecated.', JLog::WARNING, 'deprecated'); + /** * Extended Utility class for all HTML drawing classes. * - * @since 1.6 + * @since 1.6 + * @deprecated 4.0 */ abstract class JHtmlRules { @@ -30,6 +33,7 @@ abstract class JHtmlRules * @see JAccess * @see JFormFieldRules * @since 1.6 + * @deprecated 4.0 */ public static function assetFormWidget($actions, $assetId = null, $parent = null, $control = 'jform[rules]', $idPrefix = 'jform_rules') { @@ -144,6 +148,7 @@ public static function assetFormWidget($actions, $assetId = null, $parent = null * @return integer The id of the parent asset * * @since 1.6 + * @deprecated 4.0 */ protected static function _getParentAssetId($assetId) { @@ -166,6 +171,7 @@ protected static function _getParentAssetId($assetId) * @return array Array of user groups * * @since 1.6 + * @deprecated 4.0 */ protected static function _getUserGroups() { @@ -209,6 +215,7 @@ protected static function _getUserGroups() * @return array An associative array of permissions and images * * @since 1.6 + * @deprecated 4.0 */ protected static function _getImagesArray() { diff --git a/libraries/cms/html/select.php b/libraries/cms/html/select.php index 0482b3d128a9e..67f86482f5871 100644 --- a/libraries/cms/html/select.php +++ b/libraries/cms/html/select.php @@ -283,17 +283,17 @@ public static function groupedlist($data, $name, $options = array()) elseif (is_object($group)) { // Sub-list is in a property of an object - $subList = $group->$options['group.items']; + $subList = $group->{$options['group.items']}; - if (isset($group->$options['group.label'])) + if (isset($group->{$options['group.label']})) { - $label = $group->$options['group.label']; + $label = $group->{$options['group.label']}; $noGroup = false; } - if (isset($options['group.id']) && isset($group->$options['group.id'])) + if (isset($options['group.id']) && isset($group->{$options['group.id']})) { - $id = $group->$options['group.id']; + $id = $group->{$options['group.id']}; $noGroup = false; } } @@ -696,7 +696,7 @@ public static function options($arr, $optKey = 'value', $optText = 'text', $sele { foreach ($options['list.select'] as $val) { - $key2 = is_object($val) ? $val->$options['option.key'] : $val; + $key2 = is_object($val) ? $val->{$options['option.key']} : $val; if ($key == $key2) { diff --git a/libraries/cms/layout/base.php b/libraries/cms/layout/base.php index 4e4f8f4ed4aaf..6a66167d29b77 100644 --- a/libraries/cms/layout/base.php +++ b/libraries/cms/layout/base.php @@ -27,6 +27,14 @@ class JLayoutBase implements JLayout */ protected $options = null; + /** + * Data for the layout + * + * @var array + * @since 3.5 + */ + protected $data = array(); + /** * Debug information messages * @@ -123,7 +131,7 @@ public function getDebugMessages() /** * Method to render the layout. * - * @param object $displayData Object which properties are used inside the layout file to build displayed output + * @param mixed $displayData Data to be used inside the layout file to build displayed output * * @return string The necessary HTML to display the layout * @@ -131,6 +139,12 @@ public function getDebugMessages() */ public function render($displayData) { + // Automatically merge any previously data set if $displayData is an array + if (is_array($displayData)) + { + $displayData = array_merge($this->data, $displayData); + } + return ''; } @@ -151,12 +165,134 @@ public function renderDebugMessages() * * @param string $message Message to save * - * @return void + * @return self * * @since 3.2 */ public function addDebugMessage($message) { $this->debugMessages[] = $message; + + return $this; + } + + /** + * Clear the debug messages array + * + * @return self + * + * @since 3.5 + */ + public function clearDebugMessages() + { + $this->debugMessages = array(); + + return $this; + } + + /** + * Render a layout with debug info + * + * @param mixed $data Data passed to the layout + * + * @return string + * + * @since 3.5 + */ + public function debug($data = array()) + { + $this->setDebug(true); + + $output = $this->render($data); + + $this->setDebug(false); + + return $output; + } + + /** + * Method to get the value from the data array + * + * @param string $key Key to search for in the data array + * @param mixed $defaultValue Default value to return if the key is not set + * + * @return mixed Value from the data array | defaultValue if doesn't exist + * + * @since 3.5 + */ + public function get($key, $defaultValue = null) + { + return isset($this->data[$key]) ? $this->data[$key] : $defaultValue; + } + + /** + * Get the data being rendered + * + * @return array + * + * @since 3.5 + */ + public function getData() + { + return $this->data; + } + + /** + * Check if debug mode is enabled + * + * @return boolean + * + * @since 3.5 + */ + public function isDebugEnabled() + { + return $this->getOptions()->get('debug', false) === true; + } + + /** + * Method to set a value in the data array. Example: $layout->set('items', $items); + * + * @param string $key Key for the data array + * @param mixed $value Value to assign to the key + * + * @return self + * + * @since 3.5 + */ + public function set($key, $value) + { + $this->data[(string) $key] = $value; + + return $this; + } + + /** + * Set the the data passed the layout + * + * @param array $data Array with the data for the layout + * + * @return self + * + * @since 3.5 + */ + public function setData(array $data) + { + $this->data = $data; + + return $this; + } + + /** + * Change the debug mode + * + * @param boolean $debug Enable / Disable debug + * + * @return void + * + * @since 3.5 + */ + public function setDebug($debug) + { + $this->options->set('debug', (boolean) $debug); } } diff --git a/libraries/cms/layout/file.php b/libraries/cms/layout/file.php index 6541661b475b2..83ae1a0ed7fc8 100644 --- a/libraries/cms/layout/file.php +++ b/libraries/cms/layout/file.php @@ -19,19 +19,33 @@ class JLayoutFile extends JLayoutBase { /** - * @var string Dot separated path to the layout file, relative to base path + * Cached layout paths + * + * @var array + * @since 3.5 + */ + protected static $cache = array(); + + /** + * Dot separated path to the layout file, relative to base path + * + * @var string * @since 3.0 */ protected $layoutId = ''; /** - * @var string Base path to use when loading layout files + * Base path to use when loading layout files + * + * @var string * @since 3.0 */ protected $basePath = null; /** - * @var string Full path to actual layout files, after possible template override check + * Full path to actual layout files, after possible template override check + * + * @var string * @since 3.0.3 */ protected $fullPath = null; @@ -76,27 +90,38 @@ public function __construct($layoutId, $basePath = null, $options = null) * * @since 3.0 */ - public function render($displayData) + public function render($displayData = array()) { - $layoutOutput = ''; + $this->clearDebugMessages(); + + // Inherit base output from parent class + $layoutOutput = parent::render($displayData); + + // Automatically merge any previously data set if $displayData is an array + if (is_array($displayData)) + { + $displayData = array_merge($this->data, $displayData); + } // Check possible overrides, and build the full path to layout file $path = $this->getPath(); - if ($this->options->get('debug', false)) + if ($this->isDebugEnabled()) { echo "
" . $this->renderDebugMessages() . "
"; } - // If there exists such a layout file, include it and collect its output - if (!empty($path)) + // Nothing to show + if (empty($path)) { - ob_start(); - include $path; - $layoutOutput = ob_get_contents(); - ob_end_clean(); + return $layoutOutput; } + ob_start(); + include $path; + $layoutOutput .= ob_get_contents(); + ob_end_clean(); + return $layoutOutput; } @@ -111,49 +136,83 @@ protected function getPath() { JLoader::import('joomla.filesystem.path'); - if (is_null($this->fullPath) && !empty($this->layoutId)) + $layoutId = $this->getLayoutId(); + $includePaths = $this->getIncludePaths(); + $suffixes = $this->getSuffixes(); + + $this->addDebugMessage('Layout: ' . $this->layoutId); + + if (!$layoutId) + { + $this->addDebugMessage('There is no active layout'); + + return null; + } + + if (!$includePaths) + { + $this->addDebugMessage('There are no folders to search for layouts: ' . $layoutId); + + return null; + } + + $hash = md5( + json_encode( + array( + 'paths' => $includePaths, + 'suffixes' => $suffixes + ) + ) + ); + + if (!empty(static::$cache[$layoutId][$hash])) { - $this->addDebugMessage('Layout: ' . $this->layoutId); + $this->addDebugMessage('Cached path: ' . static::$cache[$layoutId][$hash]); - // Refresh paths - $this->refreshIncludePaths(); + return static::$cache[$layoutId][$hash]; + } - $this->addDebugMessage('Include Paths: ' . print_r($this->includePaths, true)); + $this->addDebugMessage('Include Paths: ' . print_r($includePaths, true)); - $suffixes = $this->options->get('suffixes', array()); + // Search for suffixed versions. Example: tags.j31.php + if ($suffixes) + { + $this->addDebugMessage('Suffixes: ' . print_r($suffixes, true)); - // Search for suffixed versions. Example: tags.j31.php - if (!empty($suffixes)) + foreach ($suffixes as $suffix) { - $this->addDebugMessage('Suffixes: ' . print_r($suffixes, true)); + $rawPath = str_replace('.', '/', $this->layoutId) . '.' . $suffix . '.php'; + $this->addDebugMessage('Searching layout for: ' . $rawPath); - foreach ($suffixes as $suffix) + if ($foundLayout = JPath::find($this->includePaths, $rawPath)) { - $rawPath = str_replace('.', '/', $this->layoutId) . '.' . $suffix . '.php'; - $this->addDebugMessage('Searching layout for: ' . $rawPath); + $this->addDebugMessage('Found layout: ' . $this->fullPath); - if ($this->fullPath = JPath::find($this->includePaths, $rawPath)) - { - $this->addDebugMessage('Found layout: ' . $this->fullPath); + static::$cache[$layoutId][$hash] = $foundLayout; - return $this->fullPath; - } + return static::$cache[$layoutId][$hash]; } } + } - // Standard version - $rawPath = str_replace('.', '/', $this->layoutId) . '.php'; - $this->addDebugMessage('Searching layout for: ' . $rawPath); + // Standard version + $rawPath = str_replace('.', '/', $this->layoutId) . '.php'; + $this->addDebugMessage('Searching layout for: ' . $rawPath); - $this->fullPath = JPath::find($this->includePaths, $rawPath); + $foundLayout = JPath::find($this->includePaths, $rawPath); - if ($this->fullPath) - { - $this->addDebugMessage('Found layout: ' . $this->fullPath); - } + if (!$foundLayout) + { + $this->addDebugMessage('Unable to find layout: ' . $layoutId); + + return null; } - return $this->fullPath; + $this->addDebugMessage('Found layout: ' . $foundLayout); + + static::$cache[$layoutId][$hash] = $foundLayout; + + return static::$cache[$layoutId][$hash]; } /** @@ -161,13 +220,15 @@ protected function getPath() * * @param string $path The path to search for layouts * - * @return void + * @return self * * @since 3.2 */ public function addIncludePath($path) { $this->addIncludePaths($path); + + return $this; } /** @@ -175,23 +236,136 @@ public function addIncludePath($path) * * @param string $paths The path or array of paths to search for layouts * - * @return void + * @return self * * @since 3.2 */ public function addIncludePaths($paths) { - if (!empty($paths)) + if (empty($paths)) { - if (is_array($paths)) - { - $this->includePaths = array_unique(array_merge($paths, $this->includePaths)); - } - else - { - array_unshift($this->includePaths, $paths); - } + return $this; + } + + $includePaths = $this->getIncludePaths(); + + if (is_array($paths)) + { + $includePaths = array_unique(array_merge($paths, $includePaths)); + } + else + { + array_unshift($includePaths, $paths); + } + + $this->setIncludePaths($includePaths); + + return $this; + } + + /** + * Clear the include paths + * + * @return self + * + * @since 3.5 + */ + public function clearIncludePaths() + { + $this->includePaths = array(); + + return $this; + } + + /** + * Get the active include paths + * + * @return array + * + * @since 3.5 + */ + public function getIncludePaths() + { + if (empty($this->includePaths)) + { + $this->includePaths = $this->getDefaultIncludePaths(); } + + return $this->includePaths; + } + + /** + * Get the active layout id + * + * @return string + * + * @since 3.5 + */ + public function getLayoutId() + { + return $this->layoutId; + } + + /** + * Get the active suffixes + * + * @return array + * + * @since 3.5 + */ + public function getSuffixes() + { + return $this->getOptions()->get('suffixes', array()); + } + + /** + * Load the automatically generated language suffixes. + * Example: array('es-ES', 'es', 'ltr') + * + * @return self + * + * @since 3.5 + */ + public function loadLanguageSuffixes() + { + $lang = JFactory::getLanguage(); + + $langTag = $lang->getTag(); + $langParts = explode('-', $langTag); + + $suffixes = array($langTag, $langParts[0]); + $suffixes[] = $lang->isRTL() ? 'rtl' : 'ltr'; + + $this->setSuffixes($suffixes); + + return $this; + } + + /** + * Load the automatically generated version suffixes. + * Example: array('j311', 'j31', 'j3') + * + * @return self + * + * @since 3.5 + */ + public function loadVersionSuffixes() + { + $cmsVersion = new JVersion; + + // Example j311 + $fullVersion = 'j' . str_replace('.', '', $cmsVersion->getShortVersion()); + + // Create suffixes like array('j311', 'j31', 'j3') + $suffixes = array( + $fullVersion, + substr($fullVersion, 0, 3), + substr($fullVersion, 0, 2), + ); + + $this->setSuffixes(array_unique($suffixes)); + + return $this; } /** @@ -199,13 +373,15 @@ public function addIncludePaths($paths) * * @param string $path The path to remove from the layout search * - * @return void + * @return self * * @since 3.2 */ public function removeIncludePath($path) { $this->removeIncludePaths($path); + + return $this; } /** @@ -213,7 +389,7 @@ public function removeIncludePath($path) * * @param string $paths The path or array of paths to remove for the layout search * - * @return void + * @return self * * @since 3.2 */ @@ -225,6 +401,8 @@ public function removeIncludePaths($paths) $this->includePaths = array_diff($this->includePaths, $paths); } + + return $this; } /** @@ -241,14 +419,11 @@ protected function validComponent($option = null) // By default we will validate the active component $component = ($option !== null) ? $option : $this->options->get('component', null); - if (!empty($component)) + // Valid option format + if (!empty($component) && substr_count($component, 'com_')) { - // Valid option format - if (substr_count($component, 'com_')) - { - // Latest check: component exists and is enabled - return JComponentHelper::isEnabled($component); - } + // Latest check: component exists and is enabled + return JComponentHelper::isEnabled($component); } return false; @@ -334,72 +509,132 @@ public function setClient($client) * * @param string $layoutId Layout to render * - * @return void + * @return self * * @since 3.2 + * + * @deprecated 3.5 Use setLayoutId() */ public function setLayout($layoutId) + { + // Log usage of deprecated function + JLog::add(__METHOD__ . '() is deprecated, use JLayoutFile::setLayoutId() instead.', JLog::WARNING, 'deprecated'); + + return $this->setLayoutId($layoutId); + } + + /** + * Set the active layout id + * + * @param string $layoutId Layout identifier + * + * @return self + * + * @since 3.5 + */ + public function setLayoutId($layoutId) { $this->layoutId = $layoutId; $this->fullPath = null; + + return $this; } /** * Refresh the list of include paths * - * @return void + * @return self * * @since 3.2 + * + * @deprecated 3.5 Use JLayoutFile::clearIncludePaths() */ protected function refreshIncludePaths() { - // Reset includePaths - $this->includePaths = array(); + // Log usage of deprecated function + JLog::add(__METHOD__ . '() is deprecated, use JLayoutFile::clearIncludePaths() instead.', JLog::WARNING, 'deprecated'); + + $this->clearIncludePaths(); + + return $this; + } - // (1 - lower priority) Frontend base layouts - $this->addIncludePaths(JPATH_ROOT . '/layouts'); + /** + * Get the default array of include paths + * + * @return array + * + * @since 3.5 + */ + public function getDefaultIncludePaths() + { + // Reset includePaths + $paths = array(); - // (2) Standard Joomla! layouts overriden - $this->addIncludePaths(JPATH_THEMES . '/' . JFactory::getApplication()->getTemplate() . '/html/layouts'); + // (1 - highest priority) Received a custom high priority path + if (!is_null($this->basePath)) + { + $paths[] = rtrim($this->basePath, DIRECTORY_SEPARATOR); + } // Component layouts & overrides if exist $component = $this->options->get('component', null); if (!empty($component)) { + // (2) Component template overrides path + $paths[] = JPATH_THEMES . '/' . JFactory::getApplication()->getTemplate() . '/html/layouts/' . $component; + // (3) Component path if ($this->options->get('client') == 0) { - $this->addIncludePaths(JPATH_SITE . '/components/' . $component . '/layouts'); + $paths[] = JPATH_SITE . '/components/' . $component . '/layouts'; } else { - $this->addIncludePaths(JPATH_ADMINISTRATOR . '/components/' . $component . '/layouts'); + $paths[] = JPATH_ADMINISTRATOR . '/components/' . $component . '/layouts'; } - - // (4) Component template overrides path - $this->addIncludePath(JPATH_THEMES . '/' . JFactory::getApplication()->getTemplate() . '/html/layouts/' . $component); } - // (5 - highest priority) Received a custom high priority path ? - if (!is_null($this->basePath)) - { - $this->addIncludePath(rtrim($this->basePath, DIRECTORY_SEPARATOR)); - } + // (4) Standard Joomla! layouts overriden + $paths[] = JPATH_THEMES . '/' . JFactory::getApplication()->getTemplate() . '/html/layouts'; + + // (5 - lower priority) Frontend base layouts + $paths[] = JPATH_ROOT . '/layouts'; + + return $paths; } /** - * Change the debug mode + * Set the include paths to search for layouts * - * @param boolean $debug Enable / Disable debug + * @param array $paths Array with paths to search in * - * @return void + * @return self * - * @since 3.2 + * @since 3.5 */ - public function setDebug($debug) + public function setIncludePaths($paths) { - $this->options->set('debug', (boolean) $debug); + $this->includePaths = (array) $paths; + + return $this; + } + + /** + * Set suffixes to search layouts + * + * @param mixed $suffixes String with a single suffix or 'auto' | 'none' or array of suffixes + * + * @return self + * + * @since 3.5 + */ + public function setSuffixes(array $suffixes) + { + $this->options->set('suffixes', $suffixes); + + return $this; } /** diff --git a/libraries/cms/layout/helper.php b/libraries/cms/layout/helper.php index ca9d4107e8efc..a89681639f6b9 100644 --- a/libraries/cms/layout/helper.php +++ b/libraries/cms/layout/helper.php @@ -26,6 +26,30 @@ class JLayoutHelper */ public static $defaultBasePath = ''; + /** + * Method to render a layout with debug info + * + * @param string $layoutFile Dot separated path to the layout file, relative to base path + * @param object $displayData Object which properties are used inside the layout file to build displayed output + * @param string $basePath Base path to use when loading layout files + * @param mixed $options Optional custom options to load. Registry or array format + * + * @return string + * + * @since 3.5 + */ + public static function debug($layoutFile, $displayData = null, $basePath = '', $options = null) + { + $basePath = empty($basePath) ? self::$defaultBasePath : $basePath; + + // Make sure we send null to JLayoutFile if no path set + $basePath = empty($basePath) ? null : $basePath; + $layout = new JLayoutFile($layoutFile, $basePath, $options); + $renderedLayout = $layout->debug($displayData); + + return $renderedLayout; + } + /** * Method to render the layout. * diff --git a/libraries/cms/menu/site.php b/libraries/cms/menu/site.php index 74efe095e170a..86418af845eaa 100644 --- a/libraries/cms/menu/site.php +++ b/libraries/cms/menu/site.php @@ -140,7 +140,7 @@ public function getItems($attributes, $values, $firstonly = false) if (JLanguageMultilang::isEnabled()) { $attributes[] = 'language'; - $values[] = array($this->language->getTag(), '*'); + $values[] = array(JFactory::getLanguage()->getTag(), '*'); } } elseif ($values[$key] === null) diff --git a/libraries/cms/version/version.php b/libraries/cms/version/version.php index 8992fcdb44301..6955df1f3d5e7 100644 --- a/libraries/cms/version/version.php +++ b/libraries/cms/version/version.php @@ -38,7 +38,7 @@ final class JVersion * @var string * @since 3.5 */ - const DEV_LEVEL = '6-dev'; + const DEV_LEVEL = '0-dev'; /** * Development status. diff --git a/libraries/joomla/date/date.php b/libraries/joomla/date/date.php index 938654e724a8d..645e07f2ebd72 100644 --- a/libraries/joomla/date/date.php +++ b/libraries/joomla/date/date.php @@ -287,7 +287,7 @@ public function format($format, $local = false, $translate = true) } // If the returned time should not be local use GMT. - if ($local == false) + if ($local == false && !empty(self::$gmt)) { parent::setTimezone(self::$gmt); } @@ -319,7 +319,7 @@ public function format($format, $local = false, $translate = true) } } - if ($local == false) + if ($local == false && !empty($this->tz)) { parent::setTimezone($this->tz); } diff --git a/libraries/joomla/feed/factory.php b/libraries/joomla/feed/factory.php index 2cd47f78622d3..66915e795bcf7 100644 --- a/libraries/joomla/feed/factory.php +++ b/libraries/joomla/feed/factory.php @@ -41,24 +41,26 @@ public function getFeed($uri) // Open the URI within the stream reader. if (!@$reader->open($uri, null, LIBXML_NOERROR | LIBXML_ERR_NONE | LIBXML_NOWARNING)) { - // If allow_url_fopen is enabled - if (ini_get('allow_url_fopen')) + // Retry with JHttpFactory that allow using CURL and Sockets as alternative method when available + + // Adding a valid user agent string, otherwise some feed-servers returning a error + $options = new \joomla\Registry\Registry; + $options->set('userAgent', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0'); + + $connector = JHttpFactory::getHttp($options); + $feed = $connector->get($uri); + + if ($feed->code != 200) { - // This is an error throw new RuntimeException('Unable to open the feed.'); } - else - { - // Retry with JHttpFactory that allow using CURL and Sockets as alternative method when available - $connector = JHttpFactory::getHttp(); - $feed = $connector->get($uri); - // Set the value to the XMLReader parser - if (!$reader->xml($feed->body, null, LIBXML_NOERROR | LIBXML_ERR_NONE | LIBXML_NOWARNING)) - { - throw new RuntimeException('Unable to parse the feed.'); - } + // Set the value to the XMLReader parser + if (!$reader->xml($feed->body, null, LIBXML_NOERROR | LIBXML_ERR_NONE | LIBXML_NOWARNING)) + { + throw new RuntimeException('Unable to parse the feed.'); } + } try diff --git a/libraries/joomla/form/fields/rules.php b/libraries/joomla/form/fields/rules.php index 6621df45f31a1..3605449def8b6 100644 --- a/libraries/joomla/form/fields/rules.php +++ b/libraries/joomla/form/fields/rules.php @@ -138,6 +138,14 @@ protected function getInput() { JHtml::_('bootstrap.tooltip'); + // Add Javascript for permission change + JHtml::_('script', 'media/system/js/permissions.min.js', false, false, false, false, true); + + // Add JText for error messages + JText::script('JLIB_RULES_REQUEST_FAILURE'); + JText::script('JLIB_RULES_SAVE_BEFORE_CHANGE_PERMISSIONS'); + JText::script('JLIB_RULES_REQUEST_FAILURE'); + // Initialise some field attributes. $section = $this->section; $component = $this->component; @@ -266,7 +274,7 @@ protected function getInput() $html[] = ''; - $html[] = '",t.writeln(o)},window.changeDynaList=function(e,n,r,i,s){var o=t.adminForm[e],u=r==i,a,f,l,c;while(o.firstChild)o.removeChild(o.firstChild);a=0;for(f in n){if(!n.hasOwnProperty(f))continue;l=n[f];if(l[0]!=r)continue;c=new Option,c.value=l[1],c.text=l[2];if(u&&s==c.value||!u&&a===0)c.selected=!0;o.options[a++]=c}o.length=a},window.radioGetCheckedValue=function(e){if(!e)return"";var t=e.length,n;if(t===undefined)return e.checked?e.value:"";for(n=0;n-1?r.options[i].value:null},window.listItemTask=function(e,n){var r=t.adminForm,i=0,s,o=r[e];if(!o)return!1;for(;;){s=r["cb"+i];if(!s)break;s.checked=!1,i++}return o.checked=!0,r.boxchecked.value=1,window.submitform(n),!1},window.submitbutton=function(t){e.submitbutton(t)},window.submitform=function(t){e.submitform(t)},window.saveorder=function(e,t){window.checkAll_button(e,t)},window.checkAll_button=function(n,r){r=r?r:"saveorder";var i,s;for(i=0;i<=n;i++){s=t.adminForm["cb"+i];if(!s){alert("You cannot change the order of items, as an item in the list is `Checked Out`");return}s.checked=!0}e.submitform(r)}}(Joomla,document); \ No newline at end of file +Joomla=window.Joomla||{},Joomla.editors=Joomla.editors||{},Joomla.editors.instances=Joomla.editors.instances||{},function(e,t){"use strict";e.submitform=function(e,n,i){n||(n=t.getElementById("adminForm")),e&&(n.task.value=e),n.noValidate=!i;var o=t.createElement("input");o.style.display="none",o.type="submit",n.appendChild(o).click(),n.removeChild(o)},e.submitbutton=function(t){e.submitform(t)},e.JText={strings:{},_:function(e,t){return"undefined"!=typeof this.strings[e.toUpperCase()]?this.strings[e.toUpperCase()]:t},load:function(e){for(var t in e)e.hasOwnProperty(t)&&(this.strings[t.toUpperCase()]=e[t]);return this}},e.replaceTokens=function(e){if(/^[0-9A-F]{32}$/i.test(e)){var n,i,o,r=t.getElementsByTagName("input");for(n=0,o=r.length;o>n;n++)i=r[n],"hidden"==i.type&&"1"==i.value&&32==i.name.length&&(i.name=e)}},e.isEmail=function(e){var t=/^[\w.!#$%&’*+\/=?^`{|}~-]+@[a-z0-9-]+(?:\.[a-z0-9-]{2,})+$/i;return t.test(e)},e.checkAll=function(e,t){if(!e.form)return!1;t=t?t:"cb";var n,i,o,r=0;for(n=0,o=e.form.elements.length;o>n;n++)i=e.form.elements[n],i.type==e.type&&0===i.id.indexOf(t)&&(i.checked=e.checked,r+=i.checked?1:0);return e.form.boxchecked&&(e.form.boxchecked.value=r),!0},e.renderMessages=function(n){e.removeMessages();var i,o,r,a,l,s,d,c=t.getElementById("system-message-container");for(i in n)if(n.hasOwnProperty(i)){for(o=n[i],r=t.createElement("div"),r.className="alert alert-"+i,a=e.JText._(i),"undefined"!=typeof a&&(l=t.createElement("h4"),l.className="alert-heading",l.innerHTML=e.JText._(i),r.appendChild(l)),s=o.length-1;s>=0;s--)d=t.createElement("p"),d.innerHTML=o[s],r.appendChild(d);c.appendChild(r)}},e.removeMessages=function(){for(var e=t.getElementById("system-message-container");e.firstChild;)e.removeChild(e.firstChild);e.style.display="none",e.offsetHeight,e.style.display=""},e.isChecked=function(e,n){if("undefined"==typeof n&&(n=t.getElementById("adminForm")),n.boxchecked.value+=e?1:-1,n.elements["checkall-toggle"]){var i,o,r,a=!0;for(i=0,r=n.elements.length;r>i;i++)if(o=n.elements[i],"checkbox"==o.type&&"checkall-toggle"!=o.name&&!o.checked){a=!1;break}n.elements["checkall-toggle"].checked=a}},e.popupWindow=function(e,t,n,i,o){var r=(screen.width-n)/2,a=(screen.height-i)/2,l="height="+i+",width="+n+",top="+a+",left="+r+",scrollbars="+o+",resizable";window.open(e,t,l).window.focus()},e.tableOrdering=function(n,i,o,r){"undefined"==typeof r&&(r=t.getElementById("adminForm")),r.filter_order.value=n,r.filter_order_Dir.value=i,e.submitform(o,r)},window.writeDynaList=function(e,n,i,o,r){var a,l,s,d="",t.writeln(d)},window.changeDynaList=function(e,n,i,o,r){for(var a,l,s,d,c=t.adminForm[e],u=i==o;c.firstChild;)c.removeChild(c.firstChild);a=0;for(l in n)n.hasOwnProperty(l)&&(s=n[l],s[0]==i&&(d=new Option,d.value=s[1],d.text=s[2],(u&&r==d.value||!u&&0===a)&&(d.selected=!0),c.options[a++]=d));c.length=a},window.radioGetCheckedValue=function(e){if(!e)return"";var t,n=e.length;if(void 0===n)return e.checked?e.value:"";for(t=0;n>t;t++)if(e[t].checked)return e[t].value;return""},window.getSelectedValue=function(e,n){var i=t[e][n],o=i.selectedIndex;return null!==o&&o>-1?i.options[o].value:null},window.listItemTask=function(e,n){var i,o=t.adminForm,r=0,a=o[e];if(!a)return!1;for(;;){if(i=o["cb"+r],!i)break;i.checked=!1,r++}return a.checked=!0,o.boxchecked.value=1,window.submitform(n),!1},window.submitbutton=function(t){e.submitbutton(t)},window.submitform=function(t){e.submitform(t)},window.saveorder=function(e,t){window.checkAll_button(e,t)},window.checkAll_button=function(n,i){i=i?i:"saveorder";var o,r;for(o=0;n>=o;o++){if(r=t.adminForm["cb"+o],!r)return void alert("You cannot change the order of items, as an item in the list is `Checked Out`");r.checked=!0}e.submitform(i)}}(Joomla,document); \ No newline at end of file diff --git a/media/system/js/permissions.js b/media/system/js/permissions.js new file mode 100644 index 0000000000000..f26fa6476996b --- /dev/null +++ b/media/system/js/permissions.js @@ -0,0 +1,102 @@ +/** + * Function to send Permissions via Ajax to Com-Config Application Controller + */ +function sendPermissions(event) { + // set the icon while storing the values + var icon = document.getElementById('icon_' + this.id); + icon.removeAttribute('class'); + icon.setAttribute('style', 'background: url(../media/system/images/modal/spinner.gif); display: inline-block; width: 16px; height: 16px'); + + //get values and prepare GET-Parameter + var id = this.id.split('_'); + var asset = 'not'; + var component = getUrlParam('component'); + var extension = getUrlParam('extension'); + var option = getUrlParam('option'); + var view = getUrlParam('view'); + var title = component; + var value = this.value; + + if (option == 'com_config' && component == false && extension == false) + { + asset = 'com_config'; + } + else if (extension == false && view == 'component'){ + asset = component; + } + else if (extension != false && view != false){ + asset = extension + '.' + view + '.' + getUrlParam('id'); + title = document.getElementById('jform_title').value; + } + else if (extension == false && view != false){ + asset = option + '.' + view + '.' + getUrlParam('id'); + title = document.getElementById('jform_title').value; + } + + var data = '&comp=' + asset + '&action=' + id[2] + '&rule=' + id[3] + '&value=' + value + '&title=' + title; + var url = 'index.php?option=com_config&task=config.store&format=raw' + data; + + // doing ajax request + jQuery.ajax({ + type: 'GET', + url: url, + datatype: 'JSON' + }).success(function (response) { + var element = event.target; + var resp = JSON.parse(response); + if (resp.data == 'true') + { + icon.removeAttribute('style'); + icon.setAttribute('class', 'icon-save'); + if (value == '1') + { + jQuery(element).parents().next('td').find('span') + .removeClass('label label-important').addClass('label label-success') + .html('Allowed'); + } + else + { + jQuery(element).parents().next('td').find('span') + .removeClass('label label-success').addClass('label label-important') + .html('Not Allowed.'); + } + } + else + { + var msg = { error: [Joomla.JText._('JLIB_RULES_DATABASE_FAILURE ')] }; + Joomla.renderMessages(msg); + icon.removeAttribute('style'); + icon.setAttribute('class', 'icon-cancel'); + } + if (resp.message == 0) + { + var msg = { error: [Joomla.JText._('JLIB_RULES_SAVE_BEFORE_CHANGE_PERMISSIONS')] }; + Joomla.renderMessages(msg); + icon.removeAttribute('style'); + icon.setAttribute('class', 'icon-cancel'); + } + }).fail(function() { + //set cancel icon on http failure + var msg = { error: [Joomla.JText._('JLIB_RULES_REQUEST_FAILURE')] }; + Joomla.renderMessages(msg); + icon.removeAttribute('style'); + icon.setAttribute('class', 'icon-cancel'); + }) +} + +/** + * Function to get parameters out of the url + */ +function getUrlParam(variable) { + var query = window.location.search.substring(1); + var vars = query.split('&'); + for (var i=0;i 'CASE WHEN (a.modified = ' . $db->quote($db->getNullDate()) . ') THEN a.created ELSE a.modified END', 'c_dsc' => 'a.created', 'p_dsc' => 'a.publish_up', - 'random' => 'RAND()', + 'random' => $db->getQuery(true)->Rand(), ); $ordering = JArrayHelper::getValue($order_map, $params->get('ordering'), 'a.publish_up'); $dir = 'DESC'; diff --git a/modules/mod_articles_news/helper.php b/modules/mod_articles_news/helper.php index 3d1ad52c80b56..8a04cef828d25 100644 --- a/modules/mod_articles_news/helper.php +++ b/modules/mod_articles_news/helper.php @@ -70,12 +70,13 @@ public static function getList(&$params) if (trim($ordering) == 'rand()') { - $model->setState('list.direction', ''); + $model->setState('list.ordering', JFactory::getDbo()->getQuery(true)->Rand()); } else { $direction = $params->get('direction', 1) ? 'DESC' : 'ASC'; $model->setState('list.direction', $direction); + $model->setState('list.ordering', $ordering); } // Retrieve Content diff --git a/modules/mod_login/tmpl/default.php b/modules/mod_login/tmpl/default.php index 1f2b37337a5d5..f68f303393582 100644 --- a/modules/mod_login/tmpl/default.php +++ b/modules/mod_login/tmpl/default.php @@ -98,16 +98,16 @@ diff --git a/modules/mod_tags_similar/helper.php b/modules/mod_tags_similar/helper.php index 06713c02258de..cff87dc7040c8 100644 --- a/modules/mod_tags_similar/helper.php +++ b/modules/mod_tags_similar/helper.php @@ -135,7 +135,7 @@ public static function getList(&$params) if ($ordering == 'random' || $ordering == 'countrandom') { - $query->order('RAND()'); + $query->order($query->Rand()); } $db->setQuery($query, 0, $maximum); diff --git a/phpunit.xml.dist b/phpunit.xml.dist index b9df133639d4a..1f1c11732c0e8 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -33,10 +33,10 @@ - - + --> diff --git a/plugins/captcha/recaptcha/recaptcha.php b/plugins/captcha/recaptcha/recaptcha.php index ad497cc192088..967a369a8a9c0 100644 --- a/plugins/captcha/recaptcha/recaptcha.php +++ b/plugins/captcha/recaptcha/recaptcha.php @@ -38,8 +38,6 @@ class PlgCaptchaRecaptcha extends JPlugin */ public function onInit($id = 'dynamic_recaptcha_1') { - JHtml::_('jquery.framework'); - $pubkey = $this->params->get('public_key', ''); if ($pubkey == null || $pubkey == '') @@ -49,23 +47,19 @@ public function onInit($id = 'dynamic_recaptcha_1') if ($this->params->get('version', '1.0') == '1.0') { - $theme = $this->params->get('theme', 'clean'); - $file = 'https://www.google.com/recaptcha/api/js/recaptcha_ajax.js'; + JHtml::_('jquery.framework'); + + $theme = $this->params->get('theme', 'clean'); + $file = 'https://www.google.com/recaptcha/api/js/recaptcha_ajax.js'; - $document = 'jQuery( document ).ready(function() - {Recaptcha.create("' . $pubkey . '", "' . $id . '", {theme: "' . $theme . '",' . $this->_getLanguage() . 'tabindex: 0});});'; + JFactory::getDocument()->addScriptDeclaration('jQuery( document ).ready(function() + {Recaptcha.create("' . $pubkey . '", "' . $id . '", {theme: "' . $theme . '",' . $this->_getLanguage() . 'tabindex: 0});});'); } else { - $theme = $this->params->get('theme2', 'light'); - $file = 'https://www.google.com/recaptcha/api.js?hl=' . JFactory::getLanguage()->getTag() . '&render=explicit'; - - $document = 'jQuery(document).ready(function($) {$(window).load(function() - {grecaptcha.render("' . $id . '", {sitekey: "' . $pubkey . '", theme: "' . $theme . '"}); - });});'; + $file = 'https://www.google.com/recaptcha/api.js?hl=' . JFactory::getLanguage()->getTag(); } - JFactory::getDocument()->addScriptDeclaration($document); JHtml::_('script', $file); return true; @@ -85,7 +79,15 @@ public function onInit($id = 'dynamic_recaptcha_1') */ public function onDisplay($name = null, $id = 'dynamic_recaptcha_1', $class = '') { - return '
'; + if ($this->params->get('version', '1.0') == '1.0') + { + return '
'; + } + else + { + return '
'; + } } /** diff --git a/plugins/editors/tinymce/tinymce.php b/plugins/editors/tinymce/tinymce.php index c9751082b544c..86f3add3ebc41 100644 --- a/plugins/editors/tinymce/tinymce.php +++ b/plugins/editors/tinymce/tinymce.php @@ -616,15 +616,64 @@ public function onInit() $btnsNames = $buttons['names']; $tinyBtns = $buttons['script']; - // Prepare config variables + // Drag and drop Images + $allowImgPaste = "false"; + $dragDropPlg = ''; + $dragdrop = $this->params->get('drag_drop', 1); + $user = JFactory::getUser(); + + if ($dragdrop && $user->authorise('core.create', 'com_media')) + { + $allowImgPaste = "true"; + $isSubDir = ''; + $session = JFactory::getSession(); + $uploadUrl = JUri::base() . 'index.php?option=com_media&task=file.upload&tmpl=component&' + . $session->getName() . '=' . $session->getId() + . '&' . JSession::getFormToken() . '=1' + . '&asset=image&format=json'; + + if (JFactory::getApplication()->isSite()) + { + $uploadUrl = htmlentities($uploadUrl, null, 'UTF-8', null); + } + + // Is Joomla installed in subdirectory + if (JUri::root(true) != '/') + { + $isSubDir = JUri::root(true); + } + + // Get specific path + $tempPath = $this->params->get('path', ''); + + if (!empty($tempPath)) + { + $tempPath = rtrim($tempPath, '/'); + $tempPath = ltrim($tempPath, '/'); + } + + $dragDropPlg = 'jdragdrop'; + + JText::script('PLG_TINY_ERR_UNSUPPORTEDBROWSER'); + JFactory::getDocument()->addScriptDeclaration( + " + var setCustomDir = '" . $isSubDir . "'; + var mediaUploadPath = '" . $tempPath . "'; + var uploadUri = '" . $uploadUrl . "'; + " + ); + } + + // Prepare config variables $plugins = implode(',', $plugins); $elements = implode(',', $elements); // Prepare config variables - $toolbar1 = implode(' ', $toolbar1_add); - $toolbar2 = implode(' ', $toolbar2_add); - $toolbar3 = implode(' ', $toolbar3_add); - $toolbar4 = implode(' ', $toolbar4_add); + $toolbar1 = implode(' ', $toolbar1_add) . ' | ' + . implode(' ', $toolbar2_add) . ' | ' + . implode(' ', $toolbar3_add) . ' | ' + . implode(' ', $toolbar4_add) . ' | ' + . implode(" | ", $btnsNames); $toolbar5 = implode(" | ", $btnsNames); // The buttons script @@ -669,9 +718,8 @@ public function onInit() theme : \"$theme\", schema: \"html5\", menubar: false, - toolbar1: \"bold italics underline strikethrough | undo redo | bullist numlist\", - toolbar2: \"$toolbar5 | code\", - plugins: \"code\", + toolbar1: \"bold italics underline strikethrough | undo redo | bullist numlist | $toolbar5 | code\", + plugins: \"$dragDropPlg code\", // Cleanup/Output inline_styles : true, gecko_spellcheck : true, @@ -686,7 +734,8 @@ public function onInit() document_base_url : \"" . JUri::root() . "\", setup: function (editor) { $tinyBtns - } + }, + paste_data_images: $allowImgPaste }); " ); @@ -694,8 +743,8 @@ public function onInit() case 1: default: /* Advanced mode*/ - $toolbar1 = "bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | formatselect | bullist numlist"; - $toolbar2 = "outdent indent | undo redo | link unlink anchor image | hr table | subscript superscript | charmap"; + $toolbar1 = "bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | formatselect | bullist numlist " + . "| outdent indent | undo redo | link unlink anchor image | hr table | subscript superscript | charmap"; JFactory::getDocument()->addScriptDeclaration( " tinyMCE.init({ @@ -718,11 +767,9 @@ public function onInit() $smallButtons invalid_elements : \"$invalid_elements\", // Plugins - plugins : \"table link image code hr charmap autolink lists importcss\", + plugins : \"table link image code hr charmap autolink lists importcss $dragDropPlg\", // Toolbar - toolbar1: \"$toolbar1\", - toolbar2: \"$toolbar2\", - toolbar3: \"$toolbar5 | code\", + toolbar1: \"$toolbar1 | $toolbar5 | code\", removed_menuitems: \"newdocument\", // URL relative_urls : $relative_urls, @@ -737,7 +784,8 @@ public function onInit() width : \"$html_width\", setup: function (editor) { $tinyBtns - } + }, + paste_data_images: $allowImgPaste }); " ); @@ -766,13 +814,9 @@ public function onInit() $smallButtons invalid_elements : \"$invalid_elements\", // Plugins - plugins : \"$plugins\", + plugins : \"$plugins $dragDropPlg\", // Toolbar - toolbar1: \"$toolbar1\", - toolbar2: \"$toolbar2\", - toolbar3: \"$toolbar3\", - toolbar4: \"$toolbar4\", - toolbar5: \"$toolbar5 | code\", + toolbar1: \"$toolbar1 | code\", removed_menuitems: \"newdocument\", // URL relative_urls : $relative_urls, @@ -805,7 +849,8 @@ public function onInit() width : \"$html_width\", setup: function (editor) { $tinyBtns - } + }, + paste_data_images: $allowImgPaste }); " ); @@ -962,11 +1007,11 @@ private function tinyButtons() if ($button->get('name')) { // Set some vars - $name = str_replace(" ", "", $button->get('text')); - $title = $button->get('text'); - $onclick = ($button->get('onclick')) ? $button->get('onclick') : null; - $options = $button->get('options'); - $icon = $button->get('name'); + $name = str_replace(" ", "", $button->get('text')); + $title = $button->get('text'); + $onclick = ($button->get('onclick')) ? $button->get('onclick') : null; + $options = $button->get('options'); + $icon = $button->get('name'); if ($button->get('link') != "#") { @@ -1040,7 +1085,7 @@ private function tinyButtons() } return array( - 'names' => $btnsNames, + 'names' => $btnsNames, 'script' => $tinyBtns ); } diff --git a/plugins/editors/tinymce/tinymce.xml b/plugins/editors/tinymce/tinymce.xml index b8ec85ccfe323..829cf279dbaf8 100644 --- a/plugins/editors/tinymce/tinymce.xml +++ b/plugins/editors/tinymce/tinymce.xml @@ -56,6 +56,22 @@ + + + + + + get('guest')) + if ($user->get('guest') && !$this->isExcluded()) { // We need to check again here, because auto-login plugins have not been fired before the first aid check. $this->_cache->store(null, $this->_cache_key); } } + + /** + * Check if the page is excluded from the cache or not. + * + * @return boolean True if the page is excluded else false + * + * @since 3.5 + */ + protected function isExcluded() + { + // Check if menu items have been excluded + if ($exclusions = $this->params->get('exclude_menu_items', array())) + { + // Get the current menu item + $active = JFactory::getApplication()->getMenu()->getActive(); + + if ($active && $active->id && in_array($active->id, (array) $exclusions)) + { + return true; + } + } + + // Check if regular expressions are being used + if ($exclusions = $this->params->get('exclude', '')) + { + // Normalize line endings + $exclusions = str_replace(array("\r\n", "\r"), "\n", $exclusions); + + // Split them + $exclusions = explode("\n", $exclusions); + + // Get current path to match against + $path = JUri::getInstance()->toString(array('path', 'query', 'fragment')); + + // Loop through each pattern + if ($exclusions) + { + foreach ($exclusions as $exclusion) + { + // Make sure the exclusion has some content + if (strlen($exclusion)) + { + if (preg_match('/' . $exclusion . '/is', $path, $match)) + { + return true; + } + } + } + } + } + + return false; + } } diff --git a/plugins/system/cache/cache.xml b/plugins/system/cache/cache.xml index 795b8ee4a17a7..0afa8e2f69955 100644 --- a/plugins/system/cache/cache.xml +++ b/plugins/system/cache/cache.xml @@ -28,6 +28,22 @@ + + +
+
diff --git a/plugins/system/languagefilter/languagefilter.xml b/plugins/system/languagefilter/languagefilter.xml index 4fc42e55f1e8e..2c47e31e5021a 100644 --- a/plugins/system/languagefilter/languagefilter.xml +++ b/plugins/system/languagefilter/languagefilter.xml @@ -54,11 +54,10 @@
- diff --git a/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php b/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php index 2ef2165593e86..0b6c06a2640dc 100644 --- a/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php +++ b/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php @@ -16,7 +16,7 @@ * * @package Joomla.UnitTest * @subpackage Component - * @since 3.4 + * @since 3.5 */ class JComponentRouterViewTest extends TestCaseDatabase { @@ -24,7 +24,7 @@ class JComponentRouterViewTest extends TestCaseDatabase * Object under test * * @var JComponentRouterView - * @since 3.4 + * @since 3.5 */ protected $object; @@ -34,7 +34,7 @@ class JComponentRouterViewTest extends TestCaseDatabase * * @return void * - * @since 3.4 + * @since 3.5 */ protected function setUp() { @@ -65,7 +65,7 @@ protected function getDataSet() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::registerView */ public function testRegisterView() @@ -85,7 +85,7 @@ public function testRegisterView() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::getViews */ public function testGetViews() @@ -100,15 +100,62 @@ public function testGetViews() $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 * - * @since 3.4 + * @dataProvider casesGetPath + * @since 3.5 * @covers JComponentRouterView::getPath */ - public function testGetPath() + public function testGetPath($input, $result) { // This test requires an application registered to JFactory $this->saveFactoryState(); @@ -122,41 +169,7 @@ public function testGetPath() $this->object->registerView($view); } - // No view, so we don't have a path to return. - $query = array('task' => 'edit'); - $this->assertEquals(array(), $this->object->getPath($query)); - - // View without any parents and children - $query = array('view' => 'form'); - $this->assertEquals(array('form' => true), $this->object->getPath($query)); - - // View without any parents, but with children - $query = array('view' => 'categories'); - $this->assertEquals(array('categories' => true), $this->object->getPath($query)); - - // View with parent and children - $query = array('view' => 'category', 'id' => '9'); - $this->assertEquals(array('category' => array('9:uncategorised'), 'categories' => true), $this->object->getPath($query)); - - //View with parent, no children - $query = array('view' => 'article', 'id' => '42:question-for-everything', 'catid' => '9'); - $this->assertEquals(array( - 'article' => array('42:question-for-everything'), - 'category' => array('9:uncategorised'), - 'categories' => true), - $this->object->getPath($query)); - - //View with parent, no children and nested view - $query = array('view' => 'article', 'id' => '42:question-for-everything', 'catid' => '20'); - $this->assertEquals(array( - 'article' => array('42:question-for-everything'), - 'category' => array('20:extensions', - '19:joomla', - '14:sample-data-articles' - ), - 'categories' => true), - $this->object->getPath($query) - ); + $this->assertEquals($result, $this->object->getPath($input)); $this->restoreFactoryState(); } @@ -166,7 +179,7 @@ public function testGetPath() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::getRules */ public function testGetRules() @@ -181,7 +194,7 @@ public function testGetRules() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::attachRules */ public function testAttachRules() @@ -197,7 +210,7 @@ public function testAttachRules() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::attachRule */ public function testAttachRule() @@ -215,7 +228,7 @@ public function testAttachRule() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::detachRule */ public function testDetachRule() @@ -233,7 +246,7 @@ public function testDetachRule() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::preprocess */ public function testPreprocess() @@ -248,7 +261,7 @@ public function testPreprocess() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::build */ public function testBuild() @@ -265,7 +278,7 @@ public function testBuild() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::parse */ public function testParse() @@ -282,7 +295,7 @@ public function testParse() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::getName */ public function testGetName() @@ -298,7 +311,7 @@ public function testGetName() * * @return void * - * @since 3.4 + * @since 3.5 * @expectedException Exception * @covers JComponentRouterView::getName */ @@ -316,6 +329,7 @@ public function testGetNameException() 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'); 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/JComponentRouterViewInspector.php b/tests/unit/suites/libraries/cms/component/router/stubs/JComponentRouterViewInspector.php index 53e8f17039f15..9e4ddde709b82 100644 --- a/tests/unit/suites/libraries/cms/component/router/stubs/JComponentRouterViewInspector.php +++ b/tests/unit/suites/libraries/cms/component/router/stubs/JComponentRouterViewInspector.php @@ -57,7 +57,32 @@ public function set($key, $value) public function getCategorySegment($id, $query) { $category = JCategories::getInstance($this->getName())->get($id); - return array_reverse($category->getPath()); + 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(); } /** diff --git a/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php b/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php index 6246a5ec31d48..6b6094d9c28f0 100644 --- a/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php +++ b/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php @@ -18,7 +18,7 @@ * @group Router * @since 3.0 */ -class JRouterSiteTest extends TestCase +class JRouterSiteTest extends TestCaseDatabase { /** * Backup of the $_SERVER variable @@ -28,6 +28,22 @@ class JRouterSiteTest extends TestCase */ private $server; + /** + * 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_extensions', JPATH_TEST_DATABASE . '/jos_extensions.csv'); + + return $dataSet; + } + /** * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed.