Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4
manifests/files/tinymce_ru-ru.xml000066600000001515150771655440013207 0ustar00 TinyMCE ru-RU 2012-10-01 Russian Translation Team smart@joomlaportal.ru www.joomlaportal.ru Copyright (C) 2005 - 2012 Open Source Matters. All rights reserved GNU General Public License version 2 or later; see LICENSE.txt 3.5.2.1 Russian Language Package for TinyMCE 3.5.2.1 in Joomla 3.0 tinymce/jscripts/tiny_mce/langs tinymce/jscripts/tiny_mce/plugins tinymce/jscripts/tiny_mce/themes manifests/files/index.html000066600000000037150771655440011656 0ustar00 manifests/files/legacy.xml000066600000001274150771655440011653 0ustar00 legacy_php_update 3.1.5 Joomla! Project admin@joomla.org www.joomla.org (C) 2005 - 2013 Open Source Matters. All rights reserved GNU General Public License version 2 or later; see LICENSE.txt view/legacy.php manifests/files/joomla.xml000066600000003562150771655440011672 0ustar00 files_joomla Joomla! Project admin@joomla.org www.joomla.org (C) 2005 - 2014 Open Source Matters. All rights reserved GNU General Public License version 2 or later; see LICENSE.txt 3.3.0 April 2014 FILES_JOOMLA_XML_DESCRIPTION administrator/components/com_admin/script.php administrator/components/com_admin/sql/updates/mysql administrator/components/com_admin/sql/updates/sqlsrv administrator/components/com_admin/sql/updates/sqlazure administrator/components/com_admin/sql/updates/postgresql administrator bin cache cli components images includes language layouts libraries logs media modules plugins templates tmp htaccess.txt web.config.txt LICENSE.txt README.txt index.php http://update.joomla.org/core/list.xml http://update.joomla.org/jed/list.xml manifests/index.html000066600000000037150771655440010554 0ustar00 manifests/packages/pkg_zoo.xml000066600000003156150771655440012534 0ustar00 ZOO Package YOOtheme March 2014 zoo 3.1.6 http://www.yootheme.com/updates Copyright (C) YOOtheme GmbH http://www.gnu.org/licenses/gpl.html GNU/GPL YOOtheme Proprietary Use License (http://www.yootheme.com/license) info@yootheme.com http://www.yootheme.com ZOO component and extensions for Joomla 2.5+ developed by YOOtheme (http://www.yootheme.com) com_zoo.zip mod_zoocategory.zip mod_zoocomment.zip mod_zooitem.zip mod_zooquickicon.zip mod_zootag.zip plg_content_zooshortcode.zip plg_finder_zoosmartsearch.zip plg_search_zoosearch.zip plg_sys_zooevent.zip file.script.php manifests/packages/pkg_ru-RU.xml000066600000001350150771655440012671 0ustar00 Russian Language Pack ru-RU 3.3.3.1 http://joomlaportal.ru JoomlaPortal.ru http://joomlaportal.ru Joomla 3.3 Russian Language Package site_ru-RU.zip admin_ru-RU.zip http://update.joomla.org/language/translationlist_3.xml manifests/packages/index.html000066600000000037150771655440012332 0ustar00 manifests/packages/zoo/file.script.php000066600000003760150771655440014105 0ustar00checkRequirements(); $requirements->displayResults(); } if (class_exists('App')) { // get zoo instance $app = App::getInstance('zoo'); $app->module->enable('mod_zooquickicon', 'icon'); $app->plugin->enable('zooshortcode'); $app->plugin->enable('zoosmartsearch'); $app->plugin->enable('zoosearch'); $app->plugin->enable('zooevent'); } $extensions = array(); foreach($results as $result) { $extensions[] = (object) array('name' => $result['name'] == 'com_zoo' ? 'ZOO extension' : $result['name'], 'status' => $result['result'], 'message' => $result['result'] ? ($type == 'update' ? 'Updated' : 'Installed').' successfully' : 'NOT Installed'); } // display extension installation results self::displayResults($extensions, 'Extensions', 'Extension'); } protected function displayResults($result, $name, $type) { ?>

$ext) : ?>
 
name; ?> status ? 'font-weight: bold; color: green;' : 'font-weight: bold; color: red;'; ?> message); ?>
mobiletemplate mobiletemplate nhuang jianbo.zhu@gmail.com http://nhuang.com nhuang http://nhuang.com/ June 2013 Copyright (C) Nhuang Studio All rights reserved. GNU General Public License version 2 or later 1.2.0 tmpl_mobiletemplate.zip plg_system_mobiletemplate.zip manifests/libraries/simplepie.xml000066600000001260150771655440013243 0ustar00 SimplePie simplepie 1.2 LIB_SIMPLEPIE_XML_DESCRIPTION 2004 Copyright (c) 2004-2009, Ryan Parman and Geoffrey Sneddon http://www.opensource.org/licenses/bsd-license.php BSD License SimplePie http://simplepie.org/ Joomla! http://www.joomla.org simplepie manifests/libraries/index.html000066600000000037150771655440012530 0ustar00 manifests/libraries/phpass.xml000066600000001134150771655440012552 0ustar00 PHPass phpass LIB_PHPASS_XML_DESCRIPTION 2004-2006 Solar Designer solar@openwall.com http://www.openwall.com/phpass/ PD / GWC 0.3 http://www.openwall.com/phpass/ PasswordHash.php index.html manifests/libraries/phpmailer.xml000066600000001425150771655440013240 0ustar00 PHPMailer phpmailer 5.2.6 LIB_PHPMAILER_XML_DESCRIPTION 2001 (c) 2001-2003, Brent R. Matzelle, (c) 2004-2009, Andy Prevost. All Rights Reserved., (c) 2010-2013, Jim Jagielski. All Rights Reserved. http://www.gnu.org/licenses/lgpl-2.1.html GNU/LGPL PHPMailer jimjag@gmail.com https://github.com/PHPMailer/PHPMailer Joomla! http://www.joomla.org phpmailer manifests/libraries/phputf8.xml000066600000001240150771655440012650 0ustar00 phputf8 phputf8 0.5 LIB_PHPUTF8_XML_DESCRIPTION 2006 Copyright various authors http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL Harry Fuecks hfuecks@gmail.com http://sourceforge.net/projects/phputf8 Joomla! http://www.joomla.org phputf8 manifests/libraries/idna_convert.xml000066600000001256150771655440013734 0ustar00 IDNA Convert idna_convert 0.8.0 LIB_IDNA_XML_DESCRIPTION 2004 2004-2011 phlyLabs Berlin, http://phlylabs.de http://www.gnu.org/licenses/lgpl-2.1.html GNU/LGPL phlyLabs phlymail@phlylabs.de http://phlylabs.de Joomla! http://www.joomla.org idna_convert manifests/libraries/joomla.xml000066600000001546150771655440012544 0ustar00 Joomla! Platform joomla 13.1 LIB_JOOMLA_XML_DESCRIPTION 2008 Copyright (C) 2005 - 2014 Open Source Matters. All rights reserved. http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL Joomla! Project admin@joomla.org http://www.joomla.org Joomla! http://www.joomla.org compat joomla legacy import.legacy.php import.php loader.php platform.php manifests/libraries/fof.xml000066600000002606150771655440012033 0ustar00 FOF fof LIB_FOF_XML_DESCRIPTION 2014-03-09 12:54:48 Nicholas K. Dionysopoulos / Akeeba Ltd nicholas@akeebabackup.com https://www.akeebabackup.com (C)2011-2014 Nicholas K. Dionysopoulos GNU GPLv2 or later 2.2.1 Akeeba Ltd https://www.AkeebaBackup.com/download.html autoloader config controller database dispatcher encrypt form hal inflector integration input layout less model platform query render string table template toolbar utils view LICENSE.txt include.php index.html version.txt .htaccess000066600000000323150771655440006362 0ustar00 Order Allow,Deny Deny from all order Allow,Deny Allow from all order Allow,Deny Allow from all index.php000066600000002154150771655440006410 0ustar00mark('afterLoad') : null; // Instantiate the application. $app = JFactory::getApplication('administrator'); // Execute the application. $app->execute(); components/com_cpanel/cpanel.php000066600000000701150771655440013024 0ustar00execute(JFactory::getApplication()->input->get('task')); $controller->redirect(); components/com_cpanel/cpanel.xml000066600000001643150771655440013043 0ustar00 com_cpanel Joomla! Project April 2006 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_CPANEL_XML_DESCRIPTION controller.php cpanel.php index.html views language/en-GB.com_cpanel.ini language/en-GB.com_cpanel.sys.ini components/com_cpanel/views/index.html000066600000000037150771655440014205 0ustar00 components/com_cpanel/views/cpanel/view.html.php000066600000003213150771655440016077 0ustar00input; /* * Set the template - this will display cpanel.php * from the selected admin template. */ $input->set('tmpl', 'cpanel'); // Display the cpanel modules $this->modules = JModuleHelper::getModules('cpanel'); // Load the RAD layer and count the number of post-installation messages if (!defined('FOF_INCLUDED')) { require_once JPATH_LIBRARIES . '/fof/include.php'; } $messages_model = FOFModel::getTmpInstance('Messages', 'PostinstallModel', array('input' => array('eid' => 700))); $messages = $messages_model->getItemList(); $this->postinstall_message_count = count($messages); parent::display($tpl); } } components/com_cpanel/views/cpanel/tmpl/default.php000066600000003640150771655440016566 0ustar00
authorise('core.manage', 'com_postinstall')) : ?>
postinstall_message_count): ?>
modules as $module) { // Get module parameters $params = new JRegistry; $params->loadString($module->params); $bootstrapSize = $params->get('bootstrap_size'); if (!$bootstrapSize) { $bootstrapSize = 12; } $spans += $bootstrapSize; if ($spans > 12) { echo '
'; $spans = $bootstrapSize; } echo JModuleHelper::renderModule($module, array('style' => 'well')); } ?>
components/com_cpanel/views/cpanel/tmpl/index.html000066600000000037150771655440016423 0ustar00 components/com_cpanel/views/cpanel/index.html000066600000000037150771655440015447 0ustar00 components/com_cpanel/index.html000066600000000037150771655440013050 0ustar00 components/com_cpanel/controller.php000066600000000676150771655440013760 0ustar00 com_banners Joomla! Project April 2006 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_BANNERS_XML_DESCRIPTION sql/install.mysql.utf8.sql sql/uninstall.mysql.utf8.sql banners.php controller.php index.html router.php helpers models com_banners com_banners_banners com_banners_categories com_banners_clients com_banners_tracks access.xml banners.php config.xml controller.php index.html controllers helpers models tables views language/en-GB.com_banners.ini language/en-GB.com_banners.sys.ini components/com_banners/tables/index.html000066600000000037150771655440014510 0ustar00 components/com_banners/tables/client.php000066600000005775150771655440014520 0ustar00checked_out_time = $_db->getNullDate(); parent::__construct('#__banner_clients', 'id', $_db); } /** * Method to set the publishing state for a row or list of rows in the database * table. The method respects checked out rows by other users and will attempt * to checkin rows that it can after adjustments are made. * * @param mixed $pks An optional array of primary key values to update. If not set the instance property value is used. * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published, 2=archived, -2=trashed] * @param integer $userId The user id of the user performing the operation. * * @return boolean True on success. * * @since 1.0.4 */ public function publish($pks = null, $state = 1, $userId = 0) { $k = $this->_tbl_key; // Sanitize input. JArrayHelper::toInteger($pks); $userId = (int) $userId; $state = (int) $state; // If there are no primary keys set check to see if the instance key is set. if (empty($pks)) { if ($this->$k) { $pks = array($this->$k); } // Nothing to set publishing state on, return false. else { $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); return false; } } // Build the WHERE clause for the primary keys. $where = $k . '=' . implode(' OR ' . $k . '=', $pks); // Determine if there is checkin support for the table. if (!property_exists($this, 'checked_out') || !property_exists($this, 'checked_out_time')) { $checkin = ''; } else { $checkin = ' AND (checked_out = 0 OR checked_out = ' . (int) $userId . ')'; } // Update the publishing state for rows with the given primary keys. $this->_db->setQuery( 'UPDATE ' . $this->_db->quoteName($this->_tbl) . ' SET ' . $this->_db->quoteName('state') . ' = ' . (int) $state . ' WHERE (' . $where . ')' . $checkin ); try { $this->_db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } // If checkin is supported and all rows were adjusted, check them in. if ($checkin && (count($pks) == $this->_db->getAffectedRows())) { // Checkin the rows. foreach ($pks as $pk) { $this->checkin($pk); } } // If the JTable instance value is in the list of primary keys that were set, set the instance. if (in_array($this->$k, $pks)) { $this->state = $state; } $this->setError(''); return true; } } components/com_banners/tables/banner.php000066600000022167150771655440014501 0ustar00created = $date->toSql(); } /** * Increase click count * * @return void */ public function clicks() { $query = 'UPDATE #__banners' . ' SET clicks = (clicks + 1)' . ' WHERE id = ' . (int) $this->id; $this->_db->setQuery($query); $this->_db->execute(); } /** * Overloaded check function * * @return boolean * * @see JTable::check * @since 1.5 */ public function check() { // Set name $this->name = htmlspecialchars_decode($this->name, ENT_QUOTES); // Set alias $this->alias = JApplication::stringURLSafe($this->alias); if (empty($this->alias)) { $this->alias = JApplication::stringURLSafe($this->name); } // Check the publish down date is not earlier than publish up. if ($this->publish_down > $this->_db->getNullDate() && $this->publish_down < $this->publish_up) { $this->setError(JText::_('JGLOBAL_START_PUBLISH_AFTER_FINISH')); return false; } // Set ordering if ($this->state < 0) { // Set ordering to 0 if state is archived or trashed $this->ordering = 0; } elseif (empty($this->ordering)) { // Set ordering to last if ordering was 0 $this->ordering = self::getNextOrder($this->_db->quoteName('catid') . '=' . $this->_db->quote($this->catid) . ' AND state>=0'); } return true; } /** * Overloaded bind function * * @param array $array Named array to bind * @param mixed $ignore An optional array or space separated list of properties to ignore while binding. * * @return mixed Null if operation was satisfactory, otherwise returns an error * * @since 1.5 */ public function bind($array, $ignore = array()) { if (isset($array['params']) && is_array($array['params'])) { $registry = new JRegistry; $registry->loadArray($array['params']); if ((int) $registry->get('width', 0) < 0) { $this->setError(JText::sprintf('JLIB_DATABASE_ERROR_NEGATIVE_NOT_PERMITTED', JText::_('COM_BANNERS_FIELD_WIDTH_LABEL'))); return false; } if ((int) $registry->get('height', 0) < 0) { $this->setError(JText::sprintf('JLIB_DATABASE_ERROR_NEGATIVE_NOT_PERMITTED', JText::_('COM_BANNERS_FIELD_HEIGHT_LABEL'))); return false; } // Converts the width and height to an absolute numeric value: $width = abs((int) $registry->get('width', 0)); $height = abs((int) $registry->get('height', 0)); // Sets the width and height to an empty string if = 0 $registry->set('width', ($width ? $width : '')); $registry->set('height', ($height ? $height : '')); $array['params'] = (string) $registry; } if (isset($array['imptotal'])) { $array['imptotal'] = abs((int) $array['imptotal']); } return parent::bind($array, $ignore); } /** * Method to store a row * * @param boolean $updateNulls True to update fields even if they are null. * * @return boolean True on success, false on failure. */ public function store($updateNulls = false) { if (empty($this->id)) { $purchase_type = $this->purchase_type; if ($purchase_type < 0 && $this->cid) { $client = JTable::getInstance('Client', 'BannersTable'); $client->load($this->cid); $purchase_type = $client->purchase_type; } if ($purchase_type < 0) { $params = JComponentHelper::getParams('com_banners'); $purchase_type = $params->get('purchase_type'); } switch ($purchase_type) { case 1: $this->reset = $this->_db->getNullDate(); break; case 2: $date = JFactory::getDate('+1 year ' . date('Y-m-d', strtotime('now'))); $this->reset = $this->_db->quote($date->toSql()); break; case 3: $date = JFactory::getDate('+1 month ' . date('Y-m-d', strtotime('now'))); $this->reset = $this->_db->quote($date->toSql()); break; case 4: $date = JFactory::getDate('+7 day ' . date('Y-m-d', strtotime('now'))); $this->reset = $this->_db->quote($date->toSql()); break; case 5: $date = JFactory::getDate('+1 day ' . date('Y-m-d', strtotime('now'))); $this->reset = $this->_db->quote($date->toSql()); break; } // Store the row parent::store($updateNulls); } else { // Get the old row $oldrow = JTable::getInstance('Banner', 'BannersTable'); if (!$oldrow->load($this->id) && $oldrow->getError()) { $this->setError($oldrow->getError()); } // Verify that the alias is unique $table = JTable::getInstance('Banner', 'BannersTable'); if ($table->load(array('alias' => $this->alias, 'catid' => $this->catid)) && ($table->id != $this->id || $this->id == 0)) { $this->setError(JText::_('COM_BANNERS_ERROR_UNIQUE_ALIAS')); return false; } // Store the new row parent::store($updateNulls); // Need to reorder ? if ($oldrow->state >= 0 && ($this->state < 0 || $oldrow->catid != $this->catid)) { // Reorder the oldrow $this->reorder($this->_db->quoteName('catid') . '=' . $this->_db->quote($oldrow->catid) . ' AND state>=0'); } } return count($this->getErrors()) == 0; } /** * Method to set the publishing state for a row or list of rows in the database * table. The method respects checked out rows by other users and will attempt * to checkin rows that it can after adjustments are made. * * @param mixed $pks An optional array of primary key values to update. If not set the instance property value is used. * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published, 2=archived, -2=trashed] * @param integer $userId The user id of the user performing the operation. * * @return boolean True on success. * * @since 1.6 */ public function publish($pks = null, $state = 1, $userId = 0) { $k = $this->_tbl_key; // Sanitize input. JArrayHelper::toInteger($pks); $userId = (int) $userId; $state = (int) $state; // If there are no primary keys set check to see if the instance key is set. if (empty($pks)) { if ($this->$k) { $pks = array($this->$k); } // Nothing to set publishing state on, return false. else { $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); return false; } } // Get an instance of the table $table = JTable::getInstance('Banner', 'BannersTable'); // For all keys foreach ($pks as $pk) { // Load the banner if (!$table->load($pk)) { $this->setError($table->getError()); } // Verify checkout if ($table->checked_out == 0 || $table->checked_out == $userId) { // Change the state $table->state = $state; $table->checked_out = 0; $table->checked_out_time = $this->_db->getNullDate(); // Check the row $table->check(); // Store the row if (!$table->store()) { $this->setError($table->getError()); } } } return count($this->getErrors()) == 0; } /** * Method to set the sticky state for a row or list of rows in the database * table. The method respects checked out rows by other users and will attempt * to checkin rows that it can after adjustments are made. * * @param mixed $pks An optional array of primary key values to update. If not set the instance property value is used. * @param integer $state The sticky state. eg. [0 = unsticked, 1 = sticked] * @param integer $userId The user id of the user performing the operation. * * @return boolean True on success. * * @since 1.6 */ public function stick($pks = null, $state = 1, $userId = 0) { $k = $this->_tbl_key; // Sanitize input. JArrayHelper::toInteger($pks); $userId = (int) $userId; $state = (int) $state; // If there are no primary keys set check to see if the instance key is set. if (empty($pks)) { if ($this->$k) { $pks = array($this->$k); } // Nothing to set publishing state on, return false. else { $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); return false; } } // Get an instance of the table $table = JTable::getInstance('Banner', 'BannersTable'); // For all keys foreach ($pks as $pk) { // Load the banner if (!$table->load($pk)) { $this->setError($table->getError()); } // Verify checkout if ($table->checked_out == 0 || $table->checked_out == $userId) { // Change the state $table->sticky = $state; $table->checked_out = 0; $table->checked_out_time = $this->_db->getNullDate(); // Check the row $table->check(); // Store the row if (!$table->store()) { $this->setError($table->getError()); } } } return count($this->getErrors()) == 0; } } components/com_banners/views/client/view.html.php000066600000005207150771655440016306 0ustar00form = $this->get('Form'); $this->item = $this->get('Item'); $this->state = $this->get('State'); $this->canDo = JHelperContent::getActions('com_banners'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { JFactory::getApplication()->input->set('hidemainmenu', true); $user = JFactory::getUser(); $isNew = ($this->item->id == 0); $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); $canDo = $this->canDo; JToolbarHelper::title($isNew ? JText::_('COM_BANNERS_MANAGER_CLIENT_NEW') : JText::_('COM_BANNERS_MANAGER_CLIENT_EDIT'), 'bookmark banners-clients'); // If not checked out, can save the item. if (!$checkedOut && ($canDo->get('core.edit') || $canDo->get('core.create'))) { JToolbarHelper::apply('client.apply'); JToolbarHelper::save('client.save'); } if (!$checkedOut && $canDo->get('core.create')) { JToolbarHelper::save2new('client.save2new'); } // If an existing item, can save to a copy. if (!$isNew && $canDo->get('core.create')) { JToolbarHelper::save2copy('client.save2copy'); } if (empty($this->item->id)) { JToolbarHelper::cancel('client.cancel'); } else { if ($this->state->params->get('save_history', 0) && $user->authorise('core.edit')) { JToolbarHelper::versions('com_banners.client', $this->item->id); } JToolbarHelper::cancel('client.cancel', 'JTOOLBAR_CLOSE'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_COMPONENTS_BANNERS_CLIENTS_EDIT'); } } components/com_banners/views/client/tmpl/edit.php000066600000004161150771655440016270 0ustar00
'general')); ?> item->id) ? JText::_('COM_BANNERS_NEW_CLIENT', true) : JText::_('COM_BANNERS_EDIT_CLIENT', true)); ?>
form->getControlGroup('contact'); echo $this->form->getControlGroup('email'); echo $this->form->getControlGroup('purchase_type'); echo $this->form->getControlGroup('track_impressions'); echo $this->form->getControlGroup('track_clicks'); echo $this->form->getControlGroups('extra'); ?>
form->getControlGroups('metadata'); ?>
components/com_banners/views/client/tmpl/index.html000066600000000037150771655440016625 0ustar00 components/com_banners/views/client/index.html000066600000000037150771655440015651 0ustar00 components/com_banners/views/tracks/view.html.php000066600000006655150771655440016327 0ustar00items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } BannersHelper::addSubmenu('tracks'); $this->addToolbar(); require_once JPATH_COMPONENT . '/models/fields/bannerclient.php'; $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { require_once JPATH_COMPONENT . '/helpers/banners.php'; $canDo = JHelperContent::getActions('com_banners', 'category', $this->state->get('filter.category_id')); JToolbarHelper::title(JText::_('COM_BANNERS_MANAGER_TRACKS'), 'bookmark banners-tracks'); $bar = JToolBar::getInstance('toolbar'); $bar->appendButton('Popup', 'export', 'JTOOLBAR_EXPORT', 'index.php?option=com_banners&view=download&tmpl=component', 600, 300); if ($canDo->get('core.delete')) { $bar->appendButton('Confirm', 'COM_BANNERS_DELETE_MSG', 'delete', 'COM_BANNERS_TRACKS_DELETE', 'tracks.delete', false); JToolbarHelper::divider(); } if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_banners'); JToolbarHelper::divider(); } JToolbarHelper::help('JHELP_COMPONENTS_BANNERS_TRACKS'); JHtmlSidebar::setAction('index.php?option=com_banners&view=tracks'); JHtmlSidebar::addFilter( JText::_('COM_BANNERS_SELECT_CLIENT'), 'filter_client_id', JHtml::_('select.options', BannersHelper::getClientOptions(), 'value', 'text', $this->state->get('filter.client_id')) ); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_CATEGORY'), 'filter_category_id', JHtml::_('select.options', JHtml::_('category.options', 'com_banners'), 'value', 'text', $this->state->get('filter.category_id')) ); JHtmlSidebar::addFilter( JText::_('COM_BANNERS_SELECT_TYPE'), 'filter_type', JHtml::_('select.options', array(JHtml::_('select.option', 1, JText::_('COM_BANNERS_IMPRESSION')), JHtml::_('select.option', 2, JText::_('COM_BANNERS_CLICK'))), 'value', 'text', $this->state->get('filter.type')) ); } /** * Returns an array of fields the table can be sorted by * * @return array Array containing the field name to sort by as the key and display text as value * * @since 3.0 */ protected function getSortFields() { return array( 'b.name' => JText::_('COM_BANNERS_HEADING_NAME'), 'cl.name' => JText::_('COM_BANNERS_HEADING_CLIENT'), 'track_type' => JText::_('COM_BANNERS_HEADING_TYPE'), 'count' => JText::_('COM_BANNERS_HEADING_COUNT'), 'track_date' => JText::_('JDATE') ); } } components/com_banners/views/tracks/tmpl/default.php000066600000012727150771655440017007 0ustar00get('id'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $sortFields = $this->getSortFields(); ?>
sidebar; ?>
pagination->getLimitBox(); ?>
items)) : ?>
items as $i => $item) : ?>
pagination->getListFooter(); ?>
name; ?>
category_title; ?>
client_name; ?> track_type == 1 ? JText::_('COM_BANNERS_IMPRESSION') : JText::_('COM_BANNERS_CLICK'); ?> count; ?> track_date, JText::_('DATE_FORMAT_LC4') . ' H:i'); ?>
components/com_banners/views/tracks/tmpl/index.html000066600000000037150771655440016636 0ustar00 components/com_banners/views/tracks/index.html000066600000000037150771655440015662 0ustar00 components/com_banners/views/tracks/view.raw.php000066600000002361150771655440016142 0ustar00get('BaseName'); $filetype = $this->get('FileType'); $mimetype = $this->get('MimeType'); $content = $this->get('Content'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $document = JFactory::getDocument(); $document->setMimeEncoding($mimetype); JFactory::getApplication()->setHeader('Content-disposition', 'attachment; filename="' . $basename . '.' . $filetype . '"; creation-date="' . JFactory::getDate()->toRFC822() . '"', true); echo $content; } } components/com_banners/views/banners/view.html.php000066600000010704150771655440016456 0ustar00categories = $this->get('CategoryOrders'); $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); $this->filterForm = $this->get('FilterForm'); $this->activeFilters = $this->get('ActiveFilters'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } BannersHelper::addSubmenu('banners'); $this->addToolbar(); require_once JPATH_COMPONENT . '/models/fields/bannerclient.php'; // Include the component HTML helpers. JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { require_once JPATH_COMPONENT . '/helpers/banners.php'; $canDo = JHelperContent::getActions('com_banners', 'category', $this->state->get('filter.category_id')); $user = JFactory::getUser(); // Get the toolbar object instance $bar = JToolBar::getInstance('toolbar'); JToolbarHelper::title(JText::_('COM_BANNERS_MANAGER_BANNERS'), 'banners.png'); if (count($user->getAuthorisedCategories('com_banners', 'core.create')) > 0) { JToolbarHelper::addNew('banner.add'); } if (($canDo->get('core.edit'))) { JToolbarHelper::editList('banner.edit'); } if ($canDo->get('core.edit.state')) { if ($this->state->get('filter.state') != 2) { JToolbarHelper::publish('banners.publish', 'JTOOLBAR_PUBLISH', true); JToolbarHelper::unpublish('banners.unpublish', 'JTOOLBAR_UNPUBLISH', true); } if ($this->state->get('filter.state') != -1) { if ($this->state->get('filter.state') != 2) { JToolbarHelper::archiveList('banners.archive'); } elseif ($this->state->get('filter.state') == 2) { JToolbarHelper::unarchiveList('banners.publish'); } } } if ($canDo->get('core.edit.state')) { JToolbarHelper::checkin('banners.checkin'); } if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete')) { JToolbarHelper::deleteList('', 'banners.delete', 'JTOOLBAR_EMPTY_TRASH'); } elseif ($canDo->get('core.edit.state')) { JToolbarHelper::trash('banners.trash'); } // Add a batch button if ($user->authorise('core.create', 'com_banners') && $user->authorise('core.edit', 'com_banners') && $user->authorise('core.edit.state', 'com_banners')) { JHtml::_('bootstrap.modal', 'collapseModal'); $title = JText::_('JTOOLBAR_BATCH'); // Instantiate a new JLayoutFile instance and render the batch button $layout = new JLayoutFile('joomla.toolbar.batch'); $dhtml = $layout->render(array('title' => $title)); $bar->appendButton('Custom', $dhtml, 'batch'); } if ($user->authorise('core.admin', 'com_banners')) { JToolbarHelper::preferences('com_banners'); } JToolbarHelper::help('JHELP_COMPONENTS_BANNERS_BANNERS'); } /** * Returns an array of fields the table can be sorted by * * @return array Array containing the field name to sort by as the key and display text as value * * @since 3.0 */ protected function getSortFields() { return array( 'ordering' => JText::_('JGRID_HEADING_ORDERING'), 'a.state' => JText::_('JSTATUS'), 'a.name' => JText::_('COM_BANNERS_HEADING_NAME'), 'a.sticky' => JText::_('COM_BANNERS_HEADING_STICKY'), 'client_name' => JText::_('COM_BANNERS_HEADING_CLIENT'), 'impmade' => JText::_('COM_BANNERS_HEADING_IMPRESSIONS'), 'clicks' => JText::_('COM_BANNERS_HEADING_CLICKS'), 'a.language' => JText::_('JGRID_HEADING_LANGUAGE'), 'a.id' => JText::_('JGRID_HEADING_ID') ); } } components/com_banners/views/banners/tmpl/default.php000066600000020570150771655440017143 0ustar00get('id'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $canOrder = $user->authorise('core.edit.state', 'com_banners.category'); $archived = $this->state->get('filter.state') == 2 ? true : false; $trashed = $this->state->get('filter.state') == -2 ? true : false; $params = (isset($this->state->params)) ? $this->state->params : new JObject; $saveOrder = $listOrder == 'a.ordering'; if ($saveOrder) { $saveOrderingUrl = 'index.php?option=com_banners&task=banners.saveOrderAjax&tmpl=component'; JHtml::_('sortablelist.sortable', 'articleList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); } $sortFields = $this->getSortFields(); ?>
sidebar; ?>
$this)); ?> items)) : ?>
items as $i => $item) : $ordering = ($listOrder == 'ordering'); $item->cat_link = JRoute::_('index.php?option=com_categories&extension=com_banners&task=edit&type=other&cid[]=' . $item->catid); $canCreate = $user->authorise('core.create', 'com_banners.category.' . $item->catid); $canEdit = $user->authorise('core.edit', 'com_banners.category.' . $item->catid); $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; $canChange = $user->authorise('core.edit.state', 'com_banners.category.' . $item->catid) && $canCheckin; ?>
pagination->getListFooter(); ?>
id); ?>
state, $i, 'banners.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> escape($item->name)); ?>
checked_out) : ?> editor, $item->checked_out_time, 'banners.', $canCheckin); ?> escape($item->name); ?> escape($item->name); ?> escape($item->alias)); ?>
escape($item->category_title); ?>
sticky, $i, $canChange); ?> client_name; ?> impmade, $item->imptotal ? $item->imptotal : JText::_('COM_BANNERS_UNLIMITED')); ?> clicks; ?> - impmade ? 100 * $item->clicks / $item->impmade : 0); ?> language == '*'): ?> language_title ? $this->escape($item->language_title) : JText::_('JUNDEFINED'); ?> id; ?>
loadTemplate('batch'); ?>
components/com_banners/views/banners/tmpl/index.html000066600000000037150771655440016777 0ustar00 components/com_banners/views/banners/tmpl/default_batch.php000066600000003152150771655440020301 0ustar00state->get('filter.published'); ?> components/com_banners/views/banners/index.html000066600000000037150771655440016023 0ustar00 components/com_banners/views/index.html000066600000000037150771655440014373 0ustar00 components/com_banners/views/clients/view.html.php000066600000005741150771655440016474 0ustar00items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); $this->filterForm = $this->get('FilterForm'); $this->activeFilters = $this->get('ActiveFilters'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } BannersHelper::addSubmenu('clients'); $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { require_once JPATH_COMPONENT . '/helpers/banners.php'; $canDo = JHelperContent::getActions('com_banners'); JToolbarHelper::title(JText::_('COM_BANNERS_MANAGER_CLIENTS'), 'banners-clients.png'); if ($canDo->get('core.create')) { JToolbarHelper::addNew('client.add'); } if ($canDo->get('core.edit')) { JToolbarHelper::editList('client.edit'); } if ($canDo->get('core.edit.state')) { JToolbarHelper::publish('clients.publish', 'JTOOLBAR_PUBLISH', true); JToolbarHelper::unpublish('clients.unpublish', 'JTOOLBAR_UNPUBLISH', true); JToolbarHelper::archiveList('clients.archive'); JToolbarHelper::checkin('clients.checkin'); } if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete')) { JToolbarHelper::deleteList('', 'clients.delete', 'JTOOLBAR_EMPTY_TRASH'); } elseif ($canDo->get('core.edit.state')) { JToolbarHelper::trash('clients.trash'); } if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_banners'); } JToolbarHelper::help('JHELP_COMPONENTS_BANNERS_CLIENTS'); } /** * Returns an array of fields the table can be sorted by * * @return array Array containing the field name to sort by as the key and display text as value * * @since 3.0 */ protected function getSortFields() { return array( 'a.status' => JText::_('JSTATUS'), 'a.name' => JText::_('COM_BANNERS_HEADING_CLIENT'), 'contact' => JText::_('COM_BANNERS_HEADING_CONTACT'), 'client_name' => JText::_('COM_BANNERS_HEADING_CLIENT'), 'nbanners' => JText::_('COM_BANNERS_HEADING_ACTIVE'), 'a.id' => JText::_('JGRID_HEADING_ID') ); } } components/com_banners/views/clients/tmpl/default.php000066600000013432150771655440017153 0ustar00get('id'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $params = (isset($this->state->params)) ? $this->state->params : new JObject; $archived = $this->state->get('filter.state') == 2 ? true : false; $trashed = $this->state->get('filter.state') == -2 ? true : false; $sortFields = $this->getSortFields(); ?>
sidebar; ?>
$this)); ?> items)) : ?>
items as $i => $item) : $ordering = ($listOrder == 'ordering'); $canCreate = $user->authorise('core.create', 'com_banners'); $canEdit = $user->authorise('core.edit', 'com_banners'); $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; $canChange = $user->authorise('core.edit.state', 'com_banners') && $canCheckin; ?>
pagination->getListFooter(); ?>
id); ?>
state, $i, 'clients.', $canChange); ?> escape($item->name)); ?>
checked_out) : ?> editor, $item->checked_out_time, 'clients.', $canCheckin); ?> escape($item->name); ?> escape($item->name); ?>
contact; ?> nbanners; ?> purchase_type < 0): ?> get('purchase_type'))); ?> purchase_type); ?> id; ?>
components/com_banners/views/clients/tmpl/index.html000066600000000037150771655440017010 0ustar00 components/com_banners/views/clients/index.html000066600000000037150771655440016034 0ustar00 components/com_banners/views/banner/view.html.php000066600000005435150771655440016300 0ustar00form = $this->get('Form'); $this->item = $this->get('Item'); $this->state = $this->get('State'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); JHtml::_('jquery.framework'); JHtml::_('script', 'media/com_banners/banner.js'); parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { JFactory::getApplication()->input->set('hidemainmenu', true); $user = JFactory::getUser(); $userId = $user->get('id'); $isNew = ($this->item->id == 0); $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); // Since we don't track these assets at the item level, use the category id. $canDo = JHelperContent::getActions('com_banners', 'category', $this->item->catid); JToolbarHelper::title($isNew ? JText::_('COM_BANNERS_MANAGER_BANNER_NEW') : JText::_('COM_BANNERS_MANAGER_BANNER_EDIT'), 'bookmark banners'); // If not checked out, can save the item. if (!$checkedOut && ($canDo->get('core.edit') || count($user->getAuthorisedCategories('com_banners', 'core.create')) > 0)) { JToolbarHelper::apply('banner.apply'); JToolbarHelper::save('banner.save'); if ($canDo->get('core.create')) { JToolbarHelper::save2new('banner.save2new'); } } // If an existing item, can save to a copy. if (!$isNew && $canDo->get('core.create')) { JToolbarHelper::save2copy('banner.save2copy'); } if (empty($this->item->id)) { JToolbarHelper::cancel('banner.cancel'); } else { if ($this->state->params->get('save_history', 0) && $user->authorise('core.edit')) { JToolbarHelper::versions('com_banners.banner', $this->item->id); } JToolbarHelper::cancel('banner.cancel', 'JTOOLBAR_CLOSE'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_COMPONENTS_BANNERS_BANNERS_EDIT'); } } components/com_banners/views/banner/tmpl/edit.php000066600000005727150771655440016270 0ustar00addScriptDeclaration($script); ?> components/com_banners/views/banner/tmpl/index.html000066600000000037150771655440016614 0ustar00 components/com_banners/views/banner/index.html000066600000000037150771655440015640 0ustar00 components/com_banners/views/download/view.html.php000066600000001624150771655440016636 0ustar00form = $this->get('Form'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } parent::display($tpl); } } components/com_banners/views/download/tmpl/default.php000066600000002166150771655440017323 0ustar00
form->getFieldset() as $field) : ?> hidden) : ?> label; ?> input; ?>
components/com_banners/views/download/tmpl/index.html000066600000000037150771655440017156 0ustar00 components/com_banners/views/download/index.html000066600000000037150771655440016202 0ustar00 components/com_banners/sql/install.mysql.utf8.sql000066600000005440150771655440016263 0ustar00CREATE TABLE `#__banners` ( `id` INTEGER NOT NULL auto_increment, `cid` INTEGER NOT NULL DEFAULT '0', `type` INTEGER NOT NULL DEFAULT '0', `name` VARCHAR(255) NOT NULL DEFAULT '', `alias` VARCHAR(255) NOT NULL DEFAULT '', `imptotal` INTEGER NOT NULL DEFAULT '0', `impmade` INTEGER NOT NULL DEFAULT '0', `clicks` INTEGER NOT NULL DEFAULT '0', `clickurl` VARCHAR(200) NOT NULL DEFAULT '', `state` TINYINT(3) NOT NULL DEFAULT '0', `catid` INTEGER UNSIGNED NOT NULL DEFAULT 0, `description` TEXT NOT NULL, `custombannercode` VARCHAR(2048) NOT NULL, `sticky` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0, `ordering` INTEGER NOT NULL DEFAULT 0, `metakey` TEXT NOT NULL, `params` TEXT NOT NULL, `own_prefix` TINYINT(1) NOT NULL DEFAULT '0', `metakey_prefix` VARCHAR(255) NOT NULL DEFAULT '', `purchase_type` TINYINT NOT NULL DEFAULT '-1', `track_clicks` TINYINT NOT NULL DEFAULT '-1', `track_impressions` TINYINT NOT NULL DEFAULT '-1', `checked_out` INTEGER UNSIGNED NOT NULL DEFAULT '0', `checked_out_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', `publish_up` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', `publish_down` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', `reset` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', `language` char(7) NOT NULL DEFAULT '', PRIMARY KEY (`id`), INDEX `idx_state` (`state`), INDEX `idx_own_prefix` (`own_prefix`), INDEX `idx_metakey_prefix` (`metakey_prefix`), INDEX `idx_banner_catid`(`catid`), INDEX `idx_language` (`language`) ) DEFAULT CHARSET=utf8; CREATE TABLE `#__banner_clients` ( `id` INTEGER NOT NULL auto_increment, `name` VARCHAR(255) NOT NULL DEFAULT '', `contact` VARCHAR(255) NOT NULL DEFAULT '', `email` VARCHAR(255) NOT NULL DEFAULT '', `extrainfo` TEXT NOT NULL, `state` TINYINT(3) NOT NULL DEFAULT '0', `checked_out` INTEGER UNSIGNED NOT NULL DEFAULT '0', `checked_out_time` DATETIME NOT NULL default '0000-00-00 00:00:00', `metakey` TEXT NOT NULL, `own_prefix` TINYINT NOT NULL DEFAULT '0', `metakey_prefix` VARCHAR(255) NOT NULL default '', `purchase_type` TINYINT NOT NULL DEFAULT '-1', `track_clicks` TINYINT NOT NULL DEFAULT '-1', `track_impressions` TINYINT NOT NULL DEFAULT '-1', PRIMARY KEY (`id`), INDEX `idx_own_prefix` (`own_prefix`), INDEX `idx_metakey_prefix` (`metakey_prefix`) ) DEFAULT CHARSET=utf8; CREATE TABLE `#__banner_tracks` ( `track_date` DATETIME NOT NULL, `track_type` INTEGER UNSIGNED NOT NULL, `banner_id` INTEGER UNSIGNED NOT NULL, `count` INTEGER UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (`track_date`, `track_type`, `banner_id`), INDEX `idx_track_date` (`track_date`), INDEX `idx_track_type` (`track_type`), INDEX `idx_banner_id` (`banner_id`) ) DEFAULT CHARSET=utf8; components/com_banners/sql/uninstall.mysql.utf8.sql000066600000000171150771655440016622 0ustar00DROP TABLE IF EXISTS `#__banners`; DROP TABLE IF EXISTS `#__banner_clients`; DROP TABLE IF EXISTS `#__banner_tracks`; components/com_banners/sql/index.html000066600000000037150771655440014035 0ustar00 components/com_banners/index.html000066600000000037150771655440013236 0ustar00 components/com_banners/config.xml000066600000004555150771655440013241 0ustar00
components/com_banners/banners.php000066600000001157150771655440013406 0ustar00authorise('core.manage', 'com_banners')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } // Execute the task. $controller = JControllerLegacy::getInstance('Banners'); $controller->execute(JFactory::getApplication()->input->get('task')); $controller->redirect(); components/com_banners/controller.php000066600000003671150771655440014144 0ustar00input->get('view', 'banners'); $layout = $this->input->get('layout', 'default'); $id = $this->input->getInt('id'); // Check for edit form. if ($view == 'banner' && $layout == 'edit' && !$this->checkEditId('com_banners.edit.banner', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_banners&view=banners', false)); return false; } elseif ($view == 'client' && $layout == 'edit' && !$this->checkEditId('com_banners.edit.client', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_banners&view=clients', false)); return false; } parent::display(); return $this; } } components/com_banners/controllers/tracks.php000066600000004535150771655440015616 0ustar00 true)) { $model = parent::getModel($name, $prefix, $config); return $model; } /** * Method to remove a record. * * @return void * * @since 1.6 */ public function delete() { // Check for request forgeries. JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Get the model. $model = $this->getModel(); // Load the filter state. $app = JFactory::getApplication(); $type = $app->getUserState($this->context . '.filter.type'); $model->setState('filter.type', $type); $begin = $app->getUserState($this->context . '.filter.begin'); $model->setState('filter.begin', $begin); $end = $app->getUserState($this->context . '.filter.end'); $model->setState('filter.end', $end); $categoryId = $app->getUserState($this->context . '.filter.category_id'); $model->setState('filter.category_id', $categoryId); $clientId = $app->getUserState($this->context . '.filter.client_id'); $model->setState('filter.client_id', $clientId); $model->setState('list.limit', 0); $model->setState('list.start', 0); $count = $model->getTotal(); // Remove the items. if (!$model->delete()) { JError::raiseWarning(500, $model->getError()); } else { $this->setMessage(JText::plural('COM_BANNERS_TRACKS_N_ITEMS_DELETED', $count)); } $this->setRedirect('index.php?option=com_banners&view=tracks'); } } components/com_banners/controllers/index.html000066600000000037150771655440015604 0ustar00 components/com_banners/controllers/client.php000066600000001135150771655440015576 0ustar00registerTask('sticky_unpublish', 'sticky_publish'); } /** * Proxy for getModel. * * @param string $name The model name. Optional. * @param string $prefix The class prefix. Optional. * @param array $config Configuration array for model. Optional. * * @return object The model. * * @since 1.6 */ public function getModel($name = 'Banner', $prefix = 'BannersModel', $config = array('ignore_request' => true)) { $model = parent::getModel($name, $prefix, $config); return $model; } /** * Stick items * * @return void * * @since 1.6 */ public function sticky_publish() { // Check for request forgeries. JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); $ids = $this->input->get('cid', array(), 'array'); $values = array('sticky_publish' => 1, 'sticky_unpublish' => 0); $task = $this->getTask(); $value = JArrayHelper::getValue($values, $task, 0, 'int'); if (empty($ids)) { JError::raiseWarning(500, JText::_('COM_BANNERS_NO_BANNERS_SELECTED')); } else { // Get the model. $model = $this->getModel(); // Change the state of the records. if (!$model->stick($ids, $value)) { JError::raiseWarning(500, $model->getError()); } else { if ($value == 1) { $ntext = 'COM_BANNERS_N_BANNERS_STUCK'; } else { $ntext = 'COM_BANNERS_N_BANNERS_UNSTUCK'; } $this->setMessage(JText::plural($ntext, count($ids))); } } $this->setRedirect('index.php?option=com_banners&view=banners'); } } components/com_banners/controllers/tracks.raw.php000066600000006340150771655440016402 0ustar00 true)); return $model; } /** * Display method for the raw track data. * * @param boolean $cachable If true, the view output will be cached * @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()}. * * @return JController This object to support chaining. * * @since 1.5 * @todo This should be done as a view, not here! */ public function display($cachable = false, $urlparams = false) { // Get the document object. $document = JFactory::getDocument(); $vName = 'tracks'; $vFormat = 'raw'; // Get and render the view. if ($view = $this->getView($vName, $vFormat)) { // Get the model for the view. $model = $this->getModel($vName); // Load the filter state. $app = JFactory::getApplication(); $type = $app->getUserState($this->context . '.filter.type'); $model->setState('filter.type', $type); $begin = $app->getUserState($this->context . '.filter.begin'); $model->setState('filter.begin', $begin); $end = $app->getUserState($this->context . '.filter.end'); $model->setState('filter.end', $end); $categoryId = $app->getUserState($this->context . '.filter.category_id'); $model->setState('filter.category_id', $categoryId); $clientId = $app->getUserState($this->context . '.filter.client_id'); $model->setState('filter.client_id', $clientId); $model->setState('list.limit', 0); $model->setState('list.start', 0); $form = JRequest::getVar('jform'); $model->setState('basename', $form['basename']); $model->setState('compressed', $form['compressed']); $config = JFactory::getConfig(); $cookie_domain = $config->get('cookie_domain', ''); $cookie_path = $config->get('cookie_path', '/'); setcookie(JApplication::getHash($this->context . '.basename'), $form['basename'], time() + 365 * 86400, $cookie_path, $cookie_domain); setcookie(JApplication::getHash($this->context . '.compressed'), $form['compressed'], time() + 365 * 86400, $cookie_path, $cookie_domain); // Push the model into the view (as default). $view->setModel($model, true); // Push document object into the view. $view->document = $document; $view->display(); } } } components/com_banners/controllers/clients.php000066600000002137150771655440015764 0ustar00 true)) { $model = parent::getModel($name, $prefix, $config); return $model; } } components/com_banners/controllers/banner.php000066600000005222150771655440015566 0ustar00input->getInt('filter_category_id'); $categoryId = JArrayHelper::getValue($data, 'catid', $filter, 'int'); $allow = null; if ($categoryId) { // If the category has been passed in the URL check it. $allow = $user->authorise('core.create', $this->option . '.category.' . $categoryId); } if ($allow === null) { // In the absence of better information, revert to the component permissions. return parent::allowAdd($data); } else { return $allow; } } /** * Method override to check if you can edit an existing record. * * @param array $data An array of input data. * @param string $key The name of the key for the primary key. * * @return boolean * * @since 1.6 */ protected function allowEdit($data = array(), $key = 'id') { $user = JFactory::getUser(); $recordId = (int) isset($data[$key]) ? $data[$key] : 0; $categoryId = 0; if ($recordId) { $categoryId = (int) $this->getModel()->getItem($recordId)->catid; } if ($categoryId) { // The category has been set. Check the category permissions. return $user->authorise('core.edit', $this->option . '.category.' . $categoryId); } else { // Since there is no asset tracking, revert to the component permissions. return parent::allowEdit($data, $key); } } /** * Method to run batch operations. * * @param string $model The model * * @return boolean True on success. * * @since 2.5 */ public function batch($model = null) { JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Set the model $model = $this->getModel('Banner', '', array()); // Preset the redirect $this->setRedirect(JRoute::_('index.php?option=com_banners&view=banners' . $this->getRedirectToListAppend(), false)); return parent::batch($model); } } components/com_banners/access.xml000066600000002224150771655440013224 0ustar00
components/com_banners/helpers/html/index.html000066600000000037150771655440015644 0ustar00 components/com_banners/helpers/html/banner.php000066600000005450150771655440015631 0ustar00', JText::_('COM_BANNERS_BATCH_CLIENT_LABEL'), '', '' ); return implode("\n", $lines); } /** * Method to get the field options. * * @return array The field option objects. * * @since 1.6 */ public static function clientlist() { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('id As value, name As text') ->from('#__banner_clients AS a') ->order('a.name'); // Get the options. $db->setQuery($query); try { $options = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage()); } return $options; } /** * Returns a pinned state on a grid * * @param integer $value The state value. * @param integer $i The row index * @param boolean $enabled An optional setting for access control on the action. * @param string $checkbox An optional prefix for checkboxes. * * @return string The Html code * * @see JHtmlJGrid::state * * @since 2.5.5 */ public static function pinned($value, $i, $enabled = true, $checkbox = 'cb') { $states = array( 1 => array( 'sticky_unpublish', 'COM_BANNERS_BANNERS_PINNED', 'COM_BANNERS_BANNERS_HTML_PIN_BANNER', 'COM_BANNERS_BANNERS_PINNED', true, 'publish', 'publish' ), 0 => array( 'sticky_publish', 'COM_BANNERS_BANNERS_UNPINNED', 'COM_BANNERS_BANNERS_HTML_UNPIN_BANNER', 'COM_BANNERS_BANNERS_UNPINNED', true, 'unpublish', 'unpublish' ), ); return JHtml::_('jgrid.state', $states, $value, $i, 'banners.', $enabled, true, $checkbox); } } components/com_banners/helpers/index.html000066600000000037150771655440014700 0ustar00 components/com_banners/helpers/banners.php000066600000010612150771655440015044 0ustar00getNullDate(); $now = JFactory::getDate(); $query = $db->getQuery(true) ->select('*') ->from('#__banners') ->where($db->quote($now) . ' >= ' . $db->quote('reset')) ->where($db->quoteName('reset') . ' != ' . $db->quote($nullDate) . ' AND ' . $db->quoteName('reset') . '!=NULL') ->where('(' . $db->quoteName('checked_out') . ' = 0 OR ' . $db->quoteName('checked_out') . ' = ' . (int) $db->quote($user->id) . ')'); $db->setQuery($query); try { $rows = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage()); return false; } JTable::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR . '/tables'); foreach ($rows as $row) { $purchase_type = $row->purchase_type; if ($purchase_type < 0 && $row->cid) { $client = JTable::getInstance('Client', 'BannersTable'); $client->load($row->cid); $purchase_type = $client->purchase_type; } if ($purchase_type < 0) { $params = JComponentHelper::getParams('com_banners'); $purchase_type = $params->get('purchase_type'); } switch ($purchase_type) { case 1: $reset = $nullDate; break; case 2: $date = JFactory::getDate('+1 year ' . date('Y-m-d', strtotime('now'))); $reset = $db->quote($date->toSql()); break; case 3: $date = JFactory::getDate('+1 month ' . date('Y-m-d', strtotime('now'))); $reset = $db->quote($date->toSql()); break; case 4: $date = JFactory::getDate('+7 day ' . date('Y-m-d', strtotime('now'))); $reset = $db->quote($date->toSql()); break; case 5: $date = JFactory::getDate('+1 day ' . date('Y-m-d', strtotime('now'))); $reset = $db->quote($date->toSql()); break; } // Update the row ordering field. $query->clear() ->update($db->quoteName('#__banners')) ->set($db->quoteName('reset') . ' = ' . $db->quote($reset)) ->set($db->quoteName('impmade') . ' = ' . $db->quote(0)) ->set($db->quoteName('clicks') . ' = ' . $db->quote(0)) ->where($db->quoteName('id') . ' = ' . $db->quote($row->id)); $db->setQuery($query); try { $db->execute(); } catch (RuntimeException $e) { JError::raiseWarning(500, $db->getMessage()); return false; } } return true; } /** * Get client list in text/value format for a select field * * @return array */ public static function getClientOptions() { $options = array(); $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('id As value, name As text') ->from('#__banner_clients AS a') ->order('a.name'); // Get the options. $db->setQuery($query); try { $options = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage()); } // Merge any additional options in the XML definition. // $options = array_merge(parent::getOptions(), $options); array_unshift($options, JHtml::_('select.option', '0', JText::_('COM_BANNERS_NO_CLIENT'))); return $options; } } components/com_banners/models/tracks.php000066600000030342150771655440014526 0ustar00getUserStateFromRequest($this->context . '.filter.type', 'filter_type'); $this->setState('filter.type', $type); $begin = $this->getUserStateFromRequest($this->context . '.filter.begin', 'filter_begin', '', 'string'); $this->setState('filter.begin', $begin); $end = $this->getUserStateFromRequest($this->context . '.filter.end', 'filter_end', '', 'string'); $this->setState('filter.end', $end); $categoryId = $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id', ''); $this->setState('filter.category_id', $categoryId); $clientId = $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', ''); $this->setState('filter.client_id', $clientId); // Load the parameters. $params = JComponentHelper::getParams('com_banners'); $this->setState('params', $params); // List state information. parent::populateState('b.name', 'asc'); } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery * * @since 1.6 */ protected function getListQuery() { require_once JPATH_COMPONENT . '/helpers/banners.php'; // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Select the required fields from the table. $query->select( 'a.track_date as track_date,' . 'a.track_type as track_type,' . $db->quoteName('a.count') . ' as ' . $db->quoteName('count') ); $query->from($db->quoteName('#__banner_tracks') . ' AS a'); // Join with the banners $query->join('LEFT', $db->quoteName('#__banners') . ' as b ON b.id=a.banner_id') ->select('b.name as name'); // Join with the client $query->join('LEFT', $db->quoteName('#__banner_clients') . ' as cl ON cl.id=b.cid') ->select('cl.name as client_name'); // Join with the category $query->join('LEFT', $db->quoteName('#__categories') . ' as cat ON cat.id=b.catid') ->select('cat.title as category_title'); // Filter by type $type = $this->getState('filter.type'); if (!empty($type)) { $query->where('a.track_type = ' . (int) $type); } // Filter by client $clientId = $this->getState('filter.client_id'); if (is_numeric($clientId)) { $query->where('b.cid = ' . (int) $clientId); } // Filter by category $catedoryId = $this->getState('filter.category_id'); if (is_numeric($catedoryId)) { $query->where('b.catid = ' . (int) $catedoryId); } // Filter by begin date $begin = $this->getState('filter.begin'); if (!empty($begin)) { $query->where('a.track_date >= ' . $db->quote($begin)); } // Filter by end date $end = $this->getState('filter.end'); if (!empty($end)) { $query->where('a.track_date <= ' . $db->quote($end)); } // Add the list ordering clause. $orderCol = $this->getState('list.ordering', 'name'); $query->order($db->escape($orderCol) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); return $query; } /** * Method to delete rows. * * @return boolean Returns true on success, false on failure. */ public function delete() { $user = JFactory::getUser(); $categoryId = $this->getState('category_id'); // Access checks. if ($categoryId) { $allow = $user->authorise('core.delete', 'com_banners.category.' . (int) $categoryId); } else { $allow = $user->authorise('core.delete', 'com_banners'); } if ($allow) { // Delete tracks from this banner $db = $this->getDbo(); $query = $db->getQuery(true) ->delete($db->quoteName('#__banner_tracks')); // Filter by type $type = $this->getState('filter.type'); if (!empty($type)) { $query->where('track_type = ' . (int) $type); } // Filter by begin date $begin = $this->getState('filter.begin'); if (!empty($begin)) { $query->where('track_date >= ' . $db->quote($begin)); } // Filter by end date $end = $this->getState('filter.end'); if (!empty($end)) { $query->where('track_date <= ' . $db->quote($end)); } $where = '1'; // Filter by client $clientId = $this->getState('filter.client_id'); if (!empty($clientId)) { $where .= ' AND cid = ' . (int) $clientId; } // Filter by category if (!empty($categoryId)) { $where .= ' AND catid = ' . (int) $categoryId; } $query->where('banner_id IN (SELECT id FROM ' . $db->quoteName('#__banners') . ' WHERE ' . $where . ')'); $db->setQuery($query); $this->setError((string) $query); try { $db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } } else { JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); } return true; } /** * Get file name * * @return string The file name * * @since 1.6 */ public function getBaseName() { if (!isset($this->basename)) { $app = JFactory::getApplication(); $basename = $this->getState('basename'); $basename = str_replace('__SITE__', $app->getCfg('sitename'), $basename); $categoryId = $this->getState('filter.category_id'); if (is_numeric($categoryId)) { if ($categoryId > 0) { $basename = str_replace('__CATID__', $categoryId, $basename); } else { $basename = str_replace('__CATID__', '', $basename); } $categoryName = $this->getCategoryName(); $basename = str_replace('__CATNAME__', $categoryName, $basename); } else { $basename = str_replace('__CATID__', '', $basename); $basename = str_replace('__CATNAME__', '', $basename); } $clientId = $this->getState('filter.client_id'); if (is_numeric($clientId)) { if ($clientId > 0) { $basename = str_replace('__CLIENTID__', $clientId, $basename); } else { $basename = str_replace('__CLIENTID__', '', $basename); } $clientName = $this->getClientName(); $basename = str_replace('__CLIENTNAME__', $clientName, $basename); } else { $basename = str_replace('__CLIENTID__', '', $basename); $basename = str_replace('__CLIENTNAME__', '', $basename); } $type = $this->getState('filter.type'); if ($type > 0) { $basename = str_replace('__TYPE__', $type, $basename); $typeName = JText::_('COM_BANNERS_TYPE' . $type); $basename = str_replace('__TYPENAME__', $typeName, $basename); } else { $basename = str_replace('__TYPE__', '', $basename); $basename = str_replace('__TYPENAME__', '', $basename); } $begin = $this->getState('filter.begin'); if (!empty($begin)) { $basename = str_replace('__BEGIN__', $begin, $basename); } else { $basename = str_replace('__BEGIN__', '', $basename); } $end = $this->getState('filter.end'); if (!empty($end)) { $basename = str_replace('__END__', $end, $basename); } else { $basename = str_replace('__END__', '', $basename); } $this->basename = $basename; } return $this->basename; } /** * Get the category name. * * @return string The category name * * @since 1.6 */ protected function getCategoryName() { $categoryId = $this->getState('filter.category_id'); if ($categoryId) { $db = $this->getDbo(); $query = $db->getQuery(true) ->select('title') ->from($db->quoteName('#__categories')) ->where($db->quoteName('id') . '=' . $db->quote($categoryId)); $db->setQuery($query); try { $name = $db->loadResult(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } } else { $name = JText::_('COM_BANNERS_NOCATEGORYNAME'); } return $name; } /** * Get the category name * * @return string The category name. * * @since 1.6 */ protected function getClientName() { $clientId = $this->getState('filter.client_id'); if ($clientId) { $db = $this->getDbo(); $query = $db->getQuery(true) ->select('name') ->from($db->quoteName('#__banner_clients')) ->where($db->quoteName('id') . '=' . $db->quote($clientId)); $db->setQuery($query); try { $name = $db->loadResult(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } } else { $name = JText::_('COM_BANNERS_NOCLIENTNAME'); } return $name; } /** * Get the file type. * * @return string The file type * * @since 1.6 */ public function getFileType() { return $this->getState('compressed') ? 'zip' : 'csv'; } /** * Get the mime type. * * @return string The mime type. * * @since 1.6 */ public function getMimeType() { return $this->getState('compressed') ? 'application/zip' : 'text/csv'; } /** * Get the content * * @return string The content. * * @since 1.6 */ public function getContent() { if (!isset($this->content)) { $this->content = ''; $this->content .= '"' . str_replace('"', '""', JText::_('COM_BANNERS_HEADING_NAME')) . '","' . str_replace('"', '""', JText::_('COM_BANNERS_HEADING_CLIENT')) . '","' . str_replace('"', '""', JText::_('JCATEGORY')) . '","' . str_replace('"', '""', JText::_('COM_BANNERS_HEADING_TYPE')) . '","' . str_replace('"', '""', JText::_('COM_BANNERS_HEADING_COUNT')) . '","' . str_replace('"', '""', JText::_('JDATE')) . '"' . "\n"; foreach ($this->getItems() as $item) { $this->content .= '"' . str_replace('"', '""', $item->name) . '","' . str_replace('"', '""', $item->client_name) . '","' . str_replace('"', '""', $item->category_title) . '","' . str_replace('"', '""', ($item->track_type == 1 ? JText::_('COM_BANNERS_IMPRESSION') : JText::_('COM_BANNERS_CLICK'))) . '","' . str_replace('"', '""', $item->count) . '","' . str_replace('"', '""', $item->track_date) . '"' . "\n"; } if ($this->getState('compressed')) { $app = JFactory::getApplication('administrator'); $files = array(); $files['track'] = array(); $files['track']['name'] = $this->getBasename() . '.csv'; $files['track']['data'] = $this->content; $files['track']['time'] = time(); $ziproot = $app->getCfg('tmp_path') . '/' . uniqid('banners_tracks_') . '.zip'; // Run the packager jimport('joomla.filesystem.folder'); jimport('joomla.filesystem.file'); $delete = JFolder::files($app->getCfg('tmp_path') . '/', uniqid('banners_tracks_'), false, true); if (!empty($delete)) { if (!JFile::delete($delete)) { // JFile::delete throws an error $this->setError(JText::_('COM_BANNERS_ERR_ZIP_DELETE_FAILURE')); return false; } } if (!$packager = JArchive::getAdapter('zip')) { $this->setError(JText::_('COM_BANNERS_ERR_ZIP_ADAPTER_FAILURE')); return false; } elseif (!$packager->create($ziproot, $files)) { $this->setError(JText::_('COM_BANNERS_ERR_ZIP_CREATE_FAILURE')); return false; } $this->content = file_get_contents($ziproot); } } return $this->content; } } components/com_banners/models/download.php000066600000003662150771655440015053 0ustar00input; $basename = $input->cookie->getString(JApplication::getHash($this->_context . '.basename'), '__SITE__'); $this->setState('basename', $basename); $compressed = $input->cookie->getInt(JApplication::getHash($this->_context . '.compressed'), 1); $this->setState('compressed', $compressed); } /** * Method to get the record form. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return mixed A JForm object on success, false on failure * * @since 1.6 */ public function getForm($data = array(), $loadData = true) { // Get the form. $form = $this->loadForm('com_banners.download', 'download', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * * @since 1.6 */ protected function loadFormData() { $data = array( 'basename' => $this->getState('basename'), 'compressed' => $this->getState('compressed') ); $this->preprocessData('com_banners.download', $data); return $data; } } components/com_banners/models/index.html000066600000000037150771655440014521 0ustar00 components/com_banners/models/client.php000066600000006761150771655440014525 0ustar00id)) { if ($record->state != -2) { return; } $user = JFactory::getUser(); if (!empty($record->catid)) { return $user->authorise('core.delete', 'com_banners.category.' . (int) $record->catid); } else { return $user->authorise('core.delete', 'com_banners'); } } } /** * Method to test whether a record can be deleted. * * @param object $record A record object. * * @return boolean True if allowed to change the state of the record. * Defaults to the permission set in the component. * * @since 1.6 */ protected function canEditState($record) { $user = JFactory::getUser(); if (!empty($record->catid)) { return $user->authorise('core.edit.state', 'com_banners.category.' . (int) $record->catid); } else { return $user->authorise('core.edit.state', 'com_banners'); } } /** * Returns a reference to the a Table object, always creating it. * * @param string $type The table type to instantiate * @param string $prefix A prefix for the table class name. Optional. * @param array $config Configuration array for model. Optional. * * @return JTable A database object * * @since 1.6 */ public function getTable($type = 'Client', $prefix = 'BannersTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Method to get the record form. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return mixed A JForm object on success, false on failure * * @since 1.6 */ public function getForm($data = array(), $loadData = true) { // Get the form. $form = $this->loadForm('com_banners.client', 'client', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * * @since 1.6 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_banners.edit.client.data', array()); if (empty($data)) { $data = $this->getItem(); } $this->preprocessData('com_banners.client', $data); return $data; } /** * Prepare and sanitise the table prior to saving. * * @param JTable $table A JTable object. * * @return void * * @since 1.6 */ protected function prepareTable($table) { $table->name = htmlspecialchars_decode($table->name, ENT_QUOTES); } } components/com_banners/models/fields/impmade.php000066600000002143150771655440016117 0ustar00id . '\').value=\'0\';"'; return ' ' . JText::_('COM_BANNERS_RESET_IMPMADE') . ''; } } components/com_banners/models/fields/imptotal.php000066600000003136150771655440016337 0ustar00id . '_unlimited\').checked=document.id(\'' . $this->id . '\').value==\'\';"'; $onclick = ' onclick="if (document.id(\'' . $this->id . '_unlimited\').checked) document.id(\'' . $this->id . '\').value=\'\';"'; $value = empty($this->value) ? '' : $this->value; $checked = empty($this->value) ? ' checked="checked"' : ''; return '' . '
' . '
'; } } components/com_banners/models/fields/bannerclient.php000066600000001662150771655440017154 0ustar00 components/com_banners/models/fields/clicks.php000066600000002140150771655440015750 0ustar00id . '\').value=\'0\';"'; return ' ' . JText::_('COM_BANNERS_RESET_CLICKS') . ''; } } components/com_banners/models/forms/client.xml000066600000006606150771655440015662 0ustar00
components/com_banners/models/forms/filter_banners.xml000066600000005703150771655440017376 0ustar00
components/com_banners/models/forms/index.html000066600000000037150771655440015647 0ustar00 components/com_banners/models/forms/download.xml000066600000000776150771655440016215 0ustar00
components/com_banners/models/forms/banner.xml000066600000017170150771655440015647 0ustar00
components/com_banners/models/forms/filter_clients.xml000066600000004671150771655440017412 0ustar00
components/com_banners/models/banners.php000066600000016544150771655440014677 0ustar00cache['categoryorders'])) { $db = $this->getDbo(); $query = $db->getQuery(true) ->select('MAX(ordering) as ' . $db->quoteName('max') . ', catid') ->select('catid') ->from('#__banners') ->group('catid'); $db->setQuery($query); $this->cache['categoryorders'] = $db->loadAssocList('catid', 0); } return $this->cache['categoryorders']; } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery * * @since 1.6 */ protected function getListQuery() { $db = $this->getDbo(); $query = $db->getQuery(true); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.id AS id, a.name AS name, a.alias AS alias,' . 'a.checked_out AS checked_out,' . 'a.checked_out_time AS checked_out_time, a.catid AS catid,' . 'a.clicks AS clicks, a.metakey AS metakey, a.sticky AS sticky,' . 'a.impmade AS impmade, a.imptotal AS imptotal,' . 'a.state AS state, a.ordering AS ordering,' . 'a.purchase_type as purchase_type,' . 'a.language, a.publish_up, a.publish_down' ) ); $query->from($db->quoteName('#__banners') . ' AS a'); // Join over the language $query->select('l.title AS language_title') ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); // Join over the users for the checked out user. $query->select('uc.name AS editor') ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); // Join over the categories. $query->select('c.title AS category_title') ->join('LEFT', '#__categories AS c ON c.id = a.catid'); // Join over the clients. $query->select('cl.name AS client_name,cl.purchase_type as client_purchase_type') ->join('LEFT', '#__banner_clients AS cl ON cl.id = a.cid'); // Filter by published state $published = $this->getState('filter.state'); if (is_numeric($published)) { $query->where('a.state = ' . (int) $published); } elseif ($published === '') { $query->where('(a.state IN (0, 1))'); } // Filter by category. $categoryId = $this->getState('filter.category_id'); if (is_numeric($categoryId)) { $query->where('a.catid = ' . (int) $categoryId); } // Filter by client. $clientId = $this->getState('filter.client_id'); if (is_numeric($clientId)) { $query->where('a.cid = ' . (int) $clientId); } // Filter by search in title $search = $this->getState('filter.search'); if (!empty($search)) { if (stripos($search, 'id:') === 0) { $query->where('a.id = ' . (int) substr($search, 3)); } else { $search = $db->quote('%' . $db->escape($search, true) . '%'); $query->where('(a.name LIKE ' . $search . ' OR a.alias LIKE ' . $search . ')'); } } // Filter on the language. if ($language = $this->getState('filter.language')) { $query->where('a.language = ' . $db->quote($language)); } // Add the list ordering clause. $orderCol = $this->state->get('list.ordering', 'ordering'); $orderDirn = $this->state->get('list.direction', 'ASC'); if ($orderCol == 'ordering' || $orderCol == 'category_title') { $orderCol = 'c.title ' . $orderDirn . ', a.ordering'; } if ($orderCol == 'client_name') { $orderCol = 'cl.name'; } $query->order($db->escape($orderCol . ' ' . $orderDirn)); return $query; } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. * * @return string A store id. * * @since 1.6 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.access'); $id .= ':' . $this->getState('filter.state'); $id .= ':' . $this->getState('filter.category_id'); $id .= ':' . $this->getState('filter.language'); return parent::getStoreId($id); } /** * Returns a reference to the a Table object, always creating it. * * @param string $type The table type to instantiate * @param string $prefix A prefix for the table class name. Optional. * @param array $config Configuration array for model. Optional. * * @return JTable A database object * * @since 1.6 */ public function getTable($type = 'Banner', $prefix = 'BannersTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Method to auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @param string $ordering An optional ordering field. * @param string $direction An optional direction (asc|desc). * * @return void * * @since 1.6 */ protected function populateState($ordering = null, $direction = null) { // Load the filter state. $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string'); $this->setState('filter.state', $state); $categoryId = $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id', ''); $this->setState('filter.category_id', $categoryId); $clientId = $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', ''); $this->setState('filter.client_id', $clientId); $language = $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', ''); $this->setState('filter.language', $language); // Load the parameters. $params = JComponentHelper::getParams('com_banners'); $this->setState('params', $params); // List state information. parent::populateState('a.name', 'asc'); } } components/com_banners/models/clients.php000066600000011501150771655440014674 0ustar00getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string'); $this->setState('filter.state', $state); // Load the parameters. $params = JComponentHelper::getParams('com_banners'); $this->setState('params', $params); // List state information. parent::populateState('a.name', 'asc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. * * @return string A store id. */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.access'); $id .= ':' . $this->getState('filter.state'); return parent::getStoreId($id); } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); $params = JComponentHelper::getParams('com_banners'); $defaultPurchase = $params->get('purchase_type', 3); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.id AS id,' . 'a.name AS name,' . 'a.contact AS contact,' . 'a.checked_out AS checked_out,' . 'a.checked_out_time AS checked_out_time, ' . 'a.state AS state,' . 'a.metakey AS metakey,' . 'a.purchase_type as purchase_type' ) ); $query->from($db->quoteName('#__banner_clients') . ' AS a'); // Join over the banners for counting $query->select('COUNT(b.id) as nbanners') ->join('LEFT', '#__banners AS b ON a.id = b.cid'); // Join over the users for the checked out user. $query->select('uc.name AS editor') ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); // Filter by published state $published = $this->getState('filter.state'); if (is_numeric($published)) { $query->where('a.state = ' . (int) $published); } elseif ($published === '') { $query->where('(a.state IN (0, 1))'); } $query->group('a.id, a.name, a.contact, a.checked_out, a.checked_out_time, a.state, a.metakey, a.purchase_type, uc.name'); // Filter by search in title $search = $this->getState('filter.search'); if (!empty($search)) { if (stripos($search, 'id:') === 0) { $query->where('a.id = ' . (int) substr($search, 3)); } else { $search = $db->quote('%' . $db->escape($search, true) . '%'); $query->where('a.name LIKE ' . $search); } } // Filter by purchase type $purchaseType = $this->getState('filter.purchase_type'); if (!empty($purchaseType)) { if ($defaultPurchase == $purchaseType) { $query->where('(a.purchase_type = ' . (int) $purchaseType . ' OR a.purchase_type = -1)'); } else { $query->where('a.purchase_type = ' . (int) $purchaseType); } } $ordering = $this->getState('list.ordering', 'ordering'); if ($ordering == 'nbanners') { $ordering = 'COUNT(b.id)'; } // Add the list ordering clause. $query->order($db->escape($ordering) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); return $query; } } components/com_banners/models/banner.php000066600000031212150771655440014501 0ustar00setError(JText::_('JGLOBAL_NO_ITEM_SELECTED')); return false; } $done = false; if (!empty($commands['category_id'])) { $cmd = JArrayHelper::getValue($commands, 'move_copy', 'c'); if ($cmd == 'c') { $result = $this->batchCopy($commands['category_id'], $pks, $contexts); if (is_array($result)) { $pks = $result; } else { return false; } } elseif ($cmd == 'm' && !$this->batchMove($commands['category_id'], $pks, $contexts)) { return false; } $done = true; } if (strlen($commands['client_id']) > 0) { if (!$this->batchClient($commands['client_id'], $pks, $contexts)) { return false; } $done = true; } if (!empty($commands['language_id'])) { if (!$this->batchLanguage($commands['language_id'], $pks, $contexts)) { return false; } $done = true; } if (!$done) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); return false; } // Clear the cache $this->cleanCache(); return true; } /** * Batch client changes for a group of banners. * * @param string $value The new value matching a client. * @param array $pks An array of row IDs. * @param array $contexts An array of item contexts. * * @return boolean True if successful, false otherwise and internal error is set. * * @since 2.5 */ protected function batchClient($value, $pks, $contexts) { // Set the variables $user = JFactory::getUser(); $table = $this->getTable(); foreach ($pks as $pk) { if ($user->authorise('core.edit', $contexts[$pk])) { $table->reset(); $table->load($pk); $table->cid = (int) $value; if (!$table->store()) { $this->setError($table->getError()); return false; } } else { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); return false; } } // Clean the cache $this->cleanCache(); return true; } /** * Batch copy items to a new category or current. * * @param integer $value The new category. * @param array $pks An array of row IDs. * @param array $contexts An array of item contexts. * * @return mixed An array of new IDs on success, boolean false on failure. * * @since 2.5 */ protected function batchCopy($value, $pks, $contexts) { $categoryId = (int) $value; $table = $this->getTable(); $i = 0; // Check that the category exists if ($categoryId) { $categoryTable = JTable::getInstance('Category'); if (!$categoryTable->load($categoryId)) { if ($error = $categoryTable->getError()) { // Fatal error $this->setError($error); return false; } else { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); return false; } } } if (empty($categoryId)) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); return false; } // Check that the user has create permission for the component $user = JFactory::getUser(); if (!$user->authorise('core.create', 'com_banners.category.' . $categoryId)) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); return false; } // Parent exists so we let's proceed while (!empty($pks)) { // Pop the first ID off the stack $pk = array_shift($pks); $table->reset(); // Check that the row actually exists if (!$table->load($pk)) { if ($error = $table->getError()) { // Fatal error $this->setError($error); return false; } else { // Not fatal error $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk)); continue; } } // Alter the title & alias $data = $this->generateNewTitle($categoryId, $table->alias, $table->name); $table->name = $data['0']; $table->alias = $data['1']; // Reset the ID because we are making a copy $table->id = 0; // New category ID $table->catid = $categoryId; // TODO: Deal with ordering? // $table->ordering = 1; // Check the row. if (!$table->check()) { $this->setError($table->getError()); return false; } // Store the row. if (!$table->store()) { $this->setError($table->getError()); return false; } // Get the new item ID $newId = $table->get('id'); // Add the new ID to the array $newIds[$i] = $newId; $i++; } // Clean the cache $this->cleanCache(); return $newIds; } /** * Method to test whether a record can be deleted. * * @param object $record A record object. * * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. * * @since 1.6 */ protected function canDelete($record) { if (!empty($record->id)) { if ($record->state != -2) { return; } $user = JFactory::getUser(); if (!empty($record->catid)) { return $user->authorise('core.delete', 'com_banners.category.' . (int) $record->catid); } else { return parent::canDelete($record); } } } /** * Method to test whether a record can have its state changed. * * @param object $record A record object. * * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. * * @since 1.6 */ protected function canEditState($record) { $user = JFactory::getUser(); // Check against the category. if (!empty($record->catid)) { return $user->authorise('core.edit.state', 'com_banners.category.' . (int) $record->catid); } // Default to component settings if category not known. else { return parent::canEditState($record); } } /** * Returns a JTable object, always creating it. * * @param string $type The table type to instantiate. [optional] * @param string $prefix A prefix for the table class name. [optional] * @param array $config Configuration array for model. [optional] * * @return JTable A database object * * @since 1.6 */ public function getTable($type = 'Banner', $prefix = 'BannersTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Method to get the record form. * * @param array $data Data for the form. [optional] * @param boolean $loadData True if the form is to load its own data (default case), false if not. [optional] * * @return mixed A JForm object on success, false on failure * * @since 1.6 */ public function getForm($data = array(), $loadData = true) { // Get the form. $form = $this->loadForm('com_banners.banner', 'banner', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } // Determine correct permissions to check. if ($this->getState('banner.id')) { // Existing record. Can only edit in selected categories. $form->setFieldAttribute('catid', 'action', 'core.edit'); } else { // New record. Can only create in selected categories. $form->setFieldAttribute('catid', 'action', 'core.create'); } // Modify the form based on access controls. if (!$this->canEditState((object) $data)) { // Disable fields for display. $form->setFieldAttribute('ordering', 'disabled', 'true'); $form->setFieldAttribute('publish_up', 'disabled', 'true'); $form->setFieldAttribute('publish_down', 'disabled', 'true'); $form->setFieldAttribute('state', 'disabled', 'true'); $form->setFieldAttribute('sticky', 'disabled', 'true'); // Disable fields while saving. // The controller has already verified this is a record you can edit. $form->setFieldAttribute('ordering', 'filter', 'unset'); $form->setFieldAttribute('publish_up', 'filter', 'unset'); $form->setFieldAttribute('publish_down', 'filter', 'unset'); $form->setFieldAttribute('state', 'filter', 'unset'); $form->setFieldAttribute('sticky', 'filter', 'unset'); } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * * @since 1.6 */ protected function loadFormData() { // Check the session for previously entered form data. $app = JFactory::getApplication(); $data = $app->getUserState('com_banners.edit.banner.data', array()); if (empty($data)) { $data = $this->getItem(); // Prime some default values. if ($this->getState('banner.id') == 0) { $filters = (array) $app->getUserState('com_banners.banners.filter'); $filterCatId = isset($filters['category_id']) ? $filters['category_id'] : null; $data->set('catid', $app->input->getInt('catid', $filterCatId)); } } $this->preprocessData('com_banners.banner', $data); return $data; } /** * Method to stick records. * * @param array &$pks The ids of the items to publish. * @param integer $value The value of the published state * * @return boolean True on success. * * @since 1.6 */ public function stick(&$pks, $value = 1) { $user = JFactory::getUser(); $table = $this->getTable(); $pks = (array) $pks; // Access checks. foreach ($pks as $i => $pk) { if ($table->load($pk)) { if (!$this->canEditState($table)) { // Prune items that you can't change. unset($pks[$i]); JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); } } } // Attempt to change the state of the records. if (!$table->stick($pks, $value, $user->get('id'))) { $this->setError($table->getError()); return false; } return true; } /** * A protected method to get a set of ordering conditions. * * @param JTable $table A record object. * * @return array An array of conditions to add to add to ordering queries. * * @since 1.6 */ protected function getReorderConditions($table) { $condition = array(); $condition[] = 'catid = ' . (int) $table->catid; $condition[] = 'state >= 0'; return $condition; } /** * Prepare and sanitise the table prior to saving. * * @param JTable $table A JTable object. * * @return void * * @since 1.6 */ protected function prepareTable($table) { $date = JFactory::getDate(); $user = JFactory::getUser(); if (empty($table->id)) { // Set the values $table->created = $date->toSql(); // Set ordering to the last item if not set if (empty($table->ordering)) { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('MAX(ordering)') ->from('#__banners'); $db->setQuery($query); $max = $db->loadResult(); $table->ordering = $max + 1; } } else { // Set the values $table->modified = $date->toSql(); $table->modified_by = $user->get('id'); } // Increment the content version number. $table->version++; } /** * Method to save the form data. * * @param array $data The form data. * * @return boolean True on success. * * @since 1.6 */ public function save($data) { $app = JFactory::getApplication(); // Alter the name for save as copy if ($app->input->get('task') == 'save2copy') { list($name, $alias) = $this->generateNewTitle($data['catid'], $data['alias'], $data['name']); $data['name'] = $name; $data['alias'] = $alias; $data['state'] = 0; } if (parent::save($data)) { return true; } return false; } } components/com_languages/languages.php000066600000001140150771655440014232 0ustar00authorise('core.manage', 'com_languages')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } $controller = JControllerLegacy::getInstance('Languages'); $controller->execute(JFactory::getApplication()->input->get('task')); $controller->redirect(); components/com_languages/views/override/view.html.php000066600000005343150771655440017166 0ustar00form = $this->get('Form'); $this->item = $this->get('Item'); $this->state = $this->get('State'); // Check for errors if (count($errors = $this->get('Errors'))) { throw new Exception(implode("\n", $errors)); } // Check whether the cache has to be refreshed $cached_time = JFactory::getApplication()->getUserState('com_languages.overrides.cachedtime.'.$this->state->get('filter.client').'.'.$this->state->get('filter.language'), 0); if (time() - $cached_time > 60 * 5) { $this->state->set('cache_expired', true); } // Add strings for translations in Javascript JText::script('COM_LANGUAGES_VIEW_OVERRIDE_NO_RESULTS'); JText::script('COM_LANGUAGES_VIEW_OVERRIDE_REQUEST_ERROR'); $this->addToolbar(); parent::display($tpl); } /** * Adds the page title and toolbar * * @return void * * @since 2.5 */ protected function addToolbar() { JFactory::getApplication()->input->set('hidemainmenu', true); $canDo = JHelperContent::getActions('com_languages'); JToolbarHelper::title(JText::_('COM_LANGUAGES_VIEW_OVERRIDE_EDIT_TITLE'), 'comments-2 langmanager'); if ($canDo->get('core.edit')) { JToolbarHelper::apply('override.apply'); JToolbarHelper::save('override.save'); } // This component does not support Save as Copy if ($canDo->get('core.edit') && $canDo->get('core.create')) { JToolbarHelper::save2new('override.save2new'); } if (empty($this->item->key)) { JToolbarHelper::cancel('override.cancel'); } else { JToolbarHelper::cancel('override.cancel', 'JTOOLBAR_CLOSE'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT'); } } components/com_languages/views/override/tmpl/edit.php000066600000010765150771655440017156 0ustar00
item->key) ? JText::_('COM_LANGUAGES_VIEW_OVERRIDE_EDIT_NEW_OVERRIDE_LEGEND') : JText::_('COM_LANGUAGES_VIEW_OVERRIDE_EDIT_EDIT_OVERRIDE_LEGEND'); ?>
form->getLabel('key'); ?>
form->getInput('key'); ?>
form->getLabel('override'); ?>
form->getInput('override'); ?>
state->get('filter.client') == 'administrator') : ?>
form->getLabel('both'); ?>
form->getInput('both'); ?>
form->getLabel('language'); ?>
form->getInput('language'); ?>
form->getLabel('client'); ?>
form->getInput('client'); ?>
form->getLabel('file'); ?>
form->getInput('file'); ?>

form->getInput('searchstring'); ?>
form->getLabel('searchtype'); ?>
form->getInput('searchtype'); ?>
components/com_languages/views/override/tmpl/index.html000066600000000037150771655440017504 0ustar00 components/com_languages/views/override/index.html000066600000000037150771655440016530 0ustar00 components/com_languages/views/languages/view.html.php000066600000007266150771655440017323 0ustar00items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); LanguagesHelper::addSubmenu('languages'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { $canDo = JHelperContent::getActions('com_languages'); JToolbarHelper::title(JText::_('COM_LANGUAGES_VIEW_LANGUAGES_TITLE'), 'comments-2 langmanager'); if ($canDo->get('core.create')) { JToolbarHelper::addNew('language.add'); } if ($canDo->get('core.edit')) { JToolbarHelper::editList('language.edit'); JToolbarHelper::divider(); } if ($canDo->get('core.edit.state')) { if ($this->state->get('filter.published') != 2) { JToolbarHelper::publishList('languages.publish'); JToolbarHelper::unpublishList('languages.unpublish'); } } if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')) { JToolbarHelper::deleteList('', 'languages.delete', 'JTOOLBAR_EMPTY_TRASH'); JToolbarHelper::divider(); } elseif ($canDo->get('core.edit.state')) { JToolbarHelper::trash('languages.trash'); JToolbarHelper::divider(); } if ($canDo->get('core.admin')) { // Add install languages link to the lang installer component $bar = JToolbar::getInstance('toolbar'); $bar->appendButton('Link', 'upload', 'COM_LANGUAGES_INSTALL', 'index.php?option=com_installer&view=languages'); JToolbarHelper::divider(); JToolbarHelper::preferences('com_languages'); JToolbarHelper::divider(); } JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_CONTENT'); JHtmlSidebar::setAction('index.php?option=com_languages&view=languages'); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_PUBLISHED'), 'filter_published', JHtml::_('select.options', JHtml::_('jgrid.publishedOptions'), 'value', 'text', $this->state->get('filter.published'), true) ); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_ACCESS'), 'filter_access', JHtml::_('select.options', JHtml::_('access.assetgroups'), 'value', 'text', $this->state->get('filter.access')) ); } /** * Returns an array of fields the table can be sorted by * * @return array Array containing the field name to sort by as the key and display text as value * * @since 3.0 */ protected function getSortFields() { return array( 'a.ordering' => JText::_('JGRID_HEADING_ORDERING'), 'a.published' => JText::_('JSTATUS'), 'a.title' => JText::_('JGLOBAL_TITLE'), 'a.title_native' => JText::_('COM_LANGUAGES_HEADING_TITLE_NATIVE'), 'a.lang_code' => JText::_('COM_LANGUAGES_FIELD_LANG_TAG_LABEL'), 'a.sef' => JText::_('COM_LANGUAGES_FIELD_LANG_CODE_LABEL'), 'a.image' => JText::_('COM_LANGUAGES_HEADING_LANG_IMAGE'), 'a.access' => JText::_('JGRID_HEADING_ACCESS'), 'a.lang_id' => JText::_('JGRID_HEADING_ID') ); } } components/com_languages/views/languages/tmpl/default.php000066600000021402150771655440017772 0ustar00get('id'); $n = count($this->items); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $canOrder = $user->authorise('core.edit.state', 'com_languages'); $saveOrder = $listOrder == 'a.ordering'; if ($saveOrder) { $saveOrderingUrl = 'index.php?option=com_languages&task=languages.saveOrderAjax&tmpl=component'; JHtml::_('sortablelist.sortable', 'contentList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); } $sortFields = $this->getSortFields(); ?>
sidebar)) : ?>
sidebar; ?>
pagination->getLimitBox(); ?>
items as $i => $item) : $ordering = ($listOrder == 'a.ordering'); $canCreate = $user->authorise('core.create', 'com_languages'); $canEdit = $user->authorise('core.edit', 'com_languages'); $canChange = $user->authorise('core.edit.state', 'com_languages'); ?>
', 'a.ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING'); ?>
pagination->getListFooter(); ?>
lang_id); ?> published, $i, 'languages.', $canChange); ?> escape($item->title); ?> escape($item->title); ?> escape($item->title_native); ?> escape($item->lang_code); ?> escape($item->sef); ?> escape($item->image); ?> image.'.gif', $item->image, array('title' => $item->image), true); ?> escape($item->access_level); ?> home == '1') : ?> escape($item->lang_id); ?>
components/com_languages/views/languages/tmpl/index.html000066600000000037150771655440017633 0ustar00 components/com_languages/views/languages/index.html000066600000000037150771655440016657 0ustar00 components/com_languages/views/multilangstatus/view.html.php000066600000002153150771655440020603 0ustar00homes = MultilangstatusHelper::getHomes(); $this->language_filter = JLanguageMultilang::isEnabled(); $this->switchers = MultilangstatusHelper::getLangswitchers(); $this->listUsersError = MultilangstatusHelper::getContacts(); $this->contentlangs = MultilangstatusHelper::getContentlangs(); $this->site_langs = MultilangstatusHelper::getSitelangs(); $this->statuses = MultilangstatusHelper::getStatus(); $this->homepages = MultilangstatusHelper::getHomepages(); parent::display($tpl); } } components/com_languages/views/multilangstatus/tmpl/default.php000066600000015761150771655440021277 0ustar00homes == 2 || $this->homes == 1 || $this->homes - 1 != count($this->contentlangs) && ($this->language_filter || $this->switchers != 0); $notice_disabled = !$this->language_filter && ($this->homes > 1 || $this->switchers != 0); $notice_switchers = !$this->switchers && ($this->homes > 1 || $this->language_filter); ?>
language_filter && $this->switchers == 0) : ?> homes == 1) : ?>
contentlangs as $contentlang) : ?> lang_code, $this->homepages) && (!array_key_exists($contentlang->lang_code, $this->site_langs) || !$contentlang->published)) : ?> lang_code, $this->site_langs)) : ?> listUsersError) : ?>
lang_code); ?>
lang_code); ?>
    listUsersError as $user) : ?>
  • name); ?>
language_filter) : ?>
switchers != 0) : ?> switchers; ?>
homes > 1) : ?> homes > 1) : ?> homes; ?>
statuses as $status) : ?> element) : ?> element) : // Published Site languages ?> lang_code && $status->published) : // Published Content languages ?> home_language) : // Published Home pages ?> contentlangs as $contentlang) : ?> lang_code, $this->site_langs)) : ?>
element; ?>
lang_code; ?> published) : ?> published && array_key_exists($contentlang->lang_code, $this->homepages)) : ?> published) : ?> lang_code, $this->homepages)) : ?>
components/com_languages/views/multilangstatus/tmpl/index.html000066600000000037150771655440021125 0ustar00 components/com_languages/views/multilangstatus/index.html000066600000000037150771655440020151 0ustar00 components/com_languages/views/index.html000066600000000037150771655440014711 0ustar00 components/com_languages/views/installed/view.html.php000066600000004362150771655440017326 0ustar00ftp = $this->get('Ftp'); $this->option = $this->get('Option'); $this->pagination = $this->get('Pagination'); $this->rows = $this->get('Data'); $this->state = $this->get('State'); $client = (int) $this->state->get('filter.client_id', 0); LanguagesHelper::addSubmenu('installed', $client); $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { $canDo = JHelperContent::getActions('com_languages'); JToolbarHelper::title(JText::_('COM_LANGUAGES_VIEW_INSTALLED_TITLE'), 'comments-2 langmanager'); if ($canDo->get('core.edit.state')) { JToolbarHelper::makeDefault('installed.setDefault'); JToolbarHelper::divider(); } if ($canDo->get('core.admin')) { // Add install languages link to the lang installer component $bar = JToolbar::getInstance('toolbar'); $bar->appendButton('Link', 'upload', 'COM_LANGUAGES_INSTALL', 'index.php?option=com_installer&view=languages'); JToolbarHelper::divider(); JToolbarHelper::preferences('com_languages'); JToolbarHelper::divider(); } JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_INSTALLED'); $this->sidebar = JHtmlSidebar::render(); } } components/com_languages/views/installed/tmpl/default.php000066600000006277150771655440020020 0ustar00get('id'); $client = $this->state->get('filter.client_id', 0) ? JText::_('JADMINISTRATOR') : JText::_('JSITE'); $clientId = $this->state->get('filter.client_id', 0); ?>
sidebar)) : ?>
sidebar; ?>
rows as $i => $row) : $canCreate = $user->authorise('core.create', 'com_languages'); $canEdit = $user->authorise('core.edit', 'com_languages'); $canChange = $user->authorise('core.edit.state', 'com_languages'); ?>
 
pagination->getListFooter(); ?>
language);?> escape($row->name); ?> escape($row->language); ?> published, $i, 'installed.', !$row->published && $canChange);?> escape($row->version); ?> escape($row->creationDate); ?> escape($row->author); ?> escape($row->authorEmail)); ?>
components/com_languages/views/installed/tmpl/index.html000066600000000037150771655440017644 0ustar00 components/com_languages/views/installed/index.html000066600000000037150771655440016670 0ustar00 components/com_languages/views/language/view.html.php000066600000004226150771655440017131 0ustar00item = $this->get('Item'); $this->form = $this->get('Form'); $this->state = $this->get('State'); $this->canDo = JHelperContent::getActions('com_languages'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { require_once JPATH_COMPONENT . '/helpers/languages.php'; JFactory::getApplication()->input->set('hidemainmenu', 1); $isNew = empty($this->item->lang_id); $canDo = $this->canDo; JToolbarHelper::title(JText::_($isNew ? 'COM_LANGUAGES_VIEW_LANGUAGE_EDIT_NEW_TITLE' : 'COM_LANGUAGES_VIEW_LANGUAGE_EDIT_EDIT_TITLE'), 'comments-2 langmanager'); // If a new item, can save. if ($isNew && $canDo->get('core.create')) { JToolbarHelper::save('language.save'); } //If an existing item, allow to Apply and Save. if (!$isNew && $canDo->get('core.edit')) { JToolbarHelper::apply('language.apply'); JToolbarHelper::save('language.save'); } // If an existing item, can save to a copy only if we have create rights. if ($canDo->get('core.create')) { JToolbarHelper::save2new('language.save2new'); } if ($isNew) { JToolbarHelper::cancel('language.cancel'); } else { JToolbarHelper::cancel('language.cancel', 'JTOOLBAR_CLOSE'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_EDIT'); $this->sidebar = JHtmlSidebar::render(); } } components/com_languages/views/language/tmpl/edit.php000066600000006345150771655440017121 0ustar00
'details')); ?> form->renderField('title'); ?> form->renderField('title_native'); ?> form->renderField('lang_code'); ?> form->renderField('sef'); ?>
form->getLabel('image'); ?>
form->getInput('image'); ?> form->getValue('image') . '.gif', $this->form->getValue('image'), array('title' => $this->form->getValue('image')), true); ?>
canDo->get('core.edit.state')) : ?> form->renderField('published'); ?> form->renderField('access'); ?> form->renderField('description'); ?> form->renderField('lang_id'); ?> form->renderFieldset('metadata'); ?> form->renderFieldset('site_name'); ?>
components/com_languages/views/language/tmpl/index.html000066600000000037150771655440017450 0ustar00 components/com_languages/views/language/index.html000066600000000037150771655440016474 0ustar00 components/com_languages/views/overrides/view.html.php000066600000004706150771655440017353 0ustar00state = $this->get('State'); $this->items = $this->get('Overrides'); $this->languages = $this->get('Languages'); $this->pagination = $this->get('Pagination'); LanguagesHelper::addSubmenu('overrides'); // Check for errors if (count($errors = $this->get('Errors'))) { throw new Exception(implode("\n", $errors)); } $this->addToolbar(); parent::display($tpl); } /** * Adds the page title and toolbar * * @return void * * @since 2.5 */ protected function addToolbar() { // Get the results for each action $canDo = JHelperContent::getActions('com_languages'); JToolbarHelper::title(JText::_('COM_LANGUAGES_VIEW_OVERRIDES_TITLE'), 'comments-2 langmanager'); if ($canDo->get('core.create')) { JToolbarHelper::addNew('override.add'); } if ($canDo->get('core.edit') && $this->pagination->total) { JToolbarHelper::editList('override.edit'); } if ($canDo->get('core.delete') && $this->pagination->total) { JToolbarHelper::deleteList('', 'overrides.delete'); } if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_languages'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES'); JHtmlSidebar::setAction('index.php?option=com_languages&view=overrides'); JHtmlSidebar::addFilter( // @todo need a label here '', 'filter_language_client', JHtml::_('select.options', $this->languages, null, 'text', $this->state->get('filter.language_client')), true ); $this->sidebar = JHtmlSidebar::render(); } } components/com_languages/views/overrides/tmpl/default.php000066600000010165150771655440020032 0ustar00state->get('filter.client') == 'site' ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); $language = $this->state->get('filter.language'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?>
sidebar)) : ?>
sidebar; ?>
pagination->getLimitBox(); ?>
authorise('core.edit', 'com_languages'); $i = 0; foreach ($this->items as $key => $text) : ?>
pagination->getListFooter(); ?>
escape($key); ?> escape($key); ?> escape($text); ?>
components/com_languages/views/overrides/tmpl/index.html000066600000000036150771655440017666 0ustar00components/com_languages/views/overrides/index.html000066600000000036150771655440016712 0ustar00components/com_languages/index.html000066600000000037150771655440013554 0ustar00 components/com_languages/config.xml000066600000000712150771655440013546 0ustar00
components/com_languages/languages.xml000066600000002105150771655440014245 0ustar00 com_languages Joomla! Project 2006 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_LANGUAGES_XML_DESCRIPTION config.xml controller.php index.html languages.php controllers helpers models tables views language/en-GB.com_languages.ini language/en-GB.com_languages.sys.ini components/com_languages/controller.php000066600000003143150771655440014454 0ustar00input->get('view', 'languages'); $layout = $this->input->get('layout', 'default'); $id = $this->input->getInt('id'); // Check for edit form. if ($view == 'language' && $layout == 'edit' && !$this->checkEditId('com_languages.edit.language', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_languages&view=languages', false)); return false; } parent::display(); return $this; } } components/com_languages/controllers/languages.php000066600000003015150771655440016603 0ustar00 true)) { $model = parent::getModel($name, $prefix, $config); return $model; } /** * Method to save the submitted ordering values for records via AJAX. * * @return void * * @since 3.1 */ public function saveOrderAjax() { $pks = $this->input->post->get('cid', array(), 'array'); $order = $this->input->post->get('order', array(), 'array'); // Sanitize the input JArrayHelper::toInteger($pks); JArrayHelper::toInteger($order); // Get the model $model = $this->getModel(); // Save the ordering $return = $model->saveorder($pks, $order); if ($return) { echo "1"; } // Close the application JFactory::getApplication()->close(); } } components/com_languages/controllers/language.php000066600000001633150771655440016424 0ustar00input->get('cid', array(), 'array'); if (!is_array($cid) || count($cid) < 1) { $this->setMessage(JText::_($this->text_prefix.'_NO_ITEM_SELECTED'), 'warning'); } else { // Get the model $model = $this->getModel('overrides'); // Remove the items if ($model->delete($cid)) { $this->setMessage(JText::plural($this->text_prefix.'_N_ITEMS_DELETED', count($cid))); } else { $this->setMessage($model->getError()); } } $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_list, false)); } } components/com_languages/controllers/installed.php000066600000002055150771655440016617 0ustar00input->get('cid', ''); $model = $this->getModel('installed'); if ($model->publish($cid)) { $msg = JText::_('COM_LANGUAGES_MSG_DEFAULT_LANGUAGE_SAVED'); $type = 'message'; } else { $msg = $this->getError(); $type = 'error'; } $clientId = $model->getState('filter.client_id'); $this->setredirect('index.php?option=com_languages&view=installed&client='.$clientId, $msg, $type); } } components/com_languages/controllers/override.php000066600000013517150771655440016464 0ustar00input->post->get('cid', array(), 'array'); $context = "$this->option.edit.$this->context"; // Get the constant name $recordId = (count($cid) ? $cid[0] : $this->input->get('id')); // Access check if (!$this->allowEdit()) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED')); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_list.$this->getRedirectToListAppend(), false)); return; } $app->setUserState($context.'.data', null); $this->setRedirect('index.php?option='.$this->option.'&view='.$this->view_item.$this->getRedirectToItemAppend($recordId, 'id')); } /** * Method to save an override * * @param string $key The name of the primary key of the URL variable (not used here). * @param string $urlVar The name of the URL variable if different from the primary key (not used here). * * @return void * * @since 2.5 */ public function save($key = null, $urlVar = null) { // Check for request forgeries JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); $app = JFactory::getApplication(); $model = $this->getModel(); $data = $this->input->post->get('jform', array(), 'array'); $context = "$this->option.edit.$this->context"; $task = $this->getTask(); $recordId = $this->input->get('id'); $data['id'] = $recordId; // Access check if (!$this->allowSave($data, 'id')) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_list.$this->getRedirectToListAppend(), false)); return; } // Validate the posted data $form = $model->getForm($data, false); if (!$form) { $app->enqueueMessage($model->getError(), 'error'); return; } // Require helper for filter functions called by JForm require_once JPATH_COMPONENT.'/helpers/languages.php'; // Test whether the data is valid. $validData = $model->validate($form, $data); // Check for validation errors. if ($validData === false) { // Get the validation messages $errors = $model->getErrors(); // Push up to three validation messages out to the user. for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) { if ($errors[$i] instanceof Exception) { $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); } else { $app->enqueueMessage($errors[$i], 'warning'); } } // Save the data in the session $app->setUserState($context.'.data', $data); // Redirect back to the edit screen $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_item.$this->getRedirectToItemAppend($recordId, 'id'), false)); return; } // Attempt to save the data if (!$model->save($validData)) { // Save the data in the session $app->setUserState($context.'.data', $validData); // Redirect back to the edit screen $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError())); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_item.$this->getRedirectToItemAppend($recordId, 'id'), false)); return; } // Add message of success $this->setMessage(JText::_('COM_LANGUAGES_VIEW_OVERRIDE_SAVE_SUCCESS')); // Redirect the user and adjust session state based on the chosen task switch ($task) { case 'apply': // Set the record data in the session $app->setUserState($context.'.data', null); // Redirect back to the edit screen $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_item.$this->getRedirectToItemAppend($validData['key'], 'id'), false)); break; case 'save2new': // Clear the record id and data from the session $app->setUserState($context.'.data', null); // Redirect back to the edit screen $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_item.$this->getRedirectToItemAppend(null, 'id'), false)); break; default: // Clear the record id and data from the session $app->setUserState($context.'.data', null); // Redirect to the list screen $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_list.$this->getRedirectToListAppend(), false)); break; } } /** * Method to cancel an edit * * @param string $key The name of the primary key of the URL variable (not used here). * * @return void * * @since 2.5 */ public function cancel($key = null, $test = null) { JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); $app = JFactory::getApplication(); $context = "$this->option.edit.$this->context"; $app->setUserState($context.'.data', null); $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_list.$this->getRedirectToListAppend(), false)); } } components/com_languages/controllers/index.html000066600000000037150771655440016122 0ustar00 components/com_languages/controllers/strings.json.php000066600000001606150771655440017302 0ustar00getModel('strings')->refresh()); } /** * Method for searching language strings * * @return void * * @since 2.5 */ public function search() { echo new JResponseJson($this->getModel('strings')->search()); } } components/com_languages/access.xml000066600000001320150771655440013536 0ustar00
components/com_languages/helpers/languages.php000066600000006317150771655440015707 0ustar00clean($value, 'cmd')); } /** * Filter method for language strings. * This method will be called by JForm while filtering the form data. * * @param string $value The language string to filter * * @return string The filtered language string * * @since 2.5 */ public static function filterText($value) { $filter = JFilterInput::getInstance(null, null, 1, 1); return $filter->clean($value); } } components/com_languages/helpers/jsonresponse.php000066600000005223150771655440016464 0ustar00success, * so you can use both flags equivalently. * * @var boolean * @since 2.5 */ public $error = false; /** * The main response message * * @var string * @since 2.5 */ public $message = null; /** * Array of messages gathered in the JApplication object * * @var array * @since 2.5 */ public $messages = null; /** * The response data * * @var mixed * @since 2.5 */ public $data = null; /** * Constructor * * @param mixed $response The Response data * @param string $message The main response message * @param boolean $error True, if the success flag shall be set to false, defaults to false * * @since 2.5 * @deprecated 4.0 Use JResponseJson instead */ public function __construct($response = null, $message = null, $error = false) { JLog::add('Class JJsonResponse is deprecated. Use class JResponseJson instead.', JLog::WARNING, 'deprecated'); $this->message = $message; // Get the message queue $messages = JFactory::getApplication()->getMessageQueue(); // Build the sorted messages list if (is_array($messages) && count($messages)) { foreach ($messages as $message) { if (isset($message['type']) && isset($message['message'])) { $lists[$message['type']][] = $message['message']; } } } // If messages exist add them to the output if (isset($lists) && is_array($lists)) { $this->messages = $lists; } // Check if we are dealing with an error if ($response instanceof Exception) { // Prepare the error response $this->success = false; $this->error = true; $this->message = $response->getMessage(); } else { // Prepare the response data $this->success = !$error; $this->error = $error; $this->data = $response; } } /** * Magic toString method for sending the response in JSON format * * @return string The response in JSON format * * @since 2.5 */ public function __toString() { return json_encode($this); } } components/com_languages/helpers/html/languages.php000066600000003640150771655440016647 0ustar00'; } public static function clients() { return array( JHtml::_('select.option', 0, JText::_('JSITE')), JHtml::_('select.option', 1, JText::_('JADMINISTRATOR')) ); } /** * Returns an array of published state filter options. * * @return string The HTML code for the select tag * @since 1.6 */ public static function publishedOptions() { // Build the active state filter options. $options = array(); $options[] = JHtml::_('select.option', '1', 'JPUBLISHED'); $options[] = JHtml::_('select.option', '0', 'JUNPUBLISHED'); $options[] = JHtml::_('select.option', '-2', 'JTRASHED'); $options[] = JHtml::_('select.option', '*', 'JALL'); return $options; } } components/com_languages/helpers/html/index.html000066600000000037150771655440016162 0ustar00 components/com_languages/helpers/multilangstatus.php000066600000007356150771655440017205 0ustar00getQuery(true) ->select('COUNT(*)') ->from($db->quoteName('#__menu')) ->where('home = 1') ->where('published = 1') ->where('client_id = 0'); $db->setQuery($query); return $db->loadResult(); } public static function getLangswitchers() { // Check if switcher is published $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('COUNT(*)') ->from($db->quoteName('#__modules')) ->where('module = ' . $db->quote('mod_languages')) ->where('published = 1') ->where('client_id = 0'); $db->setQuery($query); return $db->loadResult(); } public static function getContentlangs() { // Check for published Content Languages $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('a.lang_code AS lang_code') ->select('a.published AS published') ->from('#__languages AS a'); $db->setQuery($query); return $db->loadObjectList(); } public static function getSitelangs() { // check for published Site Languages $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('a.element AS element') ->from('#__extensions AS a') ->where('a.type = ' . $db->quote('language')) ->where('a.client_id = 0') ->where('a.enabled = 1'); $db->setQuery($query); return $db->loadObjectList('element'); } public static function getHomepages() { // Check for Home pages languages $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('language') ->from($db->quoteName('#__menu')) ->where('home = 1') ->where('published = 1') ->where('client_id = 0'); $db->setQuery($query); return $db->loadObjectList('language'); } public static function getStatus() { //check for combined status $db = JFactory::getDbo(); $query = $db->getQuery(true); // Select all fields from the languages table. $query->select('a.*', 'l.home') ->select('a.published AS published') ->select('a.lang_code AS lang_code') ->from('#__languages AS a'); // Select the language home pages $query->select('l.home AS home') ->select('l.language AS home_language') ->join('LEFT', '#__menu AS l ON l.language = a.lang_code AND l.home=1 AND l.published=1 AND l.language <> \'*\'') ->select('e.enabled AS enabled') ->select('e.element AS element') ->join('LEFT', '#__extensions AS e ON e.element = a.lang_code') ->where('e.client_id = 0') ->where('e.enabled = 1') ->where('e.state = 0'); $db->setQuery($query); return $db->loadObjectList(); } public static function getContacts() { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('u.name, count(cd.language) as counted, MAX(cd.language=' . $db->quote('*') . ') as all_languages') ->from('#__users AS u') ->join('LEFT', '#__contact_details AS cd ON cd.user_id=u.id') ->join('LEFT', '#__languages as l on cd.language=l.lang_code') ->where('EXISTS (SELECT * from #__content as c where c.created_by=u.id)') ->where('(l.published=1 or cd.language=' . $db->quote('*') . ')') ->where('cd.published=1') ->group('u.id') ->having('(counted !=' . count(JLanguageHelper::getLanguages()) . ' OR all_languages=1)') ->having('(counted !=1 OR all_languages=0)'); $db->setQuery($query); return $db->loadObjectList(); } } components/com_languages/helpers/index.html000066600000000037150771655440015216 0ustar00 components/com_languages/models/languages.php000066600000012627150771655440015531 0ustar00getUserStateFromRequest($this->context . '.search', 'filter_search'); $this->setState('filter.search', $search); $accessId = $this->getUserStateFromRequest($this->context . '.access', 'filter_access', null, 'int'); $this->setState('filter.access', $accessId); $published = $this->getUserStateFromRequest($this->context . '.published', 'filter_published', ''); $this->setState('filter.published', $published); // Load the parameters. $params = JComponentHelper::getParams('com_languages'); $this->setState('params', $params); // List state information. parent::populateState('a.ordering', 'asc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. * * @return string A store id. * @since 1.6 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.access'); $id .= ':' . $this->getState('filter.published'); return parent::getStoreId($id); } /** * Method to build an SQL query to load the list data. * * @return string An SQL query * @since 1.6 */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Select all fields from the languages table. $query->select($this->getState('list.select', 'a.*', 'l.home')) ->from($db->quoteName('#__languages') . ' AS a'); // Join over the asset groups. $query->select('ag.title AS access_level') ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); // Select the language home pages $query->select('l.home AS home') ->join('LEFT', $db->quoteName('#__menu') . ' AS l ON l.language = a.lang_code AND l.home=1 AND l.language <> ' . $db->quote('*')); // Filter on the published state. $published = $this->getState('filter.published'); if (is_numeric($published)) { $query->where('a.published = ' . (int) $published); } elseif ($published === '') { $query->where('(a.published IN (0, 1))'); } // Filter by search in title $search = $this->getState('filter.search'); if (!empty($search)) { $search = $db->quote('%' . $db->escape($search, true) . '%', false); $query->where('(a.title LIKE ' . $search . ')'); } // Filter by access level. if ($access = $this->getState('filter.access')) { $query->where('a.access = ' . (int) $access); } // Add the list ordering clause. $query->order($db->escape($this->getState('list.ordering', 'a.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); return $query; } /** * Set the published language(s) * * @param array $cid An array of language IDs. * @param integer $value The value of the published state. * * @return boolean True on success, false otherwise. * @since 1.6 */ public function setPublished($cid, $value = 0) { return JTable::getInstance('Language')->publish($cid, $value); } /** * Method to delete records. * * @param array An array of item primary keys. * * @return boolean Returns true on success, false on failure. * @since 1.6 */ public function delete($pks) { // Sanitize the array. $pks = (array) $pks; // Get a row instance. $table = JTable::getInstance('Language'); // Iterate the items to delete each one. foreach ($pks as $itemId) { if (!$table->delete((int) $itemId)) { $this->setError($table->getError()); return false; } } // Clean the cache. $this->cleanCache(); return true; } /** * Custom clean cache method, 2 places for 2 clients * * @since 1.6 */ protected function cleanCache($group = null, $client_id = 0) { parent::cleanCache('_system'); parent::cleanCache('com_languages'); } } components/com_languages/models/language.php000066600000011516150771655440015342 0ustar00input->getInt('lang_id'); $this->setState('language.id', $langId); // Load the parameters. $this->setState('params', $params); } /** * Method to get a member item. * * @param integer The id of the member to get. * * @return mixed User data object on success, false on failure. * @since 1.0 */ public function getItem($langId = null) { $langId = (!empty($langId)) ? $langId : (int) $this->getState('language.id'); $false = false; // Get a member row instance. $table = $this->getTable(); // Attempt to load the row. $return = $table->load($langId); // Check for a table object error. if ($return === false && $table->getError()) { $this->setError($table->getError()); return $false; } // Set a valid accesslevel in case '0' is stored due to a bug in the installation SQL (was fixed with PR 2714). if ($table->access == '0') { $table->access = (int) JFactory::getConfig()->get('access'); } $properties = $table->getProperties(1); $value = JArrayHelper::toObject($properties, 'JObject'); return $value; } /** * Method to get the group form. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return mixed A JForm object on success, false on failure * @since 1.6 */ public function getForm($data = array(), $loadData = true) { // Get the form. $form = $this->loadForm('com_languages.language', 'language', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * @since 1.6 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_languages.edit.language.data', array()); if (empty($data)) { $data = $this->getItem(); } $this->preprocessData('com_languages.language', $data); return $data; } /** * Method to save the form data. * * @param array The form data. * * @return boolean True on success. * @since 1.6 */ public function save($data) { $langId = (int) $this->getState('language.id'); $isNew = true; $dispatcher = JEventDispatcher::getInstance(); JPluginHelper::importPlugin('extension'); $table = $this->getTable(); // Load the row if saving an existing item. if ($langId > 0) { $table->load($langId); $isNew = false; } // Prevent white spaces, including East Asian double bytes $spaces = array('/\xE3\x80\x80/', ' '); $data['lang_code'] = str_replace($spaces, '', $data['lang_code']); $data['sef'] = str_replace($spaces, '', $data['sef']); // Bind the data if (!$table->bind($data)) { $this->setError($table->getError()); return false; } // Check the data if (!$table->check()) { $this->setError($table->getError()); return false; } // Trigger the onExtensionBeforeSave event. $result = $dispatcher->trigger('onExtensionBeforeSave', array('com_languages.language', &$table, $isNew)); // Check the event responses. if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } // Store the data if (!$table->store()) { $this->setError($table->getError()); return false; } // Trigger the onExtensionAfterSave event. $dispatcher->trigger('onExtensionAfterSave', array('com_languages.language', &$table, $isNew)); $this->setState('language.id', $table->lang_id); // Clean the cache. $this->cleanCache(); return true; } /** * Custom clean cache method * * @since 1.6 */ protected function cleanCache($group = null, $client_id = 0) { parent::cleanCache('_system'); parent::cleanCache('com_languages'); } } components/com_languages/models/overrides.php000066600000017356150771655440015571 0ustar00filter_fields = array('key', 'text'); } /** * Retrieves the overrides data * * @param boolean $all True if all overrides shall be returned without considering pagination, defaults to false * * @return array Array of objects containing the overrides of the override.ini file * * @since 2.5 */ public function getOverrides($all = false) { // Get a storage key $store = $this->getStoreId(); // Try to load the data from internal storage if (!empty($this->cache[$store])) { return $this->cache[$store]; } $client = in_array($this->state->get('filter.client'), array(0, 'site')) ? strtoupper('site') : strtoupper('administrator'); // Parse the override.ini file in order to get the keys and strings $filename = constant('JPATH_' . $client) . '/language/overrides/' . $this->getState('filter.language') . '.override.ini'; $strings = LanguagesHelper::parseFile($filename); // Filter the loaded strings according to the search box $search = $this->getState('filter.search'); if ($search != '') { $search = preg_quote($search, '~'); $matchvals = preg_grep('~' . $search . '~i', $strings); $matchkeys = array_intersect_key($strings, array_flip(preg_grep('~' . $search . '~i', array_keys($strings)))); $strings = array_merge($matchvals, $matchkeys); } // Consider the odering if ($this->getState('list.ordering') == 'text') { if (strtoupper($this->getState('list.direction')) == 'DESC') { arsort($strings); } else { asort($strings); } } else { if (strtoupper($this->getState('list.direction')) == 'DESC') { krsort($strings); } else { ksort($strings); } } // Consider the pagination if (!$all && $this->getState('list.limit') && $this->getTotal() > $this->getState('list.limit')) { $strings = array_slice($strings, $this->getStart(), $this->getState('list.limit'), true); } // Add the items to the internal cache $this->cache[$store] = $strings; return $this->cache[$store]; } /** * Method to get the total number of overrides * * @return int The total number of overrides * * @since 2.5 */ public function getTotal() { // Get a storage key $store = $this->getStoreId('getTotal'); // Try to load the data from internal storage if (!empty($this->cache[$store])) { return $this->cache[$store]; } // Add the total to the internal cache $this->cache[$store] = count($this->getOverrides(true)); return $this->cache[$store]; } /** * Method to auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @param string $ordering An optional ordering field. * @param string $direction An optional direction (asc|desc). * * @return void * * @since 2.5 */ protected function populateState($ordering = null, $direction = null) { $app = JFactory::getApplication(); // Use default language of frontend for default filter $default = JComponentHelper::getParams('com_languages')->get('site').'0'; $old_language_client = $app->getUserState('com_languages.overrides.filter.language_client', ''); $language_client = $this->getUserStateFromRequest('com_languages.overrides.filter.language_client', 'filter_language_client', $default, 'cmd'); if ($old_language_client != $language_client) { $client = substr($language_client, -1); $language = substr($language_client, 0, -1); } else { $client = $app->getUserState('com_languages.overrides.filter.client', 0); $language = $app->getUserState('com_languages.overrides.filter.language', 'en-GB'); } // Sets the search filter $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $this->setState('filter.language_client', $language.$client); $this->setState('filter.client', $client ? 'administrator' : 'site'); $this->setState('filter.language', $language); // Add filters to the session because they won't be stored there by 'getUserStateFromRequest' if they aren't in the current request $app->setUserState('com_languages.overrides.filter.client', $client); $app->setUserState('com_languages.overrides.filter.language', $language); // List state information parent::populateState('key', 'asc'); } /** * Method to get all found languages of frontend and backend. * * The resulting array has entries of the following style: * 0|1 => - * * @return array Sorted associative array of languages * * @since 2.5 */ public function getLanguages() { // Try to load the data from internal storage if (!empty($this->cache['languages'])) { return $this->cache['languages']; } // Get all languages of frontend and backend $languages = array(); $site_languages = JLanguage::getKnownLanguages(JPATH_SITE); $admin_languages = JLanguage::getKnownLanguages(JPATH_ADMINISTRATOR); // Create a single array of them foreach ($site_languages as $tag => $language) { $languages[$tag.'0'] = JText::sprintf('COM_LANGUAGES_VIEW_OVERRIDES_LANGUAGES_BOX_ITEM', $language['name'], JText::_('JSITE')); } foreach ($admin_languages as $tag => $language) { $languages[$tag.'1'] = JText::sprintf('COM_LANGUAGES_VIEW_OVERRIDES_LANGUAGES_BOX_ITEM', $language['name'], JText::_('JADMINISTRATOR')); } // Sort it by language tag and by client after that ksort($languages); // Add the languages to the internal cache $this->cache['languages'] = $languages; return $this->cache['languages']; } /** * Method to delete one or more overrides * * @param array Array of keys to delete * * @return integer Number of successfully deleted overrides, boolean false if an error occured * * @since 2.5 */ public function delete($cids) { // Check permissions first if (!JFactory::getUser()->authorise('core.delete', 'com_languages')) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); return false; } jimport('joomla.filesystem.file'); require_once JPATH_COMPONENT.'/helpers/languages.php'; $client = in_array($this->state->get('filter.client'), array(0, 'site')) ? strtoupper('site') : strtoupper('administrator'); // Parse the override.ini file in oder to get the keys and strings $filename = constant('JPATH_' . $client) . '/language/overrides/' . $this->getState('filter.language') . '.override.ini'; $strings = LanguagesHelper::parseFile($filename); // Unset strings that shall be deleted foreach ($cids as $key) { if (isset($strings[$key])) { unset($strings[$key]); } } foreach ($strings as $key => $string) { $strings[$key] = str_replace('"', '"_QQ_"', $string); } // Write override.ini file with the left strings $registry = new JRegistry; $registry->loadObject($strings); $reg = $registry->toString('INI'); $filename = constant('JPATH_' . $client) . '/language/overrides/' . $this->getState('filter.language') . '.override.ini'; if (!JFile::write($filename, $reg)) { return false; } $this->cleanCache(); return count($cids); } } components/com_languages/models/installed.php000066600000016674150771655440015550 0ustar00input->getInt('client'); $this->setState('filter.client_id', $clientId); // Load the parameters. $params = JComponentHelper::getParams('com_languages'); $this->setState('params', $params); // List state information. parent::populateState('a.name', 'asc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. * * @return string A store id. * @since 1.6 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':'.$this->getState('filter.client_id'); return parent::getStoreId($id); } /** * Method to get the client object * * @return object * @since 1.6 */ public function &getClient() { if (is_null($this->client)) { $this->client = JApplicationHelper::getClientInfo($this->getState('filter.client_id', 0)); } return $this->client; } /** * Method to get the ftp credentials * * @return object * @since 1.6 */ public function &getFtp() { if (is_null($this->ftp)) { $this->ftp = JClientHelper::setCredentialsFromRequest('ftp'); } return $this->ftp; } /** * Method to get the option * * @return object * @since 1.6 */ public function &getOption() { $option = $this->getState('option'); return $option; } /** * Method to get Languages item data * * @return array * @since 1.6 */ public function &getData() { if (is_null($this->data)) { // Get information $path = $this->getPath(); $client = $this->getClient(); $langlist = $this->getLanguageList(); // Compute all the languages $data = array (); foreach ($langlist as $lang) { $file = $path . '/' . $lang . '/' . $lang.'.xml'; $info = JApplicationHelper::parseXMLLangMetaFile($file); $row = new JObject; $row->language = $lang; if (!is_array($info)) { continue; } foreach ($info as $key => $value) { $row->$key = $value; } // if current than set published $params = JComponentHelper::getParams('com_languages'); if ($params->get($client->name, 'en-GB') == $row->language) { $row->published = 1; } else { $row->published = 0; } $row->checked_out = 0; $data[] = $row; } usort($data, array($this, 'compareLanguages')); // Prepare data $limit = $this->getState('list.limit'); $start = $this->getState('list.start'); $total = $this->getTotal(); if ($limit == 0) { $start = 0; $end = $total; } else { if ($start > $total) { $start = $total - $total % $limit; } $end = $start + $limit; if ($end > $total) { $end = $total; } } // Compute the displayed languages $this->data = array(); for ($i = $start;$i < $end;$i++) { $this->data[] = & $data[$i]; } } return $this->data; } /** * Method to get installed languages data. * * @return string An SQL query * @since 1.6 */ protected function getLanguageList() { // Create a new db object. $db = $this->getDbo(); $query = $db->getQuery(true); $client = $this->getState('filter.client_id'); $type = "language"; // Select field element from the extensions table. $query->select($this->getState('list.select', 'a.element')) ->from('#__extensions AS a'); $type = $db->quote($type); $query->where('(a.type = '.$type.')') ->where('state = 0') ->where('enabled = 1') ->where('client_id=' . (int) $client); // for client_id = 1 do we need to check language table also ? $db->setQuery($query); $this->langlist = $db->loadColumn(); return $this->langlist; } /** * Method to get the total number of Languages items * * @return integer * @since 1.6 */ public function getTotal() { if (is_null($this->total)) { $langlist = $this->getLanguageList(); $this->total = count($langlist); } return $this->total; } /** * Method to set the default language * * @return boolean * @since 1.6 */ public function publish($cid) { if ($cid) { $client = $this->getClient(); $params = JComponentHelper::getParams('com_languages'); $params->set($client->name, $cid); $table = JTable::getInstance('extension'); $id = $table->find(array('element' => 'com_languages')); // Load if (!$table->load($id)) { $this->setError($table->getError()); return false; } $table->params = (string) $params; // pre-save checks if (!$table->check()) { $this->setError($table->getError()); return false; } // save the changes if (!$table->store()) { $this->setError($table->getError()); return false; } } else { $this->setError(JText::_('COM_LANGUAGES_ERR_NO_LANGUAGE_SELECTED')); return false; } // Clean the cache of com_languages and component cache. $this->cleanCache(); $this->cleanCache('_system', 0); $this->cleanCache('_system', 1); return true; } /** * Method to get the folders * * @return array Languages folders * @since 1.6 */ protected function getFolders() { if (is_null($this->folders)) { $path = $this->getPath(); jimport('joomla.filesystem.folder'); $this->folders = JFolder::folders($path, '.', false, false, array('.svn', 'CVS', '.DS_Store', '__MACOSX', 'pdf_fonts', 'overrides')); } return $this->folders; } /** * Method to get the path * * @return string The path to the languages folders * @since 1.6 */ protected function getPath() { if (is_null($this->path)) { $client = $this->getClient(); $this->path = JLanguage::getLanguagePath($client->path); } return $this->path; } /** * Method to compare two languages in order to sort them * * @param object $lang1 the first language * @param object $lang2 the second language * * @return integer * @since 1.6 */ protected function compareLanguages($lang1, $lang2) { return strcmp($lang1->name, $lang2->name); } } components/com_languages/models/override.php000066600000013235150771655440015376 0ustar00loadForm('com_languages.override', 'override', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } $client = $this->getState('filter.client', 'site'); $language = $this->getState('filter.language', 'en-GB'); $langName = JLanguage::getInstance($language)->getName(); if (!$langName) { // If a language only exists in frontend, it's meta data cannot be // loaded in backend at the moment, so fall back to the language tag $langName = $language; } $form->setValue('client', null, JText::_('COM_LANGUAGES_VIEW_OVERRIDE_CLIENT_'.strtoupper($client))); $form->setValue('language', null, JText::sprintf('COM_LANGUAGES_VIEW_OVERRIDE_LANGUAGE', $langName, $language)); $form->setValue('file', null, JPath::clean(constant('JPATH_'.strtoupper($client)) . '/language/overrides/' . $language . '.override.ini')); return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form * * @since 2.5 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_languages.edit.override.data', array()); if (empty($data)) { $data = $this->getItem(); } $this->preprocessData('com_languages.override', $data); return $data; } /** * Method to get a single record. * * @param string $pk The key name. * * @return mixed Object on success, false otherwise. * * @since 2.5 */ public function getItem($pk = null) { require_once JPATH_COMPONENT.'/helpers/languages.php'; $input = JFactory::getApplication()->input; $pk = (!empty($pk)) ? $pk : $input->get('id'); $filename = constant('JPATH_'.strtoupper($this->getState('filter.client'))) . '/language/overrides/' . $this->getState('filter.language', 'en-GB').'.override.ini'; $strings = LanguagesHelper::parseFile($filename); $result = new stdClass; $result->key = ''; $result->override = ''; if (isset($strings[$pk])) { $result->key = $pk; $result->override = $strings[$pk]; } return $result; } /** * Method to save the form data. * * @param array $data The form data. * @param boolean $opposite_client Indicates whether the override should not be created for the current client * * @return boolean True on success, false otherwise. * * @since 2.5 */ public function save($data, $opposite_client = false) { $app = JFactory::getApplication(); require_once JPATH_COMPONENT.'/helpers/languages.php'; jimport('joomla.filesystem.file'); $client = $app->getUserState('com_languages.overrides.filter.client', 0); $language = $app->getUserState('com_languages.overrides.filter.language', 'en-GB'); // If the override should be created for both if ($opposite_client) { $client = 1 - $client; } $client = $client ? 'administrator' : 'site'; // Parse the override.ini file in oder to get the keys and strings $filename = constant('JPATH_'.strtoupper($client)) . '/language/overrides/' . $language . '.override.ini'; $strings = LanguagesHelper::parseFile($filename); if (isset($strings[$data['id']])) { // If an existent string was edited check whether // the name of the constant is still the same if ($data['key'] == $data['id']) { // If yes, simply override it $strings[$data['key']] = $data['override']; } else { // If no, delete the old string and prepend the new one unset($strings[$data['id']]); $strings = array($data['key'] => $data['override']) + $strings; } } else { // If it is a new override simply prepend it $strings = array($data['key'] => $data['override']) + $strings; } foreach ($strings as $key => $string) { $strings[$key] = str_replace('"', '"_QQ_"', $string); } // Write override.ini file with the strings $registry = new JRegistry; $registry->loadObject($strings); $reg = $registry->toString('INI'); if (!JFile::write($filename, $reg)) { return false; } // If the override should be stored for both clients save // it also for the other one and prevent endless recursion if (isset($data['both']) && $data['both'] && !$opposite_client) { return $this->save($data, true); } return true; } /** * Method to auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @return void * * @since 2.5 */ protected function populateState() { $app = JFactory::getApplication(); $client = $app->getUserStateFromRequest('com_languages.overrides.filter.client', 'filter_client', 0, 'int') ? 'administrator' : 'site'; $this->setState('filter.client', $client); $language = $app->getUserStateFromRequest('com_languages.overrides.filter.language', 'filter_language', 'en-GB', 'cmd'); $this->setState('filter.language', $language); } } components/com_languages/models/index.html000066600000000037150771655440015037 0ustar00 components/com_languages/models/forms/override.xml000066600000003666150771655440016544 0ustar00
components/com_languages/models/forms/language.xml000066600000004667150771655440016512 0ustar00
components/com_languages/models/forms/index.html000066600000000037150771655440016165 0ustar00 components/com_languages/models/strings.php000066600000010320150771655440015240 0ustar00setUserState('com_languages.overrides.cachedtime', null); // Empty the database cache first try { $this->_db->setQuery('TRUNCATE TABLE '.$this->_db->quoteName('#__overrider')); $this->_db->execute(); } catch (RuntimeException $e) { return $e; } // Create the insert query $query = $this->_db->getQuery(true) ->insert($this->_db->quoteName('#__overrider')) ->columns('constant, string, file'); // Initialize some variables $client = $app->getUserState('com_languages.overrides.filter.client', 'site') ? 'administrator' : 'site'; $language = $app->getUserState('com_languages.overrides.filter.language', 'en-GB'); $base = constant('JPATH_'.strtoupper($client)); $path = $base . '/language/' . $language; $files = array(); // Parse common language directory jimport('joomla.filesystem.folder'); if (is_dir($path)) { $files = JFolder::files($path, $language.'.*ini$', false, true); } // Parse language directories of components $files = array_merge($files, JFolder::files($base.'/components', $language.'.*ini$', 3, true)); // Parse language directories of modules $files = array_merge($files, JFolder::files($base.'/modules', $language.'.*ini$', 3, true)); // Parse language directories of templates $files = array_merge($files, JFolder::files($base.'/templates', $language.'.*ini$', 3, true)); // Parse language directories of plugins $files = array_merge($files, JFolder::files(JPATH_PLUGINS, $language.'.*ini$', 3, true)); // Parse all found ini files and add the strings to the database cache foreach ($files as $file) { $strings = LanguagesHelper::parseFile($file); if ($strings && count($strings)) { $query->clear('values'); foreach ($strings as $key => $string) { $query->values($this->_db->quote($key).','.$this->_db->quote($string).','.$this->_db->quote(JPath::clean($file))); } try { $this->_db->setQuery($query); $this->_db->execute(); } catch (RuntimeException $e) { return $e; } } } // Update the cached time $app->setUserState('com_languages.overrides.cachedtime.'.$client.'.'.$language, time()); return true; } /** * Method for searching language strings * * @return array Array of resuls on success, Exception object otherwise * * @since 2.5 */ public function search() { $results = array(); $input = JFactory::getApplication()->input; $limitstart = $input->getInt('more'); try { $searchstring = $this->_db->quote('%' . $input->getString('searchstring') . '%'); // Create the search query $query = $this->_db->getQuery(true) ->select('constant, string, file') ->from($this->_db->quoteName('#__overrider')); if ($input->get('searchtype') == 'constant') { $query->where('constant LIKE '.$searchstring); } else { $query->where('string LIKE '.$searchstring); } // Consider the limitstart according to the 'more' parameter and load the results $this->_db->setQuery($query, $limitstart, 10); $results['results'] = $this->_db->loadObjectList(); // Check whether there are more results than already loaded $query->clear('select') ->select('COUNT(id)'); $this->_db->setQuery($query); if ($this->_db->loadResult() > $limitstart + 10) { // If this is set a 'More Results' link will be displayed in the view $results['more'] = $limitstart + 10; } } catch (RuntimeException $e) { return $e; } return $results; } } components/com_search/views/index.html000066600000000037150771655440014210 0ustar00 components/com_search/views/searches/view.html.php000066600000003122150771655440016434 0ustar00items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); $this->enabled = $this->state->params->get('enabled'); $this->canDo = JHelperContent::getActions('com_search'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { $canDo = $this->canDo; JToolbarHelper::title(JText::_('COM_SEARCH_MANAGER_SEARCHES'), 'search'); if ($canDo->get('core.edit.state')) { JToolbarHelper::custom('searches.reset', 'refresh.png', 'refresh_f2.png', 'JSEARCH_RESET', false); } JToolbarHelper::divider(); if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_search'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_COMPONENTS_SEARCH'); } } components/com_search/views/searches/tmpl/default.php000066600000010514150771655440017122 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?>
pagination->getLimitBox(); ?>
state->get('filter.results')) : ?>
enabled) : ?>
×
×
items)) : ?>
items as $i => $item) : ?>
pagination->getListFooter(); ?>
escape($item->search_term); ?> hits; ?> state->get('filter.results')) : ?> returns; ?>
components/com_search/views/searches/tmpl/index.html000066600000000037150771655440016761 0ustar00 components/com_search/views/searches/index.html000066600000000037150771655440016005 0ustar00 components/com_search/search.xml000066600000002655150771655440013055 0ustar00 com_search Joomla! Project April 2006 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_SEARCH_XML_DESCRIPTION controller.php index.html router.php search.php models views language/en-GB.com_search.ini Search config.xml controller.php index.html search.php controllers helpers models views language/en-GB.com_search.ini language/en-GB.com_search.sys.ini components/com_search/index.html000066600000000037150771655440013053 0ustar00 components/com_search/config.xml000066600000003214150771655440013045 0ustar00
components/com_search/search.php000066600000001070150771655440013032 0ustar00authorise('core.manage', 'com_search')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } $controller = JControllerLegacy::getInstance('Search'); $controller->execute(JFactory::getApplication()->input->get('task')); $controller->redirect(); components/com_search/controller.php000066600000002136150771655440013754 0ustar00input->get('view', 'searches')); parent::display(); } } components/com_search/controllers/searches.php000066600000001553150771655440015736 0ustar00getModel('Searches'); if (!$model->reset()) { JError::raiseWarning(500, $model->getError()); } $this->setRedirect('index.php?option=com_search&view=searches'); } } components/com_search/controllers/index.html000066600000000037150771655440015421 0ustar00 components/com_search/access.xml000066600000000652150771655440013044 0ustar00
components/com_search/helpers/site.php000066600000001426150771655440014200 0ustar00 components/com_search/helpers/search.php000066600000015357150771655440014511 0ustar00getTag(); $search_ignore = $lang->getIgnoredSearchWords(); // Deprecated in 1.6 use $lang->getIgnoredSearchWords instead $ignoreFile = $lang->getLanguagePath() . '/' . $tag . '/' . $tag . '.ignore.php'; if (file_exists($ignoreFile)) { include $ignoreFile; } // Check for words to ignore $aterms = explode(' ', JString::strtolower($searchword)); // First case is single ignored word if (count($aterms) == 1 && in_array(JString::strtolower($searchword), $search_ignore)) { $ignored = true; } // Filter out search terms that are too small $lower_limit = $lang->getLowerLimitSearchWord(); foreach ($aterms as $aterm) { if (JString::strlen($aterm) < $lower_limit) { $search_ignore[] = $aterm; } } // Next is to remove ignored words from type 'all' or 'any' (not exact) searches with multiple words if (count($aterms) > 1 && $searchphrase != 'exact') { $pruned = array_diff($aterms, $search_ignore); $searchword = implode(' ', $pruned); } return $ignored; } /** * @since 1.5 */ public static function limitSearchWord(&$searchword) { $restriction = false; $lang = JFactory::getLanguage(); // Limit searchword to a maximum of characters $upper_limit = $lang->getUpperLimitSearchWord(); if (JString::strlen($searchword) > $upper_limit) { $searchword = JString::substr($searchword, 0, $upper_limit - 1); $restriction = true; } // Searchword must contain a minimum of characters if ($searchword && JString::strlen($searchword) < $lang->getLowerLimitSearchWord()) { $searchword = ''; $restriction = true; } return $restriction; } /** * Logs a search term * * @param string $search_term The term being searched * * @return void * * @since 1.5 * @deprecated 4.0 Use JSearchHelper::logSearch() instead */ public static function logSearch($search_term) { JLog::add(__METHOD__ . '() is deprecated, use JSearchHelper::logSearch() instead.', JLog::WARNING, 'deprecated'); JSearchHelper::logSearch($search_term, 'com_search'); } /** * Prepares results from search for display * * @param string $text The source string * @param string $searchword The searchword to select around * * @return string * * @since 1.5 */ public static function prepareSearchContent($text, $searchword) { // Strips tags won't remove the actual jscript $text = preg_replace("']*>.*?'si", "", $text); $text = preg_replace('/{.+?}/', '', $text); // $text = preg_replace('/]*>([^<]+)<\/a>/is','\2', $text); // Replace line breaking tags with whitespace $text = preg_replace("'<(br[^/>]*?/|hr[^/>]*?/|/(div|h[1-6]|li|p|td))>'si", ' ', $text); return self::_smartSubstr(strip_tags($text), $searchword); } /** * Checks an object for search terms (after stripping fields of HTML) * * @param object $object The object to check * @param string $searchTerm Search words to check for * @param array $fields List of object variables to check against * * @return boolean True if searchTerm is in object, false otherwise */ public static function checkNoHtml($object, $searchTerm, $fields) { $searchRegex = array( '#]*>.*?#si', '#]*>.*?#si', '##si', '#<[^>]*>#i' ); $terms = explode(' ', $searchTerm); if (empty($fields)) { return false; } foreach ($fields as $field) { if (!isset($object->$field)) { continue; } $text = self::remove_accents($object->$field); foreach ($searchRegex as $regex) { $text = preg_replace($regex, '', $text); } foreach ($terms as $term) { $term = self::remove_accents($term); if (JString::stristr($text, $term) !== false) { return true; } } } return false; } /** * Transliterates given text to ASCII * * @param string $str String to remove accents from * * @return string * * @since 3.2 */ public static function remove_accents($str) { $str = JLanguageTransliterate::utf8_latin_to_ascii($str); //TODO: remove other prefixes as well? return preg_replace("/[\"'^]([a-z])/ui", '\1', $str); } /** * returns substring of characters around a searchword * * @param string $text The source string * @param integer $searchword Number of chars to return * * @return string * * @since 1.5 */ public static function _smartSubstr($text, $searchword) { $lang = JFactory::getLanguage(); $length = $lang->getSearchDisplayedCharactersNumber(); $ltext = self::remove_accents($text); $textlen = JString::strlen($ltext); $lsearchword = JString::strtolower(self::remove_accents($searchword)); $wordfound = false; $pos = 0; while ($wordfound === false && $pos < $textlen) { if (($wordpos = @JString::strpos($ltext, ' ', $pos + $length)) !== false) { $chunk_size = $wordpos - $pos; } else { $chunk_size = $length; } $chunk = JString::substr($ltext, $pos, $chunk_size); $wordfound = JString::strpos(JString::strtolower($chunk), $lsearchword); if ($wordfound === false) { $pos += $chunk_size + 1; } } if ($wordfound !== false) { return (($pos > 0) ? '... ' : '') . JString::substr($text, $pos, $chunk_size) . ' ...'; } else { if (($wordpos = @JString::strpos($text, ' ', $length)) !== false) { return JString::substr($text, 0, $wordpos) . ' ...'; } else { return JString::substr($text, 0, $length); } } } } components/com_search/models/searches.php000066600000011174150771655440014653 0ustar00getUserStateFromRequest($this->context . '.filter.search', 'filter_search', false, 'string', false); $this->setState('filter.search', $search); $showResults = $this->getUserStateFromRequest($this->context . '.filter.results', 'filter_results', null, 'int', false); $this->setState('filter.results', $showResults); // Load the parameters. $params = JComponentHelper::getParams('com_search'); $this->setState('params', $params); // List state information. parent::populateState('a.hits', 'asc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. * * @return string A store id. * @since 1.6 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.results'); return parent::getStoreId($id); } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery * @since 1.6 */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.*' ) ); $query->from($db->quoteName('#__core_log_searches') . ' AS a'); // Filter by access level. if ($access = $this->getState('filter.access')) { $query->where('a.access = ' . (int) $access); } // Filter by search in title $search = $this->getState('filter.search'); if (!empty($search)) { $search = $db->quote('%' . $db->escape($search, true) . '%'); $query->where('a.search_term LIKE ' . $search); } // Add the list ordering clause. $query->order($db->escape($this->getState('list.ordering', 'a.hits')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); //echo nl2br(str_replace('#__','jos_',$query)); return $query; } /** * Override the parnet getItems to inject optional data. * * @return mixed An array of objects on success, false on failure. * @since 1.6 */ public function getItems() { $items = parent::getItems(); // Determine if number of results for search item should be calculated // by default it is `off` as it is highly query intensive if ($this->getState('filter.results')) { JPluginHelper::importPlugin('search'); $app = JFactory::getApplication(); if (!class_exists('JSite')) { // This fools the routers in the search plugins into thinking it's in the frontend JLoader::register('JSite', JPATH_COMPONENT . '/helpers/site.php'); } foreach ($items as &$item) { $results = $app->triggerEvent('onContentSearch', array($item->search_term)); $item->returns = 0; foreach ($results as $result) { $item->returns += count($result); } } } return $items; } /** * Method to reset the seach log table. * * @return boolean * @since 1.6 */ public function reset() { $db = $this->getDbo(); $query = $db->getQuery(true) ->delete($db->quoteName('#__core_log_searches')); $db->setQuery($query); try { $db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } return true; } } components/com_search/models/index.html000066600000000037150771655440014336 0ustar00 components/com_postinstall/views/messages/view.html.php000066600000001563150771655440017564 0ustar00eid = $this->input->getInt('eid', '700'); $this->token = JFactory::getSession()->getFormToken(); return parent::onBrowse($tpl); } } components/com_postinstall/views/messages/tmpl/default.php000066600000004237150771655440020250 0ustar00 items)): ?> eid == 700): ?>

items as $item): ?>
title_key) ?>

version_introduced) ?>

description_key) ?>

type !== 'message'): ?> action_key) ?> authorise('core.edit.state', 'com_postinstall')) : ?>
eid == 700): ?>

components/com_postinstall/views/messages/tmpl/index.html000066600000000037150771655440020102 0ustar00 components/com_postinstall/views/messages/index.html000066600000000037150771655440017126 0ustar00 components/com_postinstall/views/index.html000066600000000037150771655440015317 0ustar00 components/com_postinstall/index.html000066600000000037150771655440014162 0ustar00 components/com_postinstall/postinstall.php000066600000000736150771655440015260 0ustar00dispatch();components/com_postinstall/config.xml000066600000000522150771655440014153 0ustar00
components/com_postinstall/toolbar.php000066600000002125150771655440014340 0ustar00input->getInt('eid', 700); if ($eid != 700) { $model = FOFModel::getTmpInstance('Messages', 'PostinstallModel'); $extension_name = $model->getExtensionName($eid); } JToolBarHelper::title(JText::sprintf('COM_POSTINSTALL_MESSAGES_TITLE', $extension_name)); JToolBarHelper::preferences($this->config['option'], 550, 875); JToolbarHelper::help('JHELP_COMPONENTS_POST_INSTALLATION_MESSAGES'); } } components/com_postinstall/controllers/message.php000066600000002702150771655440016671 0ustar00getThisModel(); $eid = $this->input->getInt('eid', '700'); $model->resetMessages($eid); $this->setRedirect('index.php?option=com_postinstall'); } /** * Executes the action associated with an item * * @return void * * @since 3.2 */ public function action() { // CSRF prevention if ($this->csrfProtection) { $this->_csrfProtection(); } $model = $this->getThisModel(); if (!$model->getId()) { $model->setIDsFromRequest(); } $item = $model->getItem(); switch ($item->type) { case 'link': $this->setRedirect($item->action); return; break; case 'action': jimport('joomla.filesystem.file'); $file = FOFTemplateUtils::parsePath($item->action_file, true); if (JFile::exists($file)) { require_once $file; call_user_func($item->action); } break; case 'message': default: break; } $this->setRedirect('index.php?option=com_postinstall'); } } components/com_postinstall/controllers/index.html000066600000000037150771655440016530 0ustar00 components/com_postinstall/access.xml000066600000000516150771655440014152 0ustar00
components/com_postinstall/models/index.html000066600000000037150771655440015445 0ustar00 components/com_postinstall/models/messages.php000066600000010033150771655440015765 0ustar00getDbo(); // Add a forced extension filtering to the list $eid = $this->input->getInt('eid', 700); $query->where($db->qn('extension_id') . ' = ' . $db->q($eid)); // Force filter only enabled messages $published = $this->input->getInt('published', 1); $query->where($db->qn('enabled') . ' = ' . $db->q($published)); return $query; } /** * Returns the name of an extension, as registered in the #__extensions table * * @param integer $eid The extension ID * * @return string The extension name * * @since 3.2 */ public function getExtensionName($eid) { // Load the extension's information from the database $db = $this->getDbo(); $query = $db->getQuery(true) ->select(array('name', 'element', 'client_id')) ->from($db->qn('#__extensions')) ->where($db->qn('extension_id') . ' = ' . $db->q((int) $eid)); $db->setQuery($query, 0, 1); $extension = $db->loadObject(); if (!is_object($extension)) { return ''; } // Load language files $basePath = JPATH_ADMINISTRATOR; if ($extension->client_id == 0) { $basePath = JPATH_SITE; } $lang = JFactory::getLanguage(); $lang->load($extension->element, $basePath); // Return the localised name return JText::_($extension->name); } /** * Resets all messages for an extension * * @param integer $eid The extension ID whose messages we'll reset * * @return mixed False if we fail, a db cursor otherwise * * @since 3.2 */ public function resetMessages($eid) { $db = $this->getDbo(); $query = $db->getQuery(true) ->update($db->qn('#__postinstall_messages')) ->set($db->qn('enabled') . ' = ' . $db->q(1)) ->where($db->qn('extension_id') . ' = ' . $db->q($eid)); $db->setQuery($query); return $db->execute(); } /** * List post-processing. This is used to run the programmatic display * conditions against each list item and decide if we have to show it or * not. * * Do note that this a core method of the RAD Layer which operates directly * on the list it's being fed. A little touch of modern magic. * * @param array $resultArray A list of items to process * * @return void * * @since 3.2 */ protected function onProcessList(&$resultArray) { $unset_keys = array(); $language_extensions = array(); foreach ($resultArray as $key => $item) { // Filter out messages based on dynamically loaded programmatic conditions if (!empty($item->condition_file) && !empty($item->condition_method)) { jimport('joomla.filesystem.file'); $file = FOFTemplateUtils::parsePath($item->condition_file, true); if (JFile::exists($file)) { require_once $file; $result = call_user_func($item->condition_method); if ($result === false) { $unset_keys[] = $key; } } } // Load the necessary language files if (!empty($item->language_extension)) { $hash = $item->language_client_id . '-' . $item->language_extension; if (!in_array($hash, $language_extensions)) { $language_extensions[] = $hash; JFactory::getLanguage()->load($item->language_extension, $item->language_client_id == 0 ? JPATH_SITE : JPATH_ADMINISTRATOR); } } } if (!empty($unset_keys)) { foreach ($unset_keys as $key) { unset($resultArray[$key]); } } } } components/com_postinstall/postinstall.xml000066600000002136150771655440015265 0ustar00 com_postinstall Joomla! Project September 2013 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.2.0 COM_POSTINSTALL_XML_DESCRIPTION access.xml config.xml fof.xml postinstall.php toolbar.php index.html controllers models views language/en-GB.com_postinstall.ini language/en-GB.com_postinstall.sys.ini components/com_postinstall/fof.xml000066600000000605150771655440013462 0ustar00 core.edit.state browse browse browse components/com_config/model/index.html000066600000000037150771655440014153 0ustar00 components/com_config/model/application.php000066600000017411150771655440015176 0ustar00loadForm('com_config.application', 'application', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } return $form; } /** * Method to get the configuration data. * * This method will load the global configuration data straight from * JConfig. If configuration data has been saved in the session, that * data will be merged into the original data, overwriting it. * * @return array An array containg all global config data. * * @since 1.6 */ public function getData() { // Get the config data. $config = new JConfig; $data = JArrayHelper::fromObject($config); // Prime the asset_id for the rules. $data['asset_id'] = 1; // Get the text filter data $params = JComponentHelper::getParams('com_config'); $data['filters'] = JArrayHelper::fromObject($params->get('filters')); // If no filter data found, get from com_content (update of 1.6/1.7 site) if (empty($data['filters'])) { $contentParams = JComponentHelper::getParams('com_content'); $data['filters'] = JArrayHelper::fromObject($contentParams->get('filters')); } // Check for data in the session. $temp = JFactory::getApplication()->getUserState('com_config.config.global.data'); // Merge in the session data. if (!empty($temp)) { $data = array_merge($data, $temp); } return $data; } /** * Method to save the configuration data. * * @param array $data An array containing all global config data. * * @return boolean True on success, false on failure. * * @since 1.6 */ public function save($data) { $app = JFactory::getApplication(); // Save the rules if (isset($data['rules'])) { $rules = new JAccessRules($data['rules']); // Check that we aren't removing our Super User permission // Need to get groups from database, since they might have changed $myGroups = JAccess::getGroupsByUser(JFactory::getUser()->get('id')); $myRules = $rules->getData(); $hasSuperAdmin = $myRules['core.admin']->allow($myGroups); if (!$hasSuperAdmin) { $app->enqueueMessage(JText::_('COM_CONFIG_ERROR_REMOVING_SUPER_ADMIN'), 'error'); return false; } $asset = JTable::getInstance('asset'); if ($asset->loadByName('root.1')) { $asset->rules = (string) $rules; if (!$asset->check() || !$asset->store()) { $app->enqueueMessage(JText::_('SOME_ERROR_CODE'), 'error'); return; } } else { $app->enqueueMessage(JText::_('COM_CONFIG_ERROR_ROOT_ASSET_NOT_FOUND'), 'error'); return false; } unset($data['rules']); } // Save the text filters if (isset($data['filters'])) { $registry = new JRegistry; $registry->loadArray(array('filters' => $data['filters'])); $extension = JTable::getInstance('extension'); // Get extension_id $extension_id = $extension->find(array('name' => 'com_config')); if ($extension->load((int) $extension_id)) { $extension->params = (string) $registry; if (!$extension->check() || !$extension->store()) { $app->enqueueMessage(JText::_('SOME_ERROR_CODE'), 'error'); return; } } else { $app->enqueueMessage(JText::_('COM_CONFIG_ERROR_CONFIG_EXTENSION_NOT_FOUND'), 'error'); return false; } unset($data['filters']); } // Get the previous configuration. $prev = new JConfig; $prev = JArrayHelper::fromObject($prev); // Merge the new data in. We do this to preserve values that were not in the form. $data = array_merge($prev, $data); /* * Perform miscellaneous options based on configuration settings/changes. */ // Escape the offline message if present. if (isset($data['offline_message'])) { $data['offline_message'] = JFilterOutput::ampReplace($data['offline_message']); } // Purge the database session table if we are changing to the database handler. if ($prev['session_handler'] != 'database' && $data['session_handler'] == 'database') { $table = JTable::getInstance('session'); $table->purge(-1); } if (empty($data['cache_handler'])) { $data['caching'] = 0; } // Clean the cache if disabled but previously enabled. if (!$data['caching'] && $prev['caching']) { $cache = JFactory::getCache(); $cache->clean(); } // Create the new configuration object. $config = new JRegistry('config'); $config->loadArray($data); // Overwrite the old FTP credentials with the new ones. $temp = JFactory::getConfig(); $temp->set('ftp_enable', $data['ftp_enable']); $temp->set('ftp_host', $data['ftp_host']); $temp->set('ftp_port', $data['ftp_port']); $temp->set('ftp_user', $data['ftp_user']); $temp->set('ftp_pass', $data['ftp_pass']); $temp->set('ftp_root', $data['ftp_root']); // Clear cache of com_config component. $this->cleanCache('_system', 0); $this->cleanCache('_system', 1); // Write the configuration file. return $this->writeConfigFile($config); } /** * Method to unset the root_user value from configuration data. * * This method will load the global configuration data straight from * JConfig and remove the root_user value for security, then save the configuration. * * @return boolean True on success, false on failure. * * @since 1.6 */ public function removeroot() { // Get the previous configuration. $prev = new JConfig; $prev = JArrayHelper::fromObject($prev); // Create the new configuration object, and unset the root_user property $config = new JRegistry('config'); unset($prev['root_user']); $config->loadArray($prev); // Write the configuration file. return $this->writeConfigFile($config); } /** * Method to write the configuration to a file. * * @param JRegistry $config A JRegistry object containing all global config data. * * @return boolean True on success, false on failure. * * @since 2.5.4 * @throws RuntimeException */ private function writeConfigFile(JRegistry $config) { jimport('joomla.filesystem.path'); jimport('joomla.filesystem.file'); // Set the configuration file path. $file = JPATH_CONFIGURATION . '/configuration.php'; // Get the new FTP credentials. $ftp = JClientHelper::getCredentials('ftp', true); $app = JFactory::getApplication(); // Attempt to make the file writeable if using FTP. if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0644')) { $app->enqueueMessage(JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTWRITABLE'), 'notice'); } // Attempt to write the configuration file as a PHP class named JConfig. $configuration = $config->toString('PHP', array('class' => 'JConfig', 'closingtag' => false)); if (!JFile::write($file, $configuration)) { throw new RuntimeException(JText::_('COM_CONFIG_ERROR_WRITE_FAILED')); } // Attempt to make the file unwriteable if using FTP. if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0444')) { $app->enqueueMessage(JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE'), 'notice'); } return true; } } components/com_config/model/component.php000066600000010116150771655440014670 0ustar00input; // Set the component (option) we are dealing with. $component = $input->get('component'); $state = $this->loadState(); $state->set('component.option', $component); // Set an alternative path for the configuration file. if ($path = $input->getString('path')) { $path = JPath::clean(JPATH_SITE . '/' . $path); JPath::check($path); $state->set('component.path', $path); } $this->setState($state); } /** * Method to get a form object. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return mixed A JForm object on success, false on failure * * @since 3.2 */ public function getForm($data = array(), $loadData = true) { $state = $this->getState(); if ($path = $state->get('component.path')) { // Add the search path for the admin component config.xml file. JForm::addFormPath($path); } else { // Add the search path for the admin component config.xml file. JForm::addFormPath(JPATH_ADMINISTRATOR . '/components/' . $state->get('component.option')); } // Get the form. $form = $this->loadForm( 'com_config.component', 'config', array('control' => 'jform', 'load_data' => $loadData), false, '/config' ); if (empty($form)) { return false; } return $form; } /** * Get the component information. * * @return object * * @since 3.2 */ public function getComponent() { $state = $this->getState(); $option = $state->get('component.option'); // Load common and local language files. $lang = JFactory::getLanguage(); $lang->load($option, JPATH_BASE, null, false, true) || $lang->load($option, JPATH_BASE . "/components/$option", null, false, true); $result = JComponentHelper::getComponent($option); return $result; } /** * Method to save the configuration data. * * @param array $data An array containing all global config data. * * @return boolean True on success, false on failure. * * @since 3.2 * @throws RuntimeException */ public function save($data) { $table = JTable::getInstance('extension'); // Save the rules. if (isset($data['params']) && isset($data['params']['rules'])) { $rules = new JAccessRules($data['params']['rules']); $asset = JTable::getInstance('asset'); if (!$asset->loadByName($data['option'])) { $root = JTable::getInstance('asset'); $root->loadByName('root.1'); $asset->name = $data['option']; $asset->title = $data['option']; $asset->setLocation($root->id, 'last-child'); } $asset->rules = (string) $rules; if (!$asset->check() || !$asset->store()) { throw new RuntimeException($table->getError()); } // We don't need this anymore unset($data['option']); unset($data['params']['rules']); } // Load the previous Data if (!$table->load($data['id'])) { throw new RuntimeException($table->getError()); } unset($data['id']); // Bind the data. if (!$table->bind($data)) { throw new RuntimeException($table->getError()); } // Check the data. if (!$table->check()) { throw new RuntimeException($table->getError()); } // Store the data. if (!$table->store()) { throw new RuntimeException($table->getError()); } // Clean the component cache. $this->cleanCache('_system', 0); $this->cleanCache('_system', 1); return true; } } components/com_config/model/field/index.html000066600000000036150771655440015235 0ustar00components/com_config/model/field/filters.php000066600000012307150771655440015425 0ustar00getUserGroups(); // Build the form control. $html = array(); // Open the table. $html[] = ''; // The table heading. $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; // The table body. $html[] = ' '; foreach ($groups as $group) { if (!isset($this->value[$group->value])) { $this->value[$group->value] = array('filter_type' => 'BL', 'filter_tags' => '', 'filter_attributes' => ''); } $group_filter = $this->value[$group->value]; $group_filter['filter_tags'] = !empty($group_filter['filter_tags']) ? $group_filter['filter_tags'] : ''; $group_filter['filter_attributes'] = !empty($group_filter['filter_attributes']) ? $group_filter['filter_attributes'] : ''; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; } $html[] = ' '; // Close the table. $html[] = '
'; $html[] = ' ' . JText::_('JGLOBAL_FILTER_GROUPS_LABEL') . ''; $html[] = ' '; $html[] = ' ' . JText::_('JGLOBAL_FILTER_TYPE_LABEL') . ''; $html[] = ' '; $html[] = ' ' . JText::_('JGLOBAL_FILTER_TAGS_LABEL') . ''; $html[] = ' '; $html[] = ' ' . JText::_('JGLOBAL_FILTER_ATTRIBUTES_LABEL') . ''; $html[] = '
'; $html[] = ' ' . str_repeat('|—', $group->level) . $group->text; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = '
'; // Add notes $html[] = '
'; $html[] = '

' . JText::_('JGLOBAL_FILTER_TYPE_DESC') . '

'; $html[] = '

' . JText::_('JGLOBAL_FILTER_TAGS_DESC') . '

'; $html[] = '

' . JText::_('JGLOBAL_FILTER_ATTRIBUTES_DESC') . '

'; $html[] = '
'; return implode("\n", $html); } /** * A helper to get the list of user groups. * * @return array * * @since 1.6 */ protected function getUserGroups() { // Get a database object. $db = JFactory::getDBO(); // Get the user groups from the database. $query = $db->getQuery(true); $query->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level'); $query->from('#__usergroups AS a'); $query->join('LEFT', '#__usergroups AS b on a.lft > b.lft AND a.rgt < b.rgt'); $query->group('a.id, a.title, a.lft'); $query->order('a.lft ASC'); $db->setQuery($query); $options = $db->loadObjectList(); return $options; } } components/com_config/model/form/application.xml000066600000052276150771655440016162 0ustar00
components/com_config/model/form/index.html000066600000000037150771655440015116 0ustar00 components/com_config/controller/component/cancel.php000066600000001476150771655440017211 0ustar00context = 'com_config.config.global'; $this->component = $this->input->get('component'); $this->redirect = 'index.php?option=' . $this->component; parent::execute(); } } components/com_config/controller/component/display.php000066600000001176150771655440017426 0ustar00redirect() * * @since 3.2 */ public function execute() { // Check for request forgeries. if (!JSession::checkToken()) { $this->app->enqueueMessage(JText::_('JINVALID_TOKEN')); $this->app->redirect('index.php'); } // Set FTP credentials, if given. JClientHelper::setCredentialsFromRequest('ftp'); $model = new ConfigModelComponent; $form = $model->getForm(); $data = $this->input->get('jform', array(), 'array'); $id = $this->input->getInt('id'); $option = $this->input->get('component'); // Check if the user is authorized to do this. if (!JFactory::getUser()->authorise('core.admin', $option)) { $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR')); $this->app->redirect('index.php'); } $returnUri = $this->input->post->get('return', null, 'base64'); $redirect = ''; if (!empty($returnUri)) { $redirect = '&return=' . urlencode($returnUri); } // Validate the posted data. $return = $model->validate($form, $data); // Check for validation errors. if ($return === false) { /* * The validate method enqueued all messages for us, so we just need to redirect back. */ // Save the data in the session. $this->app->setUserState('com_config.config.global.data', $data); // Redirect back to the edit screen. $this->app->redirect(JRoute::_('index.php?option=com_config&view=component&component=' . $option . $redirect, false)); } // Attempt to save the configuration. $data = array( 'params' => $return, 'id' => $id, 'option' => $option ); try { $model->save($data); } catch (RuntimeException $e) { // Save the data in the session. $this->app->setUserState('com_config.config.global.data', $data); // Save failed, go back to the screen and display a notice. $this->app->enqueueMessage(JText::sprintf('JERROR_SAVE_FAILED', $e->getMessage()), 'error'); $this->app->redirect(JRoute::_('index.php?option=com_config&view=component&component=' . $option . $redirect, false)); } // Set the redirect based on the task. switch ($this->options[3]) { case 'apply': $this->app->enqueueMessage(JText::_('COM_CONFIG_SAVE_SUCCESS')); $this->app->redirect(JRoute::_('index.php?option=com_config&view=component&component=' . $option . $redirect, false)); break; case 'save': default: $redirect = 'index.php?option=' . $option; if (!empty($returnUri)) { $redirect = base64_decode($returnUri); } $this->app->redirect(JRoute::_($redirect, false)); break; } return true; } } components/com_config/controller/component/index.html000066600000000037150771655440017240 0ustar00 components/com_config/controller/application/cancel.php000066600000001745150771655440017511 0ustar00authorise('core.admin', 'com_config')) { $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR')); $this->app->redirect('index.php'); } $this->context = 'com_config.config.global'; $this->redirect = 'index.php?option=com_cpanel'; parent::execute(); } } components/com_config/controller/application/display.php000066600000001200150771655440017713 0ustar00redirect() for all cases except JSON * * @since 3.2 */ public function execute() { // Check for request forgeries. if (!JSession::checkToken()) { $this->app->enqueueMessage(JText::_('JINVALID_TOKEN')); $this->app->redirect('index.php'); } // Check if the user is authorized to do this. if (!JFactory::getUser()->authorise('core.admin')) { $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR')); $this->app->redirect('index.php'); } // Set FTP credentials, if given. JClientHelper::setCredentialsFromRequest('ftp'); $model = new ConfigModelApplication; $data = $this->input->post->get('jform', array(), 'array'); // Complete data array if needed $oldData = $model->getData(); $data = array_replace($oldData, $data); // Get request type $saveFormat = JFactory::getDocument()->getType(); // Handle service requests if ($saveFormat == 'json') { return $model->save($data); } // Must load after serving service-requests $form = $model->getForm(); // Validate the posted data. $return = $model->validate($form, $data); // Check for validation errors. if ($return === false) { /* * The validate method enqueued all messages for us, so we just need to redirect back. */ // Save the data in the session. $this->app->setUserState('com_config.config.global.data', $data); // Redirect back to the edit screen. $this->app->redirect(JRoute::_('index.php?option=com_config&controller=config.display.application', false)); } // Attempt to save the configuration. $data = $return; $return = $model->save($data); // Check the return value. if ($return === false) { /* * The save method enqueued all messages for us, so we just need to redirect back. */ // Save the data in the session. $this->app->setUserState('com_config.config.global.data', $data); // Save failed, go back to the screen and display a notice. $this->app->redirect(JRoute::_('index.php?option=com_config&controller=config.display.application', false)); } // Set the success message. $this->app->enqueueMessage(JText::_('COM_CONFIG_SAVE_SUCCESS')); // Set the redirect based on the task. switch ($this->options[3]) { case 'apply': $this->app->redirect(JRoute::_('index.php?option=com_config', false)); break; case 'save': default: $this->app->redirect(JRoute::_('index.php', false)); break; } } } components/com_config/controller/application/index.html000066600000000037150771655440017541 0ustar00 components/com_config/controller/application/removeroot.php000066600000003330150771655440020455 0ustar00app->enqueueMessage(JText::_('JINVALID_TOKEN')); $this->app->redirect('index.php'); } // Check if the user is authorized to do this. if (!JFactory::getUser()->authorise('core.admin')) { $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR')); $this->app->redirect('index.php'); } // Initialise model. $model = new ConfigModelApplication; // Attempt to save the configuration and remove root. try { $model->removeroot(); } catch (RuntimeException $e) { // Save failed, go back to the screen and display a notice. $this->app->enqueueMessage(JText::sprintf('JERROR_SAVE_FAILED', $e->getMessage()), 'error'); $this->app->redirect(JRoute::_('index.php', false)); } // Set the redirect based on the task. $this->app->enqueueMessage(JText::_('COM_CONFIG_SAVE_SUCCESS')); $this->app->redirect(JRoute::_('index.php', false)); } } components/com_config/controller/application/refreshhelp.php000066600000003064150771655440020567 0ustar00app->enqueueMessage(JText::_('COM_CONFIG_ERROR_HELPREFRESH_FETCH'), 'error'); $this->app->redirect(JRoute::_('index.php?option=com_config', false)); } elseif (!JFile::write(JPATH_BASE . '/help/helpsites.xml', $data)) { $this->app->enqueueMessage(JText::_('COM_CONFIG_ERROR_HELPREFRESH_ERROR_STORE'), 'error'); $this->app->redirect(JRoute::_('index.php?option=com_config', false)); } else { $this->app->enqueueMessage(JText::_('COM_CONFIG_HELPREFRESH_SUCCESS'), 'error'); $this->app->redirect(JRoute::_('index.php?option=com_config', false)); } } } components/com_config/views/index.html000066600000000037150771655440014210 0ustar00 components/com_config/views/component/view.html.php000066600000007457150771655440016660 0ustar00 'JHELP_COMPONENTS_BANNER_MANAGER_OPTIONS', 'com_cache' => 'JHELP_COMPONENTS_CACHE_MANAGER_SETTINGS', 'com_checkin' => 'JHELP_COMPONENTS_CHECK-IN_CONFIGURATION', 'com_contact' => 'JHELP_COMPONENTS_CONTACT_MANAGER_OPTIONS', 'com_content' => 'JHELP_COMPONENTS_ARTICLE_MANAGER_OPTIONS', 'com_finder' => 'JHELP_COMPONENTS_SMART_SEARCH_CONFIGURATION', 'com_installer' => 'JHELP_COMPONENTS_INSTALLER_CONFIGURATION', 'com_joomlaupdate' => 'JHELP_COMPONENTS_JOOMLA_UPDATE_CONFIGURATION', 'com_languages' => 'JHELP_COMPONENTS_LANGUAGE_MANAGER_OPTIONS', 'com_media' => 'JHELP_COMPONENTS_MEDIA_MANAGER_OPTIONS', 'com_menus' => 'JHELP_COMPONENTS_MENUS_CONFIGURATION', 'com_messages' => 'JHELP_COMPONENTS_MESSAGES_CONFIGURATION', 'com_modules' => 'JHELP_COMPONENTS_MODULE_MANAGER_OPTIONS', 'com_newsfeeds' => 'JHELP_COMPONENTS_NEWS_FEED_MANAGER_OPTIONS', 'com_plugins' => 'JHELP_COMPONENTS_PLUG-IN_MANAGER_OPTIONS', 'com_redirect' => 'JHELP_COMPONENTS_REDIRECT_MANAGER_OPTIONS', 'com_search' => 'JHELP_COMPONENTS_SEARCH_MANAGER_OPTIONS', 'com_tags' => 'JHELP_COMPONENTS_TAGS_MANAGER_OPTIONS', 'com_templates' => 'JHELP_COMPONENTS_TEMPLATE_MANAGER_OPTIONS', 'com_users' => 'JHELP_COMPONENTS_USERS_CONFIGURATION', 'com_weblinks' => 'JHELP_COMPONENTS_WEB_LINKS_MANAGER_OPTIONS', ); /** * Execute and display a template script. * * @param string $tpl The name of the template file to parse; automatically searches through the template paths. * * @return mixed A string if successful, otherwise a Error object. * * @since 1.5 */ public function display($tpl = null) { $form = $this->get('Form'); $component = $this->get('Component'); $user = JFactory::getUser(); $app = JFactory::getApplication(); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } // Bind the form to the data. if ($form && $component->params) { $form->bind($component->params); } $this->form = &$form; $this->component = &$component; $this->components = ConfigHelperComponent::getComponentsWithConfig(); ConfigHelperComponent::loadLanguageForComponents($this->components); $this->userIsSuperAdmin = $user->authorise('core.admin'); $this->currentComponent = JFactory::getApplication()->input->get('component'); $this->return = $app->input->get('return', '', 'base64'); $this->addToolbar(); parent::display($tpl); $app->input->set('hidemainmenu', true); } /** * Add the page title and toolbar. * * @since 3.0 */ protected function addToolbar() { JToolbarHelper::title(JText::_($this->component->option . '_configuration'), 'config.png'); JToolbarHelper::apply('component.apply'); JToolbarHelper::save('component.save'); JToolbarHelper::divider(); JToolbarHelper::cancel('component.cancel'); JToolbarHelper::divider(); // Get the correct help key for this screen if (isset($this->helpScreenArray[$this->component->option])) { JToolbarHelper::help($this->helpScreenArray[$this->component->option]); } else { JToolbarHelper::help('JHELP_SITE_GLOBAL_CONFIGURATION'); } } } components/com_config/views/component/tmpl/default.php000066600000005540150771655440017332 0ustar00getTemplate(); // Load the tooltip behavior. JHtml::_('behavior.tooltip'); JHtml::_('behavior.formvalidation'); JHtml::_('formbehavior.chosen', 'select'); ?>
form->getFieldsets(); foreach ($fieldSets as $name => $fieldSet) : ?>
description) && !empty($fieldSet->description)) : echo '

'.JText::_($fieldSet->description).'

'; endif; foreach ($this->form->getFieldset($name) as $field): ?>
hidden && $name != "permissions") : ?>
label; ?>
controls"> input; ?>
components/com_config/views/component/tmpl/index.html000066600000000037150771655440017166 0ustar00 components/com_config/views/component/tmpl/default_navigation.php000066600000002002150771655440021537 0ustar00 components/com_config/views/component/index.html000066600000000037150771655440016212 0ustar00 components/com_config/views/close/view.html.php000066600000001503150771655440015745 0ustar00addScriptDeclaration(' window.parent.location.href=window.parent.location.href; window.parent.SqueezeBox.close(); '); } } components/com_config/views/close/index.html000066600000000037150771655440015315 0ustar00 components/com_config/views/application/view.html.php000066600000004113150771655440017143 0ustar00get('Form'); $data = $this->get('Data'); $user = JFactory::getUser(); // Check for model errors. if ($errors = $this->get('Errors')) { JError::raiseError(500, implode('
', $errors)); return false; } // Bind the form to the data. if ($form && $data) { $form->bind($data); } // Get the params for com_users. $usersParams = JComponentHelper::getParams('com_users'); // Get the params for com_media. $mediaParams = JComponentHelper::getParams('com_media'); // Load settings for the FTP layer. $ftp = JClientHelper::setCredentialsFromRequest('ftp'); $this->form = &$form; $this->data = &$data; $this->ftp = &$ftp; $this->usersParams = &$usersParams; $this->mediaParams = &$mediaParams; $this->components = ConfigHelperComponent::getComponentsWithConfig(); ConfigHelperComponent::loadLanguageForComponents($this->components); $this->userIsSuperAdmin = $user->authorise('core.admin'); $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { JToolbarHelper::title(JText::_('COM_CONFIG_GLOBAL_CONFIGURATION'), 'config.png'); JToolbarHelper::apply('application.apply'); JToolbarHelper::save('application.save'); JToolbarHelper::divider(); JToolbarHelper::cancel('application.cancel'); JToolbarHelper::divider(); JToolbarHelper::help('JHELP_SITE_GLOBAL_CONFIGURATION'); } } components/com_config/views/application/tmpl/default.php000066600000007655150771655440017644 0ustar00
'page-site')); ?>
loadTemplate('site'); ?> loadTemplate('metadata'); ?>
loadTemplate('seo'); ?> loadTemplate('cookie'); ?>
loadTemplate('system'); ?> loadTemplate('debug'); ?>
loadTemplate('cache'); ?> loadTemplate('session'); ?>
loadTemplate('server'); ?> loadTemplate('locale'); ?> loadTemplate('ftp'); ?>
loadTemplate('database'); ?> loadTemplate('mail'); ?>
loadTemplate('permissions'); ?>
loadTemplate('filters'); ?>
ftp) : ?> loadTemplate('ftplogin'); ?>
components/com_config/views/application/tmpl/default_cache.php000066600000002327150771655440020756 0ustar00
form->getFieldset('cache') as $field): ?>
label; ?>
input; ?>
data['cache_handler']) && $this->data['cache_handler'] == 'memcache' || $this->data['session_handler'] == 'memcache' || $this->data['cache_handler'] == 'memcached' || $this->data['session_handler'] == 'memcached' ) : ?> form->getFieldset('memcache') as $mfield): ?>
label; ?>
input; ?>
components/com_config/views/application/tmpl/default_mail.php000066600000001212150771655440020625 0ustar00
form->getFieldset('mail') as $field): ?>
label; ?>
input; ?>
components/com_config/views/application/tmpl/default_cookie.php000066600000001216150771655440021160 0ustar00
form->getFieldset('cookie') as $field): ?>
label; ?>
input; ?>
components/com_config/views/application/tmpl/default_ftp.php000066600000001210150771655440020472 0ustar00
form->getFieldset('ftp') as $field): ?>
label; ?>
input; ?>
components/com_config/views/application/tmpl/default_database.php000066600000001222150771655440021450 0ustar00
form->getFieldset('database') as $field): ?>
label; ?>
input; ?>
components/com_config/views/application/tmpl/index.html000066600000000037150771655440017467 0ustar00 components/com_config/views/application/tmpl/default_seo.php000066600000001210150771655440020467 0ustar00
form->getFieldset('seo') as $field): ?>
label; ?>
input; ?>
components/com_config/views/application/tmpl/default_ftplogin.php000066600000002153150771655440021532 0ustar00
ftp instanceof Exception) : ?>

ftp->message); ?>

components/com_config/views/application/tmpl/default_permissions.php000066600000001121150771655440022255 0ustar00
form->getFieldset('permissions') as $field) : ?>
input; ?>
components/com_config/views/application/tmpl/default_navigation.php000066600000001623150771655440022050 0ustar00 components/com_config/views/application/tmpl/default_debug.php000066600000001214150771655440020773 0ustar00
form->getFieldset('debug') as $field): ?>
label; ?>
input; ?>
components/com_config/views/application/tmpl/default_site.php000066600000001212150771655440020647 0ustar00
form->getFieldset('site') as $field): ?>
label; ?>
input; ?>
components/com_config/views/application/tmpl/default_server.php000066600000001216150771655440021215 0ustar00
form->getFieldset('server') as $field): ?>
label; ?>
input; ?>
components/com_config/views/application/tmpl/default_filters.php000066600000001317150771655440021361 0ustar00

form->getFieldset('filters') as $field) : ?>
label; ?>
input; ?>
components/com_config/views/application/tmpl/default_session.php000066600000001220150771655440021365 0ustar00
form->getFieldset('session') as $field): ?>
label; ?>
input; ?>
components/com_config/views/application/tmpl/default_system.php000066600000001216150771655440021233 0ustar00
form->getFieldset('system') as $field): ?>
label; ?>
input; ?>
components/com_config/views/application/tmpl/default_metadata.php000066600000001222150771655440021464 0ustar00
form->getFieldset('metadata') as $field): ?>
label; ?>
input; ?>
components/com_config/views/application/tmpl/default_locale.php000066600000001220150771655440021141 0ustar00
form->getFieldset('locale') as $field): ?>
label; ?>
input; ?>
components/com_config/views/application/index.html000066600000000037150771655440016513 0ustar00 components/com_config/index.html000066600000000037150771655440013053 0ustar00 components/com_config/config.xml000066600000002025150771655440013044 0ustar00 com_config Joomla! Project April 2006 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_CONFIG_XML_DESCRIPTION config.php controller.php index.html controllers models controller model view language/en-GB.com_config.ini language/en-GB.com_config.sys.ini components/com_config/controller.php000066600000003016150771655440013752 0ustar00input->get('view', 'application'); JLog::add('ConfigController is deprecated. Use ConfigControllerApplicationDisplay or ConfigControllerComponentDisplay instead.', JLog::WARNING, 'deprecated'); if (ucfirst($vName) == 'Application') { $controller = new ConfigControllerApplicationDisplay; } elseif (ucfirst($vName) == 'Component') { $controller = new ConfigControllerComponentDisplay; } return $controller->execute(); } } components/com_config/config.php000066600000001633150771655440013037 0ustar00setHeader('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT', true); // Load classes JLoader::registerPrefix('Config', JPATH_COMPONENT); JLoader::registerPrefix('Config', JPATH_ROOT . '/components/com_config'); // Application $app = JFactory::getApplication(); $controllerHelper = new ConfigControllerHelper; $controller = $controllerHelper->parseController($app); $controller->prefix = 'Config'; // Perform the Request task $controller->execute(); components/com_config/controllers/component.php.backup000066600000007656150771655440017421 0ustar00registerTask('apply', 'save'); } /** * Cancel operation * * @return void * * @since 3.0 */ function cancel() { // Clean the session data. $app = JFactory::getApplication(); $app->setUserState('com_config.config.global.data', null); $return = $this->input->post->get('return', null, 'base64'); $redirect = 'index.php'; if (!empty($return)) { $redirect = base64_decode($return); } $this->setRedirect($redirect); } /** * Save the configuration */ public function save() { // Check for request forgeries. JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Set FTP credentials, if given. JClientHelper::setCredentialsFromRequest('ftp'); $app = JFactory::getApplication(); $model = $this->getModel('Component'); $form = $model->getForm(); $data = $this->input->get('jform', array(), 'array'); $id = $this->input->getInt('id'); $option = $this->input->get('component'); // Check if the user is authorized to do this. if (!JFactory::getUser()->authorise('core.admin', $option)) { JFactory::getApplication()->redirect('index.php', JText::_('JERROR_ALERTNOAUTHOR')); return; } $returnUri = $this->input->post->get('return', null, 'base64'); if (!empty($returnUri)) { $redirect = '&return=' . urlencode($returnUri); } // Validate the posted data. $return = $model->validate($form, $data); // Check for validation errors. if ($return === false) { // Get the validation messages. $errors = $model->getErrors(); // Push up to three validation messages out to the user. for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) { if ($errors[$i] instanceof Exception) { $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); } else { $app->enqueueMessage($errors[$i], 'warning'); } } // Save the data in the session. $app->setUserState('com_config.config.global.data', $data); // Redirect back to the edit screen. $this->setRedirect(JRoute::_('index.php?option=com_config&view=component&component=' . $option . $redirect, false)); return false; } // Attempt to save the configuration. $data = array( 'params' => $return, 'id' => $id, 'option' => $option ); $return = $model->save($data); // Check the return value. if ($return === false) { // Save the data in the session. $app->setUserState('com_config.config.global.data', $data); // Save failed, go back to the screen and display a notice. $message = JText::sprintf('JERROR_SAVE_FAILED', $model->getError()); $this->setRedirect('index.php?option=com_config&view=component&component=' . $option . $redirect, $message, 'error'); return false; } // Set the redirect based on the task. switch ($this->getTask()) { case 'apply': $message = JText::_('COM_CONFIG_SAVE_SUCCESS'); $this->setRedirect('index.php?option=com_config&view=component&component=' . $option . $redirect, $message); break; case 'save': default: $redirect = 'index.php'; if (!empty($returnUri)) { $redirect = base64_decode($returnUri); } $this->setRedirect($redirect); break; } return true; } } components/com_config/controllers/index.html000066600000000037150771655440015421 0ustar00 components/com_config/controllers/application.php000066600000004533150771655440016445 0ustar00registerTask('apply', 'save'); } /** * Method to save the configuration. * * @return bool True on success, false on failure. * * @since 1.5 * @deprecated 4.0 Use ConfigControllerApplicationSave instead. */ public function save() { JLog::add('ConfigControllerApplication is deprecated. Use ConfigControllerApplicationSave instead.', JLog::WARNING, 'deprecated'); $controller = new ConfigControllerApplicationSave; return $controller->execute(); } /** * Cancel operation * @deprecated 4.0 Use ConfigControllerApplicationCancel instead. */ public function cancel() { JLog::add('ConfigControllerApplication is deprecated. Use ConfigControllerApplicationCancel instead.', JLog::WARNING, 'deprecated'); $controller = new ConfigControllerApplicationCancel; return $controller->execute(); } public function refreshHelp() { JLog::add('ConfigControllerApplication is deprecated. Use ConfigControllerApplicationRefreshhelp instead.', JLog::WARNING, 'deprecated'); $controller = new ConfigControllerApplicationRefreshhelp; $controller->execute(); } /** * Method to remove the root property from the configuration. * * @return bool True on success, false on failure. * * @since 1.5 * @deprecated 4.0 Use ConfigControllerApplicationRemoveroot instead. */ public function removeroot() { JLog::add('ConfigControllerApplication is deprecated. Use ConfigControllerApplicationRemoveroot instead.', JLog::WARNING, 'deprecated'); $controller = new ConfigControllerApplicationRemoveroot; return $controller->execute(); } } components/com_config/controllers/component.php000066600000003050150771655440016135 0ustar00registerTask('apply', 'save'); } /** * Cancel operation * * @return void * * @since 3.0 * @deprecated 4.0 Use ConfigControllerComponentCancel instead. */ function cancel() { JLog::add('ConfigControllerComponent is deprecated. Use ConfigControllerComponentCancel instead.', JLog::WARNING, 'deprecated'); $controller = new ConfigControllerComponentCancel; $controller->execute(); } /** * Save the configuration * @deprecated 4.0 Use ConfigControllerComponentSave instead. */ public function save() { JLog::add('ConfigControllerComponent is deprecated. Use ConfigControllerComponentSave instead.', JLog::WARNING, 'deprecated'); $controller = new ConfigControllerComponentSave; return $controller->execute(); } } components/com_config/access.xml000066600000000337150771655440013044 0ustar00
components/com_config/models/index.html000066600000000036150771655440014335 0ustar00components/com_config/models/application.php000066600000001016150771655440015353 0ustar00components/com_config/models/fields/filters.php000066600000011462150771655440015774 0ustar00getUserGroups(); // Build the form control. $html = array(); // Open the table. $html[] = ''; // The table heading. $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; // The table body. $html[] = ' '; foreach ($groups as $group) { if (!isset($this->value[$group->value])) { $this->value[$group->value] = array('filter_type' => 'BL', 'filter_tags' => '', 'filter_attributes' => ''); } $group_filter = $this->value[$group->value]; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; } $html[] = ' '; // Close the table. $html[] = '
'; $html[] = ' '.JText::_('JGLOBAL_FILTER_GROUPS_LABEL').''; $html[] = ' '; $html[] = ' '.JText::_('JGLOBAL_FILTER_TYPE_LABEL').''; $html[] = ' '; $html[] = ' '.JText::_('JGLOBAL_FILTER_TAGS_LABEL').''; $html[] = ' '; $html[] = ' '.JText::_('JGLOBAL_FILTER_ATTRIBUTES_LABEL').''; $html[] = '
'; $html[] = ' '.str_repeat('|—', $group->level).$group->text; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = ' '; $html[] = '
'; // Add notes $html[] = '
'; $html[] = '

' . JText::_('JGLOBAL_FILTER_TYPE_DESC') . '

'; $html[] = '

' . JText::_('JGLOBAL_FILTER_TAGS_DESC') . '

'; $html[] = '

' . JText::_('JGLOBAL_FILTER_ATTRIBUTES_DESC') . '

'; $html[] = '
'; return implode("\n", $html); } /** * A helper to get the list of user groups. * * @return array * @since 1.6 */ protected function getUserGroups() { // Get a database object. $db = JFactory::getDbo(); // Get the user groups from the database. $query = $db->getQuery(true) ->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level') ->from('#__usergroups AS a') ->join('LEFT', '#__usergroups AS b on a.lft > b.lft AND a.rgt < b.rgt') ->group('a.id, a.title, a.lft') ->order('a.lft ASC'); $db->setQuery($query); $options = $db->loadObjectList(); return $options; } } components/com_config/models/forms/application.xml000066600000046036150771655440016525 0ustar00
components/com_config/models/forms/index.html000066600000000037150771655440015464 0ustar00 components/com_config/models/component.php000066600000001014150771655440015050 0ustar00 components/com_config/view/component/tmpl/default.php000066600000006535150771655440017154 0ustar00getTemplate(); // Load the tooltip behavior. JHtml::_('bootstrap.tooltip'); JHtml::_('behavior.formvalidation'); JHtml::_('formbehavior.chosen', 'select'); ?>
form->getFieldsets(); ?> $fieldSet) : ?>
description) && !empty($fieldSet->description)) { echo '

' . JText::_($fieldSet->description) . '

'; } ?> form->getFieldset($name) as $field) : ?> getAttribute('showon')) { JHtml::_('jquery.framework'); JHtml::_('script', 'jui/cms.js', false, true); $id = $this->form->getFormControl(); $showon = explode(':', $showon, 2); $class = ' showon_' . implode(' showon_', explode(',', $showon[1])); $rel = ' rel="showon_' . $id . '[' . $showon[0] . ']"'; } ?>
> hidden && $name != "permissions") : ?>
label; ?>
controls"> input; ?>
components/com_config/view/component/tmpl/index.html000066600000000037150771655440017003 0ustar00 components/com_config/view/component/tmpl/default_navigation.php000066600000002013150771655440021356 0ustar00 components/com_config/view/component/index.html000066600000000037150771655440016027 0ustar00 components/com_config/view/component/html.php000066600000004122150771655440015506 0ustar00model->getForm(); $component = $this->model->getComponent(); $user = JFactory::getUser(); } catch (Exception $e) { JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); return false; } // Bind the form to the data. if ($form && $component->params) { $form->bind($component->params); } $this->form = &$form; $this->component = &$component; $this->components = ConfigHelperConfig::getComponentsWithConfig(); ConfigHelperConfig::loadLanguageForComponents($this->components); $this->userIsSuperAdmin = $user->authorise('core.admin'); $this->currentComponent = JFactory::getApplication()->input->get('component'); $this->return = JFactory::getApplication()->input->get('return', '', 'base64'); $this->addToolbar(); JFactory::getApplication()->input->set('hidemainmenu', true); return parent::render(); } /** * Add the page title and toolbar. * * @return void * * @since 3.2 */ protected function addToolbar() { JToolbarHelper::title(JText::_($this->component->option . '_configuration'), 'equalizer config'); JToolbarHelper::apply('config.save.component.apply'); JToolbarHelper::save('config.save.component.save'); JToolbarHelper::divider(); JToolbarHelper::cancel('config.cancel.component'); JToolbarHelper::divider(); JToolbarHelper::help('JHELP_COMPONENTS_' . $this->currentComponent . '_OPTIONS'); } } components/com_config/view/application/tmpl/default.php000066600000007715150771655440017456 0ustar00
loadTemplate('site'); ?> loadTemplate('metadata'); ?>
loadTemplate('seo'); ?> loadTemplate('cookie'); ?>
loadTemplate('system'); ?> loadTemplate('debug'); ?> loadTemplate('cache'); ?> loadTemplate('session'); ?>
loadTemplate('server'); ?> loadTemplate('locale'); ?> loadTemplate('ftp'); ?> loadTemplate('proxy'); ?>
loadTemplate('database'); ?> loadTemplate('mail'); ?>
loadTemplate('permissions'); ?>
loadTemplate('filters'); ?>
ftp) : ?>
loadTemplate('ftplogin'); ?>
components/com_config/view/application/tmpl/default_cache.php000066600000001277150771655440020576 0ustar00name = JText::_('COM_CONFIG_CACHE_SETTINGS'); $this->fieldsname = 'cache'; if (isset($this->data['cache_handler']) && $this->data['cache_handler'] == 'memcache' || $this->data['session_handler'] == 'memcache' || $this->data['cache_handler'] == 'memcached' || $this->data['session_handler'] == 'memcached' ) { $this->fieldsname .= ',memcache'; } echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/default_mail.php000066600000000652150771655440020451 0ustar00name = JText::_('COM_CONFIG_MAIL_SETTINGS'); $this->fieldsname = 'mail'; echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/default_cookie.php000066600000000656150771655440021004 0ustar00name = JText::_('COM_CONFIG_COOKIE_SETTINGS'); $this->fieldsname = 'cookie'; echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/default_ftp.php000066600000000650150771655440020316 0ustar00name = JText::_('COM_CONFIG_FTP_SETTINGS'); $this->fieldsname = 'ftp'; echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/default_database.php000066600000000662150771655440021274 0ustar00name = JText::_('COM_CONFIG_DATABASE_SETTINGS'); $this->fieldsname = 'database'; echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/index.html000066600000000037150771655440017304 0ustar00 components/com_config/view/application/tmpl/default_seo.php000066600000000650150771655440020313 0ustar00name = JText::_('COM_CONFIG_SEO_SETTINGS'); $this->fieldsname = 'seo'; echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/default_ftplogin.php000066600000002171150771655440021347 0ustar00
ftp instanceof Exception) : ?>

ftp->message); ?>

components/com_config/view/application/tmpl/default_permissions.php000066600000000765150771655440022107 0ustar00name = JText::_('COM_CONFIG_PERMISSION_SETTINGS'); $this->fieldsname = 'permissions'; $this->formclass = 'form-vertical'; $this->showlabel = false; echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/default_navigation.php000066600000001630150771655440021663 0ustar00 components/com_config/view/application/tmpl/default_debug.php000066600000000654150771655440020617 0ustar00name = JText::_('COM_CONFIG_DEBUG_SETTINGS'); $this->fieldsname = 'debug'; echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/default_proxy.php000066600000000654150771655440020712 0ustar00name = JText::_('COM_CONFIG_PROXY_SETTINGS'); $this->fieldsname = 'proxy'; echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/default_site.php000066600000000652150771655440020473 0ustar00name = JText::_('COM_CONFIG_SITE_SETTINGS'); $this->fieldsname = 'site'; echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/default_server.php000066600000000656150771655440021041 0ustar00name = JText::_('COM_CONFIG_SERVER_SETTINGS'); $this->fieldsname = 'server'; echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/default_filters.php000066600000000763150771655440021202 0ustar00name = JText::_('COM_CONFIG_TEXT_FILTER_SETTINGS'); $this->fieldsname = 'filters'; $this->description = JText::_('COM_CONFIG_TEXT_FILTERS_DESC'); echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/default_session.php000066600000000660150771655440021211 0ustar00name = JText::_('COM_CONFIG_SESSION_SETTINGS'); $this->fieldsname = 'session'; echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/default_system.php000066600000000656150771655440021057 0ustar00name = JText::_('COM_CONFIG_SYSTEM_SETTINGS'); $this->fieldsname = 'system'; echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/default_metadata.php000066600000000662150771655440021310 0ustar00name = JText::_('COM_CONFIG_METADATA_SETTINGS'); $this->fieldsname = 'metadata'; echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/tmpl/default_locale.php000066600000000660150771655440020765 0ustar00name = JText::_('COM_CONFIG_LOCATION_SETTINGS'); $this->fieldsname = 'locale'; echo JLayoutHelper::render('joomla.content.options_default', $this); components/com_config/view/application/index.html000066600000000037150771655440016330 0ustar00 components/com_config/view/application/html.php000066600000004246150771655440016016 0ustar00model->getForm(); $data = $this->model->getData(); $user = JFactory::getUser(); } catch (Exception $e) { JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); return false; } // Bind data if ($form && $data) { $form->bind($data); } // Get the params for com_users. $usersParams = JComponentHelper::getParams('com_users'); // Get the params for com_media. $mediaParams = JComponentHelper::getParams('com_media'); // Load settings for the FTP layer. $ftp = JClientHelper::setCredentialsFromRequest('ftp'); $this->form = &$form; $this->data = &$data; $this->ftp = &$ftp; $this->usersParams = &$usersParams; $this->mediaParams = &$mediaParams; $this->components = ConfigHelperConfig::getComponentsWithConfig(); ConfigHelperConfig::loadLanguageForComponents($this->components); $this->userIsSuperAdmin = $user->authorise('core.admin'); $this->addToolbar(); return parent::render(); } /** * Add the page title and toolbar. * * @return void * * @since 3.2 */ protected function addToolbar() { JToolbarHelper::title(JText::_('COM_CONFIG_GLOBAL_CONFIGURATION'), 'equalizer config'); JToolbarHelper::apply('config.save.application.apply'); JToolbarHelper::save('config.save.application.save'); JToolbarHelper::divider(); JToolbarHelper::cancel('config.cancel.application'); JToolbarHelper::divider(); JToolbarHelper::help('JHELP_SITE_GLOBAL_CONFIGURATION'); } } components/com_config/view/application/json.php000066600000002776150771655440016031 0ustar00data = $this->model->getData(); $user = JFactory::getUser(); } catch (Exception $e) { JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); return false; } $this->userIsSuperAdmin = $user->authorise('core.admin'); // Required data $requiredData = array( "sitename" => null, "offline" => null, "access" => null, "list_limit" => null, "MetaDesc" => null, "MetaKeys" => null, "MetaRights" => null, "sef" => null, "sitename_pagetitles" => null, "debug" => null, "debug_lang" => null, "error_reporting" => null, "mailfrom" => null, "fromname" => null ); $this->data = array_intersect_key($this->data, $requiredData); return json_encode($this->data); } } components/com_config/helper/index.html000066600000000037150771655440014332 0ustar00 components/com_config/helper/component.php000066600000005222150771655440015051 0ustar00getQuery(true) ->select('element') ->from('#__extensions') ->where('type = ' . $db->quote('component')) ->where('enabled = 1'); $db->setQuery($query); $result = $db->loadColumn(); return $result; } /** * Returns true if the component has configuration options. * * @param string $components * * @return boolean * * @since 3.0 */ public static function hasComponentConfig($component) { return is_file(JPATH_ADMINISTRATOR . '/components/' . $component . '/config.xml'); } /** * Returns an array of all components with configuration options. By only * components for which the current user has 'core.manage' rights are returned. * * @param boolean $authCheck * * @return array * * @since 3.0 */ public static function getComponentsWithConfig($authCheck = true) { $result = array(); $components = self::getAllComponents(); $user = JFactory::getUser(); // Remove com_config from the array as that may have weird side effects $components = array_diff($components, array('com_config')); foreach ($components as $component) { if (self::hasComponentConfig($component) && (!$authCheck || $user->authorise('core.manage', $component))) { $result[] = $component; } } return $result; } /** * Load the sys language for the given component. * * @param string $components * * @return void * * @since 3.0 */ public static function loadLanguageForComponents($components) { $lang = JFactory::getLanguage(); foreach ($components as $component) { if (!empty($component)) { // Load the core file then // Load extension-local file. $lang->load($component . '.sys', JPATH_BASE, null, false, false) || $lang->load($component . '.sys', JPATH_ADMINISTRATOR . '/components/' . $component, null, false, false) || $lang->load($component . '.sys', JPATH_BASE, $lang->getDefault(), false, false) || $lang->load($component . '.sys', JPATH_ADMINISTRATOR . '/components/' . $component, $lang->getDefault(), false, false); } } } } components/com_config/helper/config.php000066600000004731150771655440014320 0ustar00getQuery(true) ->select('element') ->from('#__extensions') ->where('type = ' . $db->quote('component')) ->where('enabled = 1'); $db->setQuery($query); $result = $db->loadColumn(); return $result; } /** * Returns true if the component has configuration options. * * @param string $component Component name * * @return boolean * * @since 3.0 */ public static function hasComponentConfig($component) { return is_file(JPATH_ADMINISTRATOR . '/components/' . $component . '/config.xml'); } /** * Returns an array of all components with configuration options. By only * components for which the current user has 'core.manage' rights are returned. * * @param boolean $authCheck * * @return array * * @since 3.0 */ public static function getComponentsWithConfig($authCheck = true) { $result = array(); $components = self::getAllComponents(); $user = JFactory::getUser(); // Remove com_config from the array as that may have weird side effects $components = array_diff($components, array('com_config')); foreach ($components as $component) { if (self::hasComponentConfig($component) && (!$authCheck || $user->authorise('core.manage', $component))) { $result[] = $component; } } return $result; } /** * Load the sys language for the given component. * * @param string $components * * @return void * * @since 3.0 */ public static function loadLanguageForComponents($components) { $lang = JFactory::getLanguage(); foreach ($components as $component) { if (!empty($component)) { // Load the core file then // Load extension-local file. $lang->load($component . '.sys', JPATH_BASE, null, false, true) || $lang->load($component . '.sys', JPATH_ADMINISTRATOR . '/components/' . $component, null, false, true); } } } } components/com_widgetkit/js/admin.js000066600000013236150771655440013653 0ustar00/* Copyright (C) YOOtheme GmbH, YOOtheme Proprietary Use License (http://www.yootheme.com/license) */ jQuery(function(a){window.submitbutton=function(a){"cancel"==a&&(window.location="index.php?option=com_widgetkit")};window.Joomla=window.Joomla||{};window.Joomla.submitbutton=window.submitbutton;a("#tabs").tabs().prev().append('
  • '+a("#tabs").data("wkversion")+"
  • ");a("#widgetkit").delegate(".box .deletable","click",function(){a(this).parent().trigger("delete",[a(this)])});a("input:text").placeholder();a(".actions .save").css("display","none").length&&(a("#toolbar tr").prepend('Apply'), a("#toolbar ul").prepend('
  • Save
  • '),a("#toolbar.btn-toolbar").prepend('
    '),a("#toolbar-apply").bind("click",function(){a("#toolbar").addClass("saving");a(".actions .save").trigger("click")}),a(".actions .save").bind("complete",function(){a("#toolbar").removeClass("saving")}))}); (function(a){var e={get:function(a){return window.sessionStorage?sessionStorage.getItem(a):null},set:function(a,f){window.sessionStorage&&sessionStorage.setItem(a,f)}};a.fn.tabs=function(){return this.each(function(){var h=a(this).addClass("content").wrap('
    ').before('
    ');j.css({zIndex:a.zIndex});"se"==h&&j.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[h]=".ui-resizable-"+h;this.element.append(j)}}this._renderAxis=function(c){var c=c||this.element,a;for(a in this.handles){this.handles[a].constructor==String&&(this.handles[a]=d(this.handles[a],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var b= d(this.handles[a],this.element),e=0,e=/sw|ne|nw|se|n|s/.test(a)?b.outerHeight():b.outerWidth(),b=["padding",/ne|nw|n/.test(a)?"Top":/se|sw|s/.test(a)?"Bottom":/^e$/.test(a)?"Right":"Left"].join("");c.css(b,e);this._proportionallyResize()}d(this.handles[a])}};this._renderAxis(this.element);this._handles=d(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!c.resizing){if(this.className)var a=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);c.axis= a&&a[1]?a[1]:"se"}});a.autoHide&&(this._handles.hide(),d(this.element).addClass("ui-resizable-autohide").mouseenter(function(){if(!a.disabled){d(this).removeClass("ui-resizable-autohide");c._handles.show()}}).mouseleave(function(){if(!a.disabled&&!c.resizing){d(this).addClass("ui-resizable-autohide");c._handles.hide()}}));this._mouseInit()},_destroy:function(){this._mouseDestroy();var c=function(c){d(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()}; if(this.elementIsWrapper){c(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);c(this.originalElement);return this},_mouseCapture:function(c){var a=!1,b;for(b in this.handles)d(this.handles[b])[0]==c.target&&(a=!0);return!this.options.disabled&&a},_mouseStart:function(c){var a=this.options,f=this.element.position(), g=this.element;this.resizing=!0;this.documentScroll={top:d(document).scrollTop(),left:d(document).scrollLeft()};(g.is(".ui-draggable")||/absolute/.test(g.css("position")))&&g.css({position:"absolute",top:f.top,left:f.left});this._renderProxy();var f=b(this.helper.css("left")),h=b(this.helper.css("top"));a.containment&&(f+=d(a.containment).scrollLeft()||0,h+=d(a.containment).scrollTop()||0);this.offset=this.helper.offset();this.position={left:f,top:h};this.size=this._helper?{width:g.outerWidth(),height:g.outerHeight()}: {width:g.width(),height:g.height()};this.originalSize=this._helper?{width:g.outerWidth(),height:g.outerHeight()}:{width:g.width(),height:g.height()};this.originalPosition={left:f,top:h};this.sizeDiff={width:g.outerWidth()-g.width(),height:g.outerHeight()-g.height()};this.originalMousePosition={left:c.pageX,top:c.pageY};this.aspectRatio="number"==typeof a.aspectRatio?a.aspectRatio:this.originalSize.width/this.originalSize.height||1;a=d(".ui-resizable-"+this.axis).css("cursor");d("body").css("cursor", "auto"==a?this.axis+"-resize":a);g.addClass("ui-resizable-resizing");this._propagate("start",c);return!0},_mouseDrag:function(c){var a=this.helper,b=this.originalMousePosition,d=this._change[this.axis];if(!d)return!1;b=d.apply(this,[c,c.pageX-b.left||0,c.pageY-b.top||0]);this._updateVirtualBoundaries(c.shiftKey);if(this._aspectRatio||c.shiftKey)b=this._updateRatio(b,c);b=this._respectSize(b,c);this._propagate("resize",c);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+ "px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(b);this._trigger("resize",c,this.ui());return!1},_mouseStop:function(c){this.resizing=!1;var a=this.options;if(this._helper){var b=this._proportionallyResizeElements,g=b.length&&/textarea/i.test(b[0].nodeName),b=g&&d.ui.hasScroll(b[0],"left")?0:this.sizeDiff.height,g=g?0:this.sizeDiff.width,g={width:this.helper.width()-g,height:this.helper.height()-b},b=parseInt(this.element.css("left"), 10)+(this.position.left-this.originalPosition.left)||null,h=parseInt(this.element.css("top"),10)+(this.position.top-this.originalPosition.top)||null;a.animate||this.element.css(d.extend(g,{top:h,left:b}));this.helper.height(this.size.height);this.helper.width(this.size.width);this._helper&&!a.animate&&this._proportionallyResize()}d("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",c);this._helper&&this.helper.remove();return!1},_updateVirtualBoundaries:function(c){var b= this.options,d,g,h,b={minWidth:a(b.minWidth)?b.minWidth:0,maxWidth:a(b.maxWidth)?b.maxWidth:Infinity,minHeight:a(b.minHeight)?b.minHeight:0,maxHeight:a(b.maxHeight)?b.maxHeight:Infinity};if(this._aspectRatio||c)if(c=b.minHeight*this.aspectRatio,g=b.minWidth/this.aspectRatio,d=b.maxHeight*this.aspectRatio,h=b.maxWidth/this.aspectRatio,c>b.minWidth&&(b.minWidth=c),g>b.minHeight&&(b.minHeight=g),dc.width,i=a(c.height)&&b.minHeight&&b.minHeight>c.height;j&&(c.width=b.minWidth);i&&(c.height=b.minHeight);g&&(c.width=b.maxWidth);h&&(c.height=b.maxHeight);var k=this.originalPosition.left+this.originalSize.width,l=this.position.top+this.size.height,m=/sw|nw|w/.test(d),d=/nw|ne|n/.test(d);j&&m&&(c.left=k-b.minWidth);g&&m&&(c.left=k-b.maxWidth); i&&d&&(c.top=l-b.minHeight);h&&d&&(c.top=l-b.maxHeight);(b=!c.width&&!c.height)&&!c.left&&c.top?c.top=null:b&&(!c.top&&c.left)&&(c.left=null);return c},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var c=this.helper||this.element,a=0;a
    ');var a=d.browser.msie&&7>d.browser.version,b=a? 1:0,a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-b+"px",top:this.elementOffset.top-b+"px",zIndex:++c.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(c,a){return{width:this.originalSize.width+a}},w:function(c,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(c,a,b){return{top:this.originalPosition.top+ b,height:this.originalSize.height-b}},s:function(c,a,b){return{height:this.originalSize.height+b}},se:function(c,a,b){return d.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[c,a,b]))},sw:function(c,a,b){return d.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[c,a,b]))},ne:function(c,a,b){return d.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[c,a,b]))},nw:function(c,a,b){return d.extend(this._change.n.apply(this,arguments),this._change.w.apply(this, [c,a,b]))}},_propagate:function(c,a){d.ui.plugin.call(this,c,[a,this.ui()]);"resize"!=c&&this._trigger(c,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});d.ui.plugin.add("resizable","alsoResize",{start:function(){var c=d(this).data("resizable").options,a=function(c){d(c).each(function(){var c=d(this);c.data("resizable-alsoresize", {width:parseInt(c.width(),10),height:parseInt(c.height(),10),left:parseInt(c.css("left"),10),top:parseInt(c.css("top"),10)})})};"object"==typeof c.alsoResize&&!c.alsoResize.parentNode?c.alsoResize.length?(c.alsoResize=c.alsoResize[0],a(c.alsoResize)):d.each(c.alsoResize,function(c){a(c)}):a(c.alsoResize)},resize:function(c,a){var b=d(this).data("resizable"),g=b.options,h=b.originalSize,j=b.originalPosition,i={height:b.size.height-h.height||0,width:b.size.width-h.width||0,top:b.position.top-j.top|| 0,left:b.position.left-j.left||0},k=function(c,b){d(c).each(function(){var c=d(this),f=d(this).data("resizable-alsoresize"),g={},h=b&&b.length?b:c.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];d.each(h,function(c,a){var b=(f[a]||0)+(i[a]||0);b&&0<=b&&(g[a]=b||null)});c.css(g)})};"object"==typeof g.alsoResize&&!g.alsoResize.nodeType?d.each(g.alsoResize,function(c,a){k(c,a)}):k(g.alsoResize)},stop:function(){d(this).removeData("resizable-alsoresize")}});d.ui.plugin.add("resizable", "animate",{stop:function(c){var a=d(this).data("resizable"),b=a.options,g=a._proportionallyResizeElements,h=g.length&&/textarea/i.test(g[0].nodeName),j=h&&d.ui.hasScroll(g[0],"left")?0:a.sizeDiff.height,h={width:a.size.width-(h?0:a.sizeDiff.width),height:a.size.height-j},j=parseInt(a.element.css("left"),10)+(a.position.left-a.originalPosition.left)||null,i=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(d.extend(h,i&&j?{top:i,left:j}:{}),{duration:b.animateDuration, easing:b.animateEasing,step:function(){var b={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};g&&g.length&&d(g[0]).css({width:b.width,height:b.height});a._updateCache(b);a._propagate("resize",c)}})}});d.ui.plugin.add("resizable","containment",{start:function(){var a=d(this).data("resizable"),e=a.element,f=a.options.containment;if(e=f instanceof d?f.get(0):/parent/.test(f)?e.parent().get(0): f)if(a.containerElement=d(e),/document/.test(f)||f==document)a.containerOffset={left:0,top:0},a.containerPosition={left:0,top:0},a.parentData={element:d(document),left:0,top:0,width:d(document).width(),height:d(document).height()||document.body.parentNode.scrollHeight};else{var g=d(e),h=[];d(["Top","Right","Left","Bottom"]).each(function(a,c){h[a]=b(g.css("padding"+c))});a.containerOffset=g.offset();a.containerPosition=g.position();a.containerSize={height:g.innerHeight()-h[3],width:g.innerWidth()- h[1]};var f=a.containerOffset,j=a.containerSize.height,i=a.containerSize.width,i=d.ui.hasScroll(e,"left")?e.scrollWidth:i,j=d.ui.hasScroll(e)?e.scrollHeight:j;a.parentData={element:e,left:f.left,top:f.top,width:i,height:j}}},resize:function(a){var b=d(this).data("resizable"),f=b.options,g=b.containerOffset,h=b.position,a=b._aspectRatio||a.shiftKey,j={top:0,left:0},i=b.containerElement;i[0]!=document&&/static/.test(i.css("position"))&&(j=g);if(h.left<(b._helper?g.left:0))b.size.width+=b._helper?b.position.left- g.left:b.position.left-j.left,a&&(b.size.height=b.size.width/b.aspectRatio),b.position.left=f.helper?g.left:0;if(h.top<(b._helper?g.top:0))b.size.height+=b._helper?b.position.top-g.top:b.position.top,a&&(b.size.width=b.size.height*b.aspectRatio),b.position.top=b._helper?g.top:0;b.offset.left=b.parentData.left+b.position.left;b.offset.top=b.parentData.top+b.position.top;f=Math.abs(b.offset.left-j.left+b.sizeDiff.width);g=Math.abs((b._helper?b.offset.top-j.top:b.offset.top-g.top)+b.sizeDiff.height); h=b.containerElement.get(0)==b.element.parent().get(0);j=/relative|absolute/.test(b.containerElement.css("position"));h&&j&&(f-=b.parentData.left);f+b.size.width>=b.parentData.width&&(b.size.width=b.parentData.width-f,a&&(b.size.height=b.size.width/b.aspectRatio));g+b.size.height>=b.parentData.height&&(b.size.height=b.parentData.height-g,a&&(b.size.width=b.size.height*b.aspectRatio))},stop:function(){var a=d(this).data("resizable"),b=a.options,f=a.containerOffset,g=a.containerPosition,h=a.containerElement, j=d(a.helper),i=j.offset(),k=j.outerWidth()-a.sizeDiff.width,j=j.outerHeight()-a.sizeDiff.height;a._helper&&(!b.animate&&/relative/.test(h.css("position")))&&d(this).css({left:i.left-g.left-f.left,width:k,height:j});a._helper&&(!b.animate&&/static/.test(h.css("position")))&&d(this).css({left:i.left-g.left-f.left,width:k,height:j})}});d.ui.plugin.add("resizable","ghost",{start:function(){var a=d(this).data("resizable"),b=a.options,f=a.size;a.ghost=a.originalElement.clone();a.ghost.css({opacity:0.25, display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof b.ghost?b.ghost:"");a.ghost.appendTo(a.helper)},resize:function(){var a=d(this).data("resizable");a.ghost&&a.ghost.css({position:"relative",height:a.size.height,width:a.size.width})},stop:function(){var a=d(this).data("resizable");a.ghost&&a.helper&&a.helper.get(0).removeChild(a.ghost.get(0))}});d.ui.plugin.add("resizable","grid",{resize:function(){var a= d(this).data("resizable"),b=a.options,f=a.size,g=a.originalSize,h=a.originalPosition,j=a.axis;b.grid="number"==typeof b.grid?[b.grid,b.grid]:b.grid;var i=Math.round((f.width-g.width)/(b.grid[0]||1))*(b.grid[0]||1),b=Math.round((f.height-g.height)/(b.grid[1]||1))*(b.grid[1]||1);/^(se|s|e)$/.test(j)?(a.size.width=g.width+i,a.size.height=g.height+b):/^(ne)$/.test(j)?(a.size.width=g.width+i,a.size.height=g.height+b,a.position.top=h.top-b):(/^(sw)$/.test(j)?(a.size.width=g.width+i,a.size.height=g.height+ b):(a.size.width=g.width+i,a.size.height=g.height+b,a.position.top=h.top-b),a.position.left=h.left-i)}});var b=function(a){return parseInt(a,10)||0},a=function(a){return!isNaN(parseInt(a,10))}})(jQuery); (function(d){d.widget("ui.selectable",d.ui.mouse,{version:"1.9.0",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var b=this;this.element.addClass("ui-selectable");this.dragged=!1;var a;this.refresh=function(){a=d(b.options.filter,b.element[0]);a.addClass("ui-selectee");a.each(function(){var a=d(this),b=a.offset();d.data(this,"selectable-item",{element:this,$element:a,left:b.left,top:b.top,right:b.left+a.outerWidth(),bottom:b.top+a.outerHeight(), startselected:!1,selected:a.hasClass("ui-selected"),selecting:a.hasClass("ui-selecting"),unselecting:a.hasClass("ui-unselecting")})})};this.refresh();this.selectees=a.addClass("ui-selectee");this._mouseInit();this.helper=d("
    ")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled");this._mouseDestroy()},_mouseStart:function(b){var a=this;this.opos=[b.pageX, b.pageY];if(!this.options.disabled){var c=this.options;this.selectees=d(c.filter,this.element[0]);this._trigger("start",b);d(c.appendTo).append(this.helper);this.helper.css({left:b.clientX,top:b.clientY,width:0,height:0});c.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var c=d.data(this,"selectable-item");c.startselected=!0;!b.metaKey&&!b.ctrlKey&&(c.$element.removeClass("ui-selected"),c.selected=!1,c.$element.addClass("ui-unselecting"),c.unselecting=!0,a._trigger("unselecting", b,{unselecting:c.element}))});d(b.target).parents().andSelf().each(function(){var c=d.data(this,"selectable-item");if(c){var f=!b.metaKey&&!b.ctrlKey||!c.$element.hasClass("ui-selected");c.$element.removeClass(f?"ui-unselecting":"ui-selected").addClass(f?"ui-selecting":"ui-unselecting");c.unselecting=!f;c.selecting=f;(c.selected=f)?a._trigger("selecting",b,{selecting:c.element}):a._trigger("unselecting",b,{unselecting:c.element});return!1}})}},_mouseDrag:function(b){var a=this;this.dragged=!0;if(!this.options.disabled){var c= this.options,e=this.opos[0],f=this.opos[1],g=b.pageX,h=b.pageY;if(e>g)var j=g,g=e,e=j;f>h&&(j=h,h=f,f=j);this.helper.css({left:e,top:f,width:g-e,height:h-f});this.selectees.each(function(){var i=d.data(this,"selectable-item");if(i&&i.element!=a.element[0]){var j=false;c.tolerance=="touch"?j=!(i.left>g||i.righth||i.bottome&&i.rightf&&i.bottom *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var b=this.options;this.containerCache={};this.element.addClass("ui-sortable"); this.refresh();this.floating=this.items.length?"x"===b.axis||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1;this.offset=this.element.offset();this._mouseInit();this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled");this._mouseDestroy();for(var b=this.items.length-1;0<=b;b--)this.items[b].item.removeData(this.widgetName+"-item");return this},_setOption:function(b,a){"disabled"===b?(this.options[b]= a,this.widget().toggleClass("ui-sortable-disabled",!!a)):d.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(b,a){var c=this;if(this.reverting||this.options.disabled||"static"==this.options.type)return!1;this._refreshItems(b);var e=null;d(b.target).parents().each(function(){if(d.data(this,c.widgetName+"-item")==c)return e=d(this),!1});d.data(b.target,c.widgetName+"-item")==c&&(e=d(b.target));if(!e)return!1;if(this.options.handle&&!a){var f=!1;d(this.options.handle,e).find("*").andSelf().each(function(){this== b.target&&(f=!0)});if(!f)return!1}this.currentItem=e;this._removeCurrentsFromItems();return!0},_mouseStart:function(b,a,c){a=this.options;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(b);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:b.pageX-this.offset.left, top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");this.originalPosition=this._generatePosition(b);this.originalPageX=b.pageX;this.originalPageY=b.pageY;a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder(); a.containment&&this._setContainment();a.cursor&&(d("body").css("cursor")&&(this._storedCursor=d("body").css("cursor")),d("body").css("cursor",a.cursor));a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity));a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex));this.scrollParent[0]!=document&&"HTML"!=this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()); this._trigger("start",b,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;0<=c;c--)this.containers[c]._trigger("activate",b,this._uiHash(this));d.ui.ddmanager&&(d.ui.ddmanager.current=this);d.ui.ddmanager&&!a.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,b);this.dragging=!0;this.helper.addClass("ui-sortable-helper");this._mouseDrag(b);return!0},_mouseDrag:function(b){this.position=this._generatePosition(b);this.positionAbs=this._convertPositionTo("absolute"); this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var a=this.options,c=!1;this.scrollParent[0]!=document&&"HTML"!=this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageYb[this.floating?"width":"height"]?d+k>j&&d+kg&&a+lthis.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top)),a.grid))g=this.originalPageY+Math.round((g-this.originalPageY)/a.grid[1])*a.grid[1],g=this.containment?!(g-this.offset.click.topthis.containment[3])?g:!(g-this.offset.click.topthis.containment[2])?f:!(f-this.offset.click.left",options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var a,b,e;this.isMultiLine=this._isMultiLine();this.valueMethod=this.element[this.element.is("input,textarea")?"val":"text"];this.isNewMenu=!0;this.element.addClass("ui-autocomplete-input").attr("autocomplete", "off");this._on({keydown:function(f){if(this.element.prop("readOnly"))b=e=a=!0;else{b=e=a=!1;var g=d.ui.keyCode;switch(f.keyCode){case g.PAGE_UP:a=!0;this._move("previousPage",f);break;case g.PAGE_DOWN:a=!0;this._move("nextPage",f);break;case g.UP:a=!0;this._keyEvent("previous",f);break;case g.DOWN:a=!0;this._keyEvent("next",f);break;case g.ENTER:case g.NUMPAD_ENTER:this.menu.active&&(a=!0,f.preventDefault(),this.menu.select(f));break;case g.TAB:this.menu.active&&this.menu.select(f);break;case g.ESCAPE:this.menu.element.is(":visible")&& (this._value(this.term),this.close(f),f.preventDefault());break;default:b=!0,this._searchTimeout(f)}}},keypress:function(e){if(a)a=!1,e.preventDefault();else if(!b){var g=d.ui.keyCode;switch(e.keyCode){case g.PAGE_UP:this._move("previousPage",e);break;case g.PAGE_DOWN:this._move("nextPage",e);break;case g.UP:this._keyEvent("previous",e);break;case g.DOWN:this._keyEvent("next",e)}}},input:function(a){e?(e=!1,a.preventDefault()):this._searchTimeout(a)},focus:function(){this.selectedItem=null;this.previous= this._value()},blur:function(a){this.cancelBlur?delete this.cancelBlur:(clearTimeout(this.searching),this.close(a),this._change(a))}});this._initSource();this.menu=d("

    exporter as $exporter) : ?> isEnabled()) : ?> getName(); ?> getName(); ?>
    app->html->_('form.token'); ?> components/com_zoo/views/configuration/tmpl/importcsv.php000066600000010745150771655450020147 0ustar00app->document->addScript('assets:js/import.js'); ?> app->document->addScript('assets:js/configuration.js'); $this->app->document->addScript('assets:js/alias.js'); $this->app->html->_('behavior.tooltip'); // filter output JFilterOutput::objectHTMLSafe($this->application, ENT_QUOTES, array('params')); ?> app->document->addScript('assets:js/import.js'); ?> application->getParamsForm()->setValues($this->params->get('global.config.')); ?> getParamsCount('application-config')) : ?>

    render('params[config]', 'application-config'); ?>

    application->getTemplate()) { if ($params_form = $template->getParamsForm()) { echo $params_form->setValues($this->params->get('global.template.'))->render('params[template]', 'category'); echo $params_form->setValues($this->params->get('global.template.'))->render('params[template]', 'item'); } } else { echo ''.JText::_('Please select a Template').''; } ?>
    application->getAddonParamsForms() as $name => $params_form) : ?>

    setValues($this->params->get('global.'.strtolower($name).'.'))->render('addons['.strtolower($name).']'); ?>
    components/com_zoo/views/tag/tmpl/default.php000066600000007455150771655450015455 0ustar00app->document->addScript('assets:js/tag.js'); // filter output foreach ($this->tags as $tag) { JFilterOutput::objectHTMLSafe($tag, ENT_QUOTES); } ?>
    partial('menu'); ?>
    is_filtered || count($this->tags) > 0) :?> tags) > 0) : ?> tags as $tag) : ?> app->link(array('controller' => 'item','filter_category_id' => '-1', 'filter_type' => '', 'filter_author_id' => '', 'search' => $tag->name)); ?>
    app->html->_('grid.sort', 'Name', 'a.name', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Items', 'items', @$this->lists['order_Dir'], @$this->lists['order']); ?>
    pagination->getListFooter(); ?>
    name; ?> items; ?>
    is_filtered) : $title = JText::_('SEARCH_NO_TAG').'!'; $message = null; echo $this->partial('message', compact('title', 'message')); else : $title = JText::_('NO_TAGS_YET').'!'; $message = JText::_('TAG_MANAGER_DESCRIPTION'); echo $this->partial('message', compact('title', 'message')); endif; ?>
    app->html->_('form.token'); ?>
    components/com_zoo/views/tag/index.html000066600000000036150771655450014325 0ustar00components/com_zoo/views/comment/tmpl/_row.php000066600000005550150771655450015660 0ustar00comment->getAuthor(); ?>
    isGuest()) : ?>
    getAvatar(40); ?>
    name ? $author->name : JText::_('Anonymous'); ?> url) : ?>
    url; ?> email) : ?>
    email; ?>
    comment->state == Comment::STATE_UNAPPROVED) : ?> app->html->_('date', $this->comment->created, JText::_('DATE_FORMAT_LC2'), $this->app->date->getOffset()); ?>

    app->comment->filterContentOutput($this->comment->content); ?>

    | | comment->state == Comment::STATE_UNAPPROVED) : ?> | | comment->state == Comment::STATE_APPROVED) : ?> | | comment->state == Comment::STATE_SPAM) : ?> |
    comment->getItem(); ?> app->link(array('controller' => 'item', 'task' => 'edit', 'cid[]' => $item->id)); ?> name; ?> components/com_zoo/views/comment/tmpl/_reply.php000066600000001365150771655450016204 0ustar00
    Reply to Comment
    components/com_zoo/views/comment/tmpl/default.php000066600000006270150771655450016336 0ustar00app->html->_('behavior.tooltip'); // add js $this->app->document->addScript('assets:js/comment.js'); ?>
    partial('menu'); ?>
    pagination->total > 0) : ?> comments as $comment) { $this->comment = $comment; echo $this->partial('row'); } ?>
    pagination->getListFooter(); ?>
    is_filtered) : $title = JText::_('FILTER_NO_COMMENTS').'!'; $message = null; echo $this->partial('message', compact('title', 'message')); else : $title = JText::_('NO_COMMENTS_YET').'!'; $message = JText::_('COMMENTS_MANAGER_DESCRIPTION'); echo $this->partial('message', compact('title', 'message')); endif; ?>
    app->html->_('form.token'); ?>
    components/com_zoo/views/comment/tmpl/_edit.php000066600000002400150771655450015765 0ustar00comment->content); ?>
    components/com_zoo/views/comment/index.html000066600000000036150771655450015214 0ustar00components/com_zoo/views/submission/tmpl/default.php000066600000012571150771655450017070 0ustar00
    partial('menu'); ?>
    submissions) > 0) : ?> submissions); $i < $n; $i++) : $row = $this->submissions[$i]; $img = $row->state ? 'tick.png' : 'publish_x.png'; $task = $row->state ? 'unpublish' : 'publish'; $alt = $row->state ? JText::_('Published') : JText::_('Unpublished'); $action = $row->state ? JText::_('Unpublish submission') : JText::_('Publish submission'); $types = array_map(create_function('$type', 'return $type->name;'), $row->getSubmittableTypes()); // access $group = $this->app->zoo->getGroup($row->access); $group_access = JText::_($group->name); $public = !JAccess::checkGroup($group->id, 'core.login.site'); // trusted mode $trusted_mode = (int) $row->isInTrustedMode(); $trusted_mode_img = $trusted_mode ? 'tick.png' : 'publish_x.png'; $trusted_mode_alt = $trusted_mode ? JText::_('Trusted Mode enabled') : JText::_('Trusted Mode disabled'); // item edit submission $item_edit = (int) $row->getParams()->get('item_edit', 0); $item_edit_img = $item_edit ? 'tick.png' : 'publish_x.png'; $item_edit_alt = $item_edit ? JText::_('Set as Item Edit') : JText::_('Disable Item Edit'); ?>
    app->html->_('grid.sort', 'Name', 'name', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Published', 'state', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Access', 'access', @$this->lists['order_Dir'], @$this->lists['order']); ?>
    name; ?> <?php echo $trusted_mode_alt; ?> <?php echo $item_edit_alt; ?> <?php echo $alt; ?>
    partial('message', compact('title', 'message')); endif; ?>
    app->html->_('form.token'); ?>
    app->document->addScript('assets:js/alias.js'); $this->app->document->addScript('assets:js/submission.js'); // filter output JFilterOutput::objectHTMLSafe($this->submission, ENT_QUOTES, array('params')); ?>
    partial('menu'); ?>
    lists['select_published']; ?>
    lists['select_tooltip']; ?>
    lists['select_item_edit']; ?>
    lists['select_item_captcha']): ?>
    lists['select_item_captcha']; ?>
    submission->getParams()->get('captcha_guest_only', false) ? 'checked="checked"' : ''; ?> />
    lists['select_access']; ?>
    submission->isInTrustedMode() ? 'checked="checked"' : ''; ?> />
    types)) : ?> types as $type) : ?>
    application->getParamsForm()->setValues($this->submission->getParams()->get('content.')); ?> getParamsCount('submission-content')) : ?>

    render('params[content]', 'submission-content'); ?>
    application->getParamsForm()->setValues($this->submission->getParams()->get('config.')); ?> getParamsCount('submission-config')) : ?>

    render('params[config]', 'submission-config'); ?>
    app->html->_('form.token'); ?>
    components/com_zoo/views/submission/index.html000066600000000036150771655450015745 0ustar00components/com_zoo/views/index.html000066600000000036150771655450013552 0ustar00components/com_zoo/views/manager/tmpl/assignelements.php000066600000006561150771655450017706 0ustar00app->html->_('behavior.tooltip'); // add script $this->app->document->addScript('assets:js/type.js'); ?> app->html->_('behavior.tooltip'); // add script $this->app->document->addScript('assets:js/type.js'); ?> element) { echo $this->partial('editelement', array('element' => $this->element)); } components/com_zoo/views/manager/tmpl/types.php000066600000013211150771655450016017 0ustar00app->html->_('behavior.tooltip'); ?>
    partial('menu'); ?>

    applications as $application) : ?> <?php $application->getGroup(); ?> getMetaData('name'); ?>

    app->html->_('form.token'); ?>

    results)) : ?>
    not show changes made to the applications in the media folder.'); ?>
    results['missing'])) : ?>

    :

      results['missing'] as $file) : ?>
    results['modified'])) : ?>

    :

      results['modified'] as $file) : ?>
    results['unknown'])) : ?>

    :

      results['unknown'] as $file) : ?>
    Attention! Cleaning the ZOO will remove all unknown files. Modified files will not be touched.'); ?>
    app->html->_('form.token'); ?>
    components/com_zoo/views/manager/tmpl/index.html000066600000000036150771655450016140 0ustar00components/com_zoo/views/manager/tmpl/_editelement.php000066600000001746150771655450017323 0ustar00getConfigForm(); $form->application = $this->application; $name = $element->config->get('name', 'New'); $var = 'elements['.$element->identifier.']'; ?>
    (getMetaData('name'); ?>)
    render($var); ?>
    components/com_zoo/views/manager/tmpl/_assignelement.php000066600000002430150771655450017651 0ustar00identifier.']'; $form = $element->getConfigForm(); $form->layout_path = $this->path; $form->selectable_types = $element->config->get('selectable_types', array()); ?>
  • config->get('name'); ?> getGroup() != 'Core') :?> (getMetaData('name'); ?>)
    setValues($data)->render($name, 'render'); ?>
  • components/com_zoo/views/manager/tmpl/info.php000066600000005411150771655450015611 0ustar00 partial('menu'); ?>
    Cleaning database...
    app->document->addScript('assets:js/alias.js'); $this->app->document->addScript('assets:js/type.js'); // filter output JFilterOutput::objectHTMLSafe($this->type, ENT_QUOTES); ?>
  • config->get('name'); ?> (getMetaData('name'); ?>)
    getConfigForm()->setValues($data)->render($element->identifier, 'submission'); ?>
  • components/com_zoo/views/manager/tmpl/assignsubmission.php000066600000005340150771655450020257 0ustar00app->html->_('behavior.tooltip'); // add script $this->app->document->addScript('assets:js/type.js'); ?> components/com_zoo/views/new/tmpl/default.php000066600000002037150771655450015462 0ustar00
    partial('menu'); ?>

    applications as $application) : ?> <?php echo $application->getGroup(); ?> getMetaData('name'); ?>
    app->html->_('form.token'); ?>
    components/com_zoo/views/new/tmpl/application.php000066600000005362150771655450016345 0ustar00app->document->addScript('assets:js/configuration.js'); $this->app->document->addScript('assets:js/alias.js'); $this->app->html->_('behavior.tooltip'); // filter output JFilterOutput::objectHTMLSafe($this->application, ENT_QUOTES, array('params')); ?>

    application->getParamsForm()->setValues($this->params->get('global.config.'))->render('params[config]', 'application-config'); ?>

    application->getTemplate()) { if ($params_form = $template->getParamsForm()) { echo $params_form->setValues($this->params->get('global.template.'))->render('params[template]', 'category'); echo $params_form->setValues($this->params->get('global.template.'))->render('params[template]', 'item'); } } else { echo ''.JText::_('Please select a Template').''; } ?>
    application->getAddonParamsForms() as $name => $params_form) : ?>

    setValues($this->params->get('global.'.strtolower($name).'.'))->render('addons['.strtolower($name).']'); ?>
    components/com_zoo/views/update/tmpl/default.php000066600000005532150771655450016156 0ustar00app->document->addScript('assets:js/update.js'); ?>
    update) :?>

    :

      app->update->getRequiredUpdates() as $update) : ?>
    notifications)) : ?>

      notifications as $notification) : ?>
    app->path->path('component.admin:README.markdown')); ?>
    partial('message', compact('title', 'message')); endif; ?>
    app->html->_('form.token'); ?>
    components/com_zoo/views/update/index.html000066600000000036150771655450015034 0ustar00components/com_zoo/views/item/tmpl/default.php000066600000023506150771655450015633 0ustar00app->document->addScript('assets:js/item.js'); ?>
    partial('menu'); ?>
    is_filtered || $this->pagination->total > 0) :?> pagination->total > 0) : ?> app->database->getNullDate(); for ($i=0, $n=count($this->items); $i < $n; $i++) : $row = $this->items[$i]; $now = $this->app->date->create()->toUnix(); $publish_up = $this->app->date->create($row->publish_up); $publish_down = $this->app->date->create($row->publish_down); $offset = $this->app->date->getOffset(); $publish_up->setTimezone(new DateTimeZone($offset)); $publish_down->setTimezone(new DateTimeZone($offset)); $img = ''; $alt = ''; if ($now <= $publish_up->toUnix() && $row->state == 1) { $img = 'publish_y.png'; $alt = JText::_('Published'); } else if (($now <= $publish_down->toUnix() || $row->publish_down == $nullDate) && $row->state == 1 ) { $img = 'publish_g.png'; $alt = JText::_('Published'); } else if ($now > $publish_down->toUnix() && $row->state == 1) { $img = 'publish_r.png'; $alt = JText::_('Expired'); } else if ($row->state == 0) { $img = 'publish_x.png'; $alt = JText::_('Unpublished'); } if ($row->searchable == 0) { $search_img = 'publish_x.png'; $search_alt = JText::_('None searchable'); } elseif ($row->searchable == 1) { $search_img = 'tick.png'; $search_alt = JText::_('Searchable'); } if ($row->frontpage) { $frontpage_img = 'tick.png'; $frontpage_alt = JText::_('JYES'); } else { $frontpage_img = 'publish_x.png'; $frontpage_alt = JText::_('JNO'); } $comments_enabled = (int) $row->getParams()->get('config.enable_comments', 1); $comments_img = $comments_enabled ? 'tick.png' : 'publish_x.png'; $comments_alt = $comments_enabled ? JText::_('Comments enabled') : JText::_('Comments disabled'); $times = ''; if (isset($row->publish_up)) { if ($row->publish_up == $nullDate) { $times .= JText::_( 'Start: Always' ); } else { $times .= JText::_( 'Start' ) .": ". $publish_up->format('Y-m-d H:i:s', true); } } if (isset($row->publish_down)) { if ($row->publish_down == $nullDate) { $times .= "
    ". JText::_( 'Finish No Expiry' ); } else { $times .= "
    ". JText::_( 'Finish' ) .": ". $publish_down->format('Y-m-d H:i:s', true); } } // author $author = $row->created_by_alias; if (!$author) { if (isset($this->users[$row->created_by])) { $author = $this->users[$row->created_by]->name; if ($this->app->user->get()->authorise('core.edit', 'com_users')) { $author = ''. $author.''; } } else { $author = JText::_('Guest'); } } ?>
    app->html->_('grid.sort', 'Name', 'a.name', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Type', 'a.type', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Published', 'a.state', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Order Priority', 'a.priority', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Access', 'a.access', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Author', 'a.created_by', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Date', 'a.created', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Hits', 'a.hits', @$this->lists['order_Dir'], @$this->lists['order']); ?>
    pagination->getListFooter(); ?>
    name; ?> application->getType($row->type)->name; ?> <?php echo $alt; ?> <?php echo $frontpage_alt; ?> <?php echo $search_alt; ?> <?php echo $comments_alt; ?> app->zoo->getGroup($row->access)->name); ?> app->html->_('date', $row->created, JText::_('DATE_FORMAT_LC4'), $this->app->date->getOffset()); ?> hits ?>
    is_filtered) : $title = JText::_('SEARCH_NO_ITEMS').'!'; $message = null; echo $this->partial('message', compact('title', 'message')); else : $title = JText::_('NO_ITEMS_YET').'!'; $message = JText::_('ITEM_MANAGER_DESCRIPTION'); echo $this->partial('message', compact('title', 'message')); endif; ?>
    app->html->_('form.token'); ?>
    app->html->_('behavior.tooltip'); // Add chosen in Joomla 2.5 if ($this->app->joomla->isVersion('2.5')) { $this->app->document->addScript('libraries:jquery/plugins/chosen/chosen.jquery.min.js'); $this->app->document->addStylesheet('libraries:jquery/plugins/chosen/chosen.css'); } else { JHtml::_('formbehavior.chosen', '#categories'); JHtml::_('formbehavior.chosen', '#paramsprimary_category'); } // add script $this->app->document->addScript('assets:js/autosuggest.js'); $this->app->document->addScript('assets:js/item.js'); $this->app->document->addScript('assets:js/alias.js'); $this->app->document->addScript('assets:js/tag.js'); // filter output JFilterOutput::objectHTMLSafe($this->item, ENT_QUOTES, array('params', 'elements')); // Keepalive behavior JHTML::_('behavior.keepalive'); ?>
    partial('menu'); ?>
    lists['select_published']; ?>
    lists['select_searchable']; ?>
    lists['select_enable_comments']; ?>
    lists['select_frontpage']; ?>
    lists['select_categories']; ?>
    lists['select_primary_category']; ?>
    item->getElements() as $element) { // trigger beforeEdit event $render = true; $this->app->event->dispatcher->notify($this->app->event->create($element, 'element:beforeedit', array('render' => &$render))); if ($render && $edit = $element->edit()) { $element->loadAssets(); // set label $name = JText::_($element->config->get('name')); if ($description = $element->config->get('description')) { $description = ' class="editlinktip hasTip" title="'.JText::_($description).'"'; } $html = array(); $html[] = '
    '; $html[] = ''.$name.''; $html[] = $edit; $html[] = '
    '; // trigger afterEdit event $this->app->event->dispatcher->notify($this->app->event->create($element, 'element:afteredit', array('html' => &$html, 'description' => $description, 'name' => $name))); echo implode("\n", $html); } } ?>
    item->id) : ?>
    : item->id; ?>
    item->getType()->name; ?>
    item->state > 0 ? JText::_('Published') : ($this->item->state < 0 ? JText::_('Archived') : JText::_('Draft Unpublished'));?>
    item->hits;?> item->hits ? 'style="display: none; visibility: hidden;"' : null; ?>>
    item->created == null ? JText::_('New item') : $this->app->html->_('date', $this->item->created, JText::_('DATE_FORMAT_LC2'), $this->app->date->getOffset()); ?>
    item->modified == null ? JText::_('Not modified') : $this->app->html->_('date', $this->item->modified, JText::_('DATE_FORMAT_LC2'), $this->app->date->getOffset()); ?>
    item->created_by_alias) { echo $author; } else if (($user = $this->app->user->get($this->item->created_by)) && $user->name) { echo $user->name; } else { echo JText::_('Guest'); } ?>
    app->parameterform->create(dirname(__FILE__).'/params.xml'); // set details parameter $details = $this->app->parameter->create() ->set('created_by', $this->item->created_by == '' ? $this->app->user->get()->id : 'NO_CHANGE') ->set('access', $this->item->access) ->set('created_by_alias', $this->item->created_by_alias) ->set('created', $this->app->html->_('date', $this->item->created, 'Y-m-d H:i:s', true)) ->set('publish_up', $this->app->html->_('date', $this->item->publish_up, 'Y-m-d H:i:s', true)) ->set('publish_down', $this->app->html->_('date', $this->item->publish_down, 'Y', true) <= 1969 || $this->item->publish_down == $this->app->database->getNullDate() ? JText::_('Never') : $this->app->html->_('date', $this->item->publish_down, 'Y-m-d H:i:s', true)); ?>

    setValues($details)->render('details'); ?>

    setValues($this->params->get('metadata.'))->render('params[metadata]', 'metadata'); ?>
    application->getParamsForm()->setValues($this->params->get('content.')); ?> getParamsCount('item-content')) : ?>

    render('params[content]', 'item-content'); ?>
    application->getParamsForm()->setValues($this->params->get('config.')); ?> getParamsCount('item-config')) : ?>

    render('params[config]', 'item-config'); ?>
    application->getTemplate(); ?> getParamsForm(true)->setValues($this->params->get('template.')); ?> getParamsCount('item')) : ?>

    render('params[template]', 'item'); ?>

    :

    lists['most_used_tags'])) : ?>
    lists['most_used_tags'] as $tag) :?> name; ?>
    app->html->_('form.token'); ?>
    Item Edit Form
    components/com_zoo/views/item/tmpl/index.html000066600000000036150771655450015464 0ustar00components/com_zoo/views/item/tmpl/add.php000066600000002621150771655450014732 0ustar00item, ENT_QUOTES); ?>
    partial('menu'); ?>
    app->html->_('form.token'); ?>
    pagination instanceof AppPagination) : ?> items); $i < $n; $i++) { $row = &$this->items[$i]; // author $author = $row->created_by_alias; if (!$author && isset($this->users[$row->created_by])) { $author = $this->users[$row->created_by]->name; } ?> "> pagination instanceof AppPagination) : ?>
      app->html->_('grid.sort', 'Name', 'a.name', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Type', 'a.type', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Access', 'a.access', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Author', 'a.created_by', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Date', 'a.created', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'Hits', 'a.hits', @$this->lists['order_Dir'], @$this->lists['order']); ?> app->html->_('grid.sort', 'ID', 'a.id', @$this->lists['order_Dir'], @$this->lists['order']); ?>
    pagination instanceof AppPagination) { $pagination_link = $this->app->link(array( 'option' => $this->option, 'controller' => $this->controller, 'task' => 'element', 'tmpl' => 'component', 'filter_order' => $this->lists['order'], 'filter_order_Dir' => $this->lists['order_Dir'], 'object' => $this->app->request->getVar('object'), 'func' => $this->app->request->getVar('func', 'jSelectArticle'), 'app_id' => $this->application->id, 'item_filter' => $this->filter_item , 'type_filter' => $this->type_filter )); echo $this->pagination->render($pagination_link); } else { echo $this->pagination->getListFooter(); } ?>
    pagination->getRowOffset($i); ?> page_white.png name); ?>', 'app->request->getVar('object'); ?>');"> name, ENT_QUOTES, 'UTF-8'); ?> application->getType($row->type)->name; ?> app->zoo->getGroup($row->access)->name); ?> app->html->_('date', $row->created, JText::_('DATE_FORMAT_LC4'), $this->app->date->getOffset()); ?> hits ?> id; ?>
    type_filter as $type_filter) : ?> app->html->_('form.token'); ?>
    components/com_zoo/views/item/index.html000066600000000036150771655450014510 0ustar00components/com_zoo/views/frontpage/tmpl/default.php000066600000005614150771655450016662 0ustar00app->html->_('behavior.tooltip'); // filter output JFilterOutput::objectHTMLSafe($this->application, ENT_QUOTES, array('params')); ?>
    partial('menu'); ?>
    app->system->editor->display('description', $this->application->description, null, null, '60', '20', array('pagebreak', 'readmore', 'article')); ?>
    application->getParamsForm()->setValues($this->params->get('content.')); ?> getParamsCount('application-content')) : ?>

    render('params[content]', 'application-content'); ?>
    application->getParamsForm()->setValues($this->params->get('config.')); ?> getParamsCount('category-config')) : ?>

    application->getParamsForm()->setValues($this->params->get('config.'))->render('params[config]', 'category-config'); ?>
    application->getTemplate(); ?> getParamsForm(true)->setValues($this->params->get('template.')); ?> getParamsCount('category')) : ?>

    render('params[template]', 'category'); ?>

    app->html->_('form.token'); ?>
    components/com_zoo/views/frontpage/index.html000066600000000036150771655450015537 0ustar00components/com_zoo/views/category/tmpl/default.php000066600000012527150771655450016513 0ustar00categories) <= 2500) { $this->app->error->raiseNotice(0, 'Category Sorting disabled (more than 2500 categories)'); } // add js $this->app->document->addScript('assets:js/category.js'); if ($enable_category_sorting) { $this->app->document->addScript('libraries:jquery/plugins/nestedsortable/jquery.ui.nestedSortable.js'); } ?>
    partial('menu'); ?>
    categories) > 1) : ?>
    /
      app->object->create('CategoryRenderer', array($this->app, $this->application)); foreach ($this->categories[0]->getChildren() as $category) { echo $renderer->render($category); } ?>
    partial('message', compact('title', 'message')); endif; ?>
    app->html->_('form.token'); ?>
    _texts['edit_category'] = JText::_('Edit Category'); $this->_texts['published'] = JText::_('Published'); $this->_texts['unpublished'] = JText::_('Unpublished'); $this->_texts['publish_item'] = JText::_('Publish item'); $this->_texts['unpublish_item'] = JText::_('Unpublish Item'); $this->link = $app->link(array('controller' => 'category', 'changeapp' => $application->id, 'task' => 'edit')); $this->link_items = $app->link(array('controller' => 'item', 'changeapp' => $application->id, 'filter_type' => '', 'filter_author_id' => '', 'search' => '')); } public function render($category) { $img = $category->published ? 'tick.png' : 'publish_x.png'; $task = $category->published ? 'unpublish' : 'publish'; $alt = $category->published ? $this->_texts['published'] : $this->_texts['unpublished']; $action = $category->published ? $this->_texts['unpublish_item'] : $this->_texts['publish_item']; $this->_i++; ?>
  • name; ?> itemCount(); ?> <?php echo $alt; ?>
    getChildren()) : ?>
  • app->html->_('behavior.tooltip'); // Add chosen in Joomla 2.5 if ($this->app->joomla->isVersion('2.5')) { $this->app->document->addScript('libraries:jquery/plugins/chosen/chosen.jquery.min.js'); $this->app->document->addStylesheet('libraries:jquery/plugins/chosen/chosen.css'); } else { JHtml::_('formbehavior.chosen', '#parent'); } // add script $this->app->document->addScript('assets:js/alias.js'); $this->app->document->addScript('assets:js/category.js'); // filter output JFilterOutput::objectHTMLSafe($this->category, ENT_QUOTES, array('params')); // Keepalive behavior JHTML::_('behavior.keepalive'); ?>
    partial('menu'); ?>
    lists['select_published']; ?>
    lists['select_parent']; ?>
    app->system->editor->display('description', $this->category->description, null, null, '60', '20', array('pagebreak', 'readmore', 'article')) ; ?>
    application->getParamsForm()->setValues($this->params->get('content.')); ?> getParamsCount('category-content')) : ?>

    application->getParamsForm()->setValues($this->params->get('content.'))->render('params[content]', 'category-content'); ?>
    application->getParamsForm()->setValues($this->params->get('config.')); ?> getParamsCount('category-config')) : ?>

    application->getParamsForm()->setValues($this->params->get('config.'))->render('params[config]', 'category-config'); ?>
    application->getTemplate(); ?> getParamsForm(true)->setValues($this->params->get('template.')); ?> getParamsCount('category')) : ?>

    render('params[template]', 'category'); ?>

    app->parameterform->create(dirname(__FILE__).'/params.xml'); ?>

    setValues($this->params->get('metadata.'))->render('params[metadata]', 'metadata'); ?>
    app->html->_('form.token'); ?>
    Category Edit Form
    components/com_zoo/views/category/tmpl/index.html000066600000000036150771655450016343 0ustar00components/com_zoo/views/category/index.html000066600000000036150771655450015367 0ustar00components/com_zoo/file.script.php000066600000006300150771655450013353 0ustar00getParent()->getPath('extension_administrator').'/config.php'); // get zoo instance $zoo = App::getInstance('zoo'); // copy checksums file if (JFile::exists($parent->getParent()->getPath('source').'/checksums')) { JFile::copy($parent->getParent()->getPath('source').'/checksums', $zoo->path->path('component.admin:').'/checksums'); } try { // clean ZOO installation $zoo->modification->clean(); } catch (Exception $e) {} // applications foreach (JFolder::folders($parent->getParent()->getPath('source').'/media/applications', '.', false, true) as $folder) { try { if (!$manifest = $zoo->install->findManifest($folder) or !$zoo->install->installApplicationFromFolder($folder)) { $zoo->error->raiseNotice(0, JText::sprintf('Unable to install/update app from folder (%s)', $folder)); } } catch (AppException $e) {} } return true; } public function uninstall($parent) { // remove media folder if (JFolder::exists(JPATH_ROOT . '/media/zoo/applications/')) { JFolder::delete(JPATH_ROOT . '/media/zoo/applications/'); } return true; } public function update($parent) { if ($manifest = $parent->get('manifest')) { if (isset($manifest->install->sql)) { if ($parent->getParent()->parseSQLFiles($manifest->install->sql) === false) { // Install failed, rollback changes $parent->getParent()->abort(JText::sprintf('JLIB_INSTALLER_ABORT_COMP_INSTALL_SQL_ERROR', JFactory::getDBO()->stderr(true))); return false; } } } return $this->install($parent); } public function preflight($type, $parent) { // check ZOO requirements require_once($parent->getParent()->getPath('source').'/admin/installation/requirements.php'); $requirements = new AppRequirements(); if (true !== $error = $requirements->checkRequirements()) { $parent->getParent()->abort(JText::_('Component').' '.JText::_('Install').': '.JText::sprintf('Minimum requirements not fulfilled (%s: %s).', $error['name'], $error['info'])); return false; } } public function postflight($type, $parent) { $row = JTable::getInstance('extension'); if ($row->load($row->find(array('element' => 'com_zoo'))) && strlen($row->element)) { $row->client_id = 1; $row->store(); } // initialize zoo framework require_once($parent->getParent()->getPath('extension_administrator').'/config.php'); // get zoo instance $zoo = App::getInstance('zoo'); // finally update if ($zoo->update->required()) { $zoo->error->raiseNotice(0, JText::_('ZOO requires an update. Please click here.')); } } }components/com_zoo/joomla/index.html000066600000000036150771655450013676 0ustar00components/com_zoo/joomla/fields/zoosubmission.php000066600000001133150771655450016602 0ustar00field->render('zoosubmission', $this->fieldname, $this->value, $this->element, array('control_name' => "jform[{$this->group}]", 'parent' => $this->form->getValue('params'))); } }components/com_zoo/joomla/fields/index.html000066600000000036150771655450015144 0ustar00components/com_zoo/joomla/fields/zooapplication.php000066600000001135150771655450016714 0ustar00field->render('zooapplication', $this->fieldname, $this->value, $this->element, array('control_name' => "jform[{$this->group}]", 'parent' => $this->form->getValue('params'))); } }components/com_zoo/joomla/fields/zooitemorder.php000066600000001130150771655450016376 0ustar00field->render('zooitemorder', $this->fieldname, $this->value, $this->element, array('control_name' => "jform[{$this->group}]", 'parent' => $this->form->getValue('params'))); } }components/com_zoo/index.html000066600000000036150771655450012415 0ustar00components/com_zoo/installation/uninstall.sql000066600000002044150771655450015654 0ustar00-- -------------------------------------------------------- DROP TABLE IF EXISTS `#__zoo_version`; -- -------------------------------------------------------- DROP TABLE IF EXISTS `#__zoo_application`; -- -------------------------------------------------------- DROP TABLE IF EXISTS `#__zoo_category`; -- -------------------------------------------------------- DROP TABLE IF EXISTS `#__zoo_category_item`; -- -------------------------------------------------------- DROP TABLE IF EXISTS `#__zoo_comment`; -- -------------------------------------------------------- DROP TABLE IF EXISTS `#__zoo_item`; -- -------------------------------------------------------- DROP TABLE IF EXISTS `#__zoo_rating`; -- -------------------------------------------------------- DROP TABLE IF EXISTS `#__zoo_search_index`; -- -------------------------------------------------------- DROP TABLE IF EXISTS `#__zoo_submission`; -- -------------------------------------------------------- DROP TABLE IF EXISTS `#__zoo_tag`; -- --------------------------------------------------------components/com_zoo/installation/requirements.php000066600000020706150771655450016363 0ustar00 'JSON', 'extension' => 'json', 'info' => 'Check http://www.php.net/manual/en/book.json.php'), array('name' => 'Multibyte String', 'extension' => 'mbstring', 'info' => 'http://www.php.net/manual/en/book.mbstring.php') ); var $_recommended_extensions = array( array('name' => 'cURL', 'extension' => 'curl', 'info' => 'cURL is required for Facebook Connect and Twitter Authenticate to work.'), array('name' => 'Multibyte String', 'extension' => 'mbstring', 'info' => 'mbstring is designed to handle Unicode-based encodings such as UTF-8. Check http://www.php.net/manual/en/book.mbstring.php'), array('name' => 'Alternative PHP Cache (APC)', 'extension' => 'apc', 'info' => 'An opcode cache, like the Alternative PHP Cache (APC) extension, might significantly improve ZOOs memory footprint. http://www.php.net/manual/en/book.apc.php') ); var $_required_functions = array( array('function' => 'imagegd', 'info' => 'Check http://www.php.net/manual/en/image.installation.php'), array('function' => 'simplexml_load_string', 'info' => 'Check http://www.php.net/manual/en/function.simplexml-load-file.php'), array('function' => 'simplexml_load_file', 'info' => 'Check http://www.php.net/manual/en/function.simplexml-load-string.php'), array('function' => 'dom_import_simplexml', 'info' => 'Check http://www.php.net/manual/en/dom.setup.php') ); var $_recommended_functions = array(); var $_required_classes = array( array('class' => 'SimpleXMLElement', 'info' => 'Check http://de.php.net/manual/en/book.simplexml.php'), array('class' => 'ArrayObject', 'info' => 'Check http://www.php.net/manual/en/class.arrayobject.php') ); var $_recommended_classes = array(); function checkPHP() { return !version_compare(PHP_VERSION, '5.2.7', '<'); } function checkSafeMode() { return !ini_get('safe_mode'); } function checkMemoryLimit() { $memory_limit = ini_get('memory_limit'); return $memory_limit == '-1' ? true : $this->_return_bytes($memory_limit) >= 33554432; } function checkRealpathCache() { if ($this->_return_bytes((string) ini_get('realpath_cache_size')) / 1024 < 512) { return false; } return true; } function checkAPC() { return extension_loaded('apc') && class_exists('APCIterator'); } function _return_bytes ($size_str) { switch (substr ($size_str, -1)) { case 'M': case 'm': return (int) $size_str * 1048576; case 'K': case 'k': return (int) $size_str * 1024; case 'G': case 'g': return (int) $size_str * 1073741824; default: return $size_str; } } function checkRequirements() { $this->_required_results = array(); $this->_recommended_results = array(); $result = $this->_checkRequired(); $this->_checkRecommended(); return $result; } function _checkRequired() { // check php $status = $this->checkPHP(); $info = 'Zoo requires PHP 5.2.7+. Please upgrade your PHP version (http://www.php.net).'; $this->_addRequiredResult('PHP 5.2.7+', $status, $info); foreach ($this->_required_extensions as $extension) { $status = extension_loaded($extension['extension']); $this->_addRequiredResult('Extension: ' . $extension['name'], $status, $extension['info']); } foreach ($this->_required_functions as $function) { $status = function_exists($function['function']); $this->_addRequiredResult('Function: ' . $function['function'], $status, $function['info']); } foreach ($this->_required_classes as $class) { $status = class_exists($class['class']); $this->_addRequiredResult('Class: ' . $class['class'], $status, $class['info']); } foreach ($this->_required_results as $return) { if (!$return['status']) { return $return; } } return true; } function _checkRecommended() { foreach ($this->_recommended_extensions as $extension) { $status = extension_loaded($extension['extension']); $this->_addRecommendedResult('Extension: ' . $extension['name'], $status, $extension['info']); } foreach ($this->_recommended_functions as $function) { $status = function_exists($function['function']); $this->_addRecommendedResult('Function: ' . $function['function'], $status, $function['info']); } foreach ($this->_recommended_classes as $class) { $status = class_exists($class['class']); $this->_addRecommendedResult('Class: ' . $class['class'], $status, $class['info']); } // check safe mode $status = $this->checkSafeMode(); $info = 'It is recommended to turn off PHP safe mode.'; $this->_addRecommendedResult('PHP Safe Mode', $status, $info); $status = $this->checkMemoryLimit(); $info = 'It is recommended to set the php setting memory_limit to 32M or higher.'; $this->_addRecommendedResult('PHP Memory Limit', $status, $info); $status = $this->checkRealpathCache(); $info = 'It is recommended to set the php realpath cache setting realpath_cache_size to 512K or higher.'; $this->_addRecommendedResult('PHP Realpath Cache', $status, $info); if (extension_loaded('apc')) { $status = $this->checkAPC(); $info = 'It is recommended to turn on APC (version 3.1.2+).'; $this->_addRecommendedResult('Alternative PHP Cache (APC) enabled', $status, $info); } foreach ($this->_recommended_results as $return) { if (!$return['status']) { return $return['info']; } } return false; } function _addRequiredResult($name, $status, $info = '') { $this->_required_results[] = compact('name', 'status', 'info'); } function _addRecommendedResult($name, $status, $info = '') { $this->_recommended_results[] = compact('name', 'status', 'info'); } function displayResults() { ?>

    _required_results as $i => $req) : ?>
     

    _recommended_results as $i => $req) : ?>
     
    components/com_zoo/installation/updates/3.1.0.php000066600000004125150771655450015741 0ustar00')) { $addition = << Title Media Meta Description Links EOD; $content = substr($content, 0, $pos) . $addition . substr($content, $pos); JFile::write($file, $content); } } $file = "$folder/metadata.xml"; if (JFile::exists($file) and $content = JFile::read($file) and false === strpos($content, 'layout name="uikit"')) { if (false !== $pos = strpos($content, '')) { $addition = << UIkit This is an UIkit layout to render an item in the module themes. EOD; $content = substr($content, 0, $pos) . $addition . substr($content, $pos); JFile::write($file, $content); } } } } } }components/com_zoo/installation/updates/2.4.4.php000066600000002433150771655450015747 0ustar00database->getTableColumns(ZOO_TABLE_APPLICATION); if (isset($fields[ZOO_TABLE_APPLICATION]) && !array_key_exists('alias', $fields[ZOO_TABLE_APPLICATION])) { $app->database->query('ALTER TABLE '.ZOO_TABLE_APPLICATION.' ADD alias VARCHAR(255) AFTER name'); } // sanatize alias fields of the application foreach ($app->table->application->all() as $application) { if (empty($application->alias)) { $application->alias = $app->alias->application->getUniqueAlias($application->id, $app->string->sluggify($application->name)); try { $app->table->application->save($application); } catch (ApplicationTableException $e) {} } } // refresh database indexes $app->update->refreshDBTableIndexes(); } }components/com_zoo/installation/updates/2.5.7.php000066600000005576150771655450015766 0ustar00assign some new elements to your submission layouts.'); return $msg; } /* Function: run Performs the update. Returns: bool - true if updated successful */ public function run($app) { foreach ($app->application->groups() as $application) { foreach ($application->getTypes() as $type) { foreach ($application->getTemplates() as $template) { $renderer = $app->renderer->create('item')->addPath($template->getPath()); $path = 'item'; $prefix = 'item.'; if ($renderer->pathExists($path.DIRECTORY_SEPARATOR.$type->id)) { $path .= DIRECTORY_SEPARATOR.$type->id; $prefix .= $type->id.'.'; } foreach ($renderer->getLayouts($path) as $layout) { // get layout metadata $metadata = $renderer->getLayoutMetaData($prefix.$layout); if ($metadata->get('type') == 'submission') { $config = $renderer->getConfig('item'); $config = $app->data->create($config); if (isset($config[$application->getGroup().'.'.$type->id.'.'.$layout], $config[$application->getGroup().'.'.$type->id.'.'.$layout]['content'])) { if (@$config[$application->getGroup().'.'.$type->id.'.'.$layout]['content']['0']['element'] != '_itemname') { array_unshift($config[$application->getGroup().'.'.$type->id.'.'.$layout]['content'], array('altlabel' => '', 'required' => '1', 'element' => '_itemname')); } } $renderer->saveConfig($config, $template->getPath().'/renderer/item/positions.config'); } } // try to fix submission.php files $regex = '/'.preg_quote('$this->renderer->render($this->layout_path, array(\'form\' => $this->form))').'/'; $regex2 = '/'.preg_quote('$form->getItem()').'/'; $regex3 = '/'.preg_quote('$form->').'[a-z]+\(.*?\)/i'; foreach ($app->path->files($template->resource, true, '/submission\.php/') as $file) { try { $file = $app->path->path($template->resource.'/'.$file); if (is_writable($file)) { $output = file_get_contents($file); if (preg_match($regex, $output) || preg_match($regex2, $output)) { $output = preg_replace($regex, 'null', $output); $output = preg_replace($regex2, '$item', $output); $output = preg_replace($regex3, 'null', $output); JFile::write($file, $output); } } } catch (Exception $e) {} } } } } } }components/com_zoo/installation/updates/3.1.1.php000066600000001073150771655450015741 0ustar00update->refreshDBTableIndexes(); } }components/com_zoo/installation/updates/2.4.8.php000066600000001543150771655450015754 0ustar00database->getTableColumns(ZOO_TABLE_ITEM); if (isset($fields[ZOO_TABLE_ITEM]) && array_key_exists('elements', $fields[ZOO_TABLE_ITEM])) { if ($fields[ZOO_TABLE_ITEM]['elements'] != 'longtext') { $app->database->query('ALTER TABLE '.ZOO_TABLE_ITEM.' MODIFY elements LONGTEXT NOT NULL'); } } } }components/com_zoo/installation/updates/index.html000066600000000036150771655450016563 0ustar00components/com_zoo/installation/updates/2.4.12.php000066600000001561150771655450016027 0ustar00database->Quote('zooshortcut'); // query extension id and client id if ($res = $app->database->queryObject($query)) { $installer = new JInstaller(); $installer->uninstall('plugin', $res->id, 0); } } }components/com_zoo/installation/updates/2.5.beta.php000066600000015661150771655450016527 0ustar00error->raiseNotice(0, JText::_('Once you upgrade you\'ll not be able to downgrade to an earlier ZOO version. If you don\'t want to run this update, simply reinstall your previous ZOO version now.')); $msg = array(); $msg[] = JText::_('All ZOOtools will be removed by this update.'); $msg[] = JText::_('For the Gallery element you\'ll need to install YOOthemes Widgetkit! The old Gallery element will be removed by this update.'); $msg[] = JText::_('For the image lightbox and spotlight options you\'ll need to install YOOthemes Widgetkit.'); $msg[] = JText::_('There is a new Social Buttons element - it replaces the Facebook I Like element.'); $msg[] = JText::_('There is a new Media element - it will replace the Video element. The data will be converted where applicable.'); $msg[] = JText::_('Custom elements should be updated, some need to be adapted to the new elements behavior for the ZOO to function correctly.'); return $msg; } /* Function: run Performs the update. Returns: bool - true if updated successful */ public function run($app) { $json = $app->data->create(); $applications = $app->application->groups(); foreach ($applications as $application) { // convert xml types to json $files = $app->path->files($application->getResource() . 'types', false, '/\.xml$/'); foreach ($files as $file) { $path = $app->path->path($application->getResource() . 'types/').'/'; if ($xml_data = $app->data->create(json_encode(simplexml_load_file($path.$file)))) { $data = array(); $data['name'] = $xml_data['@attributes']['name']; foreach ($xml_data['params']['param'] as $param) { $element = array(); foreach ($param as $name => $option) { if ($name === '@attributes') { $element += $option; } else { $element[$name] = array(); foreach ($option as $key => $value) { if ($key === '@attributes') { if (count($value) > 1) { $element[$name][] = $value; } else { $element[$name][] = array_pop($value); } } else { foreach ($value as $child) { if (count($child) > 1) { $element[$name][] = $child; } else { $element[$name][] = array_pop($child); } } } } } } $identifier = $element['identifier']; unset($element['identifier']); $data['elements'][$identifier] = $element; } // write new type config file JFile::write($path.basename($file, '.xml').'.config', $json->_jsonEncode($data)); // remove old type xml file JFile::delete($path.$file); } } // change type of video element to media element foreach ($application->getTypes() as $type) { $changed = false; $elements = $type->elements; foreach ($elements as $key => $element) { if (isset($element['type']) && $element['type'] == 'video') { $elements[$key]['type'] = 'media'; $changed = true; } } $type->elements = $elements; if ($changed) { $type->save(); } } } // remove obsolete elements foreach (array('video', 'gallery', 'facebookilike') as $element) { if ($folder = $app->path->path('media:zoo/elements/'.$element)) { JFolder::delete($folder); } } // convert xml element data to JSON data $elements_array = array('relateditems', 'country', 'select', 'checkbox', 'radio', 'relatedcategories'); $items = $app->database->queryObjectList('SELECT id, application_id, elements, type FROM '.ZOO_TABLE_ITEM); foreach ($items as $item) { $application = $app->table->application->get($item->application_id); if ($xml_data = simplexml_load_string($item->elements)) { $element_data = array(); foreach ($xml_data as $xml_element) { if ($element_type = $xml_element->getName()) { $identifier = (string) $xml_element->attributes()->identifier; $data = array(); foreach ($xml_element->children() as $child) { $name = $child->getName(); if ($element_type == 'video' && $name == 'file' && (string) $child) { $data[$name] = $application->getType($item->type)->getElementConfig($identifier)->get('directory') . '/' . (string) $child; } else if (in_array($element_type, $elements_array)) { $data[$name][] = (string) $child; } else { $data[$name] = (string) $child; } } if ($this->_isRepeatable($app, $element_type)) { $element_data[$identifier][] = $data; } else { $element_data[$identifier] = $data; } } } $query = "UPDATE ".ZOO_TABLE_ITEM." SET elements = ".$app->database->quote($json->_jsonEncode($element_data))." WHERE id = ".$item->id; $app->database->query($query); } } // sanatize item order foreach ($app->table->application->all() as $application) { try { $item_order = $application->getParams()->get('global.config.item_order'); if (is_string($item_order)) { $application->getParams()->set('global.config.item_order', $app->itemorder->convert($item_order)); $app->table->application->save($application); } $item_order = $application->getParams()->get('config.item_order'); if (is_string($item_order)) { $application->getParams()->set('config.item_order', $app->itemorder->convert($item_order)); $app->table->application->save($application); } foreach ($application->getCategories() as $category) { $item_order = $category->getParams()->get('config.item_order'); if (is_string($item_order)) { $category->getParams()->set('config.item_order', $app->itemorder->convert($item_order)); $app->table->category->save($category); } } } catch (AppException $e) {} } // remove zoo tools jimport('joomla.installer.installer'); $uninstaller = new JInstaller(); if ($ids = $app->database->queryResultArray('SELECT extension_id as id FROM #__extensions WHERE element in ("mod_zooaccordion", "mod_zoocarousel", "mod_zoodrawer", "mod_zoomaps", "mod_zooscroller", "mod_zooslider")') and is_array($ids)) { foreach ($ids as $id) { $uninstaller->uninstall('module', $id, 0); } } } protected function _isRepeatable($app, $type) { if (isset($this->_repeatable_elements[$type])) { return $this->_repeatable_elements[$type]; } if ($file = $app->path->path("elements:$type/$type.php")) { if ($content = file_get_contents($file)) { $this->_repeatable_elements[$type] = preg_match('/class(.*)extends(.*)ElementRepeatable/i', $content); return $this->_repeatable_elements[$type]; } } return null; } }components/com_zoo/installation/updates/2.5.3.php000066600000003076150771655450015753 0ustar00path->path('media:zoo/elements/'.$element)) { JFolder::delete($folder); } } // rename _itempublishup to _itempublish_up in config files foreach ($app->path->files('root:', true, '/positions\.config/') as $file) { if (preg_match('#renderer\/item\/#', $file)) { $changed = false; if (!$path = $app->path->path('root:'.$file)) { continue; } $data = $app->data->create(file_get_contents($path)); if (!empty($data)) { foreach ($data as $layout => $positions) { foreach ($positions as $position => $elements) { foreach ($elements as $index => $element) { if (isset($element['element']) && $element['element'] == '_itempublishup') { $data[$layout][$position][$index]['element'] = '_itempublish_up'; $changed = true; } } } } } if ($changed) { $data = (string) $data; JFile::write($app->path->path('root:'.$file), $data); } } } } }components/com_zoo/installation/index.sql000066600000003563150771655450014761 0ustar00-- -------------------------------------------------------- ALTER TABLE `#__zoo_category` ADD UNIQUE `ALIAS_INDEX` (`alias`), ADD INDEX `PUBLISHED_INDEX` (`published`), ADD INDEX `APPLICATIONID_ID_INDEX` (`application_id`, `published`, `id`), ADD INDEX `APPLICATIONID_ID_INDEX2` (`application_id`, `id`); -- -------------------------------------------------------- ALTER TABLE `#__zoo_category_item` ADD INDEX `ITEMID_INDEX` (`item_id`), ADD INDEX `CATEGORYID_INDEX` (`category_id`); -- -------------------------------------------------------- ALTER TABLE `#__zoo_comment` ADD INDEX `STATE_INDEX` (`state`), ADD INDEX `CREATED_INDEX` (`created`), ADD INDEX `ITEMID_INDEX` (`item_id`), ADD INDEX `AUTHOR_INDEX` (`author`), ADD INDEX `ITEMID_STATE_INDEX` (`item_id`, `state`); -- -------------------------------------------------------- ALTER TABLE `#__zoo_item` ADD UNIQUE `ALIAS_INDEX` (`alias`), ADD INDEX `PUBLISH_INDEX` (`publish_up`, `publish_down`), ADD INDEX `STATE_INDEX` (`state`), ADD INDEX `ACCESS_INDEX` (`access`), ADD INDEX `CREATED_BY_INDEX` (`created_by`), ADD INDEX `NAME_INDEX` (`name`), ADD INDEX `APPLICATIONID_INDEX` (`application_id`), ADD INDEX `TYPE_INDEX` (`type`), ADD INDEX `MULTI_INDEX` (`application_id`, `access`, `state`, `publish_up`, `publish_down`), ADD INDEX `MULTI_INDEX2` (`id`, `access`, `state`, `publish_up`, `publish_down`), ADD INDEX `ID_APPLICATION_INDEX` (`id`, `application_id`), ADD FULLTEXT `SEARCH_FULLTEXT` (`name`); -- -------------------------------------------------------- ALTER TABLE `#__zoo_search_index` ADD FULLTEXT `SEARCH_FULLTEXT` (`value`); -- -------------------------------------------------------- ALTER TABLE `#__zoo_submission` ADD UNIQUE `ALIAS_INDEX` (`alias`); -- -------------------------------------------------------- ALTER TABLE `#__zoo_tag` ADD UNIQUE `NAME_ITEMID_INDEX` (`name`, `item_id`);components/com_zoo/installation/dependencies.config000066600000000727150771655450016745 0ustar00 { "Widgetkit": { "version": "1.0.4", "manifest": "administrator\/components\/com_widgetkit\/widgetkit.xml", "url": "http:\/\/www.yootheme.com\/widgetkit\/downloads" }, "ZLFramework-J25": { "version": "2.5.1", "manifest": "plugins\/system\/zlframework\/zlframework.xml", "url": "https:\/\/www.zoolanders.com\/" }, "ZLFramework-J15": { "version": "2.5.1", "manifest": "plugins/system/zlframework.xml", "url": "https:\/\/www.zoolanders.com\/" } }components/com_zoo/installation/install.sql000066600000012271150771655450015314 0ustar00-- -------------------------------------------------------- CREATE TABLE IF NOT EXISTS #__zoo_version ( `version` varchar(255) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 SELECT CASE WHEN ( SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = (SELECT DATABASE()) AND table_name LIKE '%zoo_application' ) THEN '' ELSE '3.1.6' END as version; -- -------------------------------------------------------- CREATE TABLE IF NOT EXISTS #__zoo_application ( `id` int(11) NOT NULL auto_increment, `name` varchar(255) NOT NULL, `alias` varchar(255) NOT NULL, `application_group` varchar(255) NOT NULL, `description` text NOT NULL, `params` text NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -------------------------------------------------------- CREATE TABLE IF NOT EXISTS #__zoo_category ( `id` int(11) NOT NULL auto_increment, `application_id` int(11) NOT NULL, `name` varchar(255) NOT NULL, `alias` varchar(255) NOT NULL, `description` text NOT NULL, `parent` int(11) NOT NULL, `ordering` int(11) NOT NULL, `published` tinyint(1) NOT NULL, `params` text NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `ALIAS_INDEX` (`alias`), KEY `PUBLISHED_INDEX` (`published`), KEY `APPLICATIONID_ID_INDEX` (`application_id`,`published`,`id`), KEY `APPLICATIONID_ID_INDEX2` (`application_id`, `id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -------------------------------------------------------- CREATE TABLE IF NOT EXISTS #__zoo_category_item ( `category_id` int(11) NOT NULL, `item_id` int(11) NOT NULL, PRIMARY KEY (`category_id`,`item_id`), KEY `ITEMID_INDEX` (`item_id`), KEY `CATEGORYID_INDEX` (`category_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -------------------------------------------------------- CREATE TABLE IF NOT EXISTS #__zoo_comment ( `id` int(11) NOT NULL auto_increment, `parent_id` int(11) NOT NULL, `item_id` int(11) NOT NULL, `user_id` varchar(255) NOT NULL, `user_type` varchar(255) NOT NULL, `author` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, `url` varchar(255) NOT NULL, `ip` varchar(255) NOT NULL, `created` datetime NOT NULL, `content` text NOT NULL, `state` tinyint(4) NOT NULL, PRIMARY KEY (`id`), KEY `STATE_INDEX` (`state`), KEY `CREATED_INDEX` (`created`), KEY `ITEMID_INDEX` (`item_id`), KEY `AUTHOR_INDEX` (`author`), KEY `ITEMID_STATE_INDEX` (`item_id`, `state`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -------------------------------------------------------- CREATE TABLE IF NOT EXISTS #__zoo_item ( `id` int(11) NOT NULL auto_increment, `application_id` int(11) NOT NULL, `type` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `alias` varchar(255) NOT NULL, `created` datetime NOT NULL, `modified` datetime NOT NULL, `modified_by` int(11) NOT NULL, `publish_up` datetime NOT NULL, `publish_down` datetime NOT NULL, `priority` int(11) NOT NULL, `hits` int(11) NOT NULL, `state` tinyint(3) NOT NULL, `access` int(11) NOT NULL, `created_by` int(11) NOT NULL, `created_by_alias` varchar(255) NOT NULL, `searchable` int(11) NOT NULL, `elements` longtext NOT NULL, `params` longtext NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `ALIAS_INDEX` (`alias`), KEY `PUBLISH_INDEX` (`publish_up`,`publish_down`), KEY `STATE_INDEX` (`state`), KEY `ACCESS_INDEX` (`access`), KEY `CREATED_BY_INDEX` (`created_by`), KEY `NAME_INDEX` (`name`), KEY `APPLICATIONID_INDEX` (`application_id`), KEY `TYPE_INDEX` (`type`), KEY `MULTI_INDEX` (`application_id`,`access`,`state`,`publish_up`,`publish_down`), KEY `MULTI_INDEX2` (`id`,`access`,`state`,`publish_up`,`publish_down`), KEY `ID_APPLICATION_INDEX` (`id`,`application_id`), FULLTEXT KEY `SEARCH_FULLTEXT` (`name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -------------------------------------------------------- CREATE TABLE IF NOT EXISTS #__zoo_rating ( `id` int(11) NOT NULL auto_increment, `item_id` int(11) default NULL, `element_id` varchar(255) default NULL, `user_id` int(11) default NULL, `value` tinyint(4) default NULL, `ip` varchar(255) default NULL, `created` datetime default NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -------------------------------------------------------- CREATE TABLE IF NOT EXISTS #__zoo_search_index ( `item_id` int(11) NOT NULL, `element_id` varchar(255) NOT NULL, `value` text NOT NULL, PRIMARY KEY (`item_id`,`element_id`), FULLTEXT KEY `SEARCH_FULLTEXT` (`value`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -------------------------------------------------------- CREATE TABLE IF NOT EXISTS #__zoo_submission ( `id` int(11) NOT NULL auto_increment, `application_id` int(11) NOT NULL, `name` varchar(255) NOT NULL, `alias` varchar(255) NOT NULL, `state` tinyint(3) NOT NULL, `access` int(11) NOT NULL, `params` text NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `ALIAS_INDEX` (`alias`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -------------------------------------------------------- CREATE TABLE IF NOT EXISTS #__zoo_tag ( `item_id` int(11) NOT NULL, `name` varchar(255) NOT NULL, PRIMARY KEY (`item_id`,`name`), UNIQUE KEY `NAME_ITEMID_INDEX` (`name`,`item_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; components/com_zoo/zoo.xml000066600000004446150771655450011762 0ustar00 com_zoo YOOtheme March 2014 http://www.yootheme.com/updates Copyright (C) YOOtheme GmbH http://www.gnu.org/licenses/gpl.html GNU/GPL YOOtheme Proprietary Use License (http://www.yootheme.com/license) info@yootheme.com http://www.yootheme.com 3.1.6 ZOO component for Joomla 2.5+ developed by YOOtheme (http://www.yootheme.com) en-GB.com_zoo.ini file.script.php installation/install.sql installation/uninstall.sql index.html router.php zoo.php assets controllers partials renderer sef_ext views index.html assets elements libraries com_zoo en-GB.com_zoo.ini en-GB.com_zoo.sys.ini index.html config.php zoo.php README.markdown assets classes controllers events framework helpers installation joomla libraries partials tables views components/com_zoo/config.php000066600000012024150771655450012376 0ustar00ZOO is developed by YOOtheme. All Rights Reserved.'); define('ZOO_TABLE_APPLICATION', '#__zoo_application'); define('ZOO_TABLE_CATEGORY', '#__zoo_category'); define('ZOO_TABLE_CATEGORY_ITEM', '#__zoo_category_item'); define('ZOO_TABLE_COMMENT', '#__zoo_comment'); define('ZOO_TABLE_ITEM', '#__zoo_item'); define('ZOO_TABLE_RATING', '#__zoo_rating'); define('ZOO_TABLE_SEARCH', '#__zoo_search_index'); define('ZOO_TABLE_SUBMISSION', '#__zoo_submission'); define('ZOO_TABLE_TAG', '#__zoo_tag'); define('ZOO_TABLE_VERSION', '#__zoo_version'); // init vars $zoo = App::getInstance('zoo'); $path = dirname(__FILE__); $cache_path = JPATH_ROOT.'/cache/com_zoo'; $media_path = JPATH_ROOT.'/media/zoo'; // register paths $zoo->path->register(JPATH_ROOT.'/modules', 'modules'); $zoo->path->register(JPATH_ROOT.'/plugins', 'plugins'); $zoo->path->register($zoo->system->config->get('tmp_path'), 'tmp'); $zoo->path->register($path.'/assets', 'assets'); $zoo->path->register($cache_path, 'cache'); $zoo->path->register($path.'/classes', 'classes'); $zoo->path->register($path, 'component.admin'); $zoo->path->register(JPATH_ROOT.'/components/com_zoo', 'component.site'); $zoo->path->register($path.'/controllers', 'controllers'); $zoo->path->register($path.'/events', 'events'); $zoo->path->register($path.'/helpers', 'helpers'); $zoo->path->register($path.'/installation', 'installation'); $zoo->path->register($path.'/joomla', 'joomla'); $zoo->path->register($path.'/joomla/elements', 'joomla.elements'); $zoo->path->register($path.'/libraries', 'libraries'); $zoo->path->register($media_path.'/applications', 'applications'); $zoo->path->register($media_path.'/assets', 'assets'); $zoo->path->register($media_path.'/elements', 'elements'); $zoo->path->register($media_path.'/libraries', 'libraries'); $zoo->path->register($path.'/partials', 'partials'); $zoo->path->register($path.'/tables', 'tables'); $zoo->path->register($path.'/installation/updates', 'updates'); $zoo->path->register($path.'/views', 'views'); // create cache folder if none existent if (!JFolder::exists($cache_path) && $zoo->request->get('option', 'cmd') != 'com_cache') { JFolder::create($cache_path); $zoo->zoo->putIndexFile($cache_path); } // register classes $zoo->loader->register('Application', 'classes:application.php'); $zoo->loader->register('Category', 'classes:category.php'); $zoo->loader->register('Comment', 'classes:comment.php'); $zoo->loader->register('CommentAuthor', 'classes:commentauthor.php'); $zoo->loader->register('CommentAuthorJoomla', 'classes:commentauthor.php'); $zoo->loader->register('CommentAuthorFacebook', 'classes:commentauthor.php'); $zoo->loader->register('CommentAuthorTwitter', 'classes:commentauthor.php'); $zoo->loader->register('Item', 'classes:item.php'); $zoo->loader->register('ItemRenderer', 'classes:renderer/item.php'); $zoo->loader->register('Submission', 'classes:submission.php'); // register and connect events $zoo->event->register('ApplicationEvent'); $zoo->event->dispatcher->connect('application:init', array('ApplicationEvent', 'init')); $zoo->event->register('ItemEvent'); $zoo->event->dispatcher->connect('item:saved', array('ItemEvent', 'saved')); $zoo->event->dispatcher->connect('item:deleted', array('ItemEvent', 'deleted')); $zoo->event->dispatcher->connect('item:stateChanged', array('ItemEvent', 'stateChanged')); $zoo->event->register('CategoryEvent'); $zoo->event->dispatcher->connect('category:saved', array('CategoryEvent', 'saved')); $zoo->event->dispatcher->connect('category:deleted', array('CategoryEvent', 'deleted')); $zoo->event->dispatcher->connect('category:stateChanged', array('CategoryEvent', 'stateChanged')); $zoo->event->register('CommentEvent'); $zoo->event->dispatcher->connect('comment:saved', array('CommentEvent', 'saved')); $zoo->event->dispatcher->connect('comment:deleted', array('CommentEvent', 'deleted')); $zoo->event->dispatcher->connect('comment:stateChanged', array('CommentEvent', 'stateChanged')); $zoo->event->register('SubmissionEvent'); $zoo->event->dispatcher->connect('submission:saved', array('SubmissionEvent', 'saved')); $zoo->event->register('LayoutEvent'); $zoo->event->dispatcher->connect('layout:init', array('LayoutEvent', 'init')); $zoo->event->register('TypeEvent'); $zoo->event->dispatcher->connect('type:beforesave', array('TypeEvent', 'beforesave')); $zoo->event->dispatcher->connect('type:copied', array('TypeEvent', 'copied')); $zoo->event->dispatcher->connect('type:deleted', array('TypeEvent', 'deleted')); $zoo->event->register('ElementEvent'); $zoo->event->dispatcher->connect('element:configform', array('ElementEvent', 'configForm')); components/com_zoo/controllers/submission.php000066600000031376150771655450015705 0ustar00table = $this->app->table->submission; // get application $this->application = $this->app->zoo->getApplication(); // set base url $this->baseurl = $this->app->link(array('controller' => $this->controller), false); // register tasks $this->registerTask('add', 'edit'); $this->registerTask('apply', 'save'); $this->registerTask('save2new', 'save' ); } public function display($cachable = false, $urlparams = false) { jimport('joomla.html.pagination'); // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Items')); $this->app->toolbar->addNew(); $this->app->toolbar->editList(); $this->app->toolbar->custom('docopy', 'copy.png', 'copy_f2.png', 'Copy'); $this->app->toolbar->deleteList(); $this->app->zoo->toolbarHelp(); $this->app->html->_('behavior.tooltip'); $state_prefix = $this->option.'_'.$this->application->id.'.submission'; $filter_order = $this->app->system->application->getUserStateFromRequest($state_prefix.'filter_order', 'filter_order', 'name', 'cmd'); $filter_order_Dir = $this->app->system->application->getUserStateFromRequest($state_prefix.'filter_order_Dir', 'filter_order_Dir', 'desc', 'word'); // get data from the table $where = array(); // application filter $where[] = 'application_id = ' . (int) $this->application->id; $options = array( 'conditions' => array(implode(' AND ', $where)), 'order' => $filter_order.' '.$filter_order_Dir); $this->submissions = $this->table->all($options); $this->submissions = array_merge($this->submissions); // table ordering and search filter $this->lists['order_Dir'] = $filter_order_Dir; $this->lists['order'] = $filter_order; // display view $this->getView()->display(); } public function edit() { // disable menu $this->app->request->setVar('hidemainmenu', 1); // get request vars $cid = $this->app->request->get('cid.0', 'int'); $edit = $cid > 0; // get item if ($edit) { $this->submission = $this->table->get($cid); } else { $this->submission = $this->app->object->create('Submission'); $this->submission->application_id = $this->application->id; $this->submission->access = 1; } // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Submission').': '.$this->submission->name.' [ '.($edit ? JText::_('Edit') : JText::_('New')).' ]'); $this->app->toolbar->apply(); $this->app->toolbar->save(); $this->app->toolbar->save2new(); $this->app->toolbar->cancel('cancel', $edit ? 'Close' : 'Cancel'); $this->app->zoo->toolbarHelp(); // published select $this->lists['select_published'] = $this->app->html->_('select.booleanlist', 'state', null, $this->submission->state); // access select $this->lists['select_access'] = $this->app->html->_('zoo.accesslevel', array(), 'access', 'class="inputbox"', 'value', 'text',$this->submission->access); // tooltip select $this->lists['select_tooltip'] = $this->app->html->_('select.booleanlist', 'params[show_tooltip]', null, $this->submission->showTooltip()); // item edit select $this->lists['select_item_edit'] = $this->app->html->_('select.booleanlist', 'params[item_edit]', null, $this->submission->getParams()->get('item_edit', false)); // item captcha select $options = array($this->app->html->_('select.option', '', '- '.JText::_('Select Plugin').' -')); $this->lists['select_item_captcha'] = $this->app->html->_('zoo.pluginlist', $options, 'params[captcha]', '', 'value', 'text', $this->submission->getParams()->get('captcha', null), null, true, 'captcha'); // type select $this->types = array(); foreach ($this->application->getTypes() as $type) { // list types with submission layouts only if (count($this->app->type->layouts($type, 'submission')) > 0) { $form = $this->submission->getForm($type->id); $this->types[$type->id]['name'] = $type->name; $options = array($this->app->html->_('select.option', '', '- '.JText::_('not submittable').' -')); $this->types[$type->id]['select_layouts'] = $this->app->html->_('zoo.layoutlist', $type, 'submission', $options, 'params[form]['.$type->id.'][layout]', '', 'value', 'text', $form->get('layout')); $options = array($this->app->html->_('select.option', '', '- '.JText::_('uncategorized').' -')); $this->types[$type->id]['select_categories'] = $this->app->html->_('zoo.categorylist', $this->application, $options, 'params[form]['.$type->id.'][category]', 'size="1"', 'value', 'text', $form->get('category')); } } // display view $this->getView()->setLayout('edit')->display(); } public function save() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $post = $this->app->request->get('post:', 'array', array()); $cid = $this->app->request->get('cid.0', 'int'); try { // get item if ($cid) { $submission = $this->table->get($cid); } else { $submission = $this->app->object->create('Submission'); $submission->application_id = $this->application->id; } // bind submission data self::bind($submission, $post, array('params')); // Force alias to be set if (!strlen(trim($submission->alias))) { $submission->alias = $this->app->string->sluggify($submission->name); } // generate unique slug $submission->alias = $this->app->alias->submission->getUniqueAlias($submission->id, $this->app->string->sluggify($submission->alias)); // set params $submission->getParams() ->set('form.', @$post['params']['form']) ->set('trusted_mode', @$post['params']['trusted_mode']) ->set('show_tooltip', @$post['params']['show_tooltip']) ->set('item_edit', @$post['params']['item_edit']) ->set('max_submissions', @$post['params']['max_submissions']) ->set('captcha', @$post['params']['captcha']) ->set('captcha_guest_only', @$post['params']['captcha_guest_only']) ->set('email_notification', @$post['params']['email_notification']) ->set('config.', @$post['params']['config']) ->set('content.', @$post['params']['content']); // save submission $this->table->save($submission); // Make sure there is at most one item edit submission if (@$post['params']['item_edit'] == true) { foreach ($this->application->getSubmissions() as $sub) { if ($sub->id != $submission->id) { // Disable item edit param $sub->getParams()->set('item_edit', 0); $this->table->save($sub); } } } // set redirect message $msg = JText::_('Submission Saved'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error Saving Submission').' ('.$e.')'); $this->_task = 'apply'; $msg = null; } $link = $this->baseurl; switch ($this->getTask()) { case 'apply' : $link .= '&task=edit&cid[]='.$submission->id; break; case 'save2new' : $link .= '&task=add'; break; } $this->setRedirect($link, $msg); } public function remove() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select a submission to delete')); } try { // delete items foreach ($cid as $id) { $this->table->delete($this->table->get($id)); } // set redirect message $msg = JText::_('Submission Deleted'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseWarning(0, JText::_('Error Deleting Submission').' ('.$e.')'); $msg = null; } $this->setRedirect($this->baseurl, $msg); } public function docopy() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select a submission to copy')); } try { // copy submissions foreach ($cid as $id) { // get submission $submission = $this->table->get($id); // copy submission $submission->id = 0; // set id to 0, to force new category $submission->name .= ' ('.JText::_('Copy').')'; // set copied name $submission->alias = $this->app->alias->submission->getUniqueAlias($id, $submission->alias.'-copy'); // set copied alias // save copied category data $this->table->save($submission); } // set redirect message $msg = JText::_('Submission Copied'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error Copying Category').' ('.$e.')'); $msg = null; } $this->setRedirect($this->baseurl, $msg); } public function publish() { $this->_editState(1); } public function unpublish() { $this->_editState(0); } protected function _editState($state) { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select a submission to edit publish state')); } try { // update item state foreach ($cid as $id) { $submission = $this->table->get($id); $submission->state = $state; $this->table->save($submission); } } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error editing Submission Published State').' ('.$e.')'); } $this->setRedirect($this->baseurl); } public function enableTrustedMode() { $this->_editTrustedMode(1); } public function disableTrustedMode() { $this->_editTrustedMode(0); } public function enableItemEdit() { $this->_editItemEdit(1); } public function disableItemEdit() { $this->_editItemEdit(0); } protected function _editTrustedMode($enabled) { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select a submission to enable/disable Trusted Mode')); } try { // update item state foreach ($cid as $id) { $submission = $this->table->get($id); // trusted mode can only be enabled for nonpublic access if ($enabled == true) { if (!JAccess::checkGroup($this->app->zoo->getGroup($submission->access)->id, 'core.login.site')) { throw new AppException('Trusted mode can\'t be enabled for public access'); } } $submission->getParams() ->set('trusted_mode', $enabled); $this->table->save($submission); } } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error enabling/disabling Submission Trusted Mode').' ('.$e.')'); } $this->setRedirect($this->baseurl); } protected function _editItemEdit($enabled) { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select a submission to enable/disable Item Edit Submission')); } try { // update item state foreach ($cid as $id) { $submission = $this->table->get($id); $submission->getParams() ->set('item_edit', $enabled); // Make sure there is at most one item edit submission if ($enabled) { foreach ($this->application->getSubmissions() as $sub) { if ($sub->id != $submission->id) { // Disable item edit param $sub->getParams()->set('item_edit', 0); $this->table->save($sub); } } } $this->table->save($submission); } } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error enabling/disabling Submission Trusted Mode').' ('.$e.')'); } $this->setRedirect($this->baseurl); } } /* Class: SubmissionControllerException */ class SubmissionControllerException extends AppException {}components/com_zoo/controllers/tag.php000066600000007512150771655450014260 0ustar00table = $this->app->table->tag; // get application $this->application = $this->app->zoo->getApplication(); // set base url $this->baseurl = $this->app->link(array('controller' => $this->controller), false); } public function display($cachable = false, $urlparams = false) { // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Tags')); $this->app->toolbar->deleteList(); $this->app->zoo->toolbarHelp(); $this->app->html->_('behavior.tooltip'); // get request vars $state_prefix = $this->option.'_'.$this->application->id.'.tags.'; $filter_order = $this->app->system->application->getUserStateFromRequest($state_prefix.'filter_order', 'filter_order', '', 'cmd'); $filter_order_Dir = $this->app->system->application->getUserStateFromRequest($state_prefix.'filter_order_Dir', 'filter_order_Dir', 'desc', 'word'); $limit = $this->app->system->application->getUserStateFromRequest('global.list.limit', 'limit', $this->app->system->config->get('list_limit'), 'int'); $limitstart = $this->app->system->application->getUserStateFromRequest($state_prefix.'limitstart', 'limitstart', 0, 'int'); $search = $this->app->system->application->getUserStateFromRequest($state_prefix.'search', 'search', '', 'string'); $search = $this->app->string->strtolower($search); // is filtered ? $this->is_filtered = !empty($search); // in case limit has been changed, adjust limitstart accordingly $limitstart = ($limit != 0 ? (floor($limitstart / $limit) * $limit) : 0); // get data $filter = ($filter_order) ? $filter_order . ' ' . $filter_order_Dir : ''; $count = (int) $this->table->count($this->application->id, $search); $limitstart = $limitstart > $count ? floor($count / $limit) * $limit : $limitstart; $this->tags = $this->table->getAll($this->application->id, $search, '', $filter, $limitstart, $limit); $this->pagination = $this->app->pagination->create($count, $limitstart, $limit); // table ordering and search filter $this->lists['order_Dir'] = $filter_order_Dir; $this->lists['order'] = $filter_order; $this->lists['search'] = $search; // display view $this->getView()->display(); } public function remove() { // init vars $tags = $this->app->request->get('cid', 'array', array()); if (count($tags) < 1) { $this->app->error->raiseError(500, JText::_('Select a tag to delete')); } try { // delete tags $this->table->delete($tags, $this->application->id); // set redirect message $msg = JText::_('Tag Deleted'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseWarning(0, JText::_('Error Deleting Tag').' ('.$e.')'); $msg = null; } $this->setRedirect($this->baseurl, $msg); } public function update() { // init vars $old = $this->app->request->getString('old'); $new = $this->app->request->getString('new'); $msg = null; try { // update tag if (!empty($new) && $old != $new) { $this->table->update($this->application->id, $old, $new); // set redirect message $msg = JText::_('Tag Updated Successfully'); } } catch (AppException $e) { // raise notice on exception $this->app->error->raiseWarning(0, JText::_('Error Updating Tag').' ('.$e.')'); } $this->setRedirect($this->baseurl, $msg); } } /* Class: TagControllerException */ class TagControllerException extends AppException {}components/com_zoo/controllers/frontpage.php000066600000004347150771655450015475 0ustar00table = $this->app->table->application; // get application $this->application = $this->app->zoo->getApplication(); // set base url $this->baseurl = $this->app->link(array('controller' => $this->controller), false); // register tasks $this->registerTask('apply', 'save'); } public function display($cachable = false, $urlparams = false) { // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Frontpage')); $this->app->toolbar->apply(); $this->app->zoo->toolbarHelp(); // get params $this->params = $this->application->getParams(); // display view $this->getView()->display(); } public function save() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $post = $this->app->request->get('post:', 'array'); $post['description'] = $this->app->request->getVar('description', '', 'post', 'string', JREQUEST_ALLOWRAW); try { // bind post self::bind($this->application, $post, array('params')); // set params $this->application->params = $this->application ->getParams() ->remove('content.') ->remove('config.') ->remove('template.') ->set('content.', @$post['params']['content']) ->set('config.', @$post['params']['config']) ->set('template.', @$post['params']['template']); // save application $this->table->save($this->application); // set redirect message $msg = JText::_('Frontpage Saved'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error Saving Frontpage').' ('.$e.')'); $msg = null; } $this->setRedirect($this->baseurl, $msg); } } /* Class: FrontpageControllerException */ class FrontpageControllerException extends AppException {}components/com_zoo/controllers/comment.php000066600000022147150771655450015150 0ustar00table = $this->app->table->comment; // get application $this->application = $this->app->zoo->getApplication(); // set base url $this->baseurl = $this->app->link(array('controller' => $this->controller), false); // registers tasks $this->registerTask('apply', 'save'); $this->registerTask('save2new', 'save' ); $this->registerTask('add', 'edit'); } public function display($cachable = false, $urlparams = false) { jimport('joomla.html.pagination'); // get request vars $state_prefix = $this->option.'_'.$this->application->id.'.comment.'; $limit = $this->app->system->application->getUserStateFromRequest('global.list.limit', 'limit', $this->app->system->config->get('list_limit'), 'int'); $limitstart = $this->app->system->application->getUserStateFromRequest($state_prefix.'limitstart', 'limitstart', 0, 'int'); $filter_state = $this->app->system->application->getUserStateFromRequest($state_prefix.'filter-state', 'filter-state', '', 'string'); $filter_item = $this->app->system->application->getUserStateFromRequest($state_prefix.'filter-item', 'filter-item', 0, 'int'); $filter_author = $this->app->system->application->getUserStateFromRequest($state_prefix.'filter-author', 'filter-author', '', 'string'); $search = $this->app->system->application->getUserStateFromRequest($state_prefix.'search', 'search', '', 'string'); $search = $this->app->string->strtolower($search); // is filtered ? $this->is_filtered = $filter_state <> '' || !empty($filter_item) || !empty($filter_author) || !empty($search); // in case limit has been changed, adjust offset accordingly $limitstart = $limit != 0 ? (floor($limitstart / $limit) * $limit) : 0; // set toolbar items if ($filter_item && $item_object = $this->app->table->item->get($filter_item)) { $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Comments on') . ': ' . $item_object->name); } else { $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Comments')); } $this->app->toolbar->custom('approve', 'publish', '', 'Approve'); $this->app->toolbar->custom('unapprove', 'unpublish', '', 'Unapprove'); $this->app->toolbar->custom('spam', 'trash', '', 'Spam'); $this->app->toolbar->deleteList(); // build where condition $where = array('b.application_id = '.(int) $this->application->id); if ($filter_state === '') { $where[] = 'a.state <> 2'; // all except spam } else { $where[] = 'a.state = '.(int) $filter_state; } if ($filter_item) { $where[] = 'a.item_id = '.(int) $filter_item; } if ($filter_author == '_anonymous_') { $where[] = 'a.author = ""'; } elseif ($filter_author) { $where[] = 'a.author = "'.$this->app->database->escape($filter_author).'"'; } if ($search) { $where[] = 'LOWER(a.content) LIKE "%'.$this->app->database->escape($search, true).'%"'; } // build query options $options = array( 'select' => 'a.*', 'from' => ZOO_TABLE_COMMENT.' AS a LEFT JOIN '.ZOO_TABLE_ITEM.' AS b ON a.item_id = b.id', 'conditions' => array(implode(' AND ', $where)), 'order' => 'a.created DESC'); // query comment table $count = $this->table->count($options); $limitstart = $limitstart > $count ? floor($count / $limit) * $limit : $limitstart; $this->comments = $this->table->all($limit > 0 ? array_merge($options, array('offset' => $limitstart, 'limit' => $limit)) : $options); $this->pagination = $this->app->pagination->create($count, $limitstart, $limit); // search filter $this->lists['search'] = $search; // state select $options = array( $this->app->html->_('select.option', '', '- '.JText::_('Select Status').' -'), $this->app->html->_('select.option', '0', JText::_('Pending')), $this->app->html->_('select.option', '1', JText::_('Approved')), $this->app->html->_('select.option', '2', JText::_('Spam'))); $this->lists['select_state'] = $this->app->html->_('select.genericlist', $options, 'filter-state', 'class="inputbox auto-submit"', 'value', 'text', $filter_state); // item select $options = array($this->app->html->_('select.option', 0, '- '.JText::_('Select Item').' -')); $this->lists['select_item'] = $this->app->html->_('zoo.itemlist', $this->application, $options, 'filter-item', 'class="inputbox auto-submit"', 'value', 'text', $filter_item); // author select $options = array( $this->app->html->_('select.option', '', '- '.JText::_('Select Author').' -'), $this->app->html->_('select.option', '_anonymous_', '- '.JText::_('Anonymous').' -')); $this->lists['select_author'] = $this->app->html->_('zoo.commentauthorlist', $this->application, $options, 'filter-author', 'class="inputbox auto-submit"', 'value', 'text', $filter_author); // get comment params $this->params = $this->app->parameter->create($this->application->getParams()->get('global.comments.', array())); // display view $this->getView()->display(); } public function edit() { // get request vars $cid = $this->app->request->getInt('cid'); // get comment $this->comment = $this->table->get($cid); // display view $this->getView()->setLayout('_edit')->display(); } public function reply() { // get request vars $this->cid = $this->app->request->getInt('cid'); // display view $this->getView()->setLayout('_reply')->display(); } public function save() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $user = $this->app->user->get(); $post = $this->app->request->get('post:', 'array'); $cid = $this->app->request->get('cid.0', 'int'); $pid = $this->app->request->getInt('parent_id', 0); $now = $this->app->date->create(); try { // get content as raw and filter it $post['content'] = $this->app->request->getVar('content', null, '', 'string', JREQUEST_ALLOWRAW); $post['content'] = $this->app->comment->filterContentInput($post['content']); // get comment or create reply if ($cid) { $comment = $this->table->get($cid); } else { $parent = $this->table->get($pid); $comment = $this->app->object->create('Comment'); $comment->item_id = $parent->getItem()->id; $comment->user_id = $user->id; $comment->author = $user->name; $comment->email = $user->email; $comment->ip = $this->app->useragent->ip(); $comment->created = $now->toSQL(); $comment->state = Comment::STATE_APPROVED; } // bind post data self::bind($comment, $post); // save comment $this->table->save($comment); // get view $view = $this->getView(); // set view vars $view->option = $this->option; $view->comment = $comment; // display view $view->setLayout('_row')->display(); } catch (AppException $e) { // raise error on exception echo json_encode(array( 'group' => 'error', 'title' => JText::_('Error Saving Comment'), 'text' => (string) $e)); } } public function remove() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $msg = null; $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select a comment to delete')); } try { // delete comments foreach ($cid as $id) { $this->table->delete($this->table->get((int) $id)); } // set redirect message $msg = JText::_('Comment(s) Deleted'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseWarning(0, JText::_('Error Deleting Comment(s)').' ('.$e.')'); $msg = null; } $this->setRedirect($this->baseurl, $msg); } /* Function: approve Approve a comment Returns: Void */ public function approve() { $this->_editState(1); } /* Function: unapprove Unapprove a comment Returns: Void */ public function unapprove() { $this->_editState(0); } /* Function: spam Mark comment as spam Returns: Void */ public function spam() { $this->_editState(2); } protected function _editState($state) { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select a comment to edit state')); } try { // update comment state foreach ($cid as $id) { $this->table->get($id)->setState($state, true); } } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error editing Comment State').' ('.$e.')'); } $this->setRedirect($this->baseurl); } } /* Class: CommentControllerException */ class CommentControllerException extends AppException {}components/com_zoo/controllers/index.html000066600000000036150771655450014763 0ustar00components/com_zoo/controllers/configuration.php000066600000026350150771655450016355 0ustar00table = $this->app->table->application; // get application $this->application = $this->app->zoo->getApplication(); // set base url $this->baseurl = $this->app->link(array('controller' => $this->controller), false); // register tasks $this->registerTask('applyassignelements', 'saveassignelements'); $this->registerTask('apply', 'save'); } public function display($cachable = false, $urlparams = false) { // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Config')); $this->app->toolbar->apply(); $this->app->zoo->toolbarHelp(); // get params $this->params = $this->application->getParams(); // template select $options = array($this->app->html->_('select.option', '', '- '.JText::_('Select Template').' -')); foreach ($this->application->getTemplates() as $template) { $options[] = $this->app->html->_('select.option', $template->name, $template->getMetaData('name')); } $this->lists['select_template'] = $this->app->html->_('select.genericlist', $options, 'template', '', 'value', 'text', $this->params->get('template')); // display view $this->getView()->setLayout('application')->display(); } public function save() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $post = $this->app->request->get('post:', 'array'); try { // bind post self::bind($this->application, $post, array('params')); // set params $params = $this->application ->getParams() ->remove('global.') ->set('template', @$post['template']) ->set('global.config.', @$post['params']['config']) ->set('global.template.', @$post['params']['template']); if (isset($post['addons']) && is_array($post['addons'])) { foreach ($post['addons'] as $addon => $value) { $params->set("global.$addon.", $value); } } // save application $this->table->save($this->application); // set redirect message $msg = JText::_('Application Saved'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error Saving Application').' ('.$e.')'); $msg = null; } $this->setRedirect($this->baseurl, $msg); } public function getApplicationParams() { // init vars $template = $this->app->request->getCmd('template'); // get params $this->params = $this->application->getParams(); // set template $this->params->set('template', $template); // display view $this->getView()->setLayout('_applicationparams')->display(); } public function importExport() { // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Import / Export')); $this->app->zoo->toolbarHelp(); $this->exporter = $this->app->export->getExporters('Zoo v2'); // display view $this->getView()->setLayout('importexport')->display(); } public function importFrom() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); $exporter = $this->app->request->getString('exporter'); try { $xml = $this->app->export->create($exporter)->export(); $file = rtrim($this->app->system->config->get('tmp_path'), '\/') . '/' . $this->app->utility->generateUUID() . '.tmp'; if (JFile::exists($file)) { JFile::delete($file); } JFile::write($file, $xml); } catch (Exception $e) { // raise error on exception $this->app->error->raiseNotice(0, JText::_('Error During Export').' ('.$e.')'); $this->setRedirect($this->baseurl.'&task=importexport'); return; } $this->_import($file); } public function import() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); $userfile = null; $jsonfile = $this->app->request->getVar('import-json', array(), 'files', 'array'); try { // validate $validator = $this->app->validator->create('file', array('extensions' => array('json'))); $userfile = $validator->clean($jsonfile); $type = 'json'; } catch (AppValidatorException $e) {} $csvfile = $this->app->request->getVar('import-csv', array(), 'files', 'array'); try { // validate $validator = $this->app->validator->create('file', array('extensions' => array('csv'))); $userfile = $validator->clean($csvfile); $type = 'csv'; } catch (AppValidatorException $e) {} if (!empty($userfile)) { $file = rtrim($this->app->system->config->get('tmp_path'), '\/') . '/' . basename($userfile['tmp_name']); if (JFile::upload($userfile['tmp_name'], $file)) { $this->_import($file, $type); } else { // raise error on exception $this->app->error->raiseNotice(0, JText::_('Error Importing (Unable to upload file.)')); $this->setRedirect($this->baseurl.'&task=importexport'); return; } } else { // raise error on exception $this->app->error->raiseNotice(0, JText::_('Error Importing (Unable to upload file.)')); $this->setRedirect($this->baseurl.'&task=importexport'); return; } } public function importCSV() { $file = $this->app->request->getCmd('file', ''); $file = rtrim($this->app->system->config->get('tmp_path'), '\/') . '/' . $file; $this->_import($file, 'importcsv'); } protected function _import($file, $type = 'json') { // disable menu $this->app->request->setVar('hidemainmenu', 1); // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Import').': '.$this->application->name); $this->app->toolbar->cancel('importexport', 'Cancel'); $this->app->zoo->toolbarHelp(); // set_time_limit doesn't work in safe mode if (!ini_get('safe_mode')) { @set_time_limit(0); } $layout = ''; switch ($type) { case 'xml': $this->app->error->raiseWarning(0, 'XML import is not supported since ZOO 2.5!'); $this->importExport(); break; case 'json': if (JFile::exists($file) && $data = $this->app->data->create(file_get_contents($file))) { $this->info = $this->app->import->getImportInfo($data); $this->file = basename($file); } else { // raise error on exception $this->app->error->raiseNotice(0, JText::_('Error Importing (Not a valid JSON file)')); $this->setRedirect($this->baseurl.'&task=importexport'); return; } $layout = 'importjson'; break; case 'csv': $this->file = basename($file); $layout = 'configcsv'; break; case 'importcsv': $this->contains_headers = $this->app->request->getBool('contains-headers', false); $this->field_separator = $this->app->request->getString('field-separator', ','); $this->field_separator = empty($this->field_separator) ? ',' : substr($this->field_separator, 0, 1); $this->field_enclosure = $this->app->request->getString('field-enclosure', '"'); $this->field_enclosure = empty($this->field_enclosure) ? '"' : substr($this->field_enclosure, 0, 1); $this->info = $this->app->import->getImportInfoCSV($file, $this->contains_headers, $this->field_separator, $this->field_enclosure); $this->file = basename($file); $layout = 'importcsv'; break; } // display view $this->getView()->setLayout($layout)->display(); } public function doImport() { // init vars $import_frontpage = $this->app->request->getBool('import-frontpage', false); $import_categories = $this->app->request->getBool('import-categories', false); $element_assignment = $this->app->request->get('element-assign', 'array', array()); $types = $this->app->request->get('types', 'array', array()); $file = $this->app->request->getCmd('file', ''); $file = rtrim($this->app->system->config->get('tmp_path'), '\/') . '/' . $file; if (JFile::exists($file)) { $this->app->import->import($file, $import_frontpage, $import_categories, $element_assignment, $types); } $this->setRedirect($this->baseurl.'&task=importexport', JText::_('Import successfull')); } public function doImportCSV() { // init vars $contains_headers = $this->app->request->getBool('contains-headers', false); $field_separator = $this->app->request->getString('field-separator', ','); $field_enclosure = $this->app->request->getString('field-enclosure', '"'); $element_assignment = $this->app->request->get('element-assign', 'array', array()); $type = $this->app->request->getCmd('type', ''); $file = $this->app->request->getCmd('file', ''); $file = rtrim($this->app->system->config->get('tmp_path'), '\/') . '/' . $file; if (JFile::exists($file)) { $this->app->import->importCSV($file, $type, $contains_headers, $field_separator, $field_enclosure, $element_assignment); } $this->setRedirect($this->baseurl.'&task=importexport', JText::_('Import successfull')); } public function doExport() { $exporter = $this->app->request->getCmd('exporter'); if ($exporter) { try { // set_time_limit doesn't work in safe mode if (!ini_get('safe_mode')) { @set_time_limit(0); } $json = $this->app->export->create($exporter)->export(); header("Pragma: public"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Expires: 0"); header("Content-Transfer-Encoding: binary"); header ("Content-Type: application/json"); header('Content-Disposition: attachment;' .' filename="'.JFilterOutput::stringURLSafe($this->application->name).'.json";' ); echo $json; } catch (AppExporterException $e) { // raise error on exception $this->app->error->raiseNotice(0, JText::_('Error Exporting').' ('.$e.')'); $this->setRedirect($this->baseurl.'&task=importexport'); return; } } } public function doExportCSV() { //init vars $files = array(); try { foreach ($this->application->getTypes() as $type) { if ($file = $this->app->export->toCSV($type)) { $files[] = $file; } } if (empty($files)) { throw new AppException(JText::sprintf('There are no items to export')); } $filepath = $this->app->path->path("tmp:").'/'.$this->application->getGroup().'.zip'; $zip = $this->app->archive->open($filepath, 'zip'); $zip->create($files, PCLZIP_OPT_REMOVE_ALL_PATH); if (is_readable($filepath) && JFile::exists($filepath)) { $this->app->filesystem->output($filepath); $files[] = $filepath; foreach ($files as $file) { if (JFile::exists($file)) { JFile::delete($file); } } } else { throw new AppException(JText::sprintf('Unable to create file %s', $filepath)); } } catch (AppException $e) { // raise error on exception $this->app->error->raiseNotice(0, JText::_('Error Exporting').' ('.$e.')'); $this->setRedirect($this->baseurl.'&task=importexport'); return; } } } /* Class: ConfigurationControllerException */ class ConfigurationControllerException extends AppException {}components/com_zoo/controllers/item.php000066600000057574150771655450014460 0ustar00table = $this->app->table->item; // get application $this->application = $this->app->zoo->getApplication(); // set base url $this->baseurl = $this->app->link(array('controller' => $this->controller), false); // set user $this->user = $this->app->user->get(); // register tasks $this->registerTask('element', 'display'); $this->registerTask('apply', 'save'); $this->registerTask('save2new', 'save'); } public function display($cachable = false, $urlparams = false) { // get app from Request (currently used in zooapplication element) if ($id = $this->app->request->getInt('app_id')) { $this->application = $this->app->table->application->get($id); } // get database $this->db = $this->app->database; // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Items')); $this->app->toolbar->addNew(); $this->app->toolbar->editList(); $this->app->toolbar->publishList(); $this->app->toolbar->unpublishList(); $this->app->toolbar->custom('togglefrontpage', 'checkin', 'checkin', 'Toggle Frontpage', true); $this->app->toolbar->custom('docopy', 'copy.png', 'copy_f2.png', 'Copy'); $this->app->toolbar->deleteList(); $this->app->zoo->toolbarHelp(); $this->app->html->_('behavior.tooltip'); // get request vars $this->filter_item = $this->app->request->getInt('item_filter', 0); $this->type_filter = $this->app->request->get('type_filter', 'array', array()); $state_prefix = $this->option.'_'.$this->application->id.'.'.($this->getTask() == 'element' ? 'element' : 'item').'.'; $filter_order = $this->app->system->application->getUserStateFromRequest($state_prefix.'filter_order', 'filter_order', 'a.created', 'cmd'); $filter_order_Dir = $this->app->system->application->getUserStateFromRequest($state_prefix.'filter_order_Dir', 'filter_order_Dir', 'desc', 'word'); $filter_category_id = $this->app->system->application->getUserStateFromRequest($state_prefix.'filter_category_id', 'filter_category_id', '-1', 'string'); $limit = $this->app->system->application->getUserStateFromRequest('global.list.limit', 'limit', $this->app->system->config->get('list_limit'), 'int'); $limitstart = $this->app->system->application->getUserStateFromRequest($state_prefix.'limitstart', 'limitstart', 0, 'int'); $filter_type = $this->app->system->application->getUserStateFromRequest($state_prefix.'filter_type', 'filter_type', '', 'string'); $filter_author_id = $this->app->system->application->getUserStateFromRequest($state_prefix.'filter_author_id', 'filter_author_id', 0, 'int'); $search = $this->app->system->application->getUserStateFromRequest($state_prefix.'search', 'search', '', 'string'); $search = $this->app->string->strtolower($search); // is filtered ? $this->is_filtered = $filter_category_id <> '-1' || !empty($filter_type) || !empty($filter_author_id) || !empty($search); $this->users = $this->table->getUsers($this->application->id); $this->groups = $this->app->zoo->getGroups(); // select $select = 'a.*, EXISTS (SELECT true FROM '.ZOO_TABLE_CATEGORY_ITEM.' WHERE item_id = a.id AND category_id = 0) as frontpage'; // get from $from = $this->table->name.' AS a'; // get data from the table $where = array(); // application filter $where[] = 'a.application_id = ' . (int) $this->application->id; // category filter if ($filter_category_id === '') { $from .= ' LEFT JOIN '.ZOO_TABLE_CATEGORY_ITEM.' AS ci ON a.id = ci.item_id'; $where[] = 'ci.item_id IS NULL'; } else if ($filter_category_id > -1) { $from .= ' LEFT JOIN '.ZOO_TABLE_CATEGORY_ITEM.' AS ci ON a.id = ci.item_id'; $where[] = 'ci.category_id = ' . (int) $filter_category_id; } // type filter if (!empty($this->type_filter)) { $where[] = 'a.type IN ("' . implode('", "', $this->type_filter) . '")'; } else if (!empty($filter_type)) { $where[] = 'a.type = "' . (string) $filter_type . '"'; } // item filter if ($this->filter_item > 0) { $where[] = 'a.id != ' . (int) $this->filter_item; } // author filter if ($filter_author_id > 0) { $where[] = 'a.created_by = ' . (int) $filter_author_id; } if ($search) { $from .= ' LEFT JOIN '.ZOO_TABLE_TAG.' AS t ON a.id = t.item_id'; $where[] = '(LOWER(a.name) LIKE '.$this->db->Quote('%'.$this->db->escape($search, true).'%', false) . ' OR LOWER(t.name) LIKE '.$this->db->Quote('%'.$this->db->escape($search, true).'%', false) . ' OR LOWER(a.alias) LIKE '.$this->db->Quote('%'.$this->db->escape($search, true).'%', false) . ')'; } $options = array( 'select' => 'a.id', 'from' => $from, 'conditions' => array(implode(' AND ', $where)), 'group' => 'a.id'); $count = $this->table->count($options); $options['select'] = $select; $options['order'] = $filter_order.' '.$filter_order_Dir; // in case limit has been changed, adjust limitstart accordingly $limitstart = ($limit != 0 ? (floor($limitstart / $limit) * $limit) : 0); $limitstart = $limitstart > $count ? floor($count / $limit) * $limit : $limitstart; $this->items = $this->table->all($limit > 0 ? array_merge($options, array('offset' => $limitstart, 'limit' => $limit)) : $options); $this->items = array_merge($this->items); $this->pagination = $this->app->pagination->create($count, $limitstart, $limit); // category select $options = array(); $options[] = $this->app->html->_('select.option', '-1', '- ' . JText::_('Select Category') . ' -'); $options[] = $this->app->html->_('select.option', '', '- ' . JText::_('uncategorized') . ' -'); $options[] = $this->app->html->_('select.option', '0', '- '.JText::_('Frontpage')); $this->lists['select_category'] = $this->app->html->_('zoo.categorylist', $this->application, $options, 'filter_category_id', 'class="inputbox auto-submit"', 'value', 'text', $filter_category_id); // type select $options = array($this->app->html->_('select.option', '0', '- '.JText::_('Select Type').' -')); $this->lists['select_type'] = $this->app->html->_('zoo.typelist', $this->application, $options, 'filter_type', 'class="inputbox auto-submit"', 'value', 'text', $filter_type, false, false, $this->type_filter); // author select $options = array($this->app->html->_('select.option', '0', '- '.JText::_('Select Author').' -')); $this->lists['select_author'] = $this->app->html->_('zoo.itemauthorlist', $options, 'filter_author_id', 'class="inputbox auto-submit"', 'value', 'text', $filter_author_id); // table ordering and search filter $this->lists['order_Dir'] = $filter_order_Dir; $this->lists['order'] = $filter_order; $this->lists['search'] = $search; // display view $layout = $this->getTask() == 'element' ? 'element' : 'default'; $this->getView()->setLayout($layout)->display(); } public function loadtags() { // get request vars $tag = $this->app->request->getString('tag', ''); echo $this->app->tag->loadTags($this->application->id, $tag); } public function add() { // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Item') .': [ '.JText::_('New').' ]'); $this->app->toolbar->cancel(); // get types $this->types = $this->application->getTypes(); // no types available ? if (count($this->types) == 0) { $this->app->error->raiseNotice(0, JText::_('Please create a type first.')); $this->app->system->application->redirect($this->app->link(array('controller' => 'manager', 'task' => 'types', 'group' => $this->application->application_group), false)); } // only one type ? then skip type selection if (count($this->types) == 1) { $type = array_shift($this->types); $this->app->system->application->redirect($this->baseurl.'&task=edit&type='.$type->id); } // display view $this->getView()->setLayout('add')->display(); } public function edit() { // disable menu $this->app->request->setVar('hidemainmenu', 1); // get request vars $cid = $this->app->request->get('cid.0', 'int'); $edit = $cid > 0; // get item if ($edit) { if (!$this->item = $this->app->table->item->get($cid)) { $this->app->error->raiseError(500, JText::sprintf('Unable to access item with id %s', $cid)); return; } } else { $this->item = $this->app->object->create('Item'); $this->item->application_id = $this->application->id; $this->item->type = $this->app->request->getVar('type'); $this->item->publish_down = $this->app->database->getNullDate(); $this->item->access = $this->app->joomla->getDefaultAccess(); } // get item params $this->params = $this->item->getParams(); // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Item').': '.$this->item->name.' [ '.($edit ? JText::_('Edit') : JText::_('New')).' ]'); $this->app->toolbar->apply(); $this->app->toolbar->save(); $this->app->toolbar->save2new(); if ($edit) { $this->app->toolbar->save2copy(); } $this->app->toolbar->cancel('cancel', $edit ? 'Close' : 'Cancel'); $this->app->zoo->toolbarHelp(); // published select $this->lists['select_published'] = $this->app->html->_('select.booleanlist', 'state', null, $this->item->state); // published searchable $this->lists['select_searchable'] = $this->app->html->_('select.booleanlist', 'searchable', null, $this->item->searchable); // categories select $related_categories = $this->item->getRelatedCategoryIds(); $this->lists['select_frontpage'] = $this->app->html->_('select.booleanlist', 'frontpage', null, in_array(0, $related_categories)); $this->lists['select_categories'] = count($this->application->getCategoryTree()) > 1 ? $this->app->html->_('zoo.categorylist', $this->application, array(), 'categories[]', 'size="15" multiple="multiple" data-no_results_text="'.JText::_('No results match0r').'" data-placeholder="'.JText::_('Select Category').'"', 'value', 'text', $related_categories, false, false, 0 ,'|_ ', '.   ', '') : ''.JText::_('Please add categories first').''; $this->lists['select_primary_category'] = $this->app->html->_('zoo.categorylist', $this->application, array($this->app->html->_('select.option', '', JText::_('COM_ZOO_NONE'))), 'params[primary_category]', 'data-no_results_text="'.JText::_('No results match').'"', 'value', 'text', $this->params->get('config.primary_category'), false, false, 0 ,'|_ ', '.   ', ''); // most used tags $this->lists['most_used_tags'] = $this->app->table->tag->getAll($this->application->id, null, null, 'items DESC, a.name ASC', null, self::MAX_MOST_USED_TAGS); // comments enabled select $this->lists['select_enable_comments'] = $this->app->html->_('select.booleanlist', 'params[enable_comments]', null, $this->params->get('config.enable_comments', 1)); // display view $this->getView()->setLayout('edit')->display(); } public function save() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $now = $this->app->date->create(); $frontpage = $this->app->request->getBool('frontpage', false); $categories = $this->app->request->get('categories', null); $details = $this->app->request->get('details', null); $cid = $this->app->request->get('cid.0', 'int'); $tzoffset = $this->app->date->getOffset(); $post = array_merge($this->app->request->get('post:', 'array', array()), $details); try { // get item if ($cid) { $item = $this->table->get($cid); } else { $item = $this->app->object->create('Item'); $item->application_id = $this->application->id; $item->type = $this->app->request->getVar('type'); } // bind item data self::bind($item, $post, array('elements', 'params', 'created_by')); $created_by = isset($post['created_by']) ? $post['created_by'] : ''; $item->created_by = empty($created_by) ? $this->app->user->get()->id : $created_by == 'NO_CHANGE' ? $item->created_by : $created_by; $tags = isset($post['tags']) ? $post['tags'] : array(); $item->setTags($tags); // bind element data $item->elements = $this->app->data->create(); foreach ($item->getElements() as $id => $element) { if (isset($post['elements'][$id])) { $element->bindData($post['elements'][$id]); } else { $element->bindData(); } } // set alias if (!strlen(trim($item->alias))) { $item->alias = $this->app->string->sluggify($item->name); } $item->alias = $this->app->alias->item->getUniqueAlias($item->id, $this->app->string->sluggify($item->alias)); // set modified $item->modified = $now->toSQL(); $item->modified_by = $this->user->get('id'); // set created date try { $item->created = $this->app->date->create($item->created, $tzoffset)->toSQL(); } catch (Exception $e) { $item->created = $this->app->date->create()->toSQL(); } // set publish up date try { $item->publish_up = $this->app->date->create($item->publish_up, $tzoffset)->toSQL(); } catch (Exception $e) { $item->publish_up = $this->app->date->create()->toSQL(); } // set publish down date try { $item->publish_down = $this->app->date->create($item->publish_down, $tzoffset)->toSQL(); } catch (Exception $e) { $item->publish_down = $this->app->database->getNullDate(); } // get primary category $primary_category = @$post['params']['primary_category']; if (empty($primary_category) && count($categories)) { $primary_category = $categories[0]; } // set params $item->getParams() ->remove('metadata.') ->remove('template.') ->remove('content.') ->remove('config.') ->set('metadata.', @$post['params']['metadata']) ->set('template.', @$post['params']['template']) ->set('content.', @$post['params']['content']) ->set('config.', @$post['params']['config']) ->set('config.enable_comments', @$post['params']['enable_comments']) ->set('config.primary_category', $primary_category); // save item $this->table->save($item); // make sure categories contain primary category if (!empty($primary_category) && !in_array($primary_category, $categories)) { $categories[] = $primary_category; } // save category relations if ($frontpage) { $categories[] = 0; } $this->app->category->saveCategoryItemRelations($item, $categories); // set redirect message $msg = JText::_('Item Saved'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error Saving Item').' ('.$e.')'); $this->_task = 'apply'; $msg = null; } $link = $this->baseurl; switch ($this->getTask()) { case 'save2copy' : case 'apply' : $link .= '&task=edit&type='.$item->type.'&cid[]='.$item->id; break; case 'save2new' : $link .= '&task=add'; break; } $this->setRedirect($link, $msg); } public function save2copy() { $this->app->request->set('cid.0', 0) ->set('id', 0) ->set('name', $this->app->request->get('name', 'string').' ('.JText::_('Copy').')'); $this->save(); } public function docopy() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $now = $this->app->date->create()->toSQL(); $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select a item to copy')); } try { // copy items foreach ($cid as $id) { // get item $item = $this->table->get($id); $categories = $item->getRelatedCategoryIds(); // copy item $item->id = 0; // set id to 0, to force new item $item->name .= ' ('.JText::_('Copy').')'; // set copied name $item->alias = $this->app->alias->item->getUniqueAlias($id, $item->alias.'-copy'); // set copied alias $item->state = 0; // unpublish item $item->created = $item->modified = $now; $item->created_by = $item->modified_by = $this->user->get('id'); $item->hits = 0; // copy tags $item->setTags($this->app->table->tag->getItemTags($id)); // save copied item/element data $this->table->save($item); // save category relations $this->app->category->saveCategoryItemRelations($item, $categories); } // set redirect message $msg = JText::_('Item Copied'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error Copying Item').' ('.$e.')'); $msg = null; } $this->setRedirect($this->baseurl, $msg); } public function remove() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select a item to delete')); } try { // delete items foreach ($cid as $id) { $this->table->delete($this->table->get($id)); } // set redirect message $msg = JText::_('Item Deleted'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseWarning(0, JText::_('Error Deleting Item').' ('.$e.')'); $msg = null; } $this->setRedirect($this->baseurl, $msg); } public function savepriority() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $msg = JText::_('Order Priority saved'); // init vars $priority = $this->app->request->get('priority', 'array', array()); try { // update the priority for items foreach ($priority as $id => $value) { $item = $this->table->get((int) $id); // only update, if changed if ($item->priority != $value) { $item->priority = $value; $this->table->save($item); } } // set redirect message $msg = json_encode(array( 'group' => 'info', 'title' => JText::_('Success!'), 'text' => JText::_('Item Priorities Saved'))); } catch (AppException $e) { // raise error on exception $msg = json_encode(array( 'group' => 'error', 'title' => JText::_('Error!'), 'text' => JText::_('Error editing item priority').' ('.$e.')')); } echo $msg; } public function resethits() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $msg = null; $cid = $this->app->request->get('cid.0', 'int'); try { // get item $item = $this->table->get($cid); // reset hits if ($item->hits > 0) { $item->hits = 0; // save item $this->table->save($item); // set redirect message $msg = JText::_('Item Hits Reseted'); } } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error Reseting Item Hits').' ('.$e.')'); $msg = null; } $this->setRedirect($this->baseurl.'&task=edit&cid[]='.$item->id, $msg); } public function publish() { $this->_editState(1); } public function unpublish() { $this->_editState(0); } public function makeSearchable() { $this->_editSearchable(1); } public function makeNoneSearchable() { $this->_editSearchable(0); } public function enableComments() { $this->_editComments(1); } public function disableComments() { $this->_editComments(0); } protected function _editState($state) { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select an item to edit publish state')); } try { // update item state foreach ($cid as $id) { $this->table->get($id)->setState($state, true); } } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error editing Item Published State').' ('.$e.')'); } $this->setRedirect($this->baseurl); } protected function _editSearchable($searchable) { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select an item to edit searchable state')); } try { // update item searchable foreach ($cid as $id) { $item = $this->table->get($id); $item->searchable = $searchable; $this->table->save($item); } } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error editing Item Searchable State').' ('.$e.')'); } $this->setRedirect($this->baseurl); } protected function _editComments($enabled) { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select an item to enable/disable comments')); } try { // update item comments foreach ($cid as $id) { $item = $this->table->get($id); $item->params = $item ->getParams() ->set('config.enable_comments', $enabled); $this->table->save($item); } } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error enabling/disabling Item Comments').' ('.$e.')'); } $this->setRedirect($this->baseurl); } public function toggleFrontpage() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select an item to toggle item frontpage setting')); } try { // toggle item frontpage foreach ($cid as $id) { $item = $this->table->get($id); $categories = $item->getRelatedCategoryIds(); if (($key = array_search('0', $categories, true)) !== false) { unset($categories[$key]); } else { array_push($categories, '0'); } $this->app->category->saveCategoryItemRelations($item, $categories); } } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error toggling item frontpage setting').' ('.$e.')'); } $this->setRedirect($this->baseurl); } public function callElement() { // get request vars $element_identifier = $this->app->request->getString('elm_id', ''); $item_id = $this->app->request->getInt('item_id', 0); $type = $this->app->request->getString('type', ''); $this->method = $this->app->request->getCmd('method', ''); $this->args = $this->app->request->getVar('args', array(), 'default', 'array'); JArrayHelper::toString($this->args); // load element if ($item_id) { $item = $this->table->get($item_id); } elseif (!empty($type)) { $item = $this->app->object->create('Item'); $item->application_id = $this->application->id; $item->type = $type; } else { return; } // execute callback method if ($element = $item->getElement($element_identifier)) { echo $element->callback($this->method, $this->args); } } } /* Class: ItemControllerException */ class ItemControllerException extends AppException {}components/com_zoo/controllers/new.php000066600000010244150771655450014272 0ustar00group = $this->app->request->getString('group'); // set base url $this->baseurl = $this->app->link(array('controller' => $this->controller), false); // if group exists if ($this->group) { // add group to base url $this->baseurl .= '&group='.$this->group; // create application object $this->application = $this->app->object->create('Application'); $this->application->setGroup($this->group); } } public function display($cachable = false, $urlparams = false) { // set toolbar items $this->app->toolbar->title(JText::_('New App'), $this->app->get('icon')); $this->app->zoo->toolbarHelp(); // get applications $this->applications = $this->app->application->groups(); // display view $this->getView()->display(); } public function add() { // disable menu $this->app->request->setVar('hidemainmenu', 1); // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('New App').': '.$this->application->getMetaData('name')); $this->app->toolbar->save(); $this->app->toolbar->cancel('cancel', 'Cancel'); $this->app->zoo->toolbarHelp(); // get params $this->params = $this->application->getParams(); // set default template $this->params->set('template', 'default'); // template select $options = array($this->app->html->_('select.option', '', '- '.JText::_('Select Template').' -')); foreach ($this->application->getTemplates() as $template) { $options[] = $this->app->html->_('select.option', $template->name, $template->getMetaData('name')); } $this->lists['select_template'] = $this->app->html->_('select.genericlist', $options, 'template', '', 'value', 'text', $this->params->get('template')); // display view $this->getView()->setLayout('application')->display(); } public function save() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $post = $this->app->request->get('post:', 'array'); try { // bind post self::bind($this->application, $post, array('params')); // Force alias if (!strlen(trim($this->application->alias))) { $this->application->alias = $this->app->string->sluggify($this->application->name); } $this->application->alias = $this->app->alias->application->getUniqueAlias($this->application->id, $this->app->string->sluggify($this->application->alias)); // set params $params = $this->application ->getParams() ->remove('global.') ->set('group', @$post['group']) ->set('template', @$post['template']) ->set('global.config.', @$post['params']['config']) ->set('global.template.', @$post['params']['template']); if (isset($post['addons']) && is_array($post['addons'])) { foreach ($post['addons'] as $addon => $value) { $params->set("global.$addon.", $value); } } // save application $this->app->table->application->save($this->application); // set redirect $msg = JText::_('Application Saved'); $link = $this->app->link(array('changeapp' => $this->application->id), false); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error Saving Application').' ('.$e.')'); // set redirect $msg = null; $link = $this->baseurl.'&task=add'; } $this->setRedirect($link, $msg); } public function getApplicationParams() { // init vars $template = $this->app->request->getCmd('template'); $this->params = $this->application->getParams(); // set template $this->params->set('template', $template); // display view $this->getView()->setLayout('_applicationparams')->display(); } } /* Class: NewControllerException */ class NewControllerException extends AppException {}components/com_zoo/controllers/category.php000066600000024667150771655450015334 0ustar00table = $this->app->table->category; // get application $this->application = $this->app->zoo->getApplication(); // set base url $this->baseurl = $this->app->link(array('controller' => $this->controller), false); // registers tasks $this->registerTask('apply', 'save'); $this->registerTask('save2new', 'save' ); $this->registerTask('add', 'edit'); } public function display($cachable = false, $urlparams = false) { // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Categories')); $this->app->toolbar->addNew(); $this->app->toolbar->editList(); $this->app->toolbar->publishList(); $this->app->toolbar->unpublishList(); $this->app->toolbar->custom('docopy', 'copy.png', 'copy_f2.png', 'Copy', false); $this->app->toolbar->deleteList(); $this->app->toolbar->custom('resetorder', 'refresh.png', 'refresh.png', 'Reorder', false); $this->app->zoo->toolbarHelp(); $this->app->html->_('behavior.tooltip'); // get data $this->categories = $this->application->getCategoryTree(false, null, true); // display view $this->getView()->display(); } public function edit() { // disable menu $this->app->request->setVar('hidemainmenu', 1); // get request vars $cid = $this->app->request->get('cid.0', 'int'); $edit = $cid > 0; // get category if ($edit) { $this->category = $this->app->table->category->get($cid); } else { $this->category = $this->app->object->create('Category'); $this->category->parent = 0; } // get category params $this->params = $this->category->getParams(); // set toolbar items $text = $edit ? JText::_('Edit') : JText::_('New'); $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Category').': '.$this->category->name.' [ '.$text.' ]'); $this->app->toolbar->apply(); $this->app->toolbar->save(); $this->app->toolbar->save2new(); $this->app->toolbar->cancel('cancel', $edit ? 'Close' : 'Cancel'); $this->app->zoo->toolbarHelp(); // select published state $this->lists['select_published'] = $this->app->html->_('select.booleanlist', 'published', 'class="inputbox"', $this->category->published); // get categories and exclude the current category $categories = $this->application->getCategories(); unset($categories[$this->category->id]); // build category tree $list = $this->app->tree->buildList(0, $this->app->tree->build($categories, 'Category')); $options = array($this->app->html->_('select.option', '0', JText::_('Root'))); foreach ($list as $item) { $options[] = $this->app->html->_('select.option', $item->id, '   '.$item->treename); } // select parent category $this->lists['select_parent'] = $this->app->html->_('zoo.genericlist', $options, 'parent', 'class="inputbox" size="10" data-no_results_text="'.JText::_('No results match').'"', 'value', 'text', $this->category->parent); // display view $this->getView()->setLayout('edit')->display(); } public function save() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $post = $this->app->request->get('post:', 'array'); $cid = $this->app->request->get('cid.0', 'int'); // set application $post['application_id'] = $this->application->id; // get raw description from post data $post['description'] = $this->app->request->getVar('description', '', 'post', 'string', JREQUEST_ALLOWRAW); try { // get category and bind post data $category = ($cid) ? $this->table->get($cid) : $this->app->object->create('Category'); self::bind($category, $post, array('params')); // Force alias to be set if (!strlen(trim($category->alias))) { $category->alias = $this->app->string->sluggify($category->name); } $category->alias = $this->app->alias->category->getUniqueAlias($category->id, $this->app->string->sluggify($category->alias)); $category->getParams() ->remove('content.') ->remove('config.') ->remove('template.') ->remove('metadata.') ->set('content.', @$post['params']['content']) ->set('config.', @$post['params']['config']) ->set('template.', @$post['params']['template']) ->set('metadata.', @$post['params']['metadata']); // save category and update category ordering $this->table->save($category); $this->table->updateorder($this->application->id, $category->parent); // set redirect message $msg = JText::_('Category Saved'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error Saving Category').' ('.$e.')'); $this->_task = 'apply'; $msg = null; } $link = $this->baseurl; switch ($this->getTask()) { case 'apply' : $link .= '&task=edit&cid[]='.$category->id; break; case 'save2new' : $link .= '&task=edit&cid[]='; break; } $this->setRedirect($link, $msg); } public function remove() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select a Category to delete')); } try { // delete categories $parents = array(); foreach ($cid as $id) { $category = $this->table->get($id); $parents[] = $category->parent; $this->table->delete($category); } // update category ordering $this->table->updateorder($this->application->id, $parents); // set redirect message $msg = JText::_('Category Deleted'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error Deleting Category').' ('.$e.')'); $msg = null; } $this->setRedirect($this->baseurl, $msg); } public function docopy() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select a category to copy')); } try { // copy categories $parents = array(); foreach ($cid as $id) { // get category $category = $this->table->get($id); // copy category $category->id = 0; // set id to 0, to force new category $category->name .= ' ('.JText::_('Copy').')'; // set copied name $category->alias = $this->app->alias->category->getUniqueAlias($id, $category->alias.'-copy'); // set copied alias $category->published = 0; // unpublish category // track parent for ordering update $parents[] = $category->parent; // save copied category data $this->table->save($category); } // update category ordering $this->table->updateorder($this->application->id, $parents); // set redirect message $msg = JText::_('Category Copied'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error Copying Category').' ('.$e.')'); $msg = null; } $this->setRedirect($this->baseurl, $msg); } public function saveorder() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // group categories by parent $category_ordering = array(); foreach ($this->app->request->get('category', 'array', array()) as $id => $parent) { $category_ordering[$parent][] = $id; } try { // get categories $categories = $this->table->getAll($this->application->id); // update category parent & ordering foreach ($category_ordering as $parent => $cat_ids) { $parent = $parent == 'root' ? 0 : $parent; foreach ($cat_ids as $ordering => $id) { // only update, if changed if (isset($categories[$id]) && ($categories[$id]->parent != $parent || $categories[$id]->ordering != $ordering)) { $categories[$id]->parent = $parent; $categories[$id]->ordering = $ordering; $this->table->save($categories[$id]); } } } // set redirect message $msg = json_encode(array( 'group' => 'info', 'title' => JText::_('Success!'), 'text' => JText::_('New ordering saved'))); } catch (AppException $e) { // raise error on exception $msg = json_encode(array( 'group' => 'error', 'title' => JText::_('Error!'), 'text' => JText::_('Error Reordering Category').' ('.$e.')')); } echo $msg; } public function resetorder() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); try { // get categories $categories = $this->application->getCategoryTree(); // track parents $parents = array(); foreach ($categories as $category) { if ($category->hasChildren()) { $parents[] = $category->id; } } // Reorder $this->table->updateorder($this->application->id, $parents, 'name'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error Reordering Categories').' ('.$e.')'); } $this->setRedirect($this->baseurl); } public function publish() { $this->_editPublished(1, JText::_('Select a category to publish')); } public function unpublish() { $this->_editPublished(0, JText::_('Select a category to unpublish')); } public function _editPublished($published, $msg) { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, $msg); } try { // update published state foreach ($cid as $id) { $this->table->get($id)->setPublished($published, true); } } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::_('Error editing Category Published State').' ('.$e.')'); $msg = null; } $this->setRedirect($this->baseurl); } } /* Class: CategorAppControllerException */ class CategorAppControllerException extends AppException {}components/com_zoo/controllers/manager.php000066600000072772150771655450015131 0ustar00baseurl = $this->app->link(array('controller' => $this->controller), false); // get application group $this->group = $this->app->request->getString('group'); // if group exists if ($this->group) { // add group to base url $this->baseurl .= '&group='.$this->group; // create application object $this->application = $this->app->object->create('Application'); $this->application->setGroup($this->group); } // register tasks $this->registerTask('addtype', 'edittype'); $this->registerTask('applytype', 'savetype'); $this->registerTask('applyelements', 'saveelements'); $this->registerTask('applyassignelements', 'saveassignelements'); $this->registerTask('applysubmission', 'savesubmission'); } public function display($cachable = false, $urlparams = false) { // set toolbar items $this->app->toolbar->title(JText::_('App Manager'), $this->app->get('icon')); JToolBar::getInstance('toolbar')->appendButton('Popup', 'stats', 'Check For Modifications', JRoute::_(JUri::root() . 'administrator/index.php?option='.$this->app->component->self->name.'&controller='.$this->controller.'&task=checkmodifications&tmpl=component', true, -1), 570, 350); JToolBar::getInstance('toolbar')->appendButton('Popup', 'preview', 'Check Requirements', JRoute::_(JUri::root() . 'administrator/index.php?option='.$this->app->component->self->name.'&controller='.$this->controller.'&task=checkrequirements&tmpl=component', true, -1), 570, 350); if ($this->app->get('cache_routes', false)) { $this->app->toolbar->custom('disableRouteCaching', 'options', 'Disable Route Caching', 'Disable Route Caching', false); } else { $this->app->toolbar->custom('enableRouteCaching', 'options', 'Enable Route Caching', 'Enable Route Caching', false); } $this->app->toolbar->custom('cleandb', 'refresh', 'Refresh', 'Clean Database', false); $this->app->toolbar->custom('dobackup', 'archive', 'Backup Database', 'Backup Database', false); $this->app->zoo->toolbarHelp(); // get applications $this->applications = $this->app->application->groups(); // display view $this->getView()->display(); } public function info() { // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Information').': '.$this->application->getMetaData('name')); $this->app->toolbar->custom('doexport', 'archive', 'Archive', 'Export', false); $this->app->toolbar->custom('uninstallapplication', 'delete', 'Delete', 'Uninstall', false); $this->app->toolbar->deleteList('APP_DELETE_WARNING', 'removeapplication'); $this->app->zoo->toolbarHelp(); // get application instances for selected group $this->applications = $this->app->application->getApplications($this->application->getGroup()); // display view $this->getView()->setLayout('info')->display(); } public function installApplication() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // get the uploaded file information $userfile = $this->app->request->getVar('install_package', null, 'files', 'array'); try { $result = $this->app->install->installApplicationFromUserfile($userfile); $update = $result == 2 ? 'updated' : 'installed'; // set redirect message $msg = JText::sprintf('Application group (%s) successfully.', $update); } catch (InstallHelperException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::sprintf('Error installing Application group (%s).', $e)); $msg = null; } $this->setRedirect($this->baseurl, $msg); } public function uninstallApplication() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); try { $this->app->install->uninstallApplication($this->application); // set redirect message $msg = JText::_('Application group uninstalled successful.'); $link = $this->baseurl; // remove current group from redirect link $link = str_replace('&group='.$this->group, '', $link); } catch (InstallHelperException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::sprintf('Error uninstalling application group (%s).', $e)); $msg = null; $link = $this->baseurl.'&task=info'; } $this->setRedirect($link, $msg); } public function removeApplication() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select a application to delete')); } try { $table = $this->app->table->application; // delete applications foreach ($cid as $id) { $table->delete($table->get($id)); } // set redirect message $msg = JText::_('Application Deleted'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::sprintf('Error Deleting Application (%s).', $e)); $msg = null; } $this->setRedirect($this->baseurl.'&task=info', $msg); } public function types() { // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Types').': ' . $this->application->getMetaData('name')); $this->app->toolbar->addNew('addtype'); $this->app->toolbar->custom('copytype', 'copy', '', 'Copy'); $this->app->toolbar->deleteList('', 'removetype'); $this->app->toolbar->editList('edittype'); $this->app->zoo->toolbarHelp(); // get types $this->types = $this->application->getTypes(); // get templates $this->templates = $this->application->getTemplates(); // get extensions / trigger layout init event $this->extensions = $this->app->event->dispatcher->notify($this->app->event->create($this->app, 'layout:init'))->getReturnValue(); // display view $this->getView()->setLayout('types')->display(); } public function editType() { // disable menu $this->app->request->setVar('hidemainmenu', 1); // get request vars $cid = $this->app->request->get('cid.0', 'string', ''); $this->edit = $cid ? true : false; // get type if (empty($cid)) { $this->type = $this->app->object->create('Type', array(null, $this->application)); } else { $this->type = $this->application->getType($cid); } // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Type').': '.$this->type->name.' [ '.($this->edit ? JText::_('Edit') : JText::_('New')).' ]'); $this->app->toolbar->apply('applytype'); $this->app->toolbar->save('savetype'); $this->app->toolbar->cancel('types', $this->edit ? 'Close' : 'Cancel'); $this->app->zoo->toolbarHelp(); // display view ob_start(); $this->getView()->setLayout('edittype')->display(); $output = ob_get_contents(); ob_end_clean(); // trigger edit event $this->app->event->dispatcher->notify($this->app->event->create($this->type, 'type:editdisplay', array('html' => &$output))); echo $output; } public function copyType() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $msg = ''; $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select a type to copy')); } // copy types foreach ($cid as $id) { try { // get type $type = $this->application->getType($id); // copy type $copy = $this->app->object->create('Type', array(null, $this->application)); $copy->identifier = $type->identifier.'-copy'; // set copied alias $this->app->type->setUniqueIndentifier($copy); // set unique identifier $copy->name = sprintf('%s (%s)', $type->name, JText::_('Copy')); // set copied name // give elements a new unique id $elements = array(); foreach ($type->elements as $identifier => $element) { if ($type->getElement($identifier) && $type->getElement($identifier)->getGroup() != 'Core') { $elements[$this->app->utility->generateUUID()] = $element; } else { $elements[$identifier] = $element; } } $copy->elements = $elements; // save copied type $copy->save(); // trigger copied event $this->app->event->dispatcher->notify($this->app->event->create($copy, 'type:copied', array('old_id' => $id))); $msg = JText::_('Type Copied'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::sprintf('Error Copying Type (%s).', $e)); $msg = null; break; } } $this->setRedirect($this->baseurl.'&task=types', $msg); } public function saveType() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $post = $this->app->request->get('post:', 'array', array()); $cid = $this->app->request->get('cid.0', 'string', ''); // get type $type = $this->application->getType($cid); // type is new ? if (!$type) { $type = $this->app->object->create('Type', array(null, $this->application)); } // filter identifier $post['identifier'] = $this->app->string->sluggify($post['identifier'] == '' ? $post['name'] : $post['identifier'], true); try { // set post data and save type $type->bind($post); // ensure unique identifier $this->app->type->setUniqueIndentifier($type); // save type $type->save(); // set redirect message $msg = JText::_('Type Saved'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::sprintf('Error Saving Type (%s).', $e)); $this->_task = 'apply'; $msg = null; } switch ($this->getTask()) { case 'applytype': $link = $this->baseurl.'&task=edittype&cid[]='.$type->id; break; case 'savetype': default: $link = $this->baseurl.'&task=types'; break; } $this->setRedirect($link, $msg); } public function removeType() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $msg = ''; $cid = $this->app->request->get('cid', 'array', array()); if (count($cid) < 1) { $this->app->error->raiseError(500, JText::_('Select a type to delete')); } foreach ($cid as $id) { try { // delete type $type = $this->application->getType($id); $type->delete(); // trigger after save event $this->app->event->dispatcher->notify($this->app->event->create($type, 'type:deleted')); // set redirect message $msg = JText::_('Type Deleted'); } catch (AppException $e) { // raise notice on exception $this->app->error->raiseNotice(0, JText::sprintf('Error Deleting Type (%s).', $e)); $msg = null; break; } } $this->setRedirect($this->baseurl.'&task=types', $msg); } public function editElements() { // disable menu $this->app->request->setVar('hidemainmenu', 1); // get request vars $cid = $this->app->request->get('cid.0', 'string', ''); // get type $this->type = $this->application->getType($cid); // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Type').': '.$this->type->name.' [ '.JText::_('Edit elements').' ]'); $this->app->toolbar->apply('applyelements'); $this->app->toolbar->save('saveelements'); $this->app->toolbar->cancel('types', 'Close'); $this->app->zoo->toolbarHelp(); // sort elements by group $this->elements = array(); foreach ($this->app->element->getAll() as $element) { $this->elements[$element->getGroup()][$element->getElementType()] = $element; } ksort($this->elements); foreach ($this->elements as $group => $elements) { ksort($elements); $this->elements[$group] = $elements; } // display view $this->getView()->setLayout('editElements')->display(); } public function addElement() { // get request vars $element = $this->app->request->getWord('element', 'text'); // load element $this->element = $this->app->element->create($element); $this->element->identifier = $this->app->utility->generateUUID(); // display view $this->getView()->setLayout('addElement')->display(); } public function saveElements() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $post = $this->app->request->get('post:', 'array', array()); $cid = $this->app->request->get('cid.0', 'string', ''); try { // save types elements $type = $this->application->getType($cid); // bind and save elements $type->bindElements($post)->save(); // reset related item search data $table = $this->app->table->item; $items = $table->getByType($type->id, $this->application->id); foreach ($items as $item) { $table->save($item); } $msg = JText::_('Elements Saved'); } catch (AppException $e) { $this->app->error->raiseNotice(0, JText::sprintf('Error Saving Elements (%s)', $e)); $this->_task = 'applyelements'; $msg = null; } switch ($this->getTask()) { case 'applyelements': $link = $this->baseurl.'&task=editelements&cid[]='.$type->id; break; case 'saveelements': default: $link = $this->baseurl.'&task=types'; break; } $this->setRedirect($link, $msg); } public function assignElements() { // disable menu $this->app->request->setVar('hidemainmenu', 1); // init vars $type = $this->app->request->getString('type'); $this->relative_path = urldecode($this->app->request->getVar('path')); $this->path = $this->relative_path ? JPATH_ROOT . '/' . $this->relative_path : ''; $this->layout = $this->app->request->getString('layout'); $dispatcher = JDispatcher::getInstance(); if (strpos($this->relative_path, 'plugins') === 0) { @list($_, $plugin_type, $plugin_name) = explode('/', $this->relative_path); JPluginHelper::importPlugin($plugin_type, $plugin_name); } $dispatcher->trigger('registerZOOEvents'); // get type $this->type = $this->application->getType($type); if ($this->type) { // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Type').': '.$this->type->name.' [ '.JText::_('Assign elements').': '. $this->layout .' ]'); $this->app->toolbar->apply('applyassignelements'); $this->app->toolbar->save('saveassignelements'); $this->app->toolbar->cancel('types'); $this->app->zoo->toolbarHelp(); // get renderer $renderer = $this->app->renderer->create('item')->addPath($this->path); // get positions and config $this->config = $renderer->getConfig('item')->get($this->group.'.'.$type.'.'.$this->layout); $prefix = 'item.'; if ($renderer->pathExists('item'.DIRECTORY_SEPARATOR.$type)) { $prefix .= $type.'.'; } $this->positions = $renderer->getPositions($prefix.$this->layout); // display view ob_start(); $this->getView()->setLayout('assignelements')->display(); $output = ob_get_contents(); ob_end_clean(); // trigger edit event $this->app->event->dispatcher->notify($this->app->event->create($this->type, 'type:assignelements', array('html' => &$output))); echo $output; } else { $this->app->error->raiseNotice(0, JText::sprintf('Unable to find type (%s).', $type)); $this->setRedirect($this->baseurl . '&task=types&group=' . $this->application->getGroup()); } } public function saveAssignElements() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $type = $this->app->request->getString('type'); $layout = $this->app->request->getString('layout'); $relative_path = $this->app->request->getVar('path'); $path = $relative_path ? JPATH_ROOT . '/' . urldecode($relative_path) : ''; $positions = $this->app->request->getVar('positions', array(), 'post', 'array'); // unset unassigned position unset($positions['unassigned']); // get renderer $renderer = $this->app->renderer->create('item')->addPath($path); // clean config $config = $renderer->getConfig('item'); foreach ($config as $key => $value) { $parts = explode('.', $key); if ($parts[0] == $this->group && !$this->application->getType($parts[1])) { $config->remove($key); } } // save config $config->set($this->group.'.'.$type.'.'.$layout, $positions); $renderer->saveConfig($config, $path.'/renderer/item/positions.config'); switch ($this->getTask()) { case 'applyassignelements': $link = $this->baseurl.'&task=assignelements&type='.$type.'&layout='.$layout.'&path='.$relative_path; break; default: $link = $this->baseurl.'&task=types'; break; } $this->setRedirect($link, JText::_('Elements Assigned')); } public function assignSubmission() { // disable menu $this->app->request->setVar('hidemainmenu', 1); // init vars $type = $this->app->request->getString('type'); $this->template = $this->app->request->getString('template'); $this->layout = $this->app->request->getString('layout'); // get type $this->type = $this->application->getType($type); // set toolbar items $this->app->system->application->JComponentTitle = $this->application->getToolbarTitle(JText::_('Type').': '.$this->type->name.' [ '.JText::_('Assign Submittable elements').': '. $this->layout .' ]'); $this->app->toolbar->apply('applysubmission'); $this->app->toolbar->save('savesubmission'); $this->app->toolbar->cancel('types'); $this->app->zoo->toolbarHelp(); // for template $this->path = $this->application->getPath().'/templates/'.$this->template; // get renderer $renderer = $this->app->renderer->create('submission')->addPath($this->path); // get positions and config $this->config = $renderer->getConfig('item')->get($this->group.'.'.$type.'.'.$this->layout); $prefix = 'item.'; if ($renderer->pathExists('item'.DIRECTORY_SEPARATOR.$type)) { $prefix .= $type.'.'; } $this->positions = $renderer->getPositions($prefix.$this->layout); // display view $this->getView()->setLayout('assignsubmission')->display(); } public function saveSubmission() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // init vars $type = $this->app->request->getString('type'); $template = $this->app->request->getString('template'); $layout = $this->app->request->getString('layout'); $positions = $this->app->request->getVar('positions', array(), 'post', 'array'); // unset unassigned position unset($positions['unassigned']); // for template, module $path = ''; if ($template) { $path = $this->application->getPath().'/templates/'.$template; } // get renderer $renderer = $this->app->renderer->create('submission')->addPath($path); // clean config $config = $renderer->getConfig('item'); foreach ($config as $key => $value) { $parts = explode('.', $key); if ($parts[0] == $this->group && !$this->application->getType($parts[1])) { $config->remove($key); } } // save config $config->set($this->group.'.'.$type.'.'.$layout, $positions); $renderer->saveConfig($config, $path.'/renderer/item/positions.config'); switch ($this->getTask()) { case 'applysubmission': $link = $this->baseurl.'&task=assignsubmission&type='.$type.'&layout='.$layout; $link .= $template ? '&template='.$template : null; break; default: $link = $this->baseurl.'&task=types'; break; } $this->setRedirect($link, JText::_('Submitable Elements Assigned')); } public function doExport() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); $filepath = $this->app->path->path("tmp:").'/'.$this->application->getGroup().'.zip'; $read_directory = $this->application->getPath() . '/'; $zip = $this->app->archive->open($filepath, 'zip'); $files = $this->app->path->files($this->application->getResource(), true); $files = array_map(create_function('$file', 'return "'.$read_directory.'".$file;'), $files); $zip->create($files, PCLZIP_OPT_REMOVE_PATH, $read_directory); if (is_readable($filepath) && JFile::exists($filepath)) { $this->app->filesystem->output($filepath); if (!JFile::delete($filepath)) { $this->app->error->raiseNotice(0, JText::sprintf('Unable to delete file(%s).', $filepath)); $this->setRedirect($this->baseurl.'&task=info'); } } else { $this->app->error->raiseNotice(0, JText::sprintf('Unable to create file (%s).', $filepath)); $this->setRedirect($this->baseurl.'&task=info'); } } public function checkRequirements() { $this->app->loader->register('AppRequirements', 'installation:requirements.php'); $requirements = $this->app->object->create('AppRequirements'); $requirements->checkRequirements(); $requirements->displayResults(); } public function checkModifications() { // add system.css for $this->app->document->addStylesheet("root:administrator/templates/system/css/system.css"); try { $this->results = $this->app->modification->check(); // display view $this->getView()->setLayout('modifications')->display(); } catch (AppModificationException $e) { $this->app->error->raiseNotice(0, $e); } } public function cleanModifications() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); try { $this->app->modification->clean(); $msg = JText::_('Unknown files removed.'); } catch (AppModificationException $e) { $msg = JText::_('Error cleaning ZOO.'); $this->app->error->raiseNotice(0, $e); } $route = JRoute::_($this->baseurl.'&task=checkmodifications&tmpl=component', false); $this->setRedirect($route, $msg); } public function verify() { $result = false; try { $result = $this->app->modification->verify(); } catch (AppModificationException $e) {} echo json_encode(compact('result')); } public function doBackup() { if ($result = $this->app->backup->all()) { $result = $this->app->backup->generateHeader() . $result; $size = strlen($result); while (@ob_end_clean()); header("Pragma: public"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Expires: 0"); header("Content-Transfer-Encoding: binary"); header('Content-Type: application/zip'); header('Content-Disposition: attachment;' .' filename="zoo-db-backup-'.time().'-'.(md5(implode(',', $this->app->backup->getTables()))).'.sql";' .' modification-date="'.date('r').'";' .' size='.$size.';'); header("Content-Length: ".$size); echo $result; return; } // raise error on exception $this->app->error->raiseNotice(0, JText::_('Error Creating Backup')); $this->setRedirect($this->baseurl); } public function restoreBackup() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); // get the uploaded file information $userfile = $this->app->request->getVar('backupfile', null, 'files', 'array'); try { $file = $this->app->validator->create('file', array('extension' => array('sql')))->clean($userfile); $this->app->backup->restore($file['tmp_name']); $msg = JText::_('Database backup successfully restored'); } catch (AppValidatorException $e) { $msg = ''; $this->app->error->raiseNotice(0, "Error uploading backup file. ($e) Please upload .sql files only."); } catch (RuntimeException $e) { $msg = ''; $this->app->error->raiseNotice(0, JText::sprintf("Error restoring ZOO backup. (%s)", $e->getMessage())); } $this->setRedirect($this->baseurl, $msg); } public function cleanDB() { // set toolbar items $this->app->toolbar->title('Cleaning database, please don\'t leave this page'); $this->item_count = $this->app->table->item->count(); $this->steps = (int) (11 + ($this->item_count / 10)); // display view $this->getView()->setLayout('cleandb')->display(); } public function cleanDBStep() { $step = $this->app->request->getInt('step', 0); $row = $this->app->request->getInt('row', 0); $offset = $this->app->request->getInt('offset', 0); // init vars $items_per_run = 10; $db = $this->app->database; $msg = ''; $error = ''; switch ($step) { case '1': if ($apps = $this->app->path->dirs('applications:')) { $db->query(sprintf("DELETE FROM ".ZOO_TABLE_APPLICATION." WHERE application_group NOT IN ('%s')", implode("', '", $apps))); } $msg = 'Cleaning application folders...'; break; case '2': $db->query("DELETE FROM ".ZOO_TABLE_ITEM." WHERE type = ''"); $row += $db->getAffectedRows(); $msg = 'Cleaning items of undefined type...'; break; case '3': $db->query("DELETE FROM ".ZOO_TABLE_ITEM." WHERE NOT EXISTS (SELECT id FROM ".ZOO_TABLE_APPLICATION." WHERE id = application_id)"); $row += $db->getAffectedRows(); $msg = 'Cleaning items that don\'t belong to an application...'; break; case '4': $db->query("DELETE FROM ".ZOO_TABLE_CATEGORY." WHERE NOT EXISTS (SELECT id FROM ".ZOO_TABLE_APPLICATION." WHERE id = application_id)"); $row += $db->getAffectedRows(); $msg = 'Cleaning categories that don\'t belong to an application...'; break; case '5': $db->query("DELETE FROM ".ZOO_TABLE_SUBMISSION." WHERE NOT EXISTS (SELECT id FROM ".ZOO_TABLE_APPLICATION." WHERE id = application_id)"); $row += $db->getAffectedRows(); $msg = 'Cleaning submissions that don\'t belong to an application...'; break; case '6': $db->query("DELETE FROM ".ZOO_TABLE_TAG." WHERE NOT EXISTS (SELECT id FROM ".ZOO_TABLE_ITEM." WHERE id = item_id)"); $row += $db->getAffectedRows(); $msg = 'Cleaning tags that don\'t belong to an item...'; break; case '7': $db->query("DELETE FROM ".ZOO_TABLE_COMMENT." WHERE NOT EXISTS (SELECT id FROM ".ZOO_TABLE_ITEM." WHERE id = item_id)"); $row += $db->getAffectedRows(); $msg = 'Cleaning comments that don\'t belong to an item...'; break; case '8': $db->query("DELETE FROM ".ZOO_TABLE_RATING." WHERE NOT EXISTS (SELECT id FROM ".ZOO_TABLE_ITEM." WHERE id = item_id)"); $row += $db->getAffectedRows(); $msg = 'Cleaning ratings that don\'t belong to an item...'; break; case '9': $db->query("DELETE FROM ".ZOO_TABLE_SEARCH." WHERE NOT EXISTS (SELECT id FROM ".ZOO_TABLE_ITEM." WHERE id = item_id)"); $row += $db->getAffectedRows(); $msg = 'Cleaning search values that don\'t belong to an item...'; break; case '10': $db->query("DELETE FROM ".ZOO_TABLE_CATEGORY_ITEM." WHERE category_id != 0 AND (NOT EXISTS (SELECT id FROM ".ZOO_TABLE_ITEM." WHERE id = item_id) OR NOT EXISTS (SELECT id FROM ".ZOO_TABLE_CATEGORY." WHERE id = category_id))"); $row += $db->getAffectedRows(); $msg = 'Cleaning category to item relations...'; break; case '11': // sanatize parent references $db->query("UPDATE ".ZOO_TABLE_CATEGORY." SET parent = 0 WHERE parent != 0 AND NOT EXISTS (SELECT id FROM (SELECT id FROM ".ZOO_TABLE_CATEGORY.") as t WHERE t.id = parent)"); $db->query("UPDATE ".ZOO_TABLE_COMMENT." SET parent_id = 0 WHERE parent_id != 0 AND NOT EXISTS (SELECT id FROM (SELECT id FROM ".ZOO_TABLE_CATEGORY.") as t WHERE t.id = parent_id)"); $msg = 'Cleaning category and comment parent relations...'; break; case '12': // get the item table $table = $this->app->table->item; try { $items = $table->all(array('offset' => $offset, 'limit' => $items_per_run)); if (empty($items)) { echo json_encode(array('forward' => $this->baseurl, 'message' => JText::sprintf('Cleaned database (Removed %s entries) and items search data has been updated.', $row))); return; } foreach ($items as $item) { try { $table->save($item); } catch (Exception $e) { $error = JText::sprintf("Error updating search data for item with id %s. (%s)", $item->id, $e); } } } catch (Exception $e) { $msg = ''; $error = JText::sprintf("Error cleaning database. (%s)", $e); } $msg = sprintf('Resaving items %s to %s', $offset, $offset + $items_per_run); $step--; $offset += $items_per_run; } echo json_encode(array( 'error' => $error, 'message' => $msg, 'step' => $step + ($offset / $items_per_run), 'redirect' => $this->baseurl.sprintf('&task=cleandbstep&format=raw&step=%s&row=%s&offset=%s', ++$step, $row, $offset) )); } public function hideUpdateNotification() { $this->app->update->hideUpdateNotification(); } public function disableRouteCaching() { $this->_toggleRouteCaching(false); } public function enableRouteCaching() { $this->_toggleRouteCaching(true); } public function getAlias() { $name = $this->app->request->getString('name', ''); $force_safe = $this->app->request->getBool('force_safe', false); echo json_encode($this->app->string->sluggify($name, $force_safe)); } protected function _toggleRouteCaching($state) { $this->app->set('cache_routes', $state); $this->app->component->self->save(); $this->app->route->clearCache(); $this->setRedirect($this->baseurl); } } /* Class: ManagerControllerException */ class ManagerControllerException extends AppException {}components/com_zoo/controllers/update.php000066600000002410150771655450014757 0ustar00baseurl = $this->app->link(array('controller' => $this->controller), false); } public function display($cachable = false, $urlparams = false) { // set toolbar items $this->app->toolbar->title(JText::_('ZOO Update'), $this->app->get('icon')); $this->app->zoo->toolbarHelp(); $this->app->html->_('behavior.tooltip'); if (!$this->update = $this->app->update->required()) { $this->app->system->application->redirect($this->app->link()); } $this->notifications = $this->app->update->getNotifications(); // display view $this->getView()->display(); } public function step() { // check for request forgeries $this->app->session->checkToken() or jexit('Invalid Token'); $response = $this->app->update->run(); echo json_encode($response); } } /* Class: UpdateAppControllerException */ class UpdateAppControllerException extends AppException {}components/com_zoo/README.markdown000066600000114224150771655450013126 0ustar00# ZOO # - Version: 3.1.6 - Date: March 2014 - Author: YOOtheme GmbH - Website: ## Changelog 3.1.6 # fixed missing matchHeight function Comments' Module Bubbles style 3.1.5 # updated UIkit icons markup to UIkit 2.0 3.1.4 + added zoo:initApp event # fixed mysubmissions pagination renderer # fixed CSV export of checkbox elements # fixed K2 importer 3.1.3 + added Joomla 3.2 compatibility ^ changed the feed order to publishing date # fixed update notifications in PHP 5.4+ # minor uikit theme fix # fixed size of image select box # fixed element access issue on search # fixed "show empty categories" for individual categories setting 3.1.2 # fixed problem with Publish Down Element submission not accepting "never" 3.1.1 # fixed mysql index problem 3.1.0 + added # items filter to pagination views (Joomla 3.0) + added UIkit templates to all apps # fixed user edit route in items view # fixed link element submission "open in new window" by default # fixed conflict issues with JViewLegacy and other components 3.0.13 # fixed a php notice on single submission view # fixed bug with Joomla 3.1.0 RelatedItem element on submission # fixed canonical links with Joomla 3.* 3.0.12 # fix for Joomla 3.1.0 # fixed Joomla importer 3.0.11 ^ refactored "Clean Database" function ^ updated jQuery to 1.9.1 ^ updated jQuery UI to 1.10.1 ^ updated mediaelement.js to 2.10.3 # fixed use of default values on submission (media element) # fixed issue with deleting tags # fixed issue with category/tag module showing wrong links 3.0.10 # fixed jQuery 1.9 compatibility 3.0.9 + added option to show Captchas for guests only # fixed pagination on mysubmissions view # fixed item category submission (required state) ^ moved sh404SEF plugin to separate Joomla plugin ^ updated jQuery to 1.9 ^ updated jQuery UI to 1.9.2 ^ updated mediaelement.js to 2.10.1 3.0.8 # fixed date display in items list view # fixed issue with item counting introduced in 3.0.7 3.0.7 # fixed rss feed link # fixed issue with category assignment (submission) # fixed issue with limiting related layout (Related Items Element) 3.0.6 ^ improved Google geocoding, by trying to geocode during item save + added application:configparams event (3rd party developers) # fixed "Add Item" not clickable on MySubmissions view (iOS) # fixed Smartsearch indexer (Joomla 3.0) # fixed Joomla import (trashed categories are no longer imported) # fixed Joomlamodule Element (doesn't show none published module any longer) 3.0.5 + added item:beforeSaveCategoryRelations event (3rd party developers) # fixed Select Element submission # fixed settings on GoogleMaps element # fixed issue with element position assignment 3.0.4 + added chosen.js to category select field (item/category edit view) + added Joomla textfiltering to frontend submission 3.0.3 # fixed problem with slug generation # fixed problem with deleting codemirror editor 3.0.2 + items in the item view can now be found via alias + the rating element now has an option for Googles Micro Data ^ ZOO allows for unicode slugs/aliases now # fixed Joomla 3.0 conversion related bugs # fixed problems prev/next buttons 3.0.1 ^ updated jQuery UI to 1.9 ^ updated mediaelement.js to 2.9.4 # fixed Joomla 3.0 conversion related bugs 3.0 + added "Save As Copy" button on item edit + added Joomla 3.0 compatibility - removed Joomla 1.5 compatibility 2.6.7 + added select, radio, checkbox elements to csv ex-/import # fixed imports of '0's in CSV import 2.6.6 + added option for alphanumeric sorting to item ordering + added Turkish language pack # fixed check for realpath cache size after installation 2.6.5 + added Route Caching (you can enable/disable it in the ZOO manager section) ^ updated jQuery to 1.8.1 ^ ZOO now returns 404 errors if items or categories can not be found ^ updated mediaelement.js to 2.9.3 # fixed redirect to menu item on submission # fixed "show empty categories" in several places # fixed links in comment reply notifcations, if replied from administration 2.6.4 ^ updated timepicker to 1.0.1 ^ updated jQuery UI to 1.8.23 (fixed issue with timepicker) ^ category_id will no longer be appended to url if navigating from primary category 2.6.3 + Googlemaps Element uses autocomplete now + update items via csv ^ updated jQuery to 1.8.0 ^ updated jQuery UI to 1.8.22 # fixed twitter comment avatars # fixed issue "Fatal error: Class 'systemHelper' not found in /administrator/components/com_zoo/framework/classes/app.php" 2.6.2 + added Item Previous/Next Element # fixed googlemaps css issue # fixed width problems with TinyMCE # fixed issue with tag saving on submission 2.6.1 # fixed route helper 2.6 + all apps are now responsive + you can now show/hide comments (Item Print Element) + added keepalive messages to Item/Category Edit views + you can now choose a menu item to redirect too (Submission) ^ response area is no longer shown on item print view # fixed issue with showing search results in the search component backend # mootools is loaded for recaptcha to work correctly # print button image displays correctly on Blog with Warp6 template 2.5.20 + added metadata to frontpage (Menu Settings) + limit the number of submissions per user + added param to show item count on categories (Category module) + added option to show empty categories ^ Date Element will accept more date formats now (Frontend Submission) ^ Frontpage RSS shows its own items only ^ updated mediaelement.js to 2.9.1 # fixed conflict between Widgetkit and ZOO (Media Element) 2.5.19 # fixed issue with core elements assignment 2.5.18 + added Captcha support to submissions/comments (Joomla 2.5) + primary category will be set on submissions + redirect user to login if item is not accessible ^ updated MediaElement.js to 2.8.2 ^ updated jQuery UI to 1.8.20 # fix to 404 redirect if ZOO is set as home page # fixed problem with display of Itemaccess Element and Itemstate Element # fix to "edit core elements" # fixed issue with type copying # fixed issue with setting a file value in IE9 (Download Element) 2.5.17 + added Item Edit Element ^ updated social buttons element (Google Plus One) ^ updated media element ^ updated jquery.cookie.js to the latest version ^ updated timepicker.js to version 1.0.0 ^ protocol is prepended to the link by default now (Link Element) ^ authors of spam comments won't be subscribed to items any longer ^ updated jQuery UI to 1.8.19 # removed API Key from Geocoding Requests (Googlemaps Element) # finder component now ignores unsearchable items (Smart Search) # item order priority is ignored for feed now # fixed conflict between mootools and jQuery slider (Timepicker in J2.5 now works properly again) # fixed display of googlemaps (My Submissions view) # fixed file upload submission (Image and Download Element) # fixed search bug in items default view # fixed css issue with tag submission # fixed socialbuttons element # fixed primary category selection # fixed to search ordering (J2.5) 2.5.16 + added "addmenuitems" event + added map type "Terrain" (GoogleMaps Element) + API Key will be used for Geocoding Requests too (Googlemaps Element) ^ updated jQuery to version 1.7.2 ^ updated jQuery UI to 1.8.18 ^ longitude/latitude coordinates may now contain a space (Google Maps element) # fixed type copying # fixes to checkbox element edit view css 2.5.15 + you can now hide the update notifications for current session # fixed problem with ZOO administration with open_basedir restriction in effect # fixed issue with Publish Down date on some systems (Submission) # fixes to protocoll part of url in Socialbutton and Media elements # fix to DB backup functionality 2.5.14 # download element will check against default access value now, if none is set # fixed bugs related to the field API change 2.5.13 + added option to fully hide/show categories on category/frontpage views + assign access level to core elements # editing a submission in none trusted mode will set the item to unpublished # fixed bug with submission (Documentation app) # Item Frontpage, Item Searchable and Item State elements no longer sortable # fix to Page Titles on frontpage (J2.5) # fixed css issues (Social Buttons Element) # fixed language problem with Facebook Like Button (Social Buttons Element) 2.5.12 # fixed problem with Download element introduced in 2.5.11 # fixed issue with CSV export (PHP < 5.3) 2.5.11 # fixed issue in cookbook app (full layout) # fixed bug with access level in download element + Widgetkit Element now submittable + Joomla Module Element now submittable + added CSV export + import into subcategories by separating categories through "///" (CSV) + import into existing categories by adding category alias (CSV) # fixed metadata import (Joomla) # fix to sh404SEF plugin ^ updated K2 importer to reflect latest changes ^ updated MediaElement.js to 2.6.5 # fix to Social Buttons element (IE) + you can now add an API Key (Googlemaps Element) 2.5.10 # fixed build problem with Finder plugin (SmartSearch) # fixed tag autocompletion 2.5.9 + added option to select primary category (frontend submission) + added MIME TYPE "application/iges" + added sunburst style to syntaxhighlighter (Documentation app - Choose in app template settings) + added War6 Sidebar Style (Category Module) ^ changes to renderer (Category Module) + added Finder plugin (SmartSearch) + item, category and comments save, delete and stateChanged events now trigger Joomla content plugin events (J2.5) # Fixed Joomla Exporter (J2.5) # Fixed Image Frontend Submission 2.5.8 # elements will receive new identifier on type copy + added application:installed event ^ updated German translation # fixed Norwegian translation + category submission: added param to allow for single or multiple selection ^ updated MediaElement.js to 2.6.4 # text and textarea element now show default value, without having to edit the item 2.5.7 ^ it is now possible to assign item core elements to submissions + added a few item core elements (mainly for item submissions) + beforesave event (submission) + new option to display date in Blog App + Warp 6 theme # fixed problems with page title on category view ^ submission errors are now being translated # fixed problem with Blog application if no template is selected # minor css fixes ^ update to comments module # consistent ordering of items related categories + Norwegian translation (Thanks to Yngve Rodli) # fixed bug with adding images into textarea editor (submission) (J1.7) 2.5.6 # fixed bug with twitter connect ^ cleanup of some javascripts + reintroduced the index.html files in ZOO folders (hello JED ;-) ) + updated MediaElement.js to 2.6.1 # it is now possible to change the width of the audio player 2.5.5 # fixed bug with Twitter and Facebook connect # fixed bug with changing menu item types ^ change for Joomla 2.5 compatibility + you can now import into existing categories (JSON import) ^ disallow "/" character in tags ^ improved consistency with category links # fixed a redirect on item view 2.5.4 ^ improved error message if ZOO minimum requirements are not met ^ improved consistency with item links ^ updated MediaElement.js to 2.5.0 + added tags to CSV import # fixed problems with showing comments from unpublished items (Comments module) # links in notification mails are now SEOed # fixed bug with email notifications on comments # fixed compatibility issue with Rockettheme Mission Control admin template 2.5.3 + ZOO automatically checks for updates now # fixed bug with ordering by rating element + added "toggle frontpage" button to item view # minor css fixes + added ZOO version to manager view # fixed problem with sorting by publish up date + you can now use youtube shortlinks e.g. "http://youtu.be/XYZ" (Media Element) # fixed bug with odd number of tags and outward, inward sorting (Tag module) + csv import: first category is set to primary category 2.5.2 # fixed possible cause for JLIB_APPLICATION_ERROR_COMPONENT_NOT_LOADING upon update # fixed default select options of several applications + added "Publish Up" core element (useful for displaying dates in blog) ^ updated MediaElement.js to 2.3.2 ^ updated jQuery to version 1.7.1 + added editDisplay event to type edit view # fixed problems with J1.7 import of categories having the same alias # minor css fixes in item edit view # fixed item ordering of RSS feeds 2.5.1 + added installer check for missing DB tables (J1.7) + added import of country element to csv import + readded deprecated functions for submission renderer ^ Tag view now displays tag in page title ^ updated Hungarian language files # fixed problem with installing ZOO Quickicon module with open_basedir restriction in effect 2.5 # fixed bug with form field values in submission # fixed bug with comments export # alpha index in Documentation app won't show empty categories tab ^ changed syntaxhighlighter of documentation app ^ reverted interface of elements hasvalue and render methods to version 2.4 ^ updated jQuery to version 1.7 + added ordering to "my submissions" view + added "clean database" functionality ^ merged "update search data" functionality into "clean database" + added search to mysubmissions view ^ readded separated_by params to elements xml 2.5 BETA 9 # fixed bug in sh404SEF plugin # fixed item ordering 2.5 BETA 8 # fixed bug where updating would delete custom layouts/positions # couple minor bugfixes and improvements 2.5 BETA 7 # fixed bug with category view, introduced in BETA 6 2.5 BETA 6 # fixed bug with having multiple tabs from different app instances open (administration) # items and categories won't inherit Browser Page Titles any longer # improved html validation of social buttons element 2.5 BETA 5 + added possibility to specify custom link text (Item Link element) # fixed bug with including subcategories in modules + added search by tag in items overview # fixed pagination links # fixed problems with saving options of select, radio, checkbox elements 2.5 BETA 4 + readded Socialbookmarks element + added separator "none" to textarea element # fixed importers - removed J1.6, mtree, docman importer + added SEO Pagetitle option (J1.7) ^ pagetitle of categories changed # fixed display of category metadata # fixed comments for WARP blog template # fixed csv import # fixed problems with update process (e.g. Gallery element won't loose data anymore) # fixed problems with saving options of select elements # when upgrading from 2.4 ZOO will not loose video files any more # fixed problems with media element 2.5 BETA 3 + added swf support to media element + added random item ordering # fixed bug with renaming types # fixed bug with copying types ^ updated media element 2.5 BETA 2 # fixed bug where type config would be overwritten 2.5 BETA ^ updated jQuery UI to 1.8.15 + added new WARP6 Blog template - removed ZOOtools (use Widgetkit instead) + added Social Buttons element + added Media element + added Widgetkit element ^ revamped Download element ^ revamped Image element ^ revamped Gallery element - removed Video element - removed Social Bookmarks element - removed Facebook I Like element ^ element data now being stored as JSON ^ ex-/import now uses JSON + added comments ex-/import # fixed minor issues with submission.css + new "Update Search Data" button in ZOO manager + update screen now shows changelog 2.4.17 # item slug will not change after frontend submission ^ remove path info from file upload # content plugins will be triggered on frontpage and category descriptions in Blog app # improved html validation of comments form # updated language packages # fixed typo in language files ^ updated framework 2.4.16 # fix to path handling on unix systems where root path is empty ^ updated jQuery to 1.6.4 ^ updated jQuery UI to 1.8.16 # fixed item frontpage toggle 2.4.15 # fixed params for zoosearch module (J1.7) # tags are being removed upon item deletion # added some missing language strings # fixed minor css issue (J1.7) # fixed bug with repeatable element and advanced options 2.4.14 # fixed bug with params array introduced in 2.4.13 2.4.13 # fixed SQL dump functionality + frontpage can be edited from items view now # fixed display of plugin names in layout view (J1.7) 2.4.12 + item id being passed to content plugins handling textareas # fixed bug with path helper on BSD systems + primary category now being im-/exported + name matching on item xml import # fixed problem with timezone offset in item edit view ^ renamed shortcut to shortcode plugin # enforcing nonetrusted mode for public submissions again (Joomla 1.7) # fixed pagination and filtering issues # fixed options.css for Joomla 1.7 - removed metadata "title" from item views + you can now assign metadata to categories + you can now assign individual page titles to items and categories + added import of Joomla 1.7 articles # fixed bug with display of comment dates in Joomla 1.7 2.4.11 ^ updated jQuery UI to 1.8.14 ^ updated jQuery to 1.6.2 # fixed bug with detecting superadmin priviliges on Joomla 1.6+ ^ admins won't receive email notifications, if new comments are rated as spam + added warning if cache path is unwritable ^ zoo modules now use the components language files instead of their own ^ modifications to reflect changes in Joomla 1.7 # fixed minor issue with installer # 'Add Tag' button now being translated # fixed problems with zoo uninstaller (Joomla 1.6) # fixed translation issue with some blog templates # fixed translations of validation errors + output Google Geocoding API errors (Googlemaps element) ^ updated ZOOmaps module # fixed issue with ZOO export 2.4.10 # ZOO tools load mootools again # fixed issues with sh404SEF (Joomla 1.5 and Joomla 1.6) # fixed bug with rating element (Joomla 1.6) ^ updated ZOOcomment module to 2.4.3 # fixed issue with lightbox not loading # fixed bug in slideshow.js # fixed bug with access level on csv imported items (Joomla 1.6) 2.4.9 # fixed bug introduced in 2.4.8 2.4.8 ^ changed socialbookmarks element to reflect changes made by Twitter # minor fix to ZOOs SEF behavior - mootools is not being loaded per default in the frontend anymore + new afterEdit element event ^ email notification if user edits his submission (and submission is set to unpublished again) + added comment to email notifications # fixed problem with date element submission in Joomla 1.6 # fixed minor bug with related items element ^ dates are now taking the users timezone into account # fixed problem with dates in Joomla 1.6 # fixed typo in notification mails ^ changed the elements field of item table to type LONGTEXT ^ syntaxhighlighter fetches brushes locally now (previous amazon) # fixed bug with created feed links in frontpage # fixed bug in ZOO shortcut plugin with using aliases ^ updated jQuery to 1.6.1 + added missing display options to facebook i like element # fixed typo in ZOO scroller markup 2.4.7 ^ fixed minor issue with RSS feed link ^ changed syntaxhighlighter syntax in documentation app ^ changed plugin names + added access levels for elements + added ZOOitemshortcut plugin + you can now specify title and link options in image frontend submission (trusted mode) # fixed problem with loading Joomla content modules in Joomla 1.6 # fixed problems with language files in Joomla 1.6 ^ performance improvements ^ enable Joomla plugins on textarea elements per default # as stated in the docs - if the app provides config or content params, you can now modify them (contributed by Daniele - Thanks!) # Fixed space for floated media elements (display: block) ^ Renamed CSS classes beginning with "align-" to "alignment-" (Warp6 related) ^ Added some base CSS in submission.css, comments.css and rating.css (Warp6 related) 2.4.6 # fixed bug during update # fixed bug with item submission (image, download) 2.4.5 # fixed timezone problem with publishing dates (submission) # fixed display problem with Finish Publishing date (Joomla 1.6) # fixed typo in notification emails # fixed bug with pagination link generation # fixed bug where users would have to enter a url while commenting (introduced in 2.4.4) ^ changed modal behavior according to Joomla 1.6.2 2.4.4 # fixed: you can now overwrite the elements renderer in the template/renderer folder again (now modules too) ^ pagination links: page 1 will not be included in link anymore ^ updater has been revamped + added office 2007 mime types ^ thumbnails are written to cache via Joomlas write function - removed message about unknown files after installation # applications language files are loaded whenever application is initialized in frontend ^ allow for German Umlaute in URLs # fixed bug, where directions would not show in IE8 (Googlemaps element) + make use of "default access level" for new items and submissions (Joomla 1.6) # fixed problem with storing params in ZOO tag module (Joomla 1.6) + added element:beforedisplay event # fixed gallery element (Joomla 1.6) + added frontpage to category filter on items view (contributed by Rene Jeppesen - Thanks!) # fixed translation string in rating element 2.4.3 + updated Italian language pack # fixed bug with replying to comments (administration) # fixed date position in blog noble template # fixed English module language files # fixed: you can now overwrite the elements renderer in the template/renderer folder again # fixed pagination in related items element (submission) # fixed typo in German language file # fixed problems with install.sql file # fixed editing in mysubmissions view (Joomla 1.6) + added editing of access level to submission 2.4.2 # fixed bug with object initialization (MySQL in STRICT MODE) # fixed bug with installation ^ updated install.sql script to use the ENGINE keyword (needed for newer MySQL versions) # fixed bug with counting category items (mysqli) ^ timepicker now includes seconds # fixed problem with storing params in some modules (Joomla 1.6) # corrected typo in language files # fixed redirect problem after comment state change in administration ^ empty folders are removed upon installation and modification cleanup ^ removed last static calls to JUser class # fixed bug with gallery element 2.4.1 # fixed bug with deleted Joomla users and comment system # fixed bug with module params # fixed bug with zoosearch plugin on Joomla 1.6 ^ unknown files are removed automatically upon installation (media folder is ignored) # fixed bugs in sh404sef standard plugin # fixed bug with submitting items in untrusted mode ^ updated spanish language pack (thanks Miljan) # fixed bug with download element # fixed bug with exporters (docman, k2, mtree) # fixed bug where custom elements would not get loaded 2.4 # fixed bug with relateditems element # fixed problem with RSS feeds (if 'add suffix' was enabled') # fixed javascript issues + added more element events ^ Socialbookmarks Element enabled by default now 2.4 BETA4 # fixed bug where frontpage settings would not be considered # fixed translation of timepicker script # fixed bug with rendering relateditems # fixed bug with displaying categories # canonical item links are now absolute # submission data is filtered before presented to the user in none trusted mode ^ some css modifications ^ changed size of some lightboxes in the administration # fixed mootools/jQuery conflict with timepickerscript 2.4 BETA3 # fixed several css issues # fixed display of quickicons module for Joomla 1.6.1 # fixed zoo search plugin for Joomla 1.6 + added element download event + added language strings + added timepicker functionality ^ moved remaining Javascripts to media folder # fixed bug with inserting images (submission: textarea element / no editor) # removed remaining static calls to helpers (fixes several bugs) # fixed submission handling on error ^ removed elements ordering field (fixes saving type elements) + added DB backup functionality + readded missing blog templates 2.4 BETA2 + added init events (triggered when objects are retrieved from database) + added workaround for PHP bug (mysql_fetch_object populates fields after constructor gets called) # fixed bug with rendering textarea elements (jplugins) # fixed bug with feeds not displaying # fixed bug with editing item submissions ^ performance improvements (specifically if you have items with many elements) + added ITEMID_STATE_INDEX to comments table # fixed bug with zoo menu item background-color # fixed bug where ZOO was unable to create cache file # fixed a bug with selecting files on item edit view + introduced default options for Video Element + introduced default value for JoomlaModule Element # fixed bug in facebookilike button # removed duplicate email notification parameter from Blog app 2.4 BETA + added "check for modifications" functionality + added notifications for comments and submissions + added event system ^ major framework overhaul 2.3.7 # fixed import/export of RelatedCategories Element - removed pnotify script # fixed bug with changing type identifier # fixed bug with menu item resizing 2.3.6 ^ updated jQuery UI to 1.8.10 + fixed app tabs now scale in administration area # fixed bug in comments admin area # fixed spelling bug in Italian language file 2.3.5 # fixed bug with category import (csv) # fixed problem with mysql strict mode and submissions 2.3.4 ^ updated jQuery 1.4.4 to jQuery 1.5.1 # fixed rare problem with setting data on elements # fixed bug with catgories not showing in alpha index # fixed bug with video element - incorrect size in IE (contributed by daniel.y.balsam - Thanks!) # fixed bug with category import (csv) 2.3.3 # fixed problem with replying to a comment # fixed minor bug with tag renaming ^ improved error message in pages app (category, frontpage, alphaindex, tag view) # fixed spelling bug in German language file + added zoo quick icons module (admin control panel icons) # import/export of zoo articles now stores category ordering + added collapsible categories (contributed by Miljan Aleksic - Thanks!) # fixed bug with csv import (line endings are recognized across OSs) # fix to admin category view 2.3.2 # fixed bug with selecting submission while editing menu item # fixed bug with pagination on comment, item and tag view (administration) # fixed bug with excact search in zoo search plugin ^ performance optimization with showing items on category/frontpage view ^ performance optimization in category view # fixed spelling bug in German language file # fixed bug with radio buttons on assign core elements # fixed sorting bug in Webkit browsers (Chrome/Safari) # fixed the Digg icon in socialbookmarks element ^ updated jQuery-ui to 1.8.7 2.3.1 ^ refactored function for detecting URLs in comments + added some Turkish characters to sluggify function # fixed bug, where deleting an item would cause a fatal error upon editing a related item # fixed akismet param in business app # after editing submissions in untrusted mode, they'll be unpublished again ^ if submitting too fast, form will stay populated now ^ reintroduced the "Add tag" button to item edit view # fixed bug with inserting images in IE 8 # fixed bug with download element 2.3 ^ improved performance with tags + added pagination to the tags default view # fixed typos in language files 2.3 BETA3 # minor bugfix to reordering categories # fixed alpha index special character handling # quick pulish/unpublish categories working now # fixed bug where loadmodule plugin causes error on feedview # fixed bug where expired item would be shown in modules # fixed bug with height setting in menu item configuration # fixed bug with missing submission values # fixed typos in language files # fixed bug with saving related items 2.3 BETA2 # fixed typo in language files # fixed tooltips in types view # fixed bug that prevented saving in the manager 2.3 BETA ^ migrated to jQuery 2.2.5 # fixed order of category tree in item edit view # fixed MySQL Database Error Disclosure Vulnerability # fixed bug with choosing ZOO items in menu item # fixed bug with table prefix 2.2.4 + csv import: fixed bug with name column + csv import: added gallery element ^ image element - "link to item" will use custom title if specified # fixed category item count ^ improved import/export performance + added new expo template to blog app 2.2.3 # fixed import of categories into ZOO 2.2.2 # fixed: added MIME types for IE images jpg, png # fixed import of categories into ZOO 2.2.1 ^ fixed memory leak in csv import (works with PHP 5.3 only) # fixed issue with sh404SEF and comments # fixed issue with autocompleter.request.js filename 2.2 # fixed bug with saving item/category relations on import + added mp4 to mime types in framework/file.php # fixed issue with sh404SEF # fixed default setting for item order in zoomodule.php 2.2 BETA 2 # fixed the module class suffix was being ignored in the Joomla Module element # fixed bug with item save # changed capitalization of autocompleter script + added sh404SEF Plugin # fixed bug with submission delete button under "my submissions" 2.2 BETA ^ major performance increase in several locations ^ updated all scripts to run Mootools 1.2 # fixed bug with date element in IE # fixed display bug with JCE editor 2.1.3 # fixed googlemaps csv import # fixed issues with publish up and publish down (submission) + added support for limiting feeditems (Joomla setting) 2.1.2 # fixed bug with google maps marker position # fixed bug there deleting an element from a type, would crash the corresponding submission + added support for unity3d files in download element # minor bugfix in validator script + added googlemaps element to csv import # corrected links to images in feed view # fixed bug, where google maps would not detect users preferred language for directions ^ submission: save category relations - only if not editing in none trusted mode # fixed path to files after docman import ^ on item copy, hits will be reset to zero # fixed bug with alpha index (other character - #). Now you can specify a value that's used in the URL + added default value option for Facebook like button 2.1.1 # fixed directions not showing in google maps element 2.1 # fixed bug with download element, where filesize would not be stored correctly # items in modules are ordered by their priority first now. # csv import into existing category (name match) # fixed timezone bug for date element # fixed publish up and down handling in submission # fixed bug with Facebook I like button element 2.1 RC + added publishing dates to submission (trusted mode) # fixed bug with JCE being cropped in item edit view + csv import now supports import to repeatable elements # fixed bug, where default settings for the radio button couldn't be set ^ images in the cache folder are now named FILENAME_HASH.Extension + added facebook "I like" button + added category import to CSV import (category will be newly created from category name) # fixed bug with item order in item module + added Docman Importer (latest version 1.5.8) + added Mosets Tree Importer (latest version 2.1.3) 2.1 BETA3 ^ changed facebook connect authentication to oauth + added print element + added csv import + added spam protection (users may only submit items every 5 minutes in public mode) + added canonical link to item view (no more duplicate content worries) + added new noble template to blog app # fixed bug with no slugs on adding applications # fixed bug with menu item ids and submissions 2.1 BETA2 # fixed bug with changing templates on app instance creation, while no app instance exists ^ added tag name to breadcrumb on tag view # fixed filtering items on related items during submission # fixed bug with deleting type, while there were no application instances ^ changed link generation for item and category links # "'"'s are now handled correctly in tags + some minor changes to generating slugs + added rel="nofollow" to comment author url # fixed bug on "my submissions", where type filter was lost on pagination + added some diacritic characters to alias generation + added "ELEMENT_LIBRARY=Element Library" entry to administrator language file ^ it is now possible to have textareas as element params ^ changed mime type for mp3 files # fixed bug with "sort into category" in none trusted mode + added new noble template to blog app - removed Gzip for CSS files (should be handled by Joomla template or plugin) + added error messages, if no template is chosen ^ updated language files + added application instance delete warning # social bookmarks element - twitter now includes url (Thanks to Jonathan Martin) # fixed some HTML markup validation errors + added application slug (needed on tag and alpha index view) # fixed bug in "assign elments" screen if no positions were defined ^ "."'s are no longer allowed in tags (as they cannot be escaped) 2.1 BETA + added submissions 2.0.3 # all template positions are now being saved on type slug rename and copy # fixed bug where an items tag would show, even though the publishing date was in the future # fixed bug where .flv movies would only play if set to autoplay # fixed some HTML markup validation errors ^ general performance upgrade + added new sans template to blog app + added "above title" media alignment option to the default template of the blog app ^ removed article separator if article is last in all templates of the blog app (CSS) ^ changed padding for last elements in text areas (CSS) # replaced deprecated ereg function from googlemaps helper # fixed bug with tags view and pagination # fixed bug where Joomlas email cloaking plugin would introduce a leading space to the email address + added k2 version 2.3 import support # fixed bug with chinese characters in slug + added requirements check button to administration ^ changed "READ MORE" to "READ_MORE" in all language files # removed unused helpers/menu.php file (caused problems with Advanced Module Manager) - removed needless $params in teaser layout (only documentation app) ^ moved comment rendering from layouts to item view (all apps) 2.0.2 # fixed bug with changing the capitalization in tags # fixed bug with capitalized letters in Gravatar email addresses # fixed bug with slug input # fixed bug with tags import # fixed typo in english language file # fix to K2 import # fixes to ZOO import # template positions are now being saved on type slug rename # fixes to xml class # fixed bug with saving utf-8 encoded category-, type slugs ^ sluggify now uses Joomlas string conversion # fixed bug with '/' being JPATH_ROOT # fixed problem with xpath and xmllib version # fixed path to zoo documentation in toolbar help # fixed path to tmp dir during app installation # fixed type name in relateditems element "choose item dialog" 2.0.1 + googlemaps element now renders item layout in popup # fixed bug with Twitter Authenticate and SEF turned on + added category module # fixed translation of country element # fixed language files to include googlemaps element # fixed minor css issue with category columns ^ updated item module to version 2.0.1 ^ updated search plugin to version 2.0.1 # fixed categories teaser description in cookbook app + country element is now searchable ^ changes to the applications installer, now accepts different archive types # fixed bug with rss feed item order # fixed bug with comment cookie scope # fixed minor CSS issue with comments in documentation app # fixed filtering bug for relateditems element # fixed bug with utf-8 encoding of the default.js file # fixed bug with saving utf-8 encoded item-, category-, type slugs # fixed bug with breadcrumbs (direct link to item) + added some exceptions to the application installer # fixed bug with alpha index 2.0.0 ^ changed error message for position.config not writable # fixed bug with gifs in imagethumbnail # fixed bug with removing last tag from item # fixed bugs with editing tags on item edit in browsers with webkit engine 2.0.0 RC 2 # fixed breadcrumbs in item view # fixed bug with comment login cookie ^ added check script to installation process # fixed bug with exception class name # fixed comment filters in backend # fixed bug with special character in app name $ updated language files # fixed capital characters in position names # fixed option parameter in element links ^ relateditems ordered by default are now ordered as ordered in item view 2.0.0 RC # fixed relateditem.js # try to set timelimit in installer 2.0.0 BETA 4 # fixed bug with item copy, if no item is selected # fixed bug with install script # fixed bug with image element link # fixed bug with related items import # fixed bug with tag import # special characters in textarea and text control # fixed relateditems delete 2.0.0 BETA 3 # fixed "add options" bug in edit elements view # fixed parameter settings in ZOO administration panel ^ updated addthis element # fixed pagination on frontpage layout in SEO mode # fixed link in item module # fixed link in image element # fixed generated link through menu_item parameter in module + added update functionality to ZOO installer # fixed links to ZOO in rss feed ^ changed editor handling in ZOO administration panel ^ if menuitem is direct link to item, the category won't be added to breadcrump # moved applications group field from params to database field 2.0.0 BETA 2 + added support for unicode characters (cyrillic, arabic, ...) in slug + added application wide use of tinyMCE editors in Joomla administration panel + added comment author caching # PHP 4 warning now functions as expected # use of htmlentities before output to text and textarea fields ^ merged commentauthor classes into single file # vertical tabs are being filtered from CData areas in xml # image element: added file exist check # bugfixes to import/export # fixed some tooltips in Joomla administration panel # bugfixes to install application # bugfixes to comments # bugfix in type delete 2.0.0 BETA + Initial Release * -> Security Fix # -> Bug Fix $ -> Language fix or change + -> Addition ^ -> Change - -> Removed ! -> Note components/com_zoo/libraries/twitter/OAuth.php000066600000063540150771655450015640 0ustar00key = $key; $this->secret = $secret; $this->callback_url = $callback_url; } function __toString() { return "OAuthConsumer[key=$this->key,secret=$this->secret]"; } } class OAuthToken { // access tokens and request tokens public $key; public $secret; /** * key = the token * secret = the token secret */ function __construct($key, $secret) { $this->key = $key; $this->secret = $secret; } /** * generates the basic string serialization of a token that a server * would respond to request_token and access_token calls with */ function to_string() { return "oauth_token=" . OAuthUtil::urlencode_rfc3986($this->key) . "&oauth_token_secret=" . OAuthUtil::urlencode_rfc3986($this->secret); } function __toString() { return $this->to_string(); } } /** * A class for implementing a Signature Method * See section 9 ("Signing Requests") in the spec */ abstract class OAuthSignatureMethod { /** * Needs to return the name of the Signature Method (ie HMAC-SHA1) * @return string */ abstract public function get_name(); /** * Build up the signature * NOTE: The output of this function MUST NOT be urlencoded. * the encoding is handled in OAuthRequest when the final * request is serialized * @param OAuthRequest $request * @param OAuthConsumer $consumer * @param OAuthToken $token * @return string */ abstract public function build_signature($request, $consumer, $token); /** * Verifies that a given signature is correct * @param OAuthRequest $request * @param OAuthConsumer $consumer * @param OAuthToken $token * @param string $signature * @return bool */ public function check_signature($request, $consumer, $token, $signature) { $built = $this->build_signature($request, $consumer, $token); return $built == $signature; } } /** * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104] * where the Signature Base String is the text and the key is the concatenated values (each first * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&' * character (ASCII code 38) even if empty. * - Chapter 9.2 ("HMAC-SHA1") */ class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod { function get_name() { return "HMAC-SHA1"; } public function build_signature($request, $consumer, $token) { $base_string = $request->get_signature_base_string(); $request->base_string = $base_string; $key_parts = array( $consumer->secret, ($token) ? $token->secret : "" ); $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); $key = implode('&', $key_parts); return base64_encode(hash_hmac('sha1', $base_string, $key, true)); } } /** * The PLAINTEXT method does not provide any security protection and SHOULD only be used * over a secure channel such as HTTPS. It does not use the Signature Base String. * - Chapter 9.4 ("PLAINTEXT") */ class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod { public function get_name() { return "PLAINTEXT"; } /** * oauth_signature is set to the concatenated encoded values of the Consumer Secret and * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is * empty. The result MUST be encoded again. * - Chapter 9.4.1 ("Generating Signatures") * * Please note that the second encoding MUST NOT happen in the SignatureMethod, as * OAuthRequest handles this! */ public function build_signature($request, $consumer, $token) { $key_parts = array( $consumer->secret, ($token) ? $token->secret : "" ); $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); $key = implode('&', $key_parts); $request->base_string = $key; return $key; } } /** * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a * verified way to the Service Provider, in a manner which is beyond the scope of this * specification. * - Chapter 9.3 ("RSA-SHA1") */ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod { public function get_name() { return "RSA-SHA1"; } // Up to the SP to implement this lookup of keys. Possible ideas are: // (1) do a lookup in a table of trusted certs keyed off of consumer // (2) fetch via http using a url provided by the requester // (3) some sort of specific discovery code based on request // // Either way should return a string representation of the certificate protected abstract function fetch_public_cert(&$request); // Up to the SP to implement this lookup of keys. Possible ideas are: // (1) do a lookup in a table of trusted certs keyed off of consumer // // Either way should return a string representation of the certificate protected abstract function fetch_private_cert(&$request); public function build_signature($request, $consumer, $token) { $base_string = $request->get_signature_base_string(); $request->base_string = $base_string; // Fetch the private key cert based on the request $cert = $this->fetch_private_cert($request); // Pull the private key ID from the certificate $privatekeyid = openssl_get_privatekey($cert); // Sign using the key $ok = openssl_sign($base_string, $signature, $privatekeyid); // Release the key resource openssl_free_key($privatekeyid); return base64_encode($signature); } public function check_signature($request, $consumer, $token, $signature) { $decoded_sig = base64_decode($signature); $base_string = $request->get_signature_base_string(); // Fetch the public key cert based on the request $cert = $this->fetch_public_cert($request); // Pull the public key ID from the certificate $publickeyid = openssl_get_publickey($cert); // Check the computed signature against the one passed in the query $ok = openssl_verify($base_string, $decoded_sig, $publickeyid); // Release the key resource openssl_free_key($publickeyid); return $ok == 1; } } class OAuthRequest { private $parameters; private $http_method; private $http_url; // for debug purposes public $base_string; public static $version = '1.0'; public static $POST_INPUT = 'php://input'; function __construct($http_method, $http_url, $parameters=NULL) { @$parameters or $parameters = array(); $parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters); $this->parameters = $parameters; $this->http_method = $http_method; $this->http_url = $http_url; } /** * attempt to build up a request from what was passed to the server */ public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) { $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") ? 'http' : 'https'; @$http_url or $http_url = $scheme . '://' . $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI']; @$http_method or $http_method = $_SERVER['REQUEST_METHOD']; // We weren't handed any parameters, so let's find the ones relevant to // this request. // If you run XML-RPC or similar you should use this to provide your own // parsed parameter-list if (!$parameters) { // Find request headers $request_headers = OAuthUtil::get_headers(); // Parse the query-string to find GET parameters $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']); // It's a POST request of the proper content-type, so parse POST // parameters and add those overriding any duplicates from GET if ($http_method == "POST" && @strstr($request_headers["Content-Type"], "application/x-www-form-urlencoded") ) { $post_data = OAuthUtil::parse_parameters( file_get_contents(self::$POST_INPUT) ); $parameters = array_merge($parameters, $post_data); } // We have a Authorization-header with OAuth data. Parse the header // and add those overriding any duplicates from GET or POST if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") { $header_parameters = OAuthUtil::split_header( $request_headers['Authorization'] ); $parameters = array_merge($parameters, $header_parameters); } } return new OAuthRequest($http_method, $http_url, $parameters); } /** * pretty much a helper function to set up the request */ public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) { @$parameters or $parameters = array(); $defaults = array("oauth_version" => OAuthRequest::$version, "oauth_nonce" => OAuthRequest::generate_nonce(), "oauth_timestamp" => OAuthRequest::generate_timestamp(), "oauth_consumer_key" => $consumer->key); if ($token) $defaults['oauth_token'] = $token->key; $parameters = array_merge($defaults, $parameters); return new OAuthRequest($http_method, $http_url, $parameters); } public function set_parameter($name, $value, $allow_duplicates = true) { if ($allow_duplicates && isset($this->parameters[$name])) { // We have already added parameter(s) with this name, so add to the list if (is_scalar($this->parameters[$name])) { // This is the first duplicate, so transform scalar (string) // into an array so we can add the duplicates $this->parameters[$name] = array($this->parameters[$name]); } $this->parameters[$name][] = $value; } else { $this->parameters[$name] = $value; } } public function get_parameter($name) { return isset($this->parameters[$name]) ? $this->parameters[$name] : null; } public function get_parameters() { return $this->parameters; } public function unset_parameter($name) { unset($this->parameters[$name]); } /** * The request parameters, sorted and concatenated into a normalized string. * @return string */ public function get_signable_parameters() { // Grab all parameters $params = $this->parameters; // Remove oauth_signature if present // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.") if (isset($params['oauth_signature'])) { unset($params['oauth_signature']); } return OAuthUtil::build_http_query($params); } /** * Returns the base string of this request * * The base string defined as the method, the url * and the parameters (normalized), each urlencoded * and the concated with &. */ public function get_signature_base_string() { $parts = array( $this->get_normalized_http_method(), $this->get_normalized_http_url(), $this->get_signable_parameters() ); $parts = OAuthUtil::urlencode_rfc3986($parts); return implode('&', $parts); } /** * just uppercases the http method */ public function get_normalized_http_method() { return strtoupper($this->http_method); } /** * parses the url and rebuilds it to be * scheme://host/path */ public function get_normalized_http_url() { $parts = parse_url($this->http_url); $port = @$parts['port']; $scheme = $parts['scheme']; $host = $parts['host']; $path = @$parts['path']; $port or $port = ($scheme == 'https') ? '443' : '80'; if (($scheme == 'https' && $port != '443') || ($scheme == 'http' && $port != '80')) { $host = "$host:$port"; } return "$scheme://$host$path"; } /** * builds a url usable for a GET request */ public function to_url() { $post_data = $this->to_postdata(); $out = $this->get_normalized_http_url(); if ($post_data) { $out .= '?'.$post_data; } return $out; } /** * builds the data one would send in a POST request */ public function to_postdata() { return OAuthUtil::build_http_query($this->parameters); } /** * builds the Authorization: header */ public function to_header($realm=null) { $first = true; if ($realm) { $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"'; $first = false; } else $out = 'Authorization: OAuth'; $total = array(); foreach ($this->parameters as $k => $v) { if (substr($k, 0, 5) != "oauth") continue; if (is_array($v)) { throw new OAuthException('Arrays not supported in headers'); } $out .= ($first) ? ' ' : ','; $out .= OAuthUtil::urlencode_rfc3986($k) . '="' . OAuthUtil::urlencode_rfc3986($v) . '"'; $first = false; } return $out; } public function __toString() { return $this->to_url(); } public function sign_request($signature_method, $consumer, $token) { $this->set_parameter( "oauth_signature_method", $signature_method->get_name(), false ); $signature = $this->build_signature($signature_method, $consumer, $token); $this->set_parameter("oauth_signature", $signature, false); } public function build_signature($signature_method, $consumer, $token) { $signature = $signature_method->build_signature($this, $consumer, $token); return $signature; } /** * util function: current timestamp */ private static function generate_timestamp() { return time(); } /** * util function: current nonce */ private static function generate_nonce() { $mt = microtime(); $rand = mt_rand(); return md5($mt . $rand); // md5s look nicer than numbers } } class OAuthServer { protected $timestamp_threshold = 300; // in seconds, five minutes protected $version = '1.0'; // hi blaine protected $signature_methods = array(); protected $data_store; function __construct($data_store) { $this->data_store = $data_store; } public function add_signature_method($signature_method) { $this->signature_methods[$signature_method->get_name()] = $signature_method; } // high level functions /** * process a request_token request * returns the request token on success */ public function fetch_request_token(&$request) { $this->get_version($request); $consumer = $this->get_consumer($request); // no token required for the initial token request $token = NULL; $this->check_signature($request, $consumer, $token); // Rev A change $callback = $request->get_parameter('oauth_callback'); $new_token = $this->data_store->new_request_token($consumer, $callback); return $new_token; } /** * process an access_token request * returns the access token on success */ public function fetch_access_token(&$request) { $this->get_version($request); $consumer = $this->get_consumer($request); // requires authorized request token $token = $this->get_token($request, $consumer, "request"); $this->check_signature($request, $consumer, $token); // Rev A change $verifier = $request->get_parameter('oauth_verifier'); $new_token = $this->data_store->new_access_token($token, $consumer, $verifier); return $new_token; } /** * verify an api call, checks all the parameters */ public function verify_request(&$request) { $this->get_version($request); $consumer = $this->get_consumer($request); $token = $this->get_token($request, $consumer, "access"); $this->check_signature($request, $consumer, $token); return array($consumer, $token); } // Internals from here /** * version 1 */ private function get_version(&$request) { $version = $request->get_parameter("oauth_version"); if (!$version) { // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present. // Chapter 7.0 ("Accessing Protected Ressources") $version = '1.0'; } if ($version !== $this->version) { throw new OAuthException("OAuth version '$version' not supported"); } return $version; } /** * figure out the signature with some defaults */ private function get_signature_method(&$request) { $signature_method = @$request->get_parameter("oauth_signature_method"); if (!$signature_method) { // According to chapter 7 ("Accessing Protected Ressources") the signature-method // parameter is required, and we can't just fallback to PLAINTEXT throw new OAuthException('No signature method parameter. This parameter is required'); } if (!in_array($signature_method, array_keys($this->signature_methods))) { throw new OAuthException( "Signature method '$signature_method' not supported " . "try one of the following: " . implode(", ", array_keys($this->signature_methods)) ); } return $this->signature_methods[$signature_method]; } /** * try to find the consumer for the provided request's consumer key */ private function get_consumer(&$request) { $consumer_key = @$request->get_parameter("oauth_consumer_key"); if (!$consumer_key) { throw new OAuthException("Invalid consumer key"); } $consumer = $this->data_store->lookup_consumer($consumer_key); if (!$consumer) { throw new OAuthException("Invalid consumer"); } return $consumer; } /** * try to find the token for the provided request's token key */ private function get_token(&$request, $consumer, $token_type="access") { $token_field = @$request->get_parameter('oauth_token'); $token = $this->data_store->lookup_token( $consumer, $token_type, $token_field ); if (!$token) { throw new OAuthException("Invalid $token_type token: $token_field"); } return $token; } /** * all-in-one function to check the signature on a request * should guess the signature method appropriately */ private function check_signature(&$request, $consumer, $token) { // this should probably be in a different method $timestamp = @$request->get_parameter('oauth_timestamp'); $nonce = @$request->get_parameter('oauth_nonce'); $this->check_timestamp($timestamp); $this->check_nonce($consumer, $token, $nonce, $timestamp); $signature_method = $this->get_signature_method($request); $signature = $request->get_parameter('oauth_signature'); $valid_sig = $signature_method->check_signature( $request, $consumer, $token, $signature ); if (!$valid_sig) { throw new OAuthException("Invalid signature"); } } /** * check that the timestamp is new enough */ private function check_timestamp($timestamp) { if( ! $timestamp ) throw new OAuthException( 'Missing timestamp parameter. The parameter is required' ); // verify that timestamp is recentish $now = time(); if (abs($now - $timestamp) > $this->timestamp_threshold) { throw new OAuthException( "Expired timestamp, yours $timestamp, ours $now" ); } } /** * check that the nonce is not repeated */ private function check_nonce($consumer, $token, $nonce, $timestamp) { if( ! $nonce ) throw new OAuthException( 'Missing nonce parameter. The parameter is required' ); // verify that the nonce is uniqueish $found = $this->data_store->lookup_nonce( $consumer, $token, $nonce, $timestamp ); if ($found) { throw new OAuthException("Nonce already used: $nonce"); } } } class OAuthDataStore { function lookup_consumer($consumer_key) { // implement me } function lookup_token($consumer, $token_type, $token) { // implement me } function lookup_nonce($consumer, $token, $nonce, $timestamp) { // implement me } function new_request_token($consumer, $callback = null) { // return a new token attached to this consumer } function new_access_token($token, $consumer, $verifier = null) { // return a new access token attached to this consumer // for the user associated with this token if the request token // is authorized // should also invalidate the request token } } class OAuthUtil { public static function urlencode_rfc3986($input) { if (is_array($input)) { return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input); } else if (is_scalar($input)) { return str_replace( '+', ' ', str_replace('%7E', '~', rawurlencode($input)) ); } else { return ''; } } // This decode function isn't taking into consideration the above // modifications to the encoding process. However, this method doesn't // seem to be used anywhere so leaving it as is. public static function urldecode_rfc3986($string) { return urldecode($string); } // Utility function for turning the Authorization: header into // parameters, has to do some unescaping // Can filter out any non-oauth parameters if needed (default behaviour) public static function split_header($header, $only_allow_oauth_parameters = true) { $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/'; $offset = 0; $params = array(); while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) { $match = $matches[0]; $header_name = $matches[2][0]; $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0]; if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) { $params[$header_name] = OAuthUtil::urldecode_rfc3986($header_content); } $offset = $match[1] + strlen($match[0]); } if (isset($params['realm'])) { unset($params['realm']); } return $params; } // helper to try to sort out headers for people who aren't running apache public static function get_headers() { if (function_exists('apache_request_headers')) { // we need this to get the actual Authorization: header // because apache tends to tell us it doesn't exist $headers = apache_request_headers(); // sanitize the output of apache_request_headers because // we always want the keys to be Cased-Like-This and arh() // returns the headers in the same case as they are in the // request $out = array(); foreach ($headers AS $key => $value) { $key = str_replace( " ", "-", ucwords(strtolower(str_replace("-", " ", $key))) ); $out[$key] = $value; } } else { // otherwise we don't have apache and are just going to have to hope // that $_SERVER actually contains what we need $out = array(); if( isset($_SERVER['CONTENT_TYPE']) ) $out['Content-Type'] = $_SERVER['CONTENT_TYPE']; if( isset($_ENV['CONTENT_TYPE']) ) $out['Content-Type'] = $_ENV['CONTENT_TYPE']; foreach ($_SERVER as $key => $value) { if (substr($key, 0, 5) == "HTTP_") { // this is chaos, basically it is just there to capitalize the first // letter of every word that is not an initial HTTP and strip HTTP // code from przemek $key = str_replace( " ", "-", ucwords(strtolower(str_replace("_", " ", substr($key, 5)))) ); $out[$key] = $value; } } } return $out; } // This function takes a input like a=b&a=c&d=e and returns the parsed // parameters like this // array('a' => array('b','c'), 'd' => 'e') public static function parse_parameters( $input ) { if (!isset($input) || !$input) return array(); $pairs = explode('&', $input); $parsed_parameters = array(); foreach ($pairs as $pair) { $split = explode('=', $pair, 2); $parameter = OAuthUtil::urldecode_rfc3986($split[0]); $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : ''; if (isset($parsed_parameters[$parameter])) { // We have already recieved parameter(s) with this name, so add to the list // of parameters with this name if (is_scalar($parsed_parameters[$parameter])) { // This is the first duplicate, so transform scalar (string) into an array // so we can add the duplicates $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]); } $parsed_parameters[$parameter][] = $value; } else { $parsed_parameters[$parameter] = $value; } } return $parsed_parameters; } public static function build_http_query($params) { if (!$params) return ''; // Urlencode both keys and values $keys = OAuthUtil::urlencode_rfc3986(array_keys($params)); $values = OAuthUtil::urlencode_rfc3986(array_values($params)); $params = array_combine($keys, $values); // Parameters are sorted by name, using lexicographical byte value ordering. // Ref: Spec: 9.1.1 (1) uksort($params, 'strcmp'); $pairs = array(); foreach ($params as $parameter => $value) { if (is_array($value)) { // If two or more parameters share the same name, they are sorted by their value // Ref: Spec: 9.1.1 (1) natsort($value); foreach ($value as $duplicate_value) { $pairs[] = $parameter . '=' . $duplicate_value; } } else { $pairs[] = $parameter . '=' . $value; } } // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61) // Each name-value pair is separated by an '&' character (ASCII code 38) return implode('&', $pairs); } } components/com_zoo/libraries/twitter/twitteroauth.php000066600000017104150771655450017356 0ustar00http_status; } function lastAPICall() { return $this->last_api_call; } /** * construct TwitterOAuth object */ function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) { $this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1(); $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret); if (!empty($oauth_token) && !empty($oauth_token_secret)) { $this->token = new OAuthConsumer($oauth_token, $oauth_token_secret); } else { $this->token = NULL; } } /** * Get a request_token from Twitter * * @returns a key/value array containing oauth_token and oauth_token_secret */ function getRequestToken($oauth_callback = NULL) { $parameters = array(); if (!empty($oauth_callback)) { $parameters['oauth_callback'] = $oauth_callback; } $request = $this->oAuthRequest($this->requestTokenURL(), 'GET', $parameters); $token = OAuthUtil::parse_parameters($request); $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); return $token; } /** * Get the authorize URL * * @returns a string */ function getAuthorizeURL($token, $sign_in_with_twitter = TRUE) { if (is_array($token)) { $token = $token['oauth_token']; } if (empty($sign_in_with_twitter)) { return $this->authorizeURL() . "?oauth_token={$token}"; } else { return $this->authenticateURL() . "?oauth_token={$token}"; } } /** * Exchange request token and secret for an access token and * secret, to sign API calls. * * @returns array("oauth_token" => "the-access-token", * "oauth_token_secret" => "the-access-secret", * "user_id" => "9436992", * "screen_name" => "abraham") */ function getAccessToken($oauth_verifier = FALSE) { $parameters = array(); if (!empty($oauth_verifier)) { $parameters['oauth_verifier'] = $oauth_verifier; } $request = $this->oAuthRequest($this->accessTokenURL(), 'GET', $parameters); $token = OAuthUtil::parse_parameters($request); $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); return $token; } /** * One time exchange of username and password for access token and secret. * * @returns array("oauth_token" => "the-access-token", * "oauth_token_secret" => "the-access-secret", * "user_id" => "9436992", * "screen_name" => "abraham", * "x_auth_expires" => "0") */ function getXAuthToken($username, $password) { $parameters = array(); $parameters['x_auth_username'] = $username; $parameters['x_auth_password'] = $password; $parameters['x_auth_mode'] = 'client_auth'; $request = $this->oAuthRequest($this->accessTokenURL(), 'POST', $parameters); $token = OAuthUtil::parse_parameters($request); $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); return $token; } /** * GET wrapper for oAuthRequest. */ function get($url, $parameters = array()) { $response = $this->oAuthRequest($url, 'GET', $parameters); if ($this->format === 'json' && $this->decode_json) { return json_decode($response); } return $response; } /** * POST wrapper for oAuthRequest. */ function post($url, $parameters = array()) { $response = $this->oAuthRequest($url, 'POST', $parameters); if ($this->format === 'json' && $this->decode_json) { return json_decode($response); } return $response; } /** * DELETE wrapper for oAuthReqeust. */ function delete($url, $parameters = array()) { $response = $this->oAuthRequest($url, 'DELETE', $parameters); if ($this->format === 'json' && $this->decode_json) { return json_decode($response); } return $response; } /** * Format and sign an OAuth / API request */ function oAuthRequest($url, $method, $parameters) { if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0) { $url = "{$this->host}{$url}.{$this->format}"; } $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters); $request->sign_request($this->sha1_method, $this->consumer, $this->token); switch ($method) { case 'GET': return $this->http($request->to_url(), 'GET'); default: return $this->http($request->get_normalized_http_url(), $method, $request->to_postdata()); } } /** * Make an HTTP request * * @return API results */ function http($url, $method, $postfields = NULL) { $this->http_info = array(); $ci = curl_init(); /* Curl settings */ curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent); curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout); curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout); curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:')); curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer); curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader')); curl_setopt($ci, CURLOPT_HEADER, FALSE); switch ($method) { case 'POST': curl_setopt($ci, CURLOPT_POST, TRUE); if (!empty($postfields)) { curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields); } break; case 'DELETE': curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE'); if (!empty($postfields)) { $url = "{$url}?{$postfields}"; } } curl_setopt($ci, CURLOPT_URL, $url); $response = curl_exec($ci); $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE); $this->http_info = array_merge($this->http_info, curl_getinfo($ci)); $this->url = $url; curl_close ($ci); return $response; } /** * Get the header info to store. */ function getHeader($ch, $header) { $i = strpos($header, ':'); if (!empty($i)) { $key = str_replace('-', '_', strtolower(substr($header, 0, $i))); $value = trim(substr($header, $i + 2)); $this->http_header[$key] = $value; } return strlen($header); } }components/com_zoo/libraries/twitter/index.html000066600000000036150771655450016073 0ustar00components/com_zoo/libraries/akismet/index.html000066600000000036150771655450016026 0ustar00components/com_zoo/libraries/akismet/akismet.php000066600000027632150771655450016212 0ustar00Usage: * * $akismet = new Akismet('http://www.example.com/blog/', 'aoeu1aoue'); * $akismet->setCommentAuthor($name); * $akismet->setCommentAuthorEmail($email); * $akismet->setCommentAuthorURL($url); * $akismet->setCommentContent($comment); * $akismet->setPermalink('http://www.example.com/blog/alex/someurl/'); * if($akismet->isCommentSpam()) * // store the comment but mark it as spam (in case of a mis-diagnosis) * else * // store the comment normally * * * Optionally you may wish to check if your WordPress API key is valid as in the example below. * * * $akismet = new Akismet('http://www.example.com/blog/', 'aoeu1aoue'); * * if ($akismet->isKeyValid()) { * // api key is okay * } else { * // api key is invalid * } * * * @package akismet * @name Akismet * @version 0.4 * @author Alex Potsides * @link http://www.achingbrain.net/ */ class Akismet { private $version = '0.4'; private $wordPressAPIKey; private $blogURL; private $comment; private $apiPort; private $akismetServer; private $akismetVersion; // This prevents some potentially sensitive information from being sent accross the wire. private $ignore = array('HTTP_COOKIE', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED_HOST', 'HTTP_MAX_FORWARDS', 'HTTP_X_FORWARDED_SERVER', 'REDIRECT_STATUS', 'SERVER_PORT', 'PATH', 'DOCUMENT_ROOT', 'SERVER_ADMIN', 'QUERY_STRING', 'PHP_SELF' ); /** * @param string $blogURL The URL of your blog. * @param string $wordPressAPIKey WordPress API key. */ public function __construct($blogURL, $wordPressAPIKey) { $this->blogURL = $blogURL; $this->wordPressAPIKey = $wordPressAPIKey; // Set some default values $this->apiPort = 80; $this->akismetServer = 'rest.akismet.com'; $this->akismetVersion = '1.1'; // Start to populate the comment data $this->comment['blog'] = $blogURL; $this->comment['user_agent'] = $_SERVER['HTTP_USER_AGENT']; if (isset($_SERVER['HTTP_REFERER'])) { $this->comment['referrer'] = $_SERVER['HTTP_REFERER']; } /* * This is necessary if the server PHP5 is running on has been set up to run PHP4 and * PHP5 concurently and is actually running through a separate proxy al a these instructions: * http://www.schlitt.info/applications/blog/archives/83_How_to_run_PHP4_and_PHP_5_parallel.html * and http://wiki.coggeshall.org/37.html * Otherwise the user_ip appears as the IP address of the PHP4 server passing the requests to the * PHP5 one... */ $this->comment['user_ip'] = $_SERVER['REMOTE_ADDR'] != getenv('SERVER_ADDR') ? $_SERVER['REMOTE_ADDR'] : getenv('HTTP_X_FORWARDED_FOR'); } /** * Makes a request to the Akismet service to see if the API key passed to the constructor is valid. * * Use this method if you suspect your API key is invalid. * * @return bool True is if the key is valid, false if not. */ public function isKeyValid() { // Check to see if the key is valid $response = $this->sendRequest('key=' . $this->wordPressAPIKey . '&blog=' . $this->blogURL, $this->akismetServer, '/' . $this->akismetVersion . '/verify-key'); return $response[1] == 'valid'; } // makes a request to the Akismet service private function sendRequest($request, $host, $path) { $http_request = "POST " . $path . " HTTP/1.0\r\n"; $http_request .= "Host: " . $host . "\r\n"; $http_request .= "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n"; $http_request .= "Content-Length: " . strlen($request) . "\r\n"; $http_request .= "User-Agent: Akismet PHP5 Class " . $this->version . " | Akismet/1.11\r\n"; $http_request .= "\r\n"; $http_request .= $request; $socketWriteRead = new SocketWriteRead($host, $this->apiPort, $http_request); $socketWriteRead->send(); return explode("\r\n\r\n", $socketWriteRead->getResponse(), 2); } // Formats the data for transmission private function getQueryString() { foreach ($_SERVER as $key => $value) { if (!in_array($key, $this->ignore)) { if ($key == 'REMOTE_ADDR') { $this->comment[$key] = $this->comment['user_ip']; } else { $this->comment[$key] = $value; } } } $query_string = ''; foreach ($this->comment as $key => $data) { if (!is_array($data)) { $query_string .= $key . '=' . urlencode(stripslashes($data)) . '&'; } } return $query_string; } /** * Tests for spam. * * Uses the web service provided by {@link http://www.akismet.com Akismet} to see whether or not the submitted comment is spam. Returns a boolean value. * * @return bool True if the comment is spam, false if not * @throws Will throw an exception if the API key passed to the constructor is invalid. */ public function isCommentSpam() { $response = $this->sendRequest($this->getQueryString(), $this->wordPressAPIKey . '.rest.akismet.com', '/' . $this->akismetVersion . '/comment-check'); if ($response[1] == 'invalid' && !$this->isKeyValid()) { throw new exception('The Wordpress API key passed to the Akismet constructor is invalid. Please obtain a valid one from http://wordpress.com/api-keys/'); } return ($response[1] == 'true'); } /** * Submit spam that is incorrectly tagged as ham. * * Using this function will make you a good citizen as it helps Akismet to learn from its mistakes. This will improve the service for everybody. */ public function submitSpam() { $this->sendRequest($this->getQueryString(), $this->wordPressAPIKey . '.' . $this->akismetServer, '/' . $this->akismetVersion . '/submit-spam'); } /** * Submit ham that is incorrectly tagged as spam. * * Using this function will make you a good citizen as it helps Akismet to learn from its mistakes. This will improve the service for everybody. */ public function submitHam() { $this->sendRequest($this->getQueryString(), $this->wordPressAPIKey . '.' . $this->akismetServer, '/' . $this->akismetVersion . '/submit-ham'); } /** * To override the user IP address when submitting spam/ham later on * * @param string $userip An IP address. Optional. */ public function setUserIP($userip) { $this->comment['user_ip'] = $userip; } /** * To override the referring page when submitting spam/ham later on * * @param string $referrer The referring page. Optional. */ public function setReferrer($referrer) { $this->comment['referrer'] = $referrer; } /** * A permanent URL referencing the blog post the comment was submitted to. * * @param string $permalink The URL. Optional. */ public function setPermalink($permalink) { $this->comment['permalink'] = $permalink; } /** * The type of comment being submitted. * * May be blank, comment, trackback, pingback, or a made up value like "registration" or "wiki". */ public function setCommentType($commentType) { $this->comment['comment_type'] = $commentType; } /** * The name that the author submitted with the comment. */ public function setCommentAuthor($commentAuthor) { $this->comment['comment_author'] = $commentAuthor; } /** * The email address that the author submitted with the comment. * * The address is assumed to be valid. */ public function setCommentAuthorEmail($authorEmail) { $this->comment['comment_author_email'] = $authorEmail; } /** * The URL that the author submitted with the comment. */ public function setCommentAuthorURL($authorURL) { $this->comment['comment_author_url'] = $authorURL; } /** * The comment's body text. */ public function setCommentContent($commentBody) { $this->comment['comment_content'] = $commentBody; } /** * Defaults to 80 */ public function setAPIPort($apiPort) { $this->apiPort = $apiPort; } /** * Defaults to rest.akismet.com */ public function setAkismetServer($akismetServer) { $this->akismetServer = $akismetServer; } /** * Defaults to '1.1' */ public function setAkismetVersion($akismetVersion) { $this->akismetVersion = $akismetVersion; } } /** * Utility class used by Akismet * * This class is used by Akismet to do the actual sending and receiving of data. It opens a connection to a remote host, sends some data and the reads the response and makes it available to the calling program. * * The code that makes up this class originates in the Akismet WordPress plugin, which is {@link http://akismet.com/download/ available on the Akismet website}. * * N.B. It is not necessary to call this class directly to use the Akismet class. This is included here mainly out of a sense of completeness. * * @package akismet * @name SocketWriteRead * @version 0.1 * @author Alex Potsides * @link http://www.achingbrain.net/ */ class SocketWriteRead { private $host; private $port; private $request; private $response; private $responseLength; private $errorNumber; private $errorString; /** * @param string $host The host to send/receive data. * @param int $port The port on the remote host. * @param string $request The data to send. * @param int $responseLength The amount of data to read. Defaults to 1160 bytes. */ public function __construct($host, $port, $request, $responseLength = 1160) { $this->host = $host; $this->port = $port; $this->request = $request; $this->responseLength = $responseLength; $this->errorNumber = 0; $this->errorString = ''; } /** * Sends the data to the remote host. * * @throws An exception is thrown if a connection cannot be made to the remote host. */ public function send() { $this->response = ''; $fs = fsockopen($this->host, $this->port, $this->errorNumber, $this->errorString, 3); if ($this->errorNumber != 0) { throw new Exception('Error connecting to host: ' . $this->host . ' Error number: ' . $this->errorNumber . ' Error message: ' . $this->errorString); } if ($fs !== false) { @fwrite($fs, $this->request); while (!feof($fs)) { $this->response .= fgets($fs, $this->responseLength); } fclose($fs); } } /** * Returns the server response text * * @return string */ public function getResponse() { return $this->response; } /** * Returns the error number * * If there was no error, 0 will be returned. * * @return int */ public function getErrorNumner() { return $this->errorNumber; } /** * Returns the error string * * If there was no error, an empty string will be returned. * * @return string */ public function getErrorString() { return $this->errorString; } } components/com_zoo/libraries/mollom/index.html000066600000000036150771655450015670 0ustar00components/com_zoo/libraries/mollom/mollom.php000066600000057013150771655450015712 0ustar00 * @version 1.1.3 * * @copyright Copyright (c) 2008, Tijs Verkoyen. All rights reserved. * @license http://mollom.local/license BSD License */ class Mollom { /** * The allowed reverse proxy addresses * * @var array */ private static $allowedReverseProxyAddresses = array(); /** * Your private key * * Set it by calling Mollom::setPrivateKey(''); * * @var string */ private static $privateKey; /** * Your public key * * Set it by calling Mollom::setPublicKey(''); * * @var string */ private static $publicKey; /** * Reverse proxy allowed? * * @var bool */ private static $reverseProxy = false; /** * The default server * * No need to change * * @var string */ private static $serverHost = 'xmlrpc.mollom.com'; /** * The cache for the serverlist * * No need to change * * @var array */ private static $serverList = array(); /** * Default timeout * * @var int */ private static $timeout = 10; /** * The default user-agent * * Change it by calling Mollom::setUserAgent(''); * * @var string */ private static $userAgent = 'MollomPHP/1.1.3'; /** * The current Mollom-version * * No need to change * * @var string */ private static $version = '1.0'; /** * Build the value so we can use it in XML-RPC requests * * @return string * @param mixed $value */ private function buildValue($value) { // get type $type = gettype($value); // build value switch ($type) { case 'string': // escape it, cause Mollom can't handle CDATA (no pun intended) $value = htmlspecialchars($value, ENT_QUOTES, 'ISO-8859-15'); return ''. $value .''."\n"; case 'array': // init struct $struct = ''."\n"; $struct .= ' '."\n"; // loop array foreach ($value as $key => $value) $struct .= str_replace("\n", '', ''. "\n" .''. $key .''. self::buildValue($value) .'') . "\n"; $struct .= ' '."\n"; $struct .= ''."\n"; // return return $struct; default: return ''. $value .''."\n"; } } /** * Validates the answer for a CAPTCHA * * When the answer is false, you should request a new image- or audio-CAPTCHA, make sure your provide the current Mollom-sessionid. * The sessionid will be used to track spambots that try to solve CAPTHCA's by brute force. * * @return bool * @param string $sessionId * @param string $solution */ public static function checkCaptcha($sessionId, $solution) { // redefine $sessionId = (string) $sessionId; $solution = (string) $solution; // set autor ip $authorIp = self::getIpAddress(); // set parameters $parameters['session_id'] = $sessionId; $parameters['solution'] = $solution; if($authorIp != null) $parameters['author_ip'] = (string) $authorIp; // do the call $responseString = self::doCall('checkCaptcha', $parameters); // validate if(!isset($responseString->params->param->value->boolean)) throw new Exception('Invalid response in checkCapthca.'); // return if((string) $responseString->params->param->value->boolean == '1') return true; // fallback return false; } /** * Check if the data is spam or not, and gets an assessment of the datas quality * * This function will be used most. The more data you submit the more accurate the claasification will be. * If the spamstatus is 'unsure', you could send the user an extra check (eg. a captcha). * * REMARK: the Mollom-sessionid is NOT related to HTTP-session, so don't send 'session_id'. * * The function will return an array with 3 elements: * - spam the spam-status (unknown/ham/spam/unsure) * - quality an assessment of the content's quality (between 0 and 1) * - session_id Molloms session_id * * @return array * @param string[optional] $sessionId * @param string[optional] $postTitle * @param string[optional] $postBody * @param string[optional] $authorName * @param string[optional] $authorUrl * @param string[optional] $authorEmail * @param string[optional] $authorOpenId * @param string[optional] $authorId */ public static function checkContent($sessionId = null, $postTitle = null, $postBody = null, $authorName = null, $authorUrl = null, $authorEmail = null, $authorOpenId = null, $authorId = null) { // validate if($sessionId === null && $postTitle === null && $postBody === null && $authorName === null && $authorUrl === null && $authorEmail === null && $authorOpenId === null && $authorId === null) throw new Exception('Specify at least on argument'); // init var $parameters = array(); $aReturn = array(); // add parameters if($sessionId !== null) $parameters['session_id'] = (string) $sessionId; if($postTitle !== null) $parameters['post_title'] = (string) $postTitle; if($postBody !== null) $parameters['post_body'] = (string) $postBody; if($authorName !== null) $parameters['author_name'] = (string) $authorName; if($authorUrl !== null) $parameters['author_url'] = (string) $authorUrl; if($authorEmail !== null) $parameters['author_mail'] = (string) $authorEmail; if($authorOpenId != null) $parameters['author_openid'] = (string) $authorOpenId; if($authorId != null) $parameters['author_id'] = (string) $authorId; // set autor ip $authorIp = self::getIpAddress(); if($authorIp != null) $parameters['author_ip'] = (string) $authorIp; // do the call $responseString = self::doCall('checkContent', $parameters); // validate if(!isset($responseString->params->param->value->struct->member)) throw new Exception('Invalid response in checkContent.'); // loop parts foreach ($responseString->params->param->value->struct->member as $part) { // get key $key = $part->name; // get value switch ($part->name) { case 'spam': $value = (string) $part->value->int; switch($value) { case '0': $aReturn['spam'] = 'unknown'; break; case '1': $aReturn['spam'] = 'ham'; break; case '2': $aReturn['spam'] = 'spam'; break; case '3': $aReturn['spam'] = 'unsure'; break; } break; case 'quality': $aReturn['quality'] = (float) $part->value->double; break; case 'session_id': $aReturn['session_id'] = (string) $part->value->string; break; } } // return return $aReturn; } /** * Make the call * * @return SimpleXMLElement * @param string $method * @param array[optional] $parameters */ private static function doCall($method, $parameters = array(), $server = null, $counter = 0) { // count available servers $countServerList = count(self::$serverList); if($server === null && $countServerList == 0) throw new Exception('No servers found, populate the serverlist. See setServerList().'); // redefine var $method = (string) $method; $parameters = (array) $parameters; // possible methods $aPossibleMethods = array('checkCaptcha', 'checkContent', 'getAudioCaptcha', 'getImageCaptcha', 'getServerList', 'getStatistics', 'sendFeedback', 'verifyKey'); // check if method is valid if(!in_array($method, $aPossibleMethods)) throw new Exception('Invalid method. Only '. implode(', ', $aPossibleMethods) .' are possible methods.'); // check if public key is set if(self::$publicKey === null) throw new Exception('Public key wasn\'t set.'); // check if private key is set if(self::$privateKey === null) throw new Exception('Private key wasn\'t set.'); // still null if($server === null) $server = self::$serverList[$counter]; // cleanup server string $server = str_replace(array('http://', 'https://'), '', $server); // create timestamp $time = gmdate("Y-m-d\TH:i:s.\\0\\0\\0O", time()); // create nonce $nonce = md5(time()); // create has $hash = base64_encode( pack("H*", sha1((str_pad(self::$privateKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) . pack("H*", sha1((str_pad(self::$privateKey, 64, chr(0x00)) ^ (str_repeat(chr(0x36), 64))) . $time . ':'. $nonce .':'. self::$privateKey)))) ); // add parameters $parameters['public_key'] = self::$publicKey; $parameters['time'] = $time; $parameters['hash'] = $hash; $parameters['nonce'] = $nonce; // build request $requestBody = '' ."\n"; $requestBody .= '' ."\n"; $requestBody .= ' mollom.'. $method .'' ."\n"; $requestBody .= ' ' ."\n"; $requestBody .= ' '."\n"; $requestBody .= ' '. self::buildValue($parameters) ."\n"; $requestBody .= ' '."\n"; $requestBody .= ' ' ."\n"; $requestBody .= '' ."\n"; // create curl $curl = @curl_init(); // set useragent @curl_setopt($curl, CURLOPT_USERAGENT, self::$userAgent); // set options @curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); @curl_setopt($curl, CURLOPT_POST, true); @curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); @curl_setopt($curl, CURLOPT_HEADER, true); @curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); @curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, self::$timeout); @curl_setopt($curl, CURLOPT_TIMEOUT, self::$timeout); // set url @curl_setopt($curl, CURLOPT_URL, $server .'/'. self::$version); // set body @curl_setopt($curl, CURLOPT_POSTFIELDS, $requestBody); // get response $response = @curl_exec($curl); // get errors $errorNumber = (int) @curl_errno($curl); $errorString = @curl_error($curl); // close @curl_close($curl); // validate response if($response === false || $errorNumber != 0) { // increment counter $counter++; // no servers left if($errorNumber == 28 && !isset(self::$serverList[$counter]) && $countServerList != 0) throw new Exception('No more servers available, try to increase the timeout.'); // timeout elseif($errorNumber == 28 && isset(self::$serverList[$counter])) return self::doCall($method, $parameters, self::$serverList[$counter], $counter); // other error else throw new Exception('Something went wrong. Maybe the following message can be handy.
    '. $errorString, $errorNumber); } // process response $parts = explode("\r\n\r\n", $response); // validate if(!isset($parts[0]) || !isset($parts[1])) throw new Exception('Invalid response in doCall.'); // get headers $headers = $parts[0]; // rebuild body array_shift($parts); $body = implode('', $parts); // validate header $aValidHeaders = array('HTTP/1.0 200', 'HTTP/1.1 200'); if(!in_array(substr($headers, 0, 12), $aValidHeaders)) throw new Exception('Invalid headers.'); // do some validation $responseXML = @simplexml_load_string($body); if($responseXML === false) throw new Exception('Invalid body.'); if(isset($responseXML->fault)) { $code = (isset($responseXML->fault->value->struct->member[0]->value->int)) ? (int) $responseXML->fault->value->struct->member[0]->value->int : 'unknown'; $message = (isset($responseXML->fault->value->struct->member[1]->value->string)) ? (string) $responseXML->fault->value->struct->member[1]->value->string : 'unknown'; // handle errors switch ($code) { // code 1000 (Parse error or internal problem) case 1000: throw new Exception('[error '.$code .'] '. $message, $code); // code 1100 (Serverlist outdated) case 1100: throw new Exception('[error '.$code .'] '. $message, $code); // code 1200 (Server too busy) case 1200: if(self::$serverList === null) self::getServerList(); // do call again return self::doCall($method, $parameters, self::$serverList[$counter], $counter++); break; default: throw new Exception('[error '.$code .'] '. $message, $code); } } // return return $responseXML; } /** * Get a CAPTCHA-mp3 generated by Mollom * * If your already called getAudioCaptcha make sure you provide at least the $sessionId. It will be used * to identify visitors that are trying to break a CAPTCHA with brute force. * * REMARK: the Mollom-sessionid is NOT related to HTTP-session, so don't send 'session_id'. * * The function will return an array with 3 elements: * - session_id the session_id from Mollom * - url the url to the mp3-file * - html html that can be used on your website to display the CAPTCHA * * @return array * @param string[optional] $sessionId */ public static function getAudioCaptcha($sessionId = null) { // init vars $aReturn = array(); $parameters = array(); // set autor ip $authorIp = self::getIpAddress(); // set parameters if($sessionId != null) $parameters['session_id'] = (string) $sessionId; if($authorIp != null) $parameters['author_ip'] = (string) $authorIp; // do the call $responseString = self::doCall('getAudioCaptcha', $parameters); // validate if(!isset($responseString->params->param->value->struct->member)) throw new Exception('Invalid response in getAudioCaptcha.'); // loop elements foreach ($responseString->params->param->value->struct->member as $part) $aReturn[(string) $part->name] = (string) $part->value->string; // add image html $aReturn['html'] = ''."\n" ."\t".''."\n" ."\t".''."\n" .''; // return return $aReturn; } /** * Get a CAPTCHA-image generated by Mollom * * If your already called getImageCaptcha make sure you provide at least the $sessionId. It will be used * to identify visitors that are trying to break a CAPTCHA with brute force. * * REMARK: the Mollom-sessionid is NOT related to HTTP-session, so don't send 'session_id'. * * The function will return an array with 3 elements: * - session_id the session_id from Mollom * - url the url to the image * - html html that can be used on your website to display the CAPTCHA * * @return array * @param string[optional] $sessionId */ public static function getImageCaptcha($sessionId = null) { // init vars $aReturn = array(); $parameters = array(); // set autor ip $authorIp = self::getIpAddress(); // set parameters if($sessionId !== null) $parameters['session_id'] = (string) $sessionId; if($authorIp !== null) $parameters['author_ip'] = (string) $authorIp; // do the call $responseString = self::doCall('getImageCaptcha', $parameters); // validate if(!isset($responseString->params->param->value->struct->member)) throw new Exception('Invalid response in getImageCaptcha.'); // loop elements foreach ($responseString->params->param->value->struct->member as $part) $aReturn[(string) $part->name] = (string) $part->value->string; // add image html $aReturn['html'] = 'Mollom CAPTCHA'; // return return $aReturn; } /** * Get the real IP-address * * @return string */ public static function getIpAddress() { // pre check if(!isset($_SERVER['REMOTE_ADDR'])) return null; // get ip $ipAddress = $_SERVER['REMOTE_ADDR']; if(self::$reverseProxy) { if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { if(!empty(self::$allowedReverseProxyAddresses) && in_array($ipAddress, self::$allowedProxyAddresses, true)) { return array_pop(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])); } } // running in a cluster environment if(isset($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP']; } // fallback return $ipAddress; } /** * Obtains a list of valid servers * * @return array */ public static function getServerList($counter = 0) { // do the call $responseString = self::doCall('getServerList', array(), self::$serverHost, $counter); // validate if(!isset($responseString->params->param->value->array->data->value)) throw new Exception('Invalid response in getServerList.'); // loop servers and add them foreach ($responseString->params->param->value->array->data->value as $server) self::$serverList[] = (string) $server->string; if(count(self::$serverList) == 0) self::$serverList = array('http://xmlrpc3.mollom.com', 'http://xmlrpc2.mollom.com', 'http://xmlrpc1.mollom.com'); // return return self::$serverList; } /** * Retrieve statistics from Mollom * * Allowed types are listed below: * - total_days Number of days Mollom has been used * - total_accepted Total of blocked spam * - total_rejected Total accepted posts (not working?) * - yesterday_accepted Amount of spam blocked yesterday * - yesterday_rejected Number of posts accepted yesterday (not working?) * - today_accepted Amount of spam blocked today * - today_rejected Number of posts accepted today (not working?) * * @return int * @param string $type */ public static function getStatistics($type) { // possible types $aPossibleTypes = array('total_days', 'total_accepted', 'total_rejected', 'yesterday_accepted', 'yesterday_rejected', 'today_accepted', 'today_rejected'); // redefine $type = (string) $type; // validate if(!in_array($type, $aPossibleTypes)) throw new Exception('Invalid type. Only '. implode(', ', $aPossibleTypes) .' are possible types.'); // do the call $responseString = self::doCall('getStatistics', array('type' => $type)); // validate if(!isset($responseString->params->param->value->int)) throw new Exception('Invalid response in getStatistics.'); // return return (int) $responseString->params->param->value->int; } /** * Send feedback to Mollom. * * With this method you can help train Mollom. Implement this method if possible. The more feedback is provided the more accurate * Mollom will be. * * Allowed feedback-strings are listed below: * - spam Spam or unsolicited advertising * - profanity Obscene, violent or profane content * - low-quality Low-quality content or writing * - unwanted Unwanted, taunting or off-topic content * * @return bool * @param string $sessionId * @param string $feedback */ public static function sendFeedback($sessionId, $feedback) { // possible feedback $aPossibleFeedback = array('spam', 'profanity', 'low-quality', 'unwanted'); // redefine $sessionId = (string) $sessionId; $feedback = (string) $feedback; // validate if(!in_array($feedback, $aPossibleFeedback)) throw new Exception('Invalid feedback. Only '. implode(', ', $aPossibleFeedback) .' are possible feedback-strings.'); // build parameters $parameters['session_id'] = $sessionId; $parameters['feedback'] = $feedback; // do the call $responseString = self::doCall('sendFeedback', $parameters); // validate if(!isset($responseString->params->param->value->boolean)) throw new Exception('Invalid response in sendFeedback.'); // return if((string) $responseString->params->param->value->boolean == 1) return true; // fallback return false; } /** * Set the allowed reverse proxy Addresses * * @return void * @param array $addresses */ public static function setAllowedReverseProxyAddresses($addresses) { // store allowed ip-addresses self::$allowedReverseProxyAddresses = (array) $addresses; // set reverse proxy self::$reverseProxy = (!empty($addresses)) ? true : false; } /** * Set the private key * * @return void * @param string $key */ public static function setPrivateKey($key) { self::$privateKey = (string) $key; } /** * Set the public key * * @return void * @param string $key */ public static function setPublicKey($key) { self::$publicKey = (string) $key; } /** * Set the server list * * @return void * @param array $servers */ public static function setServerList($servers) { // redefine $server = (array) $servers; // loop servers foreach ($servers as $server) self::$serverList[] = $server; } /** * Set timeout * * @return void * @param int $timeout */ public static function setTimeOut($timeout) { // redefine $timeout = (int) $timeout; // validate if($timeout == 0) throw new Exception('Invalid timeout. Timeout shouldn\'t be 0.'); // set property self::$timeout = $timeout; } /** * Set the user agent * * @return void * @param string $newUserAgent */ public static function setUserAgent($newUserAgent) { self::$userAgent .= ' '. (string) $newUserAgent; } /** * Verifies your key * * Returns information about the status of your key. Mollom will respond with a boolean value (true/false). * False means that your keys is disabled or doesn't exists. True means the key is enabled and working properly. * * @return bool */ public static function verifyKey() { // do the call $responseString = self::doCall('verifyKey'); // validate if(!isset($responseString->params->param->value->boolean)) throw new Exception('Invalid response in verifyKey.'); // return if((string) $responseString->params->param->value->boolean == '1') return true; // fallback return false; } } components/com_zoo/libraries/index.html000066600000000036150771655450014371 0ustar00components/com_zoo/libraries/facebook/index.html000066600000000036150771655450016142 0ustar00components/com_zoo/libraries/facebook/facebook.php000066600000004437150771655450016440 0ustar00app = $app; $this->setAppId($config['app_id']); $this->setAppSecret($config['app_secret']); $this->setAccessToken($config['access_token']); } public function accessTokenURL() { return 'https://graph.facebook.com/oauth/access_token'; } public function authorizeURL() { return 'https://graph.facebook.com/oauth/authorize'; } public function meURL() { return 'https://graph.facebook.com/me'; } public function graphURL() { return 'https://graph.facebook.com'; } public function setAppId($app_id) { $this->app_id = $app_id; return $this; } public function getAppId() { return $this->app_id; } public function setAppSecret($app_secret) { $this->app_secret = $app_secret; return $this; } public function getAppSecret() { return $this->app_secret; } public function setAccessToken($access_token) { $this->access_token = $access_token; return $this; } public function getAccessToken() { return $this->access_token; } public function getAuthenticateURL($redirect) { return $this->authorizeURL().'?client_id='.$this->getAppId().'&redirect_uri='.urlencode($redirect); } public function getAccessTokenURL($code, $redirect_uri) { return $this->accessTokenURL().'?client_id='.$this->getAppId().'&client_secret='.$this->getAppSecret().'&code='.$code.'&redirect_uri='.urlencode($redirect_uri); } public function getCurrentUserProfile() { if (!empty($this->access_token)) { $url = $this->meURL() . '?access_token='.$this->access_token; $result = $this->app->http->get($url, array('ssl_verifypeer' => false)); $result = json_decode($result['body']); return $result; } return 0; } public function getProfile($fb_uid) { if (empty($fb_uid)) { throw new FacebookException('Facebook unique id missing.'); } $url = $this->graphURL() . '/'.$fb_uid.'?fields=picture'; try { $result = $this->app->http->get($url, array('ssl_verifypeer' => false)); } catch (AppException $e) { return; } $result = json_decode($result['body']); return $result; } } /* Class: FacebookException */ class FacebookException extends AppException {}components/com_zoo/libraries/pcl/index.html000066600000000036150771655450015147 0ustar00components/com_zoo/libraries/pcl/pclzip.lib.php000066600000577416150771655450015756 0ustar00zipname = $p_zipname; $this->zip_fd = 0; $this->magic_quotes_status = -1; // ----- Return return; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : // create($p_filelist, $p_add_dir="", $p_remove_dir="") // create($p_filelist, $p_option, $p_option_value, ...) // Description : // This method supports two different synopsis. The first one is historical. // This method creates a Zip Archive. The Zip file is created in the // filesystem. The files and directories indicated in $p_filelist // are added in the archive. See the parameters description for the // supported format of $p_filelist. // When a directory is in the list, the directory and its content is added // in the archive. // In this synopsis, the function takes an optional variable list of // options. See bellow the supported options. // Parameters : // $p_filelist : An array containing file or directory names, or // a string containing one filename or one directory name, or // a string containing a list of filenames and/or directory // names separated by spaces. // $p_add_dir : A path to add before the real path of the archived file, // in order to have it memorized in the archive. // $p_remove_dir : A path to remove from the real path of the file to archive, // in order to have a shorter path memorized in the archive. // When $p_add_dir and $p_remove_dir are set, $p_remove_dir // is removed first, before $p_add_dir is added. // Options : // PCLZIP_OPT_ADD_PATH : // PCLZIP_OPT_REMOVE_PATH : // PCLZIP_OPT_REMOVE_ALL_PATH : // PCLZIP_OPT_COMMENT : // PCLZIP_CB_PRE_ADD : // PCLZIP_CB_POST_ADD : // Return Values : // 0 on failure, // The list of the added files, with a status of the add action. // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- function create($p_filelist) { $v_result=1; // ----- Reset the error handler $this->privErrorReset(); // ----- Set default values $v_options = array(); $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; // ----- Look for variable options arguments $v_size = func_num_args(); // ----- Look for arguments if ($v_size > 1) { // ----- Get the arguments $v_arg_list = func_get_args(); // ----- Remove from the options list the first argument array_shift($v_arg_list); $v_size--; // ----- Look for first arg if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { // ----- Parse the options $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array (PCLZIP_OPT_REMOVE_PATH => 'optional', PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', PCLZIP_OPT_ADD_PATH => 'optional', PCLZIP_CB_PRE_ADD => 'optional', PCLZIP_CB_POST_ADD => 'optional', PCLZIP_OPT_NO_COMPRESSION => 'optional', PCLZIP_OPT_COMMENT => 'optional', PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', PCLZIP_OPT_TEMP_FILE_ON => 'optional', PCLZIP_OPT_TEMP_FILE_OFF => 'optional' //, PCLZIP_OPT_CRYPT => 'optional' )); if ($v_result != 1) { return 0; } } // ----- Look for 2 args // Here we need to support the first historic synopsis of the // method. else { // ----- Get the first argument $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; // ----- Look for the optional second argument if ($v_size == 2) { $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; } else if ($v_size > 2) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); return 0; } } } // ----- Look for default option values $this->privOptionDefaultThreshold($v_options); // ----- Init $v_string_list = array(); $v_att_list = array(); $v_filedescr_list = array(); $p_result_list = array(); // ----- Look if the $p_filelist is really an array if (is_array($p_filelist)) { // ----- Look if the first element is also an array // This will mean that this is a file description entry if (isset($p_filelist[0]) && is_array($p_filelist[0])) { $v_att_list = $p_filelist; } // ----- The list is a list of string names else { $v_string_list = $p_filelist; } } // ----- Look if the $p_filelist is a string else if (is_string($p_filelist)) { // ----- Create a list from the string $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); } // ----- Invalid variable type for $p_filelist else { PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); return 0; } // ----- Reformat the string list if (sizeof($v_string_list) != 0) { foreach ($v_string_list as $v_string) { if ($v_string != '') { $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; } else { } } } // ----- For each file in the list check the attributes $v_supported_attributes = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' ,PCLZIP_ATT_FILE_MTIME => 'optional' ,PCLZIP_ATT_FILE_CONTENT => 'optional' ,PCLZIP_ATT_FILE_COMMENT => 'optional' ); foreach ($v_att_list as $v_entry) { $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], $v_options, $v_supported_attributes); if ($v_result != 1) { return 0; } } // ----- Expand the filelist (expand directories) $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); if ($v_result != 1) { return 0; } // ----- Call the create fct $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); if ($v_result != 1) { return 0; } // ----- Return return $p_result_list; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : // add($p_filelist, $p_add_dir="", $p_remove_dir="") // add($p_filelist, $p_option, $p_option_value, ...) // Description : // This method supports two synopsis. The first one is historical. // This methods add the list of files in an existing archive. // If a file with the same name already exists, it is added at the end of the // archive, the first one is still present. // If the archive does not exist, it is created. // Parameters : // $p_filelist : An array containing file or directory names, or // a string containing one filename or one directory name, or // a string containing a list of filenames and/or directory // names separated by spaces. // $p_add_dir : A path to add before the real path of the archived file, // in order to have it memorized in the archive. // $p_remove_dir : A path to remove from the real path of the file to archive, // in order to have a shorter path memorized in the archive. // When $p_add_dir and $p_remove_dir are set, $p_remove_dir // is removed first, before $p_add_dir is added. // Options : // PCLZIP_OPT_ADD_PATH : // PCLZIP_OPT_REMOVE_PATH : // PCLZIP_OPT_REMOVE_ALL_PATH : // PCLZIP_OPT_COMMENT : // PCLZIP_OPT_ADD_COMMENT : // PCLZIP_OPT_PREPEND_COMMENT : // PCLZIP_CB_PRE_ADD : // PCLZIP_CB_POST_ADD : // Return Values : // 0 on failure, // The list of the added files, with a status of the add action. // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- function add($p_filelist) { $v_result=1; // ----- Reset the error handler $this->privErrorReset(); // ----- Set default values $v_options = array(); $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; // ----- Look for variable options arguments $v_size = func_num_args(); // ----- Look for arguments if ($v_size > 1) { // ----- Get the arguments $v_arg_list = func_get_args(); // ----- Remove form the options list the first argument array_shift($v_arg_list); $v_size--; // ----- Look for first arg if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { // ----- Parse the options $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array (PCLZIP_OPT_REMOVE_PATH => 'optional', PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', PCLZIP_OPT_ADD_PATH => 'optional', PCLZIP_CB_PRE_ADD => 'optional', PCLZIP_CB_POST_ADD => 'optional', PCLZIP_OPT_NO_COMPRESSION => 'optional', PCLZIP_OPT_COMMENT => 'optional', PCLZIP_OPT_ADD_COMMENT => 'optional', PCLZIP_OPT_PREPEND_COMMENT => 'optional', PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', PCLZIP_OPT_TEMP_FILE_ON => 'optional', PCLZIP_OPT_TEMP_FILE_OFF => 'optional' //, PCLZIP_OPT_CRYPT => 'optional' )); if ($v_result != 1) { return 0; } } // ----- Look for 2 args // Here we need to support the first historic synopsis of the // method. else { // ----- Get the first argument $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; // ----- Look for the optional second argument if ($v_size == 2) { $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; } else if ($v_size > 2) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); // ----- Return return 0; } } } // ----- Look for default option values $this->privOptionDefaultThreshold($v_options); // ----- Init $v_string_list = array(); $v_att_list = array(); $v_filedescr_list = array(); $p_result_list = array(); // ----- Look if the $p_filelist is really an array if (is_array($p_filelist)) { // ----- Look if the first element is also an array // This will mean that this is a file description entry if (isset($p_filelist[0]) && is_array($p_filelist[0])) { $v_att_list = $p_filelist; } // ----- The list is a list of string names else { $v_string_list = $p_filelist; } } // ----- Look if the $p_filelist is a string else if (is_string($p_filelist)) { // ----- Create a list from the string $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); } // ----- Invalid variable type for $p_filelist else { PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); return 0; } // ----- Reformat the string list if (sizeof($v_string_list) != 0) { foreach ($v_string_list as $v_string) { $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; } } // ----- For each file in the list check the attributes $v_supported_attributes = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' ,PCLZIP_ATT_FILE_MTIME => 'optional' ,PCLZIP_ATT_FILE_CONTENT => 'optional' ,PCLZIP_ATT_FILE_COMMENT => 'optional' ); foreach ($v_att_list as $v_entry) { $v_result = $this->privFileDescrParseAtt($v_entry, $v_filedescr_list[], $v_options, $v_supported_attributes); if ($v_result != 1) { return 0; } } // ----- Expand the filelist (expand directories) $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); if ($v_result != 1) { return 0; } // ----- Call the create fct $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); if ($v_result != 1) { return 0; } // ----- Return return $p_result_list; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : listContent() // Description : // This public method, gives the list of the files and directories, with their // properties. // The properties of each entries in the list are (used also in other functions) : // filename : Name of the file. For a create or add action it is the filename // given by the user. For an extract function it is the filename // of the extracted file. // stored_filename : Name of the file / directory stored in the archive. // size : Size of the stored file. // compressed_size : Size of the file's data compressed in the archive // (without the headers overhead) // mtime : Last known modification date of the file (UNIX timestamp) // comment : Comment associated with the file // folder : true | false // index : index of the file in the archive // status : status of the action (depending of the action) : // Values are : // ok : OK ! // filtered : the file / dir is not extracted (filtered by user) // already_a_directory : the file can not be extracted because a // directory with the same name already exists // write_protected : the file can not be extracted because a file // with the same name already exists and is // write protected // newer_exist : the file was not extracted because a newer file exists // path_creation_fail : the file is not extracted because the folder // does not exist and can not be created // write_error : the file was not extracted because there was a // error while writing the file // read_error : the file was not extracted because there was a error // while reading the file // invalid_header : the file was not extracted because of an archive // format error (bad file header) // Note that each time a method can continue operating when there // is an action error on a file, the error is only logged in the file status. // Return Values : // 0 on an unrecoverable failure, // The list of the files in the archive. // -------------------------------------------------------------------------------- function listContent() { $v_result=1; // ----- Reset the error handler $this->privErrorReset(); // ----- Check archive if (!$this->privCheckFormat()) { return(0); } // ----- Call the extracting fct $p_list = array(); if (($v_result = $this->privList($p_list)) != 1) { unset($p_list); return(0); } // ----- Return return $p_list; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : // extract($p_path="./", $p_remove_path="") // extract([$p_option, $p_option_value, ...]) // Description : // This method supports two synopsis. The first one is historical. // This method extract all the files / directories from the archive to the // folder indicated in $p_path. // If you want to ignore the 'root' part of path of the memorized files // you can indicate this in the optional $p_remove_path parameter. // By default, if a newer file with the same name already exists, the // file is not extracted. // // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append // at the end of the path value of PCLZIP_OPT_PATH. // Parameters : // $p_path : Path where the files and directories are to be extracted // $p_remove_path : First part ('root' part) of the memorized path // (if any similar) to remove while extracting. // Options : // PCLZIP_OPT_PATH : // PCLZIP_OPT_ADD_PATH : // PCLZIP_OPT_REMOVE_PATH : // PCLZIP_OPT_REMOVE_ALL_PATH : // PCLZIP_CB_PRE_EXTRACT : // PCLZIP_CB_POST_EXTRACT : // Return Values : // 0 or a negative value on failure, // The list of the extracted files, with a status of the action. // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- function extract() { $v_result=1; // ----- Reset the error handler $this->privErrorReset(); // ----- Check archive if (!$this->privCheckFormat()) { return(0); } // ----- Set default values $v_options = array(); // $v_path = "./"; $v_path = ''; $v_remove_path = ""; $v_remove_all_path = false; // ----- Look for variable options arguments $v_size = func_num_args(); // ----- Default values for option $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; // ----- Look for arguments if ($v_size > 0) { // ----- Get the arguments $v_arg_list = func_get_args(); // ----- Look for first arg if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { // ----- Parse the options $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array (PCLZIP_OPT_PATH => 'optional', PCLZIP_OPT_REMOVE_PATH => 'optional', PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', PCLZIP_OPT_ADD_PATH => 'optional', PCLZIP_CB_PRE_EXTRACT => 'optional', PCLZIP_CB_POST_EXTRACT => 'optional', PCLZIP_OPT_SET_CHMOD => 'optional', PCLZIP_OPT_BY_NAME => 'optional', PCLZIP_OPT_BY_EREG => 'optional', PCLZIP_OPT_BY_PREG => 'optional', PCLZIP_OPT_BY_INDEX => 'optional', PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', PCLZIP_OPT_REPLACE_NEWER => 'optional' ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', PCLZIP_OPT_TEMP_FILE_ON => 'optional', PCLZIP_OPT_TEMP_FILE_OFF => 'optional' )); if ($v_result != 1) { return 0; } // ----- Set the arguments if (isset($v_options[PCLZIP_OPT_PATH])) { $v_path = $v_options[PCLZIP_OPT_PATH]; } if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; } if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; } if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { // ----- Check for '/' in last path char if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { $v_path .= '/'; } $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; } } // ----- Look for 2 args // Here we need to support the first historic synopsis of the // method. else { // ----- Get the first argument $v_path = $v_arg_list[0]; // ----- Look for the optional second argument if ($v_size == 2) { $v_remove_path = $v_arg_list[1]; } else if ($v_size > 2) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); // ----- Return return 0; } } } // ----- Look for default option values $this->privOptionDefaultThreshold($v_options); // ----- Trace // ----- Call the extracting fct $p_list = array(); $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options); if ($v_result < 1) { unset($p_list); return(0); } // ----- Return return $p_list; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : // extractByIndex($p_index, $p_path="./", $p_remove_path="") // extractByIndex($p_index, [$p_option, $p_option_value, ...]) // Description : // This method supports two synopsis. The first one is historical. // This method is doing a partial extract of the archive. // The extracted files or folders are identified by their index in the // archive (from 0 to n). // Note that if the index identify a folder, only the folder entry is // extracted, not all the files included in the archive. // Parameters : // $p_index : A single index (integer) or a string of indexes of files to // extract. The form of the string is "0,4-6,8-12" with only numbers // and '-' for range or ',' to separate ranges. No spaces or ';' // are allowed. // $p_path : Path where the files and directories are to be extracted // $p_remove_path : First part ('root' part) of the memorized path // (if any similar) to remove while extracting. // Options : // PCLZIP_OPT_PATH : // PCLZIP_OPT_ADD_PATH : // PCLZIP_OPT_REMOVE_PATH : // PCLZIP_OPT_REMOVE_ALL_PATH : // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and // not as files. // The resulting content is in a new field 'content' in the file // structure. // This option must be used alone (any other options are ignored). // PCLZIP_CB_PRE_EXTRACT : // PCLZIP_CB_POST_EXTRACT : // Return Values : // 0 on failure, // The list of the extracted files, with a status of the action. // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- //function extractByIndex($p_index, options...) function extractByIndex($p_index) { $v_result=1; // ----- Reset the error handler $this->privErrorReset(); // ----- Check archive if (!$this->privCheckFormat()) { return(0); } // ----- Set default values $v_options = array(); // $v_path = "./"; $v_path = ''; $v_remove_path = ""; $v_remove_all_path = false; // ----- Look for variable options arguments $v_size = func_num_args(); // ----- Default values for option $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; // ----- Look for arguments if ($v_size > 1) { // ----- Get the arguments $v_arg_list = func_get_args(); // ----- Remove form the options list the first argument array_shift($v_arg_list); $v_size--; // ----- Look for first arg if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { // ----- Parse the options $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array (PCLZIP_OPT_PATH => 'optional', PCLZIP_OPT_REMOVE_PATH => 'optional', PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', PCLZIP_OPT_ADD_PATH => 'optional', PCLZIP_CB_PRE_EXTRACT => 'optional', PCLZIP_CB_POST_EXTRACT => 'optional', PCLZIP_OPT_SET_CHMOD => 'optional', PCLZIP_OPT_REPLACE_NEWER => 'optional' ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', PCLZIP_OPT_TEMP_FILE_ON => 'optional', PCLZIP_OPT_TEMP_FILE_OFF => 'optional' )); if ($v_result != 1) { return 0; } // ----- Set the arguments if (isset($v_options[PCLZIP_OPT_PATH])) { $v_path = $v_options[PCLZIP_OPT_PATH]; } if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; } if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; } if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { // ----- Check for '/' in last path char if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { $v_path .= '/'; } $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; } if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; } else { } } // ----- Look for 2 args // Here we need to support the first historic synopsis of the // method. else { // ----- Get the first argument $v_path = $v_arg_list[0]; // ----- Look for the optional second argument if ($v_size == 2) { $v_remove_path = $v_arg_list[1]; } else if ($v_size > 2) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); // ----- Return return 0; } } } // ----- Trace // ----- Trick // Here I want to reuse extractByRule(), so I need to parse the $p_index // with privParseOptions() $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); $v_options_trick = array(); $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, array (PCLZIP_OPT_BY_INDEX => 'optional' )); if ($v_result != 1) { return 0; } $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; // ----- Look for default option values $this->privOptionDefaultThreshold($v_options); // ----- Call the extracting fct if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { return(0); } // ----- Return return $p_list; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : // delete([$p_option, $p_option_value, ...]) // Description : // This method removes files from the archive. // If no parameters are given, then all the archive is emptied. // Parameters : // None or optional arguments. // Options : // PCLZIP_OPT_BY_INDEX : // PCLZIP_OPT_BY_NAME : // PCLZIP_OPT_BY_EREG : // PCLZIP_OPT_BY_PREG : // Return Values : // 0 on failure, // The list of the files which are still present in the archive. // (see PclZip::listContent() for list entry format) // -------------------------------------------------------------------------------- function delete() { $v_result=1; // ----- Reset the error handler $this->privErrorReset(); // ----- Check archive if (!$this->privCheckFormat()) { return(0); } // ----- Set default values $v_options = array(); // ----- Look for variable options arguments $v_size = func_num_args(); // ----- Look for arguments if ($v_size > 0) { // ----- Get the arguments $v_arg_list = func_get_args(); // ----- Parse the options $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, array (PCLZIP_OPT_BY_NAME => 'optional', PCLZIP_OPT_BY_EREG => 'optional', PCLZIP_OPT_BY_PREG => 'optional', PCLZIP_OPT_BY_INDEX => 'optional' )); if ($v_result != 1) { return 0; } } // ----- Magic quotes trick $this->privDisableMagicQuotes(); // ----- Call the delete fct $v_list = array(); if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { $this->privSwapBackMagicQuotes(); unset($v_list); return(0); } // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); // ----- Return return $v_list; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : deleteByIndex() // Description : // ***** Deprecated ***** // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. // -------------------------------------------------------------------------------- function deleteByIndex($p_index) { $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); // ----- Return return $p_list; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : properties() // Description : // This method gives the properties of the archive. // The properties are : // nb : Number of files in the archive // comment : Comment associated with the archive file // status : not_exist, ok // Parameters : // None // Return Values : // 0 on failure, // An array with the archive properties. // -------------------------------------------------------------------------------- function properties() { // ----- Reset the error handler $this->privErrorReset(); // ----- Magic quotes trick $this->privDisableMagicQuotes(); // ----- Check archive if (!$this->privCheckFormat()) { $this->privSwapBackMagicQuotes(); return(0); } // ----- Default properties $v_prop = array(); $v_prop['comment'] = ''; $v_prop['nb'] = 0; $v_prop['status'] = 'not_exist'; // ----- Look if file exists if (@is_file($this->zipname)) { // ----- Open the zip file if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) { $this->privSwapBackMagicQuotes(); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); // ----- Return return 0; } // ----- Read the central directory informations $v_central_dir = array(); if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { $this->privSwapBackMagicQuotes(); return 0; } // ----- Close the zip file $this->privCloseFd(); // ----- Set the user attributes $v_prop['comment'] = $v_central_dir['comment']; $v_prop['nb'] = $v_central_dir['entries']; $v_prop['status'] = 'ok'; } // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); // ----- Return return $v_prop; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : duplicate() // Description : // This method creates an archive by copying the content of an other one. If // the archive already exist, it is replaced by the new one without any warning. // Parameters : // $p_archive : The filename of a valid archive, or // a valid PclZip object. // Return Values : // 1 on success. // 0 or a negative value on error (error code). // -------------------------------------------------------------------------------- function duplicate($p_archive) { $v_result = 1; // ----- Reset the error handler $this->privErrorReset(); // ----- Look if the $p_archive is a PclZip object if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) { // ----- Duplicate the archive $v_result = $this->privDuplicate($p_archive->zipname); } // ----- Look if the $p_archive is a string (so a filename) else if (is_string($p_archive)) { // ----- Check that $p_archive is a valid zip file // TBC : Should also check the archive format if (!is_file($p_archive)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); $v_result = PCLZIP_ERR_MISSING_FILE; } else { // ----- Duplicate the archive $v_result = $this->privDuplicate($p_archive); } } // ----- Invalid variable else { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); $v_result = PCLZIP_ERR_INVALID_PARAMETER; } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : merge() // Description : // This method merge the $p_archive_to_add archive at the end of the current // one ($this). // If the archive ($this) does not exist, the merge becomes a duplicate. // If the $p_archive_to_add archive does not exist, the merge is a success. // Parameters : // $p_archive_to_add : It can be directly the filename of a valid zip archive, // or a PclZip object archive. // Return Values : // 1 on success, // 0 or negative values on error (see below). // -------------------------------------------------------------------------------- function merge($p_archive_to_add) { $v_result = 1; // ----- Reset the error handler $this->privErrorReset(); // ----- Check archive if (!$this->privCheckFormat()) { return(0); } // ----- Look if the $p_archive_to_add is a PclZip object if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) { // ----- Merge the archive $v_result = $this->privMerge($p_archive_to_add); } // ----- Look if the $p_archive_to_add is a string (so a filename) else if (is_string($p_archive_to_add)) { // ----- Create a temporary archive $v_object_archive = new PclZip($p_archive_to_add); // ----- Merge the archive $v_result = $this->privMerge($v_object_archive); } // ----- Invalid variable else { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); $v_result = PCLZIP_ERR_INVALID_PARAMETER; } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : errorCode() // Description : // Parameters : // -------------------------------------------------------------------------------- function errorCode() { if (PCLZIP_ERROR_EXTERNAL == 1) { return(PclErrorCode()); } else { return($this->error_code); } } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : errorName() // Description : // Parameters : // -------------------------------------------------------------------------------- function errorName($p_with_code=false) { $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' ); if (isset($v_name[$this->error_code])) { $v_value = $v_name[$this->error_code]; } else { $v_value = 'NoName'; } if ($p_with_code) { return($v_value.' ('.$this->error_code.')'); } else { return($v_value); } } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : errorInfo() // Description : // Parameters : // -------------------------------------------------------------------------------- function errorInfo($p_full=false) { if (PCLZIP_ERROR_EXTERNAL == 1) { return(PclErrorString()); } else { if ($p_full) { return($this->errorName(true)." : ".$this->error_string); } else { return($this->error_string." [code ".$this->error_code."]"); } } } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** // ***** ***** // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privCheckFormat() // Description : // This method check that the archive exists and is a valid zip archive. // Several level of check exists. (futur) // Parameters : // $p_level : Level of check. Default 0. // 0 : Check the first bytes (magic codes) (default value)) // 1 : 0 + Check the central directory (futur) // 2 : 1 + Check each file header (futur) // Return Values : // true on success, // false on error, the error code is set. // -------------------------------------------------------------------------------- function privCheckFormat($p_level=0) { $v_result = true; // ----- Reset the file system cache clearstatcache(); // ----- Reset the error handler $this->privErrorReset(); // ----- Look if the file exits if (!is_file($this->zipname)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); return(false); } // ----- Check that the file is readeable if (!is_readable($this->zipname)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); return(false); } // ----- Check the magic code // TBC // ----- Check the central header // TBC // ----- Check each file header // TBC // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privParseOptions() // Description : // This internal methods reads the variable list of arguments ($p_options_list, // $p_size) and generate an array with the options and values ($v_result_list). // $v_requested_options contains the options that can be present and those that // must be present. // $v_requested_options is an array, with the option value as key, and 'optional', // or 'mandatory' as value. // Parameters : // See above. // Return Values : // 1 on success. // 0 on failure. // -------------------------------------------------------------------------------- function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) { $v_result=1; // ----- Read the options $i=0; while ($i<$p_size) { // ----- Check if the option is supported if (!isset($v_requested_options[$p_options_list[$i]])) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); // ----- Return return PclZip::errorCode(); } // ----- Look for next option switch ($p_options_list[$i]) { // ----- Look for options that request a path value case PCLZIP_OPT_PATH : case PCLZIP_OPT_REMOVE_PATH : case PCLZIP_OPT_ADD_PATH : // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return return PclZip::errorCode(); } // ----- Get the value $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); $i++; break; case PCLZIP_OPT_TEMP_FILE_THRESHOLD : // ----- Check the number of parameters if (($i+1) >= $p_size) { PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); return PclZip::errorCode(); } // ----- Check for incompatible options if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); return PclZip::errorCode(); } // ----- Check the value $v_value = $p_options_list[$i+1]; if ((!is_integer($v_value)) || ($v_value<0)) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); return PclZip::errorCode(); } // ----- Get the value (and convert it in bytes) $v_result_list[$p_options_list[$i]] = $v_value*1048576; $i++; break; case PCLZIP_OPT_TEMP_FILE_ON : // ----- Check for incompatible options if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); return PclZip::errorCode(); } $v_result_list[$p_options_list[$i]] = true; break; case PCLZIP_OPT_TEMP_FILE_OFF : // ----- Check for incompatible options if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); return PclZip::errorCode(); } // ----- Check for incompatible options if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); return PclZip::errorCode(); } $v_result_list[$p_options_list[$i]] = true; break; case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return return PclZip::errorCode(); } // ----- Get the value if ( is_string($p_options_list[$i+1]) && ($p_options_list[$i+1] != '')) { $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); $i++; } else { } break; // ----- Look for options that request an array of string for value case PCLZIP_OPT_BY_NAME : // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return return PclZip::errorCode(); } // ----- Get the value if (is_string($p_options_list[$i+1])) { $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; } else if (is_array($p_options_list[$i+1])) { $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; } else { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return return PclZip::errorCode(); } $i++; break; // ----- Look for options that request an EREG or PREG expression case PCLZIP_OPT_BY_EREG : // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG // to PCLZIP_OPT_BY_PREG $p_options_list[$i] = PCLZIP_OPT_BY_PREG; case PCLZIP_OPT_BY_PREG : //case PCLZIP_OPT_CRYPT : // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return return PclZip::errorCode(); } // ----- Get the value if (is_string($p_options_list[$i+1])) { $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; } else { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return return PclZip::errorCode(); } $i++; break; // ----- Look for options that takes a string case PCLZIP_OPT_COMMENT : case PCLZIP_OPT_ADD_COMMENT : case PCLZIP_OPT_PREPEND_COMMENT : // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '" .PclZipUtilOptionText($p_options_list[$i]) ."'"); // ----- Return return PclZip::errorCode(); } // ----- Get the value if (is_string($p_options_list[$i+1])) { $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; } else { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '" .PclZipUtilOptionText($p_options_list[$i]) ."'"); // ----- Return return PclZip::errorCode(); } $i++; break; // ----- Look for options that request an array of index case PCLZIP_OPT_BY_INDEX : // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return return PclZip::errorCode(); } // ----- Get the value $v_work_list = array(); if (is_string($p_options_list[$i+1])) { // ----- Remove spaces $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); // ----- Parse items $v_work_list = explode(",", $p_options_list[$i+1]); } else if (is_integer($p_options_list[$i+1])) { $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; } else if (is_array($p_options_list[$i+1])) { $v_work_list = $p_options_list[$i+1]; } else { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return return PclZip::errorCode(); } // ----- Reduce the index list // each index item in the list must be a couple with a start and // an end value : [0,3], [5-5], [8-10], ... // ----- Check the format of each item $v_sort_flag=false; $v_sort_value=0; for ($j=0; $j= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return return PclZip::errorCode(); } // ----- Get the value $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; $i++; break; // ----- Look for options that request a call-back case PCLZIP_CB_PRE_EXTRACT : case PCLZIP_CB_POST_EXTRACT : case PCLZIP_CB_PRE_ADD : case PCLZIP_CB_POST_ADD : /* for futur use case PCLZIP_CB_PRE_DELETE : case PCLZIP_CB_POST_DELETE : case PCLZIP_CB_PRE_LIST : case PCLZIP_CB_POST_LIST : */ // ----- Check the number of parameters if (($i+1) >= $p_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return return PclZip::errorCode(); } // ----- Get the value $v_function_name = $p_options_list[$i+1]; // ----- Check that the value is a valid existing function if (!function_exists($v_function_name)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); // ----- Return return PclZip::errorCode(); } // ----- Set the attribute $v_result_list[$p_options_list[$i]] = $v_function_name; $i++; break; default : // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Unknown parameter '" .$p_options_list[$i]."'"); // ----- Return return PclZip::errorCode(); } // ----- Next options $i++; } // ----- Look for mandatory options if ($v_requested_options !== false) { for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { // ----- Look for mandatory option if ($v_requested_options[$key] == 'mandatory') { // ----- Look if present if (!isset($v_result_list[$key])) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); // ----- Return return PclZip::errorCode(); } } } } // ----- Look for default values if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privOptionDefaultThreshold() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privOptionDefaultThreshold(&$p_options) { $v_result=1; if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { return $v_result; } // ----- Get 'memory_limit' configuration value $v_memory_limit = ini_get('memory_limit'); $v_memory_limit = trim($v_memory_limit); $last = strtolower(substr($v_memory_limit, -1)); if($last == 'g') //$v_memory_limit = $v_memory_limit*1024*1024*1024; $v_memory_limit = $v_memory_limit*1073741824; if($last == 'm') //$v_memory_limit = $v_memory_limit*1024*1024; $v_memory_limit = $v_memory_limit*1048576; if($last == 'k') $v_memory_limit = $v_memory_limit*1024; $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); // ----- Sanity check : No threshold if value lower than 1M if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privFileDescrParseAtt() // Description : // Parameters : // Return Values : // 1 on success. // 0 on failure. // -------------------------------------------------------------------------------- function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) { $v_result=1; // ----- For each file in the list check the attributes foreach ($p_file_list as $v_key => $v_value) { // ----- Check if the option is supported if (!isset($v_requested_options[$v_key])) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); // ----- Return return PclZip::errorCode(); } // ----- Look for attribute switch ($v_key) { case PCLZIP_ATT_FILE_NAME : if (!is_string($v_value)) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); return PclZip::errorCode(); } $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); if ($p_filedescr['filename'] == '') { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); return PclZip::errorCode(); } break; case PCLZIP_ATT_FILE_NEW_SHORT_NAME : if (!is_string($v_value)) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); return PclZip::errorCode(); } $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); if ($p_filedescr['new_short_name'] == '') { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); return PclZip::errorCode(); } break; case PCLZIP_ATT_FILE_NEW_FULL_NAME : if (!is_string($v_value)) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); return PclZip::errorCode(); } $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); if ($p_filedescr['new_full_name'] == '') { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); return PclZip::errorCode(); } break; // ----- Look for options that takes a string case PCLZIP_ATT_FILE_COMMENT : if (!is_string($v_value)) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); return PclZip::errorCode(); } $p_filedescr['comment'] = $v_value; break; case PCLZIP_ATT_FILE_MTIME : if (!is_integer($v_value)) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); return PclZip::errorCode(); } $p_filedescr['mtime'] = $v_value; break; case PCLZIP_ATT_FILE_CONTENT : $p_filedescr['content'] = $v_value; break; default : // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Unknown parameter '".$v_key."'"); // ----- Return return PclZip::errorCode(); } // ----- Look for mandatory options if ($v_requested_options !== false) { for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { // ----- Look for mandatory option if ($v_requested_options[$key] == 'mandatory') { // ----- Look if present if (!isset($p_file_list[$key])) { PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); return PclZip::errorCode(); } } } } // end foreach } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privFileDescrExpand() // Description : // This method look for each item of the list to see if its a file, a folder // or a string to be added as file. For any other type of files (link, other) // just ignore the item. // Then prepare the information that will be stored for that file. // When its a folder, expand the folder with all the files that are in that // folder (recursively). // Parameters : // Return Values : // 1 on success. // 0 on failure. // -------------------------------------------------------------------------------- function privFileDescrExpand(&$p_filedescr_list, &$p_options) { $v_result=1; // ----- Create a result list $v_result_list = array(); // ----- Look each entry for ($i=0; $iprivCalculateStoredFilename($v_descr, $p_options); // ----- Add the descriptor in result list $v_result_list[sizeof($v_result_list)] = $v_descr; // ----- Look for folder if ($v_descr['type'] == 'folder') { // ----- List of items in folder $v_dirlist_descr = array(); $v_dirlist_nb = 0; if ($v_folder_handler = @opendir($v_descr['filename'])) { while (($v_item_handler = @readdir($v_folder_handler)) !== false) { // ----- Skip '.' and '..' if (($v_item_handler == '.') || ($v_item_handler == '..')) { continue; } // ----- Compose the full filename $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; // ----- Look for different stored filename // Because the name of the folder was changed, the name of the // files/sub-folders also change if (($v_descr['stored_filename'] != $v_descr['filename']) && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { if ($v_descr['stored_filename'] != '') { $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; } else { $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; } } $v_dirlist_nb++; } @closedir($v_folder_handler); } else { // TBC : unable to open folder in read mode } // ----- Expand each element of the list if ($v_dirlist_nb != 0) { // ----- Expand if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { return $v_result; } // ----- Concat the resulting list $v_result_list = array_merge($v_result_list, $v_dirlist_descr); } else { } // ----- Free local array unset($v_dirlist_descr); } } // ----- Get the result list $p_filedescr_list = $v_result_list; // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privCreate() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privCreate($p_filedescr_list, &$p_result_list, &$p_options) { $v_result=1; $v_list_detail = array(); // ----- Magic quotes trick $this->privDisableMagicQuotes(); // ----- Open the file in write mode if (($v_result = $this->privOpenFd('wb')) != 1) { // ----- Return return $v_result; } // ----- Add the list of files $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); // ----- Close $this->privCloseFd(); // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privAdd() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privAdd($p_filedescr_list, &$p_result_list, &$p_options) { $v_result=1; $v_list_detail = array(); // ----- Look if the archive exists or is empty if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) { // ----- Do a create $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); // ----- Return return $v_result; } // ----- Magic quotes trick $this->privDisableMagicQuotes(); // ----- Open the zip file if (($v_result=$this->privOpenFd('rb')) != 1) { // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); // ----- Return return $v_result; } // ----- Read the central directory informations $v_central_dir = array(); if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); return $v_result; } // ----- Go to beginning of File @rewind($this->zip_fd); // ----- Creates a temporay file $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; // ----- Open the temporary file in write mode if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); // ----- Return return PclZip::errorCode(); } // ----- Copy the files from the archive to the temporary file // TBC : Here I should better append the file and go back to erase the central dir $v_size = $v_central_dir['offset']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = fread($this->zip_fd, $v_read_size); @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Swap the file descriptor // Here is a trick : I swap the temporary fd with the zip fd, in order to use // the following methods on the temporary fil and not the real archive $v_swap = $this->zip_fd; $this->zip_fd = $v_zip_temp_fd; $v_zip_temp_fd = $v_swap; // ----- Add the files $v_header_list = array(); if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) { fclose($v_zip_temp_fd); $this->privCloseFd(); @unlink($v_zip_temp_name); $this->privSwapBackMagicQuotes(); // ----- Return return $v_result; } // ----- Store the offset of the central dir $v_offset = @ftell($this->zip_fd); // ----- Copy the block of file headers from the old archive $v_size = $v_central_dir['size']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @fread($v_zip_temp_fd, $v_read_size); @fwrite($this->zip_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Create the Central Dir files header for ($i=0, $v_count=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) { fclose($v_zip_temp_fd); $this->privCloseFd(); @unlink($v_zip_temp_name); $this->privSwapBackMagicQuotes(); // ----- Return return $v_result; } $v_count++; } // ----- Transform the header to a 'usable' info $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); } // ----- Zip file comment $v_comment = $v_central_dir['comment']; if (isset($p_options[PCLZIP_OPT_COMMENT])) { $v_comment = $p_options[PCLZIP_OPT_COMMENT]; } if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; } if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; } // ----- Calculate the size of the central header $v_size = @ftell($this->zip_fd)-$v_offset; // ----- Create the central dir footer if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) { // ----- Reset the file list unset($v_header_list); $this->privSwapBackMagicQuotes(); // ----- Return return $v_result; } // ----- Swap back the file descriptor $v_swap = $this->zip_fd; $this->zip_fd = $v_zip_temp_fd; $v_zip_temp_fd = $v_swap; // ----- Close $this->privCloseFd(); // ----- Close the temporary file @fclose($v_zip_temp_fd); // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); // ----- Delete the zip file // TBC : I should test the result ... @unlink($this->zipname); // ----- Rename the temporary file // TBC : I should test the result ... //@rename($v_zip_temp_name, $this->zipname); PclZipUtilRename($v_zip_temp_name, $this->zipname); // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privOpenFd() // Description : // Parameters : // -------------------------------------------------------------------------------- function privOpenFd($p_mode) { $v_result=1; // ----- Look if already open if ($this->zip_fd != 0) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); // ----- Return return PclZip::errorCode(); } // ----- Open the zip file if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); // ----- Return return PclZip::errorCode(); } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privCloseFd() // Description : // Parameters : // -------------------------------------------------------------------------------- function privCloseFd() { $v_result=1; if ($this->zip_fd != 0) @fclose($this->zip_fd); $this->zip_fd = 0; // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privAddList() // Description : // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is // different from the real path of the file. This is usefull if you want to have PclTar // running in any directory, and memorize relative path from an other directory. // Parameters : // $p_list : An array containing the file or directory names to add in the tar // $p_result_list : list of added files with their properties (specially the status field) // $p_add_dir : Path to add in the filename path archived // $p_remove_dir : Path to remove in the filename path archived // Return Values : // -------------------------------------------------------------------------------- // function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) function privAddList($p_filedescr_list, &$p_result_list, &$p_options) { $v_result=1; // ----- Add the files $v_header_list = array(); if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) { // ----- Return return $v_result; } // ----- Store the offset of the central dir $v_offset = @ftell($this->zip_fd); // ----- Create the Central Dir files header for ($i=0,$v_count=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) { // ----- Return return $v_result; } $v_count++; } // ----- Transform the header to a 'usable' info $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); } // ----- Zip file comment $v_comment = ''; if (isset($p_options[PCLZIP_OPT_COMMENT])) { $v_comment = $p_options[PCLZIP_OPT_COMMENT]; } // ----- Calculate the size of the central header $v_size = @ftell($this->zip_fd)-$v_offset; // ----- Create the central dir footer if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) { // ----- Reset the file list unset($v_header_list); // ----- Return return $v_result; } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privAddFileList() // Description : // Parameters : // $p_filedescr_list : An array containing the file description // or directory names to add in the zip // $p_result_list : list of added files with their properties (specially the status field) // Return Values : // -------------------------------------------------------------------------------- function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) { $v_result=1; $v_header = array(); // ----- Recuperate the current number of elt in list $v_nb = sizeof($p_result_list); // ----- Loop on the files for ($j=0; ($jprivAddFile($p_filedescr_list[$j], $v_header, $p_options); if ($v_result != 1) { return $v_result; } // ----- Store the file infos $p_result_list[$v_nb++] = $v_header; } } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privAddFile() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privAddFile($p_filedescr, &$p_header, &$p_options) { $v_result=1; // ----- Working variable $p_filename = $p_filedescr['filename']; // TBC : Already done in the fileAtt check ... ? if ($p_filename == "") { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); // ----- Return return PclZip::errorCode(); } // ----- Look for a stored different filename /* TBC : Removed if (isset($p_filedescr['stored_filename'])) { $v_stored_filename = $p_filedescr['stored_filename']; } else { $v_stored_filename = $p_filedescr['stored_filename']; } */ // ----- Set the file properties clearstatcache(); $p_header['version'] = 20; $p_header['version_extracted'] = 10; $p_header['flag'] = 0; $p_header['compression'] = 0; $p_header['crc'] = 0; $p_header['compressed_size'] = 0; $p_header['filename_len'] = strlen($p_filename); $p_header['extra_len'] = 0; $p_header['disk'] = 0; $p_header['internal'] = 0; $p_header['offset'] = 0; $p_header['filename'] = $p_filename; // TBC : Removed $p_header['stored_filename'] = $v_stored_filename; $p_header['stored_filename'] = $p_filedescr['stored_filename']; $p_header['extra'] = ''; $p_header['status'] = 'ok'; $p_header['index'] = -1; // ----- Look for regular file if ($p_filedescr['type']=='file') { $p_header['external'] = 0x00000000; $p_header['size'] = filesize($p_filename); } // ----- Look for regular folder else if ($p_filedescr['type']=='folder') { $p_header['external'] = 0x00000010; $p_header['mtime'] = filemtime($p_filename); $p_header['size'] = filesize($p_filename); } // ----- Look for virtual file else if ($p_filedescr['type'] == 'virtual_file') { $p_header['external'] = 0x00000000; $p_header['size'] = strlen($p_filedescr['content']); } // ----- Look for filetime if (isset($p_filedescr['mtime'])) { $p_header['mtime'] = $p_filedescr['mtime']; } else if ($p_filedescr['type'] == 'virtual_file') { $p_header['mtime'] = time(); } else { $p_header['mtime'] = filemtime($p_filename); } // ------ Look for file comment if (isset($p_filedescr['comment'])) { $p_header['comment_len'] = strlen($p_filedescr['comment']); $p_header['comment'] = $p_filedescr['comment']; } else { $p_header['comment_len'] = 0; $p_header['comment'] = ''; } // ----- Look for pre-add callback if (isset($p_options[PCLZIP_CB_PRE_ADD])) { // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_header, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);'); $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header); if ($v_result == 0) { // ----- Change the file status $p_header['status'] = "skipped"; $v_result = 1; } // ----- Update the informations // Only some fields can be modified if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); } } // ----- Look for empty stored filename if ($p_header['stored_filename'] == "") { $p_header['status'] = "filtered"; } // ----- Check the path length if (strlen($p_header['stored_filename']) > 0xFF) { $p_header['status'] = 'filename_too_long'; } // ----- Look if no error, or file not skipped if ($p_header['status'] == 'ok') { // ----- Look for a file if ($p_filedescr['type'] == 'file') { // ----- Look for using temporary file to zip if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) { $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); if ($v_result < PCLZIP_ERR_NO_ERROR) { return $v_result; } } // ----- Use "in memory" zip algo else { // ----- Open the source file if (($v_file = @fopen($p_filename, "rb")) == 0) { PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); return PclZip::errorCode(); } // ----- Read the file content $v_content = @fread($v_file, $p_header['size']); // ----- Close the file @fclose($v_file); // ----- Calculate the CRC $p_header['crc'] = @crc32($v_content); // ----- Look for no compression if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { // ----- Set header parameters $p_header['compressed_size'] = $p_header['size']; $p_header['compression'] = 0; } // ----- Look for normal compression else { // ----- Compress the content $v_content = @gzdeflate($v_content); // ----- Set header parameters $p_header['compressed_size'] = strlen($v_content); $p_header['compression'] = 8; } // ----- Call the header generation if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { @fclose($v_file); return $v_result; } // ----- Write the compressed (or not) content @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); } } // ----- Look for a virtual file (a file from string) else if ($p_filedescr['type'] == 'virtual_file') { $v_content = $p_filedescr['content']; // ----- Calculate the CRC $p_header['crc'] = @crc32($v_content); // ----- Look for no compression if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { // ----- Set header parameters $p_header['compressed_size'] = $p_header['size']; $p_header['compression'] = 0; } // ----- Look for normal compression else { // ----- Compress the content $v_content = @gzdeflate($v_content); // ----- Set header parameters $p_header['compressed_size'] = strlen($v_content); $p_header['compression'] = 8; } // ----- Call the header generation if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { @fclose($v_file); return $v_result; } // ----- Write the compressed (or not) content @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); } // ----- Look for a directory else if ($p_filedescr['type'] == 'folder') { // ----- Look for directory last '/' if (@substr($p_header['stored_filename'], -1) != '/') { $p_header['stored_filename'] .= '/'; } // ----- Set the file properties $p_header['size'] = 0; //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked $p_header['external'] = 0x00000010; // Value for a folder : to be checked // ----- Call the header generation if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { return $v_result; } } } // ----- Look for post-add callback if (isset($p_options[PCLZIP_CB_POST_ADD])) { // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_header, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. // eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);'); $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header); if ($v_result == 0) { // ----- Ignored $v_result = 1; } // ----- Update the informations // Nothing can be modified } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privAddFileUsingTempFile() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) { $v_result=PCLZIP_ERR_NO_ERROR; // ----- Working variable $p_filename = $p_filedescr['filename']; // ----- Open the source file if (($v_file = @fopen($p_filename, "rb")) == 0) { PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); return PclZip::errorCode(); } // ----- Creates a compressed temporary file $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { fclose($v_file); PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); return PclZip::errorCode(); } // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks $v_size = filesize($p_filename); while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @fread($v_file, $v_read_size); //$v_binary_data = pack('a'.$v_read_size, $v_buffer); @gzputs($v_file_compressed, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Close the file @fclose($v_file); @gzclose($v_file_compressed); // ----- Check the minimum file size if (filesize($v_gzip_temp_name) < 18) { PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes'); return PclZip::errorCode(); } // ----- Extract the compressed attributes if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); return PclZip::errorCode(); } // ----- Read the gzip file header $v_binary_data = @fread($v_file_compressed, 10); $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data); // ----- Check some parameters $v_data_header['os'] = bin2hex($v_data_header['os']); // ----- Read the gzip file footer @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8); $v_binary_data = @fread($v_file_compressed, 8); $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data); // ----- Set the attributes $p_header['compression'] = ord($v_data_header['cm']); //$p_header['mtime'] = $v_data_header['mtime']; $p_header['crc'] = $v_data_footer['crc']; $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18; // ----- Close the file @fclose($v_file_compressed); // ----- Call the header generation if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { return $v_result; } // ----- Add the compressed data if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); return PclZip::errorCode(); } // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks fseek($v_file_compressed, 10); $v_size = $p_header['compressed_size']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @fread($v_file_compressed, $v_read_size); //$v_binary_data = pack('a'.$v_read_size, $v_buffer); @fwrite($this->zip_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Close the file @fclose($v_file_compressed); // ----- Unlink the temporary file @unlink($v_gzip_temp_name); // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privCalculateStoredFilename() // Description : // Based on file descriptor properties and global options, this method // calculate the filename that will be stored in the archive. // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privCalculateStoredFilename(&$p_filedescr, &$p_options) { $v_result=1; // ----- Working variables $p_filename = $p_filedescr['filename']; if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; } else { $p_add_dir = ''; } if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; } else { $p_remove_dir = ''; } if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; } else { $p_remove_all_dir = 0; } // ----- Look for full name change if (isset($p_filedescr['new_full_name'])) { // ----- Remove drive letter if any $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); } // ----- Look for path and/or short name change else { // ----- Look for short name change // Its when we cahnge just the filename but not the path if (isset($p_filedescr['new_short_name'])) { $v_path_info = pathinfo($p_filename); $v_dir = ''; if ($v_path_info['dirname'] != '') { $v_dir = $v_path_info['dirname'].'/'; } $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; } else { // ----- Calculate the stored filename $v_stored_filename = $p_filename; } // ----- Look for all path to remove if ($p_remove_all_dir) { $v_stored_filename = basename($p_filename); } // ----- Look for partial path remove else if ($p_remove_dir != "") { if (substr($p_remove_dir, -1) != '/') $p_remove_dir .= "/"; if ( (substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./")) { if ( (substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./")) { $p_remove_dir = "./".$p_remove_dir; } if ( (substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./")) { $p_remove_dir = substr($p_remove_dir, 2); } } $v_compare = PclZipUtilPathInclusion($p_remove_dir, $v_stored_filename); if ($v_compare > 0) { if ($v_compare == 2) { $v_stored_filename = ""; } else { $v_stored_filename = substr($v_stored_filename, strlen($p_remove_dir)); } } } // ----- Remove drive letter if any $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); // ----- Look for path to add if ($p_add_dir != "") { if (substr($p_add_dir, -1) == "/") $v_stored_filename = $p_add_dir.$v_stored_filename; else $v_stored_filename = $p_add_dir."/".$v_stored_filename; } } // ----- Filename (reduce the path of stored name) $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); $p_filedescr['stored_filename'] = $v_stored_filename; // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privWriteFileHeader() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privWriteFileHeader(&$p_header) { $v_result=1; // ----- Store the offset position of the file $p_header['offset'] = ftell($this->zip_fd); // ----- Transform UNIX mtime to DOS format mdate/mtime $v_date = getdate($p_header['mtime']); $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; // ----- Packed data $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, $p_header['version_extracted'], $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'], $p_header['compressed_size'], $p_header['size'], strlen($p_header['stored_filename']), $p_header['extra_len']); // ----- Write the first 148 bytes of the header in the archive fputs($this->zip_fd, $v_binary_data, 30); // ----- Write the variable fields if (strlen($p_header['stored_filename']) != 0) { fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); } if ($p_header['extra_len'] != 0) { fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privWriteCentralFileHeader() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privWriteCentralFileHeader(&$p_header) { $v_result=1; // TBC //for(reset($p_header); $key = key($p_header); next($p_header)) { //} // ----- Transform UNIX mtime to DOS format mdate/mtime $v_date = getdate($p_header['mtime']); $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; // ----- Packed data $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, $p_header['version'], $p_header['version_extracted'], $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'], $p_header['compressed_size'], $p_header['size'], strlen($p_header['stored_filename']), $p_header['extra_len'], $p_header['comment_len'], $p_header['disk'], $p_header['internal'], $p_header['external'], $p_header['offset']); // ----- Write the 42 bytes of the header in the zip file fputs($this->zip_fd, $v_binary_data, 46); // ----- Write the variable fields if (strlen($p_header['stored_filename']) != 0) { fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); } if ($p_header['extra_len'] != 0) { fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); } if ($p_header['comment_len'] != 0) { fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privWriteCentralHeader() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) { $v_result=1; // ----- Packed data $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, $p_nb_entries, $p_size, $p_offset, strlen($p_comment)); // ----- Write the 22 bytes of the header in the zip file fputs($this->zip_fd, $v_binary_data, 22); // ----- Write the variable fields if (strlen($p_comment) != 0) { fputs($this->zip_fd, $p_comment, strlen($p_comment)); } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privList() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privList(&$p_list) { $v_result=1; // ----- Magic quotes trick $this->privDisableMagicQuotes(); // ----- Open the zip file if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) { // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); // ----- Return return PclZip::errorCode(); } // ----- Read the central directory informations $v_central_dir = array(); if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { $this->privSwapBackMagicQuotes(); return $v_result; } // ----- Go to beginning of Central Dir @rewind($this->zip_fd); if (@fseek($this->zip_fd, $v_central_dir['offset'])) { $this->privSwapBackMagicQuotes(); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); // ----- Return return PclZip::errorCode(); } // ----- Read each entry for ($i=0; $i<$v_central_dir['entries']; $i++) { // ----- Read the file header if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) { $this->privSwapBackMagicQuotes(); return $v_result; } $v_header['index'] = $i; // ----- Get the only interesting attributes $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); unset($v_header); } // ----- Close the zip file $this->privCloseFd(); // ----- Magic quotes trick $this->privSwapBackMagicQuotes(); // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privConvertHeader2FileInfo() // Description : // This function takes the file informations from the central directory // entries and extract the interesting parameters that will be given back. // The resulting file infos are set in the array $p_info // $p_info['filename'] : Filename with full path. Given by user (add), // extracted in the filesystem (extract). // $p_info['stored_filename'] : Stored filename in the archive. // $p_info['size'] = Size of the file. // $p_info['compressed_size'] = Compressed size of the file. // $p_info['mtime'] = Last modification date of the file. // $p_info['comment'] = Comment associated with the file. // $p_info['folder'] = true/false : indicates if the entry is a folder or not. // $p_info['status'] = status of the action on the file. // $p_info['crc'] = CRC of the file content. // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privConvertHeader2FileInfo($p_header, &$p_info) { $v_result=1; // ----- Get the interesting attributes $v_temp_path = PclZipUtilPathReduction($p_header['filename']); $p_info['filename'] = $v_temp_path; $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); $p_info['stored_filename'] = $v_temp_path; $p_info['size'] = $p_header['size']; $p_info['compressed_size'] = $p_header['compressed_size']; $p_info['mtime'] = $p_header['mtime']; $p_info['comment'] = $p_header['comment']; $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); $p_info['index'] = $p_header['index']; $p_info['status'] = $p_header['status']; $p_info['crc'] = $p_header['crc']; // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privExtractByRule() // Description : // Extract a file or directory depending of rules (by index, by name, ...) // Parameters : // $p_file_list : An array where will be placed the properties of each // extracted file // $p_path : Path to add while writing the extracted files // $p_remove_path : Path to remove (from the file memorized path) while writing the // extracted files. If the path does not match the file path, // the file is extracted with its memorized path. // $p_remove_path does not apply to 'list' mode. // $p_path and $p_remove_path are commulative. // Return Values : // 1 on success,0 or less on error (see error code list) // -------------------------------------------------------------------------------- function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) { $v_result=1; // ----- Magic quotes trick $this->privDisableMagicQuotes(); // ----- Check the path if ( ($p_path == "") || ( (substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path,1,2)!=":/"))) $p_path = "./".$p_path; // ----- Reduce the path last (and duplicated) '/' if (($p_path != "./") && ($p_path != "/")) { // ----- Look for the path end '/' while (substr($p_path, -1) == "/") { $p_path = substr($p_path, 0, strlen($p_path)-1); } } // ----- Look for path to remove format (should end by /) if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) { $p_remove_path .= '/'; } $p_remove_path_size = strlen($p_remove_path); // ----- Open the zip file if (($v_result = $this->privOpenFd('rb')) != 1) { $this->privSwapBackMagicQuotes(); return $v_result; } // ----- Read the central directory informations $v_central_dir = array(); if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); return $v_result; } // ----- Start at beginning of Central Dir $v_pos_entry = $v_central_dir['offset']; // ----- Read each entry $j_start = 0; for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) { // ----- Read next Central dir entry @rewind($this->zip_fd); if (@fseek($this->zip_fd, $v_pos_entry)) { // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); // ----- Return return PclZip::errorCode(); } // ----- Read the file header $v_header = array(); if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) { // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); return $v_result; } // ----- Store the index $v_header['index'] = $i; // ----- Store the file position $v_pos_entry = ftell($this->zip_fd); // ----- Look for the specific extract rules $v_extract = false; // ----- Look for extract by name rule if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { // ----- Look if the filename is in the list for ($j=0; ($j strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { $v_extract = true; } } // ----- Look for a filename elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { $v_extract = true; } } } // ----- Look for extract by ereg rule // ereg() is deprecated with PHP 5.3 /* else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { $v_extract = true; } } */ // ----- Look for extract by preg rule else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { $v_extract = true; } } // ----- Look for extract by index rule else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { // ----- Look if the index is in the list for ($j=$j_start; ($j=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { $v_extract = true; } if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { $j_start = $j+1; } if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { break; } } } // ----- Look for no rule, which means extract all the archive else { $v_extract = true; } // ----- Check compression method if ( ($v_extract) && ( ($v_header['compression'] != 8) && ($v_header['compression'] != 0))) { $v_header['status'] = 'unsupported_compression'; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { $this->privSwapBackMagicQuotes(); PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, "Filename '".$v_header['stored_filename']."' is " ."compressed by an unsupported compression " ."method (".$v_header['compression'].") "); return PclZip::errorCode(); } } // ----- Check encrypted files if (($v_extract) && (($v_header['flag'] & 1) == 1)) { $v_header['status'] = 'unsupported_encryption'; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { $this->privSwapBackMagicQuotes(); PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, "Unsupported encryption for " ." filename '".$v_header['stored_filename'] ."'"); return PclZip::errorCode(); } } // ----- Look for real extraction if (($v_extract) && ($v_header['status'] != 'ok')) { $v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++]); if ($v_result != 1) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); return $v_result; } $v_extract = false; } // ----- Look for real extraction if ($v_extract) { // ----- Go to the file position @rewind($this->zip_fd); if (@fseek($this->zip_fd, $v_header['offset'])) { // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); // ----- Return return PclZip::errorCode(); } // ----- Look for extraction as string if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { $v_string = ''; // ----- Extracting the file $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); if ($v_result1 < 1) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); return $v_result1; } // ----- Get the only interesting attributes if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) { // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); return $v_result; } // ----- Set the file content $p_file_list[$v_nb_extracted]['content'] = $v_string; // ----- Next extracted file $v_nb_extracted++; // ----- Look for user callback abort if ($v_result1 == 2) { break; } } // ----- Look for extraction in standard output elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { // ----- Extracting the file in standard output $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); if ($v_result1 < 1) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); return $v_result1; } // ----- Get the only interesting attributes if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); return $v_result; } // ----- Look for user callback abort if ($v_result1 == 2) { break; } } // ----- Look for normal extraction else { // ----- Extracting the file $v_result1 = $this->privExtractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_options); if ($v_result1 < 1) { $this->privCloseFd(); $this->privSwapBackMagicQuotes(); return $v_result1; } // ----- Get the only interesting attributes if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); return $v_result; } // ----- Look for user callback abort if ($v_result1 == 2) { break; } } } } // ----- Close the zip file $this->privCloseFd(); $this->privSwapBackMagicQuotes(); // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privExtractFile() // Description : // Parameters : // Return Values : // // 1 : ... ? // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback // -------------------------------------------------------------------------------- function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) { $v_result=1; // ----- Read the file header if (($v_result = $this->privReadFileHeader($v_header)) != 1) { // ----- Return return $v_result; } // ----- Check that the file header is coherent with $p_entry info if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { // TBC } // ----- Look for all path to remove if ($p_remove_all_path == true) { // ----- Look for folder entry that not need to be extracted if (($p_entry['external']&0x00000010)==0x00000010) { $p_entry['status'] = "filtered"; return $v_result; } // ----- Get the basename of the path $p_entry['filename'] = basename($p_entry['filename']); } // ----- Look for path to remove else if ($p_remove_path != "") { if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) { // ----- Change the file status $p_entry['status'] = "filtered"; // ----- Return return $v_result; } $p_remove_path_size = strlen($p_remove_path); if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) { // ----- Remove the path $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); } } // ----- Add the path if ($p_path != '') { $p_entry['filename'] = $p_path."/".$p_entry['filename']; } // ----- Check a base_dir_restriction if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { $v_inclusion = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], $p_entry['filename']); if ($v_inclusion == 0) { PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, "Filename '".$p_entry['filename']."' is " ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); return PclZip::errorCode(); } } // ----- Look for pre-extract callback if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_entry, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); if ($v_result == 0) { // ----- Change the file status $p_entry['status'] = "skipped"; $v_result = 1; } // ----- Look for abort result if ($v_result == 2) { // ----- This status is internal and will be changed in 'skipped' $p_entry['status'] = "aborted"; $v_result = PCLZIP_ERR_USER_ABORTED; } // ----- Update the informations // Only some fields can be modified $p_entry['filename'] = $v_local_header['filename']; } // ----- Look if extraction should be done if ($p_entry['status'] == 'ok') { // ----- Look for specific actions while the file exist if (file_exists($p_entry['filename'])) { // ----- Look if file is a directory if (is_dir($p_entry['filename'])) { // ----- Change the file status $p_entry['status'] = "already_a_directory"; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR // For historical reason first PclZip implementation does not stop // when this kind of error occurs. if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, "Filename '".$p_entry['filename']."' is " ."already used by an existing directory"); return PclZip::errorCode(); } } // ----- Look if file is write protected else if (!is_writeable($p_entry['filename'])) { // ----- Change the file status $p_entry['status'] = "write_protected"; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR // For historical reason first PclZip implementation does not stop // when this kind of error occurs. if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Filename '".$p_entry['filename']."' exists " ."and is write protected"); return PclZip::errorCode(); } } // ----- Look if the extracted file is older else if (filemtime($p_entry['filename']) > $p_entry['mtime']) { // ----- Change the file status if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { } else { $p_entry['status'] = "newer_exist"; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR // For historical reason first PclZip implementation does not stop // when this kind of error occurs. if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Newer version of '".$p_entry['filename']."' exists " ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); return PclZip::errorCode(); } } } else { } } // ----- Check the directory availability and create it if necessary else { if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) $v_dir_to_check = $p_entry['filename']; else if (!strstr($p_entry['filename'], "/")) $v_dir_to_check = ""; else $v_dir_to_check = dirname($p_entry['filename']); if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { // ----- Change the file status $p_entry['status'] = "path_creation_fail"; // ----- Return //return $v_result; $v_result = 1; } } } // ----- Look if extraction should be done if ($p_entry['status'] == 'ok') { // ----- Do the extraction (if not a folder) if (!(($p_entry['external']&0x00000010)==0x00000010)) { // ----- Look for not compressed file if ($p_entry['compression'] == 0) { // ----- Opening destination file if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { // ----- Change the file status $p_entry['status'] = "write_error"; // ----- Return return $v_result; } // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks $v_size = $p_entry['compressed_size']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @fread($this->zip_fd, $v_read_size); /* Try to speed up the code $v_binary_data = pack('a'.$v_read_size, $v_buffer); @fwrite($v_dest_file, $v_binary_data, $v_read_size); */ @fwrite($v_dest_file, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Closing the destination file fclose($v_dest_file); // ----- Change the file mtime touch($p_entry['filename'], $p_entry['mtime']); } else { // ----- TBC // Need to be finished if (($p_entry['flag'] & 1) == 1) { PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); return PclZip::errorCode(); } // ----- Look for using temporary file to unzip if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) { $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); if ($v_result < PCLZIP_ERR_NO_ERROR) { return $v_result; } } // ----- Look for extract in memory else { // ----- Read the compressed file in a buffer (one shot) $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); // ----- Decompress the file $v_file_content = @gzinflate($v_buffer); unset($v_buffer); if ($v_file_content === FALSE) { // ----- Change the file status // TBC $p_entry['status'] = "error"; return $v_result; } // ----- Opening destination file if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { // ----- Change the file status $p_entry['status'] = "write_error"; return $v_result; } // ----- Write the uncompressed data @fwrite($v_dest_file, $v_file_content, $p_entry['size']); unset($v_file_content); // ----- Closing the destination file @fclose($v_dest_file); } // ----- Change the file mtime @touch($p_entry['filename'], $p_entry['mtime']); } // ----- Look for chmod option if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { // ----- Change the mode of the file @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); } } } // ----- Change abort status if ($p_entry['status'] == "aborted") { $p_entry['status'] = "skipped"; } // ----- Look for post-extract callback elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_entry, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); // ----- Look for abort result if ($v_result == 2) { $v_result = PCLZIP_ERR_USER_ABORTED; } } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privExtractFileUsingTempFile() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privExtractFileUsingTempFile(&$p_entry, &$p_options) { $v_result=1; // ----- Creates a temporary file $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { fclose($v_file); PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); return PclZip::errorCode(); } // ----- Write gz file format header $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); @fwrite($v_dest_file, $v_binary_data, 10); // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks $v_size = $p_entry['compressed_size']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @fread($this->zip_fd, $v_read_size); //$v_binary_data = pack('a'.$v_read_size, $v_buffer); @fwrite($v_dest_file, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Write gz file format footer $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); @fwrite($v_dest_file, $v_binary_data, 8); // ----- Close the temporary file @fclose($v_dest_file); // ----- Opening destination file if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { $p_entry['status'] = "write_error"; return $v_result; } // ----- Open the temporary gz file if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { @fclose($v_dest_file); $p_entry['status'] = "read_error"; PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); return PclZip::errorCode(); } // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks $v_size = $p_entry['size']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @gzread($v_src_file, $v_read_size); //$v_binary_data = pack('a'.$v_read_size, $v_buffer); @fwrite($v_dest_file, $v_buffer, $v_read_size); $v_size -= $v_read_size; } @fclose($v_dest_file); @gzclose($v_src_file); // ----- Delete the temporary file @unlink($v_gzip_temp_name); // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privExtractFileInOutput() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privExtractFileInOutput(&$p_entry, &$p_options) { $v_result=1; // ----- Read the file header if (($v_result = $this->privReadFileHeader($v_header)) != 1) { return $v_result; } // ----- Check that the file header is coherent with $p_entry info if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { // TBC } // ----- Look for pre-extract callback if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_entry, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); if ($v_result == 0) { // ----- Change the file status $p_entry['status'] = "skipped"; $v_result = 1; } // ----- Look for abort result if ($v_result == 2) { // ----- This status is internal and will be changed in 'skipped' $p_entry['status'] = "aborted"; $v_result = PCLZIP_ERR_USER_ABORTED; } // ----- Update the informations // Only some fields can be modified $p_entry['filename'] = $v_local_header['filename']; } // ----- Trace // ----- Look if extraction should be done if ($p_entry['status'] == 'ok') { // ----- Do the extraction (if not a folder) if (!(($p_entry['external']&0x00000010)==0x00000010)) { // ----- Look for not compressed file if ($p_entry['compressed_size'] == $p_entry['size']) { // ----- Read the file in a buffer (one shot) $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); // ----- Send the file to the output echo $v_buffer; unset($v_buffer); } else { // ----- Read the compressed file in a buffer (one shot) $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); // ----- Decompress the file $v_file_content = gzinflate($v_buffer); unset($v_buffer); // ----- Send the file to the output echo $v_file_content; unset($v_file_content); } } } // ----- Change abort status if ($p_entry['status'] == "aborted") { $p_entry['status'] = "skipped"; } // ----- Look for post-extract callback elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_entry, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); // ----- Look for abort result if ($v_result == 2) { $v_result = PCLZIP_ERR_USER_ABORTED; } } return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privExtractFileAsString() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) { $v_result=1; // ----- Read the file header $v_header = array(); if (($v_result = $this->privReadFileHeader($v_header)) != 1) { // ----- Return return $v_result; } // ----- Check that the file header is coherent with $p_entry info if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { // TBC } // ----- Look for pre-extract callback if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_entry, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. // eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); if ($v_result == 0) { // ----- Change the file status $p_entry['status'] = "skipped"; $v_result = 1; } // ----- Look for abort result if ($v_result == 2) { // ----- This status is internal and will be changed in 'skipped' $p_entry['status'] = "aborted"; $v_result = PCLZIP_ERR_USER_ABORTED; } // ----- Update the informations // Only some fields can be modified $p_entry['filename'] = $v_local_header['filename']; } // ----- Look if extraction should be done if ($p_entry['status'] == 'ok') { // ----- Do the extraction (if not a folder) if (!(($p_entry['external']&0x00000010)==0x00000010)) { // ----- Look for not compressed file // if ($p_entry['compressed_size'] == $p_entry['size']) if ($p_entry['compression'] == 0) { // ----- Reading the file $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); } else { // ----- Reading the file $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); // ----- Decompress the file if (($p_string = @gzinflate($v_data)) === FALSE) { // TBC } } // ----- Trace } else { // TBC : error : can not extract a folder in a string } } // ----- Change abort status if ($p_entry['status'] == "aborted") { $p_entry['status'] = "skipped"; } // ----- Look for post-extract callback elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_entry, $v_local_header); // ----- Swap the content to header $v_local_header['content'] = $p_string; $p_string = ''; // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. // eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); // ----- Swap back the content to header $p_string = $v_local_header['content']; unset($v_local_header['content']); // ----- Look for abort result if ($v_result == 2) { $v_result = PCLZIP_ERR_USER_ABORTED; } } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privReadFileHeader() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privReadFileHeader(&$p_header) { $v_result=1; // ----- Read the 4 bytes signature $v_binary_data = @fread($this->zip_fd, 4); $v_data = unpack('Vid', $v_binary_data); // ----- Check signature if ($v_data['id'] != 0x04034b50) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); // ----- Return return PclZip::errorCode(); } // ----- Read the first 42 bytes of the header $v_binary_data = fread($this->zip_fd, 26); // ----- Look for invalid block size if (strlen($v_binary_data) != 26) { $p_header['filename'] = ""; $p_header['status'] = "invalid_header"; // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); // ----- Return return PclZip::errorCode(); } // ----- Extract the values $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); // ----- Get filename $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); // ----- Get extra_fields if ($v_data['extra_len'] != 0) { $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); } else { $p_header['extra'] = ''; } // ----- Extract properties $p_header['version_extracted'] = $v_data['version']; $p_header['compression'] = $v_data['compression']; $p_header['size'] = $v_data['size']; $p_header['compressed_size'] = $v_data['compressed_size']; $p_header['crc'] = $v_data['crc']; $p_header['flag'] = $v_data['flag']; $p_header['filename_len'] = $v_data['filename_len']; // ----- Recuperate date in UNIX format $p_header['mdate'] = $v_data['mdate']; $p_header['mtime'] = $v_data['mtime']; if ($p_header['mdate'] && $p_header['mtime']) { // ----- Extract time $v_hour = ($p_header['mtime'] & 0xF800) >> 11; $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; $v_seconde = ($p_header['mtime'] & 0x001F)*2; // ----- Extract date $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; $v_month = ($p_header['mdate'] & 0x01E0) >> 5; $v_day = $p_header['mdate'] & 0x001F; // ----- Get UNIX date format $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); } else { $p_header['mtime'] = time(); } // TBC //for(reset($v_data); $key = key($v_data); next($v_data)) { //} // ----- Set the stored filename $p_header['stored_filename'] = $p_header['filename']; // ----- Set the status field $p_header['status'] = "ok"; // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privReadCentralFileHeader() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privReadCentralFileHeader(&$p_header) { $v_result=1; // ----- Read the 4 bytes signature $v_binary_data = @fread($this->zip_fd, 4); $v_data = unpack('Vid', $v_binary_data); // ----- Check signature if ($v_data['id'] != 0x02014b50) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); // ----- Return return PclZip::errorCode(); } // ----- Read the first 42 bytes of the header $v_binary_data = fread($this->zip_fd, 42); // ----- Look for invalid block size if (strlen($v_binary_data) != 42) { $p_header['filename'] = ""; $p_header['status'] = "invalid_header"; // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); // ----- Return return PclZip::errorCode(); } // ----- Extract the values $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); // ----- Get filename if ($p_header['filename_len'] != 0) $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); else $p_header['filename'] = ''; // ----- Get extra if ($p_header['extra_len'] != 0) $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); else $p_header['extra'] = ''; // ----- Get comment if ($p_header['comment_len'] != 0) $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); else $p_header['comment'] = ''; // ----- Extract properties // ----- Recuperate date in UNIX format //if ($p_header['mdate'] && $p_header['mtime']) // TBC : bug : this was ignoring time with 0/0/0 if (1) { // ----- Extract time $v_hour = ($p_header['mtime'] & 0xF800) >> 11; $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; $v_seconde = ($p_header['mtime'] & 0x001F)*2; // ----- Extract date $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; $v_month = ($p_header['mdate'] & 0x01E0) >> 5; $v_day = $p_header['mdate'] & 0x001F; // ----- Get UNIX date format $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); } else { $p_header['mtime'] = time(); } // ----- Set the stored filename $p_header['stored_filename'] = $p_header['filename']; // ----- Set default status to ok $p_header['status'] = 'ok'; // ----- Look if it is a directory if (substr($p_header['filename'], -1) == '/') { //$p_header['external'] = 0x41FF0010; $p_header['external'] = 0x00000010; } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privCheckFileHeaders() // Description : // Parameters : // Return Values : // 1 on success, // 0 on error; // -------------------------------------------------------------------------------- function privCheckFileHeaders(&$p_local_header, &$p_central_header) { $v_result=1; // ----- Check the static values // TBC if ($p_local_header['filename'] != $p_central_header['filename']) { } if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { } if ($p_local_header['flag'] != $p_central_header['flag']) { } if ($p_local_header['compression'] != $p_central_header['compression']) { } if ($p_local_header['mtime'] != $p_central_header['mtime']) { } if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { } // ----- Look for flag bit 3 if (($p_local_header['flag'] & 8) == 8) { $p_local_header['size'] = $p_central_header['size']; $p_local_header['compressed_size'] = $p_central_header['compressed_size']; $p_local_header['crc'] = $p_central_header['crc']; } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privReadEndCentralDir() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privReadEndCentralDir(&$p_central_dir) { $v_result=1; // ----- Go to the end of the zip file $v_size = filesize($this->zipname); @fseek($this->zip_fd, $v_size); if (@ftell($this->zip_fd) != $v_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); // ----- Return return PclZip::errorCode(); } // ----- First try : look if this is an archive with no commentaries (most of the time) // in this case the end of central dir is at 22 bytes of the file end $v_found = 0; if ($v_size > 26) { @fseek($this->zip_fd, $v_size-22); if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); // ----- Return return PclZip::errorCode(); } // ----- Read for bytes $v_binary_data = @fread($this->zip_fd, 4); $v_data = @unpack('Vid', $v_binary_data); // ----- Check signature if ($v_data['id'] == 0x06054b50) { $v_found = 1; } $v_pos = ftell($this->zip_fd); } // ----- Go back to the maximum possible size of the Central Dir End Record if (!$v_found) { $v_maximum_size = 65557; // 0xFFFF + 22; if ($v_maximum_size > $v_size) $v_maximum_size = $v_size; @fseek($this->zip_fd, $v_size-$v_maximum_size); if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); // ----- Return return PclZip::errorCode(); } // ----- Read byte per byte in order to find the signature $v_pos = ftell($this->zip_fd); $v_bytes = 0x00000000; while ($v_pos < $v_size) { // ----- Read a byte $v_byte = @fread($this->zip_fd, 1); // ----- Add the byte //$v_bytes = ($v_bytes << 8) | Ord($v_byte); // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); // ----- Compare the bytes if ($v_bytes == 0x504b0506) { $v_pos++; break; } $v_pos++; } // ----- Look if not found end of central dir if ($v_pos == $v_size) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); // ----- Return return PclZip::errorCode(); } } // ----- Read the first 18 bytes of the header $v_binary_data = fread($this->zip_fd, 18); // ----- Look for invalid block size if (strlen($v_binary_data) != 18) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); // ----- Return return PclZip::errorCode(); } // ----- Extract the values $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); // ----- Check the global size if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { // ----- Removed in release 2.2 see readme file // The check of the file size is a little too strict. // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. // While decrypted, zip has training 0 bytes if (0) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'The central dir is not at the end of the archive.' .' Some trailing bytes exists after the archive.'); // ----- Return return PclZip::errorCode(); } } // ----- Get comment if ($v_data['comment_size'] != 0) { $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); } else $p_central_dir['comment'] = ''; $p_central_dir['entries'] = $v_data['entries']; $p_central_dir['disk_entries'] = $v_data['disk_entries']; $p_central_dir['offset'] = $v_data['offset']; $p_central_dir['size'] = $v_data['size']; $p_central_dir['disk'] = $v_data['disk']; $p_central_dir['disk_start'] = $v_data['disk_start']; // TBC //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { //} // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privDeleteByRule() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privDeleteByRule(&$p_result_list, &$p_options) { $v_result=1; $v_list_detail = array(); // ----- Open the zip file if (($v_result=$this->privOpenFd('rb')) != 1) { // ----- Return return $v_result; } // ----- Read the central directory informations $v_central_dir = array(); if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { $this->privCloseFd(); return $v_result; } // ----- Go to beginning of File @rewind($this->zip_fd); // ----- Scan all the files // ----- Start at beginning of Central Dir $v_pos_entry = $v_central_dir['offset']; @rewind($this->zip_fd); if (@fseek($this->zip_fd, $v_pos_entry)) { // ----- Close the zip file $this->privCloseFd(); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); // ----- Return return PclZip::errorCode(); } // ----- Read each entry $v_header_list = array(); $j_start = 0; for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) { // ----- Read the file header $v_header_list[$v_nb_extracted] = array(); if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) { // ----- Close the zip file $this->privCloseFd(); return $v_result; } // ----- Store the index $v_header_list[$v_nb_extracted]['index'] = $i; // ----- Look for the specific extract rules $v_found = false; // ----- Look for extract by name rule if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { // ----- Look if the filename is in the list for ($j=0; ($j strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { $v_found = true; } elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { $v_found = true; } } // ----- Look for a filename elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { $v_found = true; } } } // ----- Look for extract by ereg rule // ereg() is deprecated with PHP 5.3 /* else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { $v_found = true; } } */ // ----- Look for extract by preg rule else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { $v_found = true; } } // ----- Look for extract by index rule else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { // ----- Look if the index is in the list for ($j=$j_start; ($j=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { $v_found = true; } if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { $j_start = $j+1; } if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { break; } } } else { $v_found = true; } // ----- Look for deletion if ($v_found) { unset($v_header_list[$v_nb_extracted]); } else { $v_nb_extracted++; } } // ----- Look if something need to be deleted if ($v_nb_extracted > 0) { // ----- Creates a temporay file $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; // ----- Creates a temporary zip archive $v_temp_zip = new PclZip($v_zip_temp_name); // ----- Open the temporary zip file in write mode if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { $this->privCloseFd(); // ----- Return return $v_result; } // ----- Look which file need to be kept for ($i=0; $izip_fd); if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { // ----- Close the zip file $this->privCloseFd(); $v_temp_zip->privCloseFd(); @unlink($v_zip_temp_name); // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); // ----- Return return PclZip::errorCode(); } // ----- Read the file header $v_local_header = array(); if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { // ----- Close the zip file $this->privCloseFd(); $v_temp_zip->privCloseFd(); @unlink($v_zip_temp_name); // ----- Return return $v_result; } // ----- Check that local file header is same as central file header if ($this->privCheckFileHeaders($v_local_header, $v_header_list[$i]) != 1) { // TBC } unset($v_local_header); // ----- Write the file header if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { // ----- Close the zip file $this->privCloseFd(); $v_temp_zip->privCloseFd(); @unlink($v_zip_temp_name); // ----- Return return $v_result; } // ----- Read/write the data block if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { // ----- Close the zip file $this->privCloseFd(); $v_temp_zip->privCloseFd(); @unlink($v_zip_temp_name); // ----- Return return $v_result; } } // ----- Store the offset of the central dir $v_offset = @ftell($v_temp_zip->zip_fd); // ----- Re-Create the Central Dir files header for ($i=0; $iprivWriteCentralFileHeader($v_header_list[$i])) != 1) { $v_temp_zip->privCloseFd(); $this->privCloseFd(); @unlink($v_zip_temp_name); // ----- Return return $v_result; } // ----- Transform the header to a 'usable' info $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); } // ----- Zip file comment $v_comment = ''; if (isset($p_options[PCLZIP_OPT_COMMENT])) { $v_comment = $p_options[PCLZIP_OPT_COMMENT]; } // ----- Calculate the size of the central header $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; // ----- Create the central dir footer if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { // ----- Reset the file list unset($v_header_list); $v_temp_zip->privCloseFd(); $this->privCloseFd(); @unlink($v_zip_temp_name); // ----- Return return $v_result; } // ----- Close $v_temp_zip->privCloseFd(); $this->privCloseFd(); // ----- Delete the zip file // TBC : I should test the result ... @unlink($this->zipname); // ----- Rename the temporary file // TBC : I should test the result ... //@rename($v_zip_temp_name, $this->zipname); PclZipUtilRename($v_zip_temp_name, $this->zipname); // ----- Destroy the temporary archive unset($v_temp_zip); } // ----- Remove every files : reset the file else if ($v_central_dir['entries'] != 0) { $this->privCloseFd(); if (($v_result = $this->privOpenFd('wb')) != 1) { return $v_result; } if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { return $v_result; } $this->privCloseFd(); } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privDirCheck() // Description : // Check if a directory exists, if not it creates it and all the parents directory // which may be useful. // Parameters : // $p_dir : Directory path to check. // Return Values : // 1 : OK // -1 : Unable to create directory // -------------------------------------------------------------------------------- function privDirCheck($p_dir, $p_is_dir=false) { $v_result = 1; // ----- Remove the final '/' if (($p_is_dir) && (substr($p_dir, -1)=='/')) { $p_dir = substr($p_dir, 0, strlen($p_dir)-1); } // ----- Check the directory availability if ((is_dir($p_dir)) || ($p_dir == "")) { return 1; } // ----- Extract parent directory $p_parent_dir = dirname($p_dir); // ----- Just a check if ($p_parent_dir != $p_dir) { // ----- Look for parent directory if ($p_parent_dir != "") { if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) { return $v_result; } } } // ----- Create the directory if (!@mkdir($p_dir, 0777)) { // ----- Error log PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); // ----- Return return PclZip::errorCode(); } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privMerge() // Description : // If $p_archive_to_add does not exist, the function exit with a success result. // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privMerge(&$p_archive_to_add) { $v_result=1; // ----- Look if the archive_to_add exists if (!is_file($p_archive_to_add->zipname)) { // ----- Nothing to merge, so merge is a success $v_result = 1; // ----- Return return $v_result; } // ----- Look if the archive exists if (!is_file($this->zipname)) { // ----- Do a duplicate $v_result = $this->privDuplicate($p_archive_to_add->zipname); // ----- Return return $v_result; } // ----- Open the zip file if (($v_result=$this->privOpenFd('rb')) != 1) { // ----- Return return $v_result; } // ----- Read the central directory informations $v_central_dir = array(); if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) { $this->privCloseFd(); return $v_result; } // ----- Go to beginning of File @rewind($this->zip_fd); // ----- Open the archive_to_add file if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) { $this->privCloseFd(); // ----- Return return $v_result; } // ----- Read the central directory informations $v_central_dir_to_add = array(); if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) { $this->privCloseFd(); $p_archive_to_add->privCloseFd(); return $v_result; } // ----- Go to beginning of File @rewind($p_archive_to_add->zip_fd); // ----- Creates a temporay file $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; // ----- Open the temporary file in write mode if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) { $this->privCloseFd(); $p_archive_to_add->privCloseFd(); PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); // ----- Return return PclZip::errorCode(); } // ----- Copy the files from the archive to the temporary file // TBC : Here I should better append the file and go back to erase the central dir $v_size = $v_central_dir['offset']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = fread($this->zip_fd, $v_read_size); @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Copy the files from the archive_to_add into the temporary file $v_size = $v_central_dir_to_add['offset']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Store the offset of the central dir $v_offset = @ftell($v_zip_temp_fd); // ----- Copy the block of file headers from the old archive $v_size = $v_central_dir['size']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @fread($this->zip_fd, $v_read_size); @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Copy the block of file headers from the archive_to_add $v_size = $v_central_dir_to_add['size']; while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Merge the file comments $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; // ----- Calculate the size of the (new) central header $v_size = @ftell($v_zip_temp_fd)-$v_offset; // ----- Swap the file descriptor // Here is a trick : I swap the temporary fd with the zip fd, in order to use // the following methods on the temporary fil and not the real archive fd $v_swap = $this->zip_fd; $this->zip_fd = $v_zip_temp_fd; $v_zip_temp_fd = $v_swap; // ----- Create the central dir footer if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) { $this->privCloseFd(); $p_archive_to_add->privCloseFd(); @fclose($v_zip_temp_fd); $this->zip_fd = null; // ----- Reset the file list unset($v_header_list); // ----- Return return $v_result; } // ----- Swap back the file descriptor $v_swap = $this->zip_fd; $this->zip_fd = $v_zip_temp_fd; $v_zip_temp_fd = $v_swap; // ----- Close $this->privCloseFd(); $p_archive_to_add->privCloseFd(); // ----- Close the temporary file @fclose($v_zip_temp_fd); // ----- Delete the zip file // TBC : I should test the result ... @unlink($this->zipname); // ----- Rename the temporary file // TBC : I should test the result ... //@rename($v_zip_temp_name, $this->zipname); PclZipUtilRename($v_zip_temp_name, $this->zipname); // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privDuplicate() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privDuplicate($p_archive_filename) { $v_result=1; // ----- Look if the $p_archive_filename exists if (!is_file($p_archive_filename)) { // ----- Nothing to duplicate, so duplicate is a success. $v_result = 1; // ----- Return return $v_result; } // ----- Open the zip file if (($v_result=$this->privOpenFd('wb')) != 1) { // ----- Return return $v_result; } // ----- Open the temporary file in write mode if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) { $this->privCloseFd(); PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); // ----- Return return PclZip::errorCode(); } // ----- Copy the files from the archive to the temporary file // TBC : Here I should better append the file and go back to erase the central dir $v_size = filesize($p_archive_filename); while ($v_size != 0) { $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = fread($v_zip_temp_fd, $v_read_size); @fwrite($this->zip_fd, $v_buffer, $v_read_size); $v_size -= $v_read_size; } // ----- Close $this->privCloseFd(); // ----- Close the temporary file @fclose($v_zip_temp_fd); // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privErrorLog() // Description : // Parameters : // -------------------------------------------------------------------------------- function privErrorLog($p_error_code=0, $p_error_string='') { if (PCLZIP_ERROR_EXTERNAL == 1) { PclError($p_error_code, $p_error_string); } else { $this->error_code = $p_error_code; $this->error_string = $p_error_string; } } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privErrorReset() // Description : // Parameters : // -------------------------------------------------------------------------------- function privErrorReset() { if (PCLZIP_ERROR_EXTERNAL == 1) { PclErrorReset(); } else { $this->error_code = 0; $this->error_string = ''; } } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privDisableMagicQuotes() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privDisableMagicQuotes() { $v_result=1; // ----- Look if function exists if ( (!function_exists("get_magic_quotes_runtime")) || (!function_exists("set_magic_quotes_runtime"))) { return $v_result; } // ----- Look if already done if ($this->magic_quotes_status != -1) { return $v_result; } // ----- Get and memorize the magic_quote value $this->magic_quotes_status = @get_magic_quotes_runtime(); // ----- Disable magic_quotes if ($this->magic_quotes_status == 1) { @set_magic_quotes_runtime(0); } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : privSwapBackMagicQuotes() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function privSwapBackMagicQuotes() { $v_result=1; // ----- Look if function exists if ( (!function_exists("get_magic_quotes_runtime")) || (!function_exists("set_magic_quotes_runtime"))) { return $v_result; } // ----- Look if something to do if ($this->magic_quotes_status != -1) { return $v_result; } // ----- Swap back magic_quotes if ($this->magic_quotes_status == 1) { @set_magic_quotes_runtime($this->magic_quotes_status); } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- } // End of class // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclZipUtilPathReduction() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function PclZipUtilPathReduction($p_dir) { $v_result = ""; // ----- Look for not empty path if ($p_dir != "") { // ----- Explode path by directory names $v_list = explode("/", $p_dir); // ----- Study directories from last to first $v_skip = 0; for ($i=sizeof($v_list)-1; $i>=0; $i--) { // ----- Look for current path if ($v_list[$i] == ".") { // ----- Ignore this directory // Should be the first $i=0, but no check is done } else if ($v_list[$i] == "..") { $v_skip++; } else if ($v_list[$i] == "") { // ----- First '/' i.e. root slash if ($i == 0) { $v_result = "/".$v_result; if ($v_skip > 0) { // ----- It is an invalid path, so the path is not modified // TBC $v_result = $p_dir; $v_skip = 0; } } // ----- Last '/' i.e. indicates a directory else if ($i == (sizeof($v_list)-1)) { $v_result = $v_list[$i]; } // ----- Double '/' inside the path else { // ----- Ignore only the double '//' in path, // but not the first and last '/' } } else { // ----- Look for item to skip if ($v_skip > 0) { $v_skip--; } else { $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); } } } // ----- Look for skip if ($v_skip > 0) { while ($v_skip > 0) { $v_result = '../'.$v_result; $v_skip--; } } } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclZipUtilPathInclusion() // Description : // This function indicates if the path $p_path is under the $p_dir tree. Or, // said in an other way, if the file or sub-dir $p_path is inside the dir // $p_dir. // The function indicates also if the path is exactly the same as the dir. // This function supports path with duplicated '/' like '//', but does not // support '.' or '..' statements. // Parameters : // Return Values : // 0 if $p_path is not inside directory $p_dir // 1 if $p_path is inside directory $p_dir // 2 if $p_path is exactly the same as $p_dir // -------------------------------------------------------------------------------- function PclZipUtilPathInclusion($p_dir, $p_path) { $v_result = 1; // ----- Look for path beginning by ./ if ( ($p_dir == '.') || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); } if ( ($p_path == '.') || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); } // ----- Explode dir and path by directory separator $v_list_dir = explode("/", $p_dir); $v_list_dir_size = sizeof($v_list_dir); $v_list_path = explode("/", $p_path); $v_list_path_size = sizeof($v_list_path); // ----- Study directories paths $i = 0; $j = 0; while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { // ----- Look for empty dir (path reduction) if ($v_list_dir[$i] == '') { $i++; continue; } if ($v_list_path[$j] == '') { $j++; continue; } // ----- Compare the items if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) { $v_result = 0; } // ----- Next items $i++; $j++; } // ----- Look if everything seems to be the same if ($v_result) { // ----- Skip all the empty items while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { // ----- There are exactly the same $v_result = 2; } else if ($i < $v_list_dir_size) { // ----- The path is shorter than the dir $v_result = 0; } } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclZipUtilCopyBlock() // Description : // Parameters : // $p_mode : read/write compression mode // 0 : src & dest normal // 1 : src gzip, dest normal // 2 : src normal, dest gzip // 3 : src & dest gzip // Return Values : // -------------------------------------------------------------------------------- function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) { $v_result = 1; if ($p_mode==0) { while ($p_size != 0) { $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @fread($p_src, $v_read_size); @fwrite($p_dest, $v_buffer, $v_read_size); $p_size -= $v_read_size; } } else if ($p_mode==1) { while ($p_size != 0) { $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @gzread($p_src, $v_read_size); @fwrite($p_dest, $v_buffer, $v_read_size); $p_size -= $v_read_size; } } else if ($p_mode==2) { while ($p_size != 0) { $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @fread($p_src, $v_read_size); @gzwrite($p_dest, $v_buffer, $v_read_size); $p_size -= $v_read_size; } } else if ($p_mode==3) { while ($p_size != 0) { $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); $v_buffer = @gzread($p_src, $v_read_size); @gzwrite($p_dest, $v_buffer, $v_read_size); $p_size -= $v_read_size; } } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclZipUtilRename() // Description : // This function tries to do a simple rename() function. If it fails, it // tries to copy the $p_src file in a new $p_dest file and then unlink the // first one. // Parameters : // $p_src : Old filename // $p_dest : New filename // Return Values : // 1 on success, 0 on failure. // -------------------------------------------------------------------------------- function PclZipUtilRename($p_src, $p_dest) { $v_result = 1; // ----- Try to rename the files if (!@rename($p_src, $p_dest)) { // ----- Try to copy & unlink the src if (!@copy($p_src, $p_dest)) { $v_result = 0; } else if (!@unlink($p_src)) { $v_result = 0; } } // ----- Return return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclZipUtilOptionText() // Description : // Translate option value in text. Mainly for debug purpose. // Parameters : // $p_option : the option value. // Return Values : // The option text value. // -------------------------------------------------------------------------------- function PclZipUtilOptionText($p_option) { $v_list = get_defined_constants(); for (reset($v_list); $v_key = key($v_list); next($v_list)) { $v_prefix = substr($v_key, 0, 10); if (( ($v_prefix == 'PCLZIP_OPT') || ($v_prefix == 'PCLZIP_CB_') || ($v_prefix == 'PCLZIP_ATT')) && ($v_list[$v_key] == $p_option)) { return $v_key; } } $v_result = 'Unknown'; return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclZipUtilTranslateWinPath() // Description : // Translate windows path by replacing '\' by '/' and optionally removing // drive letter. // Parameters : // $p_path : path to translate. // $p_remove_disk_letter : true | false // Return Values : // The path translated. // -------------------------------------------------------------------------------- function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) { if (stristr(php_uname(), 'windows')) { // ----- Look for potential disk letter if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { $p_path = substr($p_path, $v_position+1); } // ----- Change potential windows directory separator if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { $p_path = strtr($p_path, '\\', '/'); } } return $p_path; } // -------------------------------------------------------------------------------- ?> components/com_zoo/helpers/itemorder.php000066600000001571150771655450014572 0ustar00 array('_itemcreated'), 'rdate' => array('_itemcreated', '_reversed'), 'alpha' => array('_itemname'), 'ralpha' => array('_itemname', '_reversed'), 'hits' => array('_itemhits'), 'rhits' => array('_itemhits', '_reversed'), 'random' => array('_random')); return isset($orderings[$order]) ? $orderings[$order] : array('_itemname'); } }components/com_zoo/helpers/modification.php000066600000004416150771655450015246 0ustar00check(); return empty($result); } /** * Checks for ZOO modifications. * * @return array modified files * @throws AppModificationException * @since 2.0 */ public function check() { if (!$checksum = $this->app->path->path('component.admin:checksums')) { throw new AppModificationException(JText::_('Unable to locate checksums file in ' . $this->app->path->path('component.admin:'))); } $path = $this->app->path->path('component.admin:'); $this->app->checksum->verify($path, $checksum, $result, array( create_function('$path', 'return (in_array($path, array("zoo.xml", "file.script.php")) ? "admin/" . $path : $path);'), create_function('$path', 'if (preg_match("#^admin#", $path)) return preg_replace("#^admin/#", "", $path);'), ), $this->app->path->relative($path).'/'); $path = $this->app->path->path('component.site:'); $this->app->checksum->verify($path, $checksum, $result, array( create_function('$path', 'if (preg_match("#^site#", $path)) return preg_replace("#^site/#", "", $path);') ), $this->app->path->relative($path).'/'); return $result; } /** * Cleans any modifications from the filessystem. * * @return boolean true on success * @since 2.0 */ public function clean() { // check for modifications $results = $this->check(); if (isset($results['unknown'])) { foreach ($results['unknown'] as $file) { if (!empty($file) && ($file = $this->app->path->path('root:'.$file))) { // remove unknown file if (!JFile::delete($file)) { $this->app->error->raiseWarning(0, sprintf(JText::_('Could not remove file (%s)'), $file)); } } } } return true; } } /** * AppModificationException identifies an Exception in the ModificationHelper class * @see ModificationHelper */ class AppModificationException extends AppException {}components/com_zoo/helpers/imagethumbnail.php000066600000020063150771655450015563 0ustar00app->object->create('AppImageThumbnail', array($file)); } /** * Checks for the required php functions * * @return boolean * * @since 2.0 */ public function check() { $gd_functions = array( 'getimagesize', 'imagecreatefromgif', 'imagecreatefromjpeg', 'imagecreatefrompng', 'imagecreatetruecolor', 'imagecopyresized', 'imagecopy', 'imagegif', 'imagejpeg', 'imagepng' ); foreach ($gd_functions as $name) { if (!function_exists($name)) return false; } return true; } } /** * Image thumbnail class. * * @package Component.Helpers * @since 2.0 */ class AppImageThumbnail { /** * App instance * * @var App * @since 2.0 */ public $app; /** * The image file path * @var string */ public $img_file; /** * The image format * @var string */ public $img_format; /** * The image source * @var resource */ public $img_source; /** * The image width * @var string */ public $img_width; /** * The image height * @var string */ public $img_height; /** * The thumb width * @var string */ public $thumb_width; /** * The thumb height * @var string */ public $thumb_height; /** * The thumb resize * @var boolean */ public $thumb_resize; /** * The thumb quality * @var int */ public $thumb_quality; /** * Class constructor * * @param string $file The file path. * @since 2.0 */ public function __construct($file) { $this->img_file = $file; $this->thumb_resize = true; $this->thumb_quality = 90; // get image info list($width, $height, $type, $attr) = @getimagesize($this->img_file, $info); // set image dimensions and type if (is_array($info)) { $this->img_width = $width; $this->img_height = $height; $this->thumb_width = $width; $this->thumb_height = $height; switch ($type) { case 1: $this->img_format = 'gif'; $this->img_source = imagecreatefromgif($this->img_file); break; case 2: $this->img_format = 'jpeg'; $this->img_source = imagecreatefromjpeg($this->img_file); break; case 3: $this->img_format = 'png'; $this->img_source = imagecreatefrompng($this->img_file); break; default: $this->img_format = null; $this->img_source = null; break; } } } /** * Set resize * * @param boolean $resize Resize value * * @return void * @since 2.0 */ public function setResize($resize) { $this->thumb_resize = $resize; } /** * Set thumb dimensions * * @param int $width * @param int $height * * @return void * @since 2.0 */ public function setSize($width, $height) { $this->thumb_width = $width; $this->thumb_height = $height; } /** * Size thumb width * * @param int $width * * @return void * @since 2.0 */ public function sizeWidth($width) { $this->thumb_width = $width; $this->thumb_height = @($width / $this->img_width) * $this->img_height; } /** * Size thumb height * * @param int $height * * @return void * @since 2.0 */ public function sizeHeight($height) { $this->thumb_width = @($height / $this->img_height) * $this->img_width; $this->thumb_height = $height; } /** * Save file * * @param string $file the file to save * * @return boolean true on success * @since 2.0 */ public function save($file) { $return = false; if ($this->img_format) { $src = $this->img_source; $src_x = 0; $src_y = 0; // smart resize thumbnail image if ($this->thumb_resize) { $resized_width = @($this->thumb_height / $this->img_height) * $this->img_width; $resized_height = @($this->thumb_width / $this->img_width) * $this->img_height; if ($this->thumb_width <= $resized_width) { $width = $resized_width; $height = $this->thumb_height; $src_x = intval(($resized_width - $this->thumb_width) / 2); } else { $width = $this->thumb_width; $height = $resized_height; $src_y = intval(($resized_height - $this->thumb_height) / 2); } $src = imagecreatetruecolor($width, $height); // save transparent colors if ($this->img_format == 'png') { imagecolortransparent($src, imagecolorallocate($src, 0, 0, 0)); imagealphablending($src, false); imagesavealpha($src, true); } // get and reallocate transparency-color for gif if ($this->img_format == 'gif') { imagealphablending($src, false); $transindex = imagecolortransparent($this->img_source) <= imagecolorstotal($src) ? imagecolortransparent($this->img_source) : imagecolorstotal($src); if ($transindex >= 0) { $transcol = imagecolorsforindex($this->img_source, $transindex); $transindex = imagecolorallocatealpha($src, $transcol['red'], $transcol['green'], $transcol['blue'], 127); imagefill($src, 0, 0, $transindex); } } if (function_exists('imagecopyresampled')) { @imagecopyresampled($src, $this->img_source, 0, 0, 0, 0, $width, $height, $this->img_width, $this->img_height); } else { @imagecopyresized($src, $this->img_source, 0, 0, 0, 0, $width, $height, $this->img_width, $this->img_height); } // restore transparency for gif if ($this->img_format == 'gif') { if ($transindex >= 0) { imagecolortransparent($src, $transindex); for ($y=0; $y < imagesy($src); ++$y) { for ($x=0; $x < imagesx($src); ++$x) { if (((imagecolorat($src, $x, $y)>>24) & 0x7F) >= 100) { imagesetpixel($src, $x, $y, $transindex); } } } } } } // create thumbnail image $thumbnail = imagecreatetruecolor($this->thumb_width, $this->thumb_height); // save transparent colors for png if ($this->img_format == 'png') { imagecolortransparent($thumbnail, imagecolorallocate($src, 0, 0, 0)); imagealphablending($thumbnail, false); imagesavealpha($thumbnail, true); } // get and reallocate transparency-color for gif if ($this->img_format == 'gif') { imagealphablending($thumbnail, false); $transindex = imagecolortransparent($src); if ($transindex >= 0) { $transcol = imagecolorsforindex($src, $transindex); $transindex = imagecolorallocatealpha($thumbnail, $transcol['red'], $transcol['green'], $transcol['blue'], 127); imagefill($thumbnail, 0, 0, $transindex); } } @imagecopy($thumbnail, $src, 0, 0, $src_x, $src_y, $this->thumb_width, $this->thumb_height); // restore transparency for gif if ($this->img_format == 'gif') { if ($transindex >= 0) { imagecolortransparent($thumbnail, $transindex); for ($y=0; $y < imagesy($thumbnail); ++$y) { for ($x=0; $x < imagesx($thumbnail); ++$x) { if (((imagecolorat($thumbnail, $x, $y)>>24) & 0x7F) >= 100) { imagesetpixel($thumbnail, $x, $y, $transindex); } } } } } // save thumbnail to file ob_start(); switch ($this->img_format) { case 'gif': $return = imagegif($thumbnail); break; case 'jpeg': $return = imagejpeg($thumbnail, null, $this->thumb_quality); break; case 'png': $return = imagepng($thumbnail); break; } $output = ob_get_contents(); ob_end_clean(); JFile::write($file, $output); // free memory resources imagedestroy($thumbnail); imagedestroy($src); } return $return; } }components/com_zoo/helpers/export.php000066600000017474150771655450014132 0ustar00app->path->register($this->app->path->path('classes:exporter'), 'exporter'); } /** * Creates an AppExporter instance * * @param string $type Type of AppExporter to create * * @return AppExporter * * @since 2.0 */ public function create($type) { $type = preg_replace('/[^A-Z0-9_\.-]/i', '', $type); // load renderer class $class = 'AppExporter'.$type; $this->app->loader->register($class, 'exporter:'.strtolower($type).'.php'); return $this->app->object->create($class); } /** * Get all exporters * * @param array $ignore Exporters to ignore * * @return array All AppExporters * * @since 2.0 */ public function getExporters($ignore = array()) { $ignore = (array) $ignore; $exporters = array(); foreach ($this->app->path->files('exporter:', false, '/\.php$/') as $file) { if ($instance = $this->create(basename($file, '.php'))) { if (!in_array($instance->getName(), $ignore)) { $exporters[] = $instance; } } } return $exporters; } /** * Exports items of a type to a csv file * * @param Type $type The type object * * @return string File path, false if no items were found * * @since 2.0 */ public function toCSV($type) { $item_table = $this->app->table->item; $type->getApplication()->getCategoryTree(); $data = array(); $i = 1; $maxima = array(); foreach ($item_table->getByType($type->id, $type->getApplication()->id) as $item) { // item properties $data[$i]['Id'] = $item->id; $data[$i]['Name'] = $item->name; $data[$i]['Alias'] = $item->alias; $data[$i]['Author Alias'] = $item->getAuthor(); $data[$i]['Created Date'] = $item->created; // categories $data[$i]['Category'] = array(); foreach ($item->getRelatedCategories() as $category) { $name = $category->name.'|||'.$category->alias; while (($category = $category->getParent()) && $category->id) { $name = $category->name.'|||'.$category->alias."///$name"; } $data[$i]['Category'][] = $name; } // tags $data[$i]['Tag'] = $item->getTags(); // elements foreach ($type->getElements() as $identifier => $element) { if (!isset($item->elements[$identifier])) { continue; } $name = $element->config->get('name') ? $element->config->get('name') : $element->getElementType(); switch ($element->getElementType()) { case 'text': case 'textarea': case 'link': case 'email': case 'date': $data[$i][$name] = array(); foreach ($item->elements[$identifier] as $self) { $data[$i][$name][] = @$self['value']; } break; case 'select': case 'radio': case 'checkbox': $data[$i][$name] = isset($item->elements[$identifier]['option']) ? $item->elements[$identifier]['option'] : array(); break; case 'country': $data[$i][$name] = isset($item->elements[$identifier]['country']) ? $item->elements[$identifier]['country'] : array(); break; case 'gallery': $data[$i][$name] = @$item->elements[$identifier]['value']; break; case 'image': case 'download': $data[$i][$name] = @$item->elements[$identifier]['file']; break; case 'googlemaps': $data[$i][$name] = @$item->elements[$identifier]['location']; break; } } foreach ($data[$i] as $key => $value) { if (is_array($value)) { $maxima[$key] = max(1, @$maxima[$key], count($value)); } } $item_table->unsetObject($item->id); $i++; } if (empty($data)) { return false; } // use maxima to pad arrays foreach ($maxima as $key => $num) { foreach (array_keys($data) as $i) { $data[$i][$key] = array_pad($data[$i][$key], $num, ''); } } // set header array_unshift($data, array()); foreach ($data[1] as $key => $value) { $num = is_array($value) ? count($value) : 1; $data[0] = array_merge($data[0], array_fill(0, max(1, $num), $key)); } $file = rtrim($this->app->system->config->get('tmp_path'), '\/')."/$type->id.csv"; if (($handle = fopen($file, "w")) !== false) { foreach ($data as $row) { fputcsv($handle, $this->app->data->create($row)->flattenRecursive(),'~'); } fclose($handle); } else { throw new AppExporterException(sprintf('Unable to write to file %s.', $file)); } return $file; } } /** * The AppExporter base class. * * @package Component.Helpers * @since 2.0 */ abstract class AppExporter { /** * App instance * * @var App * @since 2.0 */ public $app; /** * The data created during export * * @var array * @since 2.0 */ protected $_data; /** * The exporter name * * @var array * @since 2.0 */ protected $_name; /** * The category attributes that are being exported * * @var array * @since 2.0 */ public $category_attributes = array('parent', 'published', 'description', 'ordering'); /** * The item attributes that are being exported * * @var array * @since 2.0 */ public $item_attributes = array('searchable', 'state', 'created', 'modified', 'hits', 'author', 'access', 'priority', 'publish_up', 'publish_down'); /** * The comment attributes that are being exported * * @var array * @since 2.0 */ public $comment_attributes = array('parent_id', 'user_id', 'user_type', 'author', 'email', 'url', 'ip', 'created', 'content', 'state', 'username'); /** * Class constructor * * @since 2.0 */ public function __construct() { $this->app = App::getInstance('zoo'); $this->_data = $this->app->data->create(array('categories' => array(), 'items' => array())); } /** * Get exporter name * * @return string name * * @since 2.0 */ public function getName() { return $this->_name; } /** * Get exporter type * * @return string type * * @since 2.0 */ public function getType() { return strtolower(str_replace('AppExporter', '', get_class($this))); } /** * Check if exporter is enabled * May be overloaded by the child class. * * @return boolean * * @since 2.0 */ public function isEnabled() { return true; } /** * Do the export. * Must be overloaded by the child class. * * @return string The export xml * * @since 2.0 */ public function export() { return (string) $this->_data; } /** * Adds a category to the exporters data * * @param string $name Category name * @param string $id Category id * @param array $data Category data * * @return self * * @since 2.0 */ protected function _addCategory($name, $id = '', $data = array()) { if (empty($id)) { $id = JFilterOutput::stringURLSafe($name); } while (isset($this->_data['categories'][$id])) { $id .= '-2'; } $data['name'] = $name; $this->_data['categories'][$id] = $data; return $this; } /** * Adds an item to the exporters data * * @param string $name Item name * @param string $id Item id * @param array $group Item group * @param array $data Item data * * @return self * * @since 2.0 */ protected function _addItem($name, $id = '', $group = 'default', $data = array()) { if (empty($id)) { $id = JFilterOutput::stringURLSafe($name); } while (isset($this->_data['items'][$id])) { $id .= '-2'; } $data['group'] = $group; $data['name'] = $name; $this->_data['items'][$id] = $data; return $this; } } /** * AppExporterException identifies an Exception in the AppExporter class * @see AppExporter */ class AppExporterException extends AppException {}components/com_zoo/helpers/backup.php000066600000007562150771655450014053 0ustar00 $define) { if (preg_match('/^ZOO_TABLE_/', $key)) { $tables[$key] = $define; } } return $tables; } /** * Creates a backup of all ZOO tables * * @param callable $callback A callback to be called on all result rows * * @return string|false filename on success, else false * * @since 2.0 */ public function all($callback = true) { return $this->table($this->getTables(), $callback); } /** * Creates a backup of tables * * @param array $tables Table(s) to backup * @param function $callback The callback to call when the backup is done. Default: false * * @return string the mysql statements * * @since 2.0 */ public function table($tables, $callback = false) { // set_time_limit doesn't work in safe mode if (!ini_get('safe_mode')) { @set_time_limit(0); } // init vars $db = $this->app->database; $tables = (array) $tables; $result = array(); if (!empty($tables)) { foreach ($tables as $table) { $table = $db->replacePrefix($table); // create comments $result[] = "\n\n-- --------------------------------------------------------\n"; $result[] = '--'; $result[] = '-- Table structure for table '.$table; $result[] = "--\n"; $rows = $db->queryAssocList('SELECT * FROM '.$table); if (is_callable($callback)) { $rows = array_map($callback, $rows); } $result[] = 'DROP TABLE IF EXISTS '.$table.';'; $create = $db->queryAssoc('SHOW CREATE TABLE '.$table); $create = preg_replace("#(TYPE)=(MyISAM)#i", "ENGINE=MyISAM", $create); $create = $create['Create Table']; $result[] = "$create;\n"; // create comments $result[] = '--'; $result[] = '-- Table data for table '.$table; $result[] = '--'; $insert = 'INSERT INTO '.$table.' VALUES('; foreach ($rows as $row) { $result[] = $insert.'"'.implode('","', array_map(array($db, 'escape'), $row))."\");"; } } return implode("\n", $result); } } /** * Restores a backup from sql dump file * * @param array $file The sql dump file * * @return boolean true on success * * @since 2.0 */ public function restore($file) { if (JFile::exists($file)) { $db = $this->app->database; // read index.sql $buffer = file_get_contents($file); // Create an array of queries from the sql file jimport('joomla.installer.helper'); $queries = JInstallerHelper::splitSql($buffer); if (!empty($queries)) { foreach ($queries as $query) { $query = trim($query); if (!empty($query)) { $db->query($query); } } return true; } } throw new RuntimeException("File not found ($file)"); } /** * Generates a header for the backup file * * @return string The header for the backup file * * @since 2.0 */ public function generateHeader() { $header = array('-- ZOO SQL Dump'); $header[] = '-- version '.$this->app->zoo->version(); $header[] = '-- http://www.yootheme.com'; $header[] = '--'; $header[] = '-- Host: '.trim(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''); $header[] = '-- Creation Date: '.$this->app->date->create()->format('%Y-%m-%d %H:%M:%S'); $header[] = '-- Server Software: '.trim(isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : ''); $header[] = "\n"; $header[] = '-- '; $header[] = '-- Database: '.$this->app->system->config->get('db'); $header[] = '-- '; return implode("\n", $header); } }components/com_zoo/helpers/archive.php000066600000003175150771655450014223 0ustar00loader->register('PclZip', 'libraries:pcl/pclzip.lib.php'); } /** * Open an archive file, works for zip archives only * * @param string $file The full file path to open * @param string $format The file format. If not specified, will be guessed by the file extension (currently works for zip archives only) * * @return PclZip * * @since 2.0 */ public function open($file, $format = 'zip') { // auto-detect format if (!$format) { $format = $this->format($file); } // create archive object if ($format == 'zip') { return new PclZip($file); } return null; } /** * Get the archive format based on the file extension * * Any tar-related format (tgz, gz, etc) will be returned as tar * * @param string $file The filename or the full file path * * @return string The file format (zip or tar) * * @since 2.0 */ public function format($file) { // detect .zip format if (preg_match('/\.zip$/i', $file)) { return 'zip'; } // detect .tar format if (preg_match('/\.tar$|\.tar\.gz$|\.tgz$|\.tar\.bz2$|\.tbz2$/i', $file)) { return 'tar'; } return null; } }components/com_zoo/helpers/submission.php000066600000005655150771655450015002 0ustar00 $value) { $result[$key] = $this->filterData($value); } return $result; } elseif (is_object($data)) { $result = new stdClass(); foreach (get_object_vars($data) as $key => $value) { $result->$key = $this->filterData($value); } return $result; } else { // remove all html tags or escape if in [code] tag $data = preg_replace_callback('/\[code\](.+?)\[\/code\]/is', create_function('$matches', 'return htmlspecialchars($matches[0]);'), $data); $data = strip_tags($data); return $data; } } /** * Retrieve hash of submission, type, item. * * @param int $submission_id * @param string $type_id * @param int $item_id * * @return string The resulting hash * @since 2.0 */ public function getSubmissionHash($submission_id, $type_id, $item_id = 0) { // get secret from config $secret = $this->app->system->config->get('config.secret'); $item_id = empty($item_id) ? 0 : $item_id; return md5($submission_id.$type_id.$item_id.$secret); } /** * Send notification email * * @param Item $item Item * @param array $recipients Array email => name * @param string $layout The layout * * @since 2.0 */ public function sendNotificationMail($item, $recipients, $layout) { // workaround to make sure JSite is loaded $this->app->loader->register('JSite', 'root:includes/application.php'); // init vars $website_name = $this->app->system->config->get('sitename'); $item_link = JURI::root().'administrator/index.php?'.http_build_query(array( 'option' => $this->app->component->self->name, 'controller' => 'item', 'changeapp' => $item->application_id, 'task' => 'edit', 'cid[]' => $item->id, ), '', '&'); // send email to $recipients foreach ($recipients as $email => $name) { if (empty($email)) { continue; } $mail = $this->app->mail->create(); $mail->setSubject(JText::_("New Submission notification")." - ".$item->name); $mail->setBodyFromTemplate($item->getApplication()->getTemplate()->resource.$layout, compact( 'item', 'submission', 'website_name', 'email', 'name', 'item_link' )); $mail->addRecipient($email); $mail->Send(); } } } /** * SubmissionHelperException identifies an Exception in the SubmissionHelper class * @see SubmissionHelper */ class SubmissionHelperException extends AppException {}components/com_zoo/helpers/import.php000066600000056656150771655450014130 0ustar00app->data->create(file_get_contents($json_file)))) { throw new ImportHelperException('No valid json file.'); } // get application if (!$application = $this->app->zoo->getApplication()) { throw new ImportHelperException('No application to import too.'); } // import frontpage if (isset($data['categories'], $data['categories']['_root']) && $import_frontpage) { $this->_importFrontpage($application, $data['categories']['_root']); } // import categories $categories = array(); if (isset($data['categories']) && count($data['categories']) && $import_categories) { $categories_to_import = $data['categories']; unset($categories_to_import['_root']); $categories = $this->_importCategories($application, $categories_to_import); } // import items if (isset($data['items'])) { $this->_importItems($application, $data['items'], $element_assignment, $types, $categories); } return true; } /** * Import the frontpage settings * * @param Application $application The Application object * @param array $frontpage the frontpage settings * * @since 2.0 */ private function _importFrontpage(Application $application, $frontpage) { $application->description = $frontpage['description']; // set frontpage content params if (isset($frontpage['content'])) { $application->getParams()->set('content.', $frontpage['content']); } // set frontpage metadata params if (isset($frontpage['metadata'])) { $application->getParams()->set('metadata.', $frontpage['metadata']); } // save application try { $this->app->table->application->save($application); } catch (AppException $e) { $this->app->error->raiseNotice(0, JText::_('Error Importing Frontpage').' ('.$e.')'); } } /** * Import the categories * * @param Application $application The Application object * @param array $categories the categories data * * @since 2.0 */ private function _importCategories(Application $application, $categories = array()) { // init vars $db = $this->app->database; $table = $this->app->table->category; $category_vars = array_keys(get_class_vars('Category')); // first iteration: save category vars $category_objects = array(); foreach ($categories as $alias => $category) { $category_obj = $this->app->object->create('Category'); $category_obj->alias = $this->app->string->sluggify($alias); // set a valid category alias $category_obj->alias = $this->app->alias->category->getUniqueAlias(0, $category_obj->alias); // set category values foreach ($category as $property => $value) { if (in_array($property, $category_vars)) { $category_obj->$property = $value; } } $category_obj->parent = 0; $category_obj->application_id = $application->id; // set category content params if (isset($category['content'])) { $category_obj->getParams()->set('content.', $category['content']); } // set category metadata params if (isset($category['metadata'])) { $category_obj->getParams()->set('metadata.', $category['metadata']); } $db->query('INSERT INTO '.ZOO_TABLE_CATEGORY.'(alias) VALUES ('.$db->quote($category_obj->alias).')'); $category_obj->id = $db->insertid(); // store category for second iteration $category_objects[$alias] = $category_obj; } // second iteration: set parent relationship foreach ($categories as $alias => $category) { // only save if parent is set if (isset($category_objects[$alias])) { if (!empty($category['parent']) && $category['parent'] != '_root') { $category_objects[$alias]->parent = $category_objects[$category['parent']]->id; } } // save the category try { $table->save($category_objects[$alias]); } catch (AppException $e) { $this->app->error->raiseNotice(0, JText::_('Error Importing Category').' ('.$e.')'); } } return $category_objects; } /** * Imports the items * * @param Application $application The Application object * @param array $items the items to import * @param array $element_assignment The element assignment array * @param array $types The selected types array * @param array $categories The category objects * * @since 2.0 */ private function _importItems(Application $application, $items = array(), $element_assignment = array(), $types = array(), $categories = array()) { // init vars $db = $this->app->database; $table = $this->app->table->item; $comment_table = $this->app->table->comment; $item_vars = array_keys(get_class_vars('Item')); $comment_vars = array_keys(get_class_vars('Comment')); $user_id = $this->app->user->get()->get('id'); $app_types = $application->getTypes(); $authors = $this->app->data->create($db->queryObjectList('SELECT id, username, name FROM #__users', 'id')); // disconnect from comment save event $this->app->event->dispatcher->disconnect('comment:saved', array('CommentEvent', 'saved')); $item_objects = array(); foreach ($items as $alias => $item) { if (isset($item['group'], $types[$item['group']]) && !empty($types[$item['group']]) && $type = $app_types[$types[$item['group']]]) { $item_obj = $this->app->object->create('Item'); $item_obj->alias = $this->app->string->sluggify($alias); $item_obj->type = $type->id; // set a valid category alias $item_obj->alias = $this->app->alias->item->getUniqueAlias(0, $item_obj->alias); $db->query('INSERT INTO '.$table->name.'(alias) VALUES ('.$db->quote($item_obj->alias).')'); $item_obj->id = $db->insertid(); // set item values foreach ($item as $property => $value) { if (in_array($property, $item_vars)) { $item_obj->$property = $value; } } // fix access if j16 if ($this->app->joomla->version->isCompatible('1.6') && $item_obj->access == 0) { $item_obj->access = $this->app->joomla->getDefaultAccess(); } // store application id $item_obj->application_id = $application->id; // store tags if (isset($item['tags'])) { $item_obj->setTags($item['tags']); } // store author $item_obj->created_by_alias = ""; if (isset($item['author'])) { if ($key = $authors->searchRecursive($item['author'])) { $item_obj->created_by = (int) $authors[$key]->id; } else { $item_obj->created_by_alias = $item['author']; } } // if author is unknown set current user as author if (!$item_obj->created_by) { $item_obj->created_by = $user_id; } // store modified_by $item_obj->modified_by = $user_id; // store element_data $item_obj->elements = $this->app->data->create(); if (isset($item['elements'])) { foreach ($item['elements'] as $old_element_alias => $element) { if (isset($element['data']) && isset($element_assignment[$item['group']][$old_element_alias][$type->id]) && ($element_alias = $element_assignment[$item['group']][$old_element_alias][$type->id]) && ($element_obj = $item_obj->getElement($element_alias))) { $element_obj->bindData($element['data']); } } } // set metadata, content, config params $item_obj->getParams()->set('metadata.', @$item['metadata']); $item_obj->getParams()->set('content.', @$item['content']); $item_obj->getParams()->set('config.', @$item['config']); $item_objects[$alias] = $item_obj; // save item -> category relationship if (isset($item['categories'])) { if (isset($item['config']['primary_category'], $categories[$item['config']['primary_category']])) { $item_obj->getParams()->set('config.primary_category', $categories[$item['config']['primary_category']]->id); } else if (isset($item['config']['primary_category']) && $id = $this->app->alias->category->translateAliasToID($item['config']['primary_category'])) { $item_obj->getParams()->set('config.primary_category', $id); } $item_categories = array(); foreach ($item['categories'] as $category_alias) { if (isset($categories[$category_alias]) || $category_alias == '_root') { $item_categories[] = $category_alias == '_root' ? 0 : (int) $categories[$category_alias]->id; } else if ($id = $this->app->alias->category->translateAliasToID($category_alias)) { $item_categories[] = $id; } } if (!empty($item_categories)) { $this->app->category->saveCategoryItemRelations($item_obj, $item_categories); } } // save comments if (isset($item['comments']) && is_array($item['comments'])) { $comments = array(); foreach ($item['comments'] as $key => $comment) { $comment_obj = $this->app->object->create('comment'); $comment_obj->item_id = $item_obj->id; // set item values foreach ($comment as $property => $value) { if (in_array($property, $comment_vars)) { $comment_obj->$property = $value; } } if (isset($comment_obj->user_type) && $comment_obj->user_type == 'joomla') { if (isset($comment['username']) && ($key = $authors->searchRecursive($comment['username']))) { $comment_obj->user_id = (int) $authors[$key]->id; $comment_obj->author = (string) $authors[$key]->name; } else { $comment_obj->user_id = $comment_obj->user_type = ''; } } $comment_table->save($comment_obj); $comments[$key] = $comment_obj; } // sanatize parent ids foreach ($comments as $key => $comment) { if ($comment->parent_id && isset($comments[$comment->parent_id])) { $comment->parent_id = $comments[$comment->parent_id]->id; $comment_table->save($comment); } } } } } foreach ($item_objects as $item) { foreach ($item->getElements() as $element) { // sanatize relateditems elements if ($element->getElementType() == 'relateditems') { $relateditems = $element->get('item', array()); $new_related_items = array(); foreach ($relateditems as $relateditem) { if (isset($items[$relateditem])) { $new_related_items[] = $item_objects[$relateditem]->id; } } $element->set('item', $new_related_items); // sanitize relatedcategories elements aliases } else if ($element->getElementType() == 'relatedcategories') { $relatedcategories = $element->get('category', array()); $new_related_categories = array(); foreach ($relatedcategories as $relatedcategory) { if (isset($categories[$relatedcategory])) { $new_related_categories[] = $categories[$relatedcategory]->id; } else if ($id = $this->app->alias->category->translateAliasToID($relatedcategory)) { $new_related_categories[] = $id; } } $element->set('category', $new_related_categories); } } try { $table->save($item); } catch (AppException $e) { $this->app->error->raiseNotice(0, JText::_('Error Importing Item').' ('.$e.')'); } } return $item_objects; } /** * Builds the assign element info from JSON. * * @param AppData $data the export data * * @return array Assign element info */ public function getImportInfo(AppData $data) { $info = array(); $application = $this->app->zoo->getApplication(); // get frontpage count $info['frontpage_count'] = (bool) $data->find('categories._root'); // get category count $info['category_count'] = max(array(count($data->get('categories', array())) - ((int) $info['frontpage_count']), 0)); // get types $type_elements = array(); foreach ($application->getTypes() as $type) { foreach ($type->getElements() as $element) { $type_elements[$type->id][$element->getElementType()][] = $element; } } // get item types $info['items'] = array(); foreach ($data->get('items', array()) as $alias => $item) { $group = $item['group']; if (!isset($info['items'][$group])) { $info['items'][$group]['item_count'] = 0; $info['items'][$group]['elements'] = array(); if (isset($item['elements'])) { foreach ($item['elements'] as $alias => $element) { if (!isset($info['items'][$group]['elements'][$alias])) { // add element type $info['items'][$group]['elements'][$alias]['type'] = ucfirst($element['type']); // add element name $info['items'][$group]['elements'][$alias]['name'] = $element['name']; // add elements to assign too $info['items'][$group]['elements'][$alias]['assign'] = array(); foreach ($type_elements as $type => $assign_elements) { if (isset($assign_elements[$element['type']])) { $info['items'][$group]['elements'][$alias]['assign'][$type] = $assign_elements[$element['type']]; } } } } } } $info['items'][$group]['item_count'] += 1; } return $info; } /** * Import from JSON file. * * @param string $file The csv file * @param string $type The type to import to * @param boolean $contains_headers does the csv file contain a header row * @param string $field_separator the field separator * @param string $field_enclosure the field enclosure * @param string $element_assignment the element assignment * * @return boolean true on success * @throws ImportHelperException * @since 2.0 */ public function importCSV($file, $type = '', $contains_headers = false, $field_separator = ',', $field_enclosure = '"', $element_assignment = array()) { // set_time_limit doesn't work in safe mode if (!ini_get('safe_mode')) { @set_time_limit(0); } // get application if (!$application = $this->app->zoo->getApplication()) { throw new ImportHelperException('No application to import too.'); } if (!$type_obj = $application->getType($type)) { throw new ImportHelperException('Could not find type.'); } $assignments = array(); foreach ($element_assignment as $column => $value) { if (!empty($value[$type])) { $assignments[$value[$type]][] = $column; } } if (!isset($assignments['_name'])) { throw new ImportHelperException('No item name was assigned.'); } // make sure the line endings are recognized irrespective of the OS ini_set('auto_detect_line_endings', true); if (($handle = fopen($file, "r")) === FALSE) { throw new ImportHelperException('Could not open csv file.'); } $item_table = $this->app->table->item; $category_table = $this->app->table->category; $user_id = $this->app->user->get()->get('id'); $now = $this->app->date->create()->toSQL(); $access = $this->app->joomla->getDefaultAccess(); $app_categories = $application->getCategories(); $app_category_names = array_map(create_function('$cat', 'return $cat->name;'), $app_categories); $app_category_alias = array_map(create_function('$cat', 'return $cat->alias;'), $app_categories); $alias_matches = array(); while (($data = fgetcsv($handle, 0, $field_separator, $field_enclosure)) !== FALSE) { if ($contains_headers) { $contains_headers = false; continue; } $item = false; // First check: is there an _id specified? if so, try to load the item if (isset($assignments['_id']) && is_array($assignments['_id'])) { $column = current($assignments['_id']); if ($id = (int) @$data[$column]) { $item = $item_table->get($id); if ($item->application_id != $application->id) { $item = false; } } } if (!$item) { $item = $this->app->object->create('Item'); $item->application_id = $application->id; $item->type = $type; // set access $item->access = $access; // store created by $item->created_by = $user_id; // set created, modified $item->created = $item->modified = $now; // store modified_by $item->modified_by = $user_id; } // store element_data and item name $item_categories = array(); $tags = array(); $elements = $item->getElements(); foreach ($assignments as $assignment => $columns) { $column = current($columns); switch ($assignment) { case '_name': $item->name = trim(@$data[$column]); break; case '_alias': $item->alias = $this->app->string->sluggify(@$data[$column]); break; case '_created_by_alias': $item->created_by_alias = @$data[$column]; break; case '_created': if (!empty($data[$column])) { $item->created = $data[$column]; } break; default: if (substr($assignment, 0, 9) == '_category') { foreach ($columns as $column) { $item_categories[] = @$data[$column]; } } else if (substr($assignment, 0, 4) == '_tag') { foreach ($columns as $column) { $tags[] = @$data[$column]; } } else if (isset($elements[$assignment])) { switch ($elements[$assignment]->getElementType()) { case 'text': case 'textarea': case 'link': case 'email': case 'date': $element_data = array(); foreach ($columns as $column) { if (is_numeric($data[$column]) || !empty($data[$column])) { $element_data[$column] = array('value' => $data[$column]); } } $elements[$assignment]->bindData($element_data); break; case 'country': $element_data = array(); foreach ($columns as $column) { if (!empty($data[$column])) { $element_data['country'][] = $data[$column]; } } $elements[$assignment]->bindData($element_data); break; case 'select': case 'radio': case 'checkbox': $element_data = array(); foreach ($columns as $column) { if (is_numeric($data[$column]) || !empty($data[$column])) { $element_data['option'][] = $data[$column]; } } $elements[$assignment]->bindData($element_data); break; case 'gallery': $data[$column] = trim(@$data[$column], '/\\'); $elements[$assignment]->bindData(array('value' => $data[$column])); break; case 'image': case 'download': $elements[$assignment]->bindData(array('file' => @$data[$column])); break; case 'googlemaps': $elements[$assignment]->bindData(array('location' => @$data[$column])); break; } } break; } } if (empty($item->name)) { continue; } $item->setTags($tags); // If not alias was set, use the name to generate it if (!strlen(trim($item->alias))) { $item->alias = $this->app->string->sluggify($item->name); } if (empty($item->alias)) { $item->alias = '42'; } // set a valid category alias $item->alias = $this->app->alias->item->getUniqueAlias($item->id, $item->alias); try { $item_table->save($item); // store categories $related_categories = array(); foreach ($item_categories as $category_name) { $names = array_filter(explode('///', $category_name)); $previous_id = 0; $found = true; for ($i = 0; $i < count($names); $i++) { list($name, $alias) = array_pad(explode('|||', $names[$i]), 2, false); // did the alias change? if ($alias && isset($alias_matches[$alias])) { $alias = $alias_matches[$alias]; } // try to find category through alias, if category is not found, try to match name if (!($id = array_search($alias, $app_category_alias)) && !$alias) { $id = array_search($name, $app_category_names); foreach (array_keys($app_category_names, $name) as $key) { if ($previous_id && isset($app_categories[$key]) && $app_categories[$key]->parent == $previous_id) { $id = $key; } } } if (!$found || !$id) { $found = false; $category = $this->app->object->create('Category'); $category->application_id = $application->id; $category->name = trim($name); $category->parent = $previous_id; // set a valid category alias $category->alias = $this->app->alias->category->getUniqueAlias(0, $this->app->string->sluggify($alias ? $alias : $name)); try { $category_table->save($category); $app_categories[$category->id] = $category; $app_category_names[$category->id] = $category->name; $app_category_alias[$category->id] = $alias_matches[$alias] = $category->alias; $id = $category->id; } catch (CategoryTableException $e) {} } if ($id && $i == count($names) - 1) { $related_categories[] = $id; } else { $previous_id = $id; } } } // add category to item relations if (!empty($related_categories)) { $this->app->category->saveCategoryItemRelations($item, $related_categories); // make first category found primary category if (!$item->getPrimaryCategoryId()) { $item->getParams()->set('config.primary_category', $related_categories[0]); $item_table->save($item); } } } catch (ItemTableException $e) {} } fclose($handle); return true; } /** * Builds the assign element info from csv. * * @param string $file * @param boolean $contains_headers * @param string $field_separator * @param string $field_enclosure * * @return array Assign element info * @since 2.0 */ public function getImportInfoCSV($file, $contains_headers = false, $field_separator = ',', $field_enclosure = '"') { $info = array(); $application = $this->app->zoo->getApplication(); // get types $info['types'] = array(); foreach ($application->getTypes() as $type) { $info['types'][$type->id] = array(); foreach ($type->getElements() as $element) { // filter elements if (in_array($element->getElementType(), array('text', 'textarea', 'link', 'email', 'image', 'gallery', 'download', 'date', 'googlemaps', 'country', 'select', 'radio', 'checkbox'))) { $info['types'][$type->id][$element->getElementType()][] = $element; } } } // get item types $info['item_count'] = 0; $info['columns'] = array(); // make sure the line endings are recognized irrespective of the OS ini_set('auto_detect_line_endings', true); // get column names and row count $row = 0; if (($handle = fopen($file, "r")) !== false) { while (($data = fgetcsv($handle, 0, $field_separator, $field_enclosure)) !== false) { if ($row == 0) { // get column names from header row if ($contains_headers) { $info['columns'] = $data; } else { $info['columns'] = array_fill(0, count($data), ''); } } // get max column count $row++; } // get item count $info['item_count'] = $contains_headers ? $row - 1 : $row; fclose($handle); } return $info; } } /** * ImportHelperException identifies an Exception in the ImportHelper class * @see ImportHelper */ class ImportHelperException extends AppException {}components/com_zoo/helpers/tag.php000066600000001427150771655450013353 0ustar00app->table->tag->getAll($application_id, $tag, '', 'a.name asc'); foreach ($tag_objects as $tag) { $tags[] = $tag->name; } } return json_encode($tags); } } components/com_zoo/helpers/plugin.php000066600000001011150771655450014063 0ustar00app->database->query("UPDATE #__extensions SET enabled = 1 WHERE element = '$plugin'"); } }components/com_zoo/helpers/zoo.php000066600000017766150771655450013424 0ustar00_application)) { return $this->_application; } // get joomla and application table $joomla = $this->app->system->application; $table = $this->app->table->application; // handle admin if ($joomla->isAdmin()) { // create application from user state, or search for default $id = $joomla->getUserState('com_zooapplication'); $apps = $table->all(array('order' => 'name')); if (isset($apps[$id])) { $this->_application = $apps[$id]; } else if (!empty($apps)) { $this->_application = array_shift($apps); } return $this->_application; } // handle site if ($joomla->isSite()) { // get component params $params = $joomla->getParams(); // create application from menu item params / request if ($item_id = $this->app->request->getInt('item_id') and $item = $this->app->table->item->get($item_id)) { $this->_application = $item->getApplication(); } else if ($category_id = $this->app->request->getInt('category_id') and $category = $this->app->table->category->get($category_id)) { $this->_application = $category->getApplication(); } else if ($submission_id = $this->app->request->getInt('submission_id') and $submission = $this->app->table->submission->get($submission_id)) { $this->_application = $submission->getApplication(); } else if ($id = $this->app->request->getInt('app_id')) { $this->_application = $table->get($id); } else if ($id = $params->get('application') and $application = $table->get((int) $id)) { $this->_application = $application; } else { // try to get application from default menu item $menu = $this->app->system->application->getMenu('site'); $default = $menu->getDefault(); if (isset($default->component) && $default->component == 'com_zoo') { if ($app_id = $menu->getParams($default->id)->get('application')) { $this->_application = $table->get((int) $app_id); } } } // trigger event $this->app->event->dispatcher->notify($this->app->event->create(null, 'zoo:initApp', array('application' => &$this->_application))); return $this->_application; } return null; } /** * Add help button to current toolbar to show help url in popup window. * * @param string $ref Help url * @since 2.0 */ public function toolbarHelp($ref = 'http://docs.yootheme.com/home/category/zoo-20') { JToolBar::getInstance('toolbar')->appendButton('Link', 'help', 'Help', $ref); } /** * Resize and cache image file. * * @param string $file * @param int $width * @param int $height * * @return string image path * @since 2.0 */ public function resizeImage($file, $width, $height) { // init vars $width = (int) $width; $height = (int) $height; $file_info = pathinfo($file); $thumbfile = $this->app->path->path('cache:').'/images/'.$file_info['filename'].'_'.md5($file.$width.$height).'.'.$file_info['extension']; $cache_time = 86400; // cache time 24h // check thumbnail directory if (!JFolder::exists(dirname($thumbfile))) { JFolder::create(dirname($thumbfile)); } // create or re-cache thumbnail if ($this->app->imagethumbnail->check() && (!is_file($thumbfile) || ($cache_time > 0 && time() > (filemtime($thumbfile) + $cache_time)))) { $thumbnail = $this->app->imagethumbnail->create($file); if ($width > 0 && $height > 0) { $thumbnail->setSize($width, $height); $thumbnail->save($thumbfile); } else if ($width > 0 && $height == 0) { $thumbnail->sizeWidth($width); $thumbnail->save($thumbfile); } else if ($width == 0 && $height > 0) { $thumbnail->sizeHeight($height); $thumbnail->save($thumbfile); } else { if (JFile::exists($file)) { JFile::copy($file, $thumbfile); } } $this->putIndexFile(dirname($thumbfile)); } if (is_file($thumbfile)) { return $thumbfile; } return $file; } /** * Trigger joomla content plugins on given text. * * @param string $text * @param array $params * @param string $context * * @return string The text after the plugins are applied to it * @since 2.0 */ public function triggerContentPlugins($text, $params = array(), $context = 'com_zoo') { // import joomla content plugins JPluginHelper::importPlugin('content'); $registry = new JRegistry(''); $registry->loadArray($params); $dispatcher = JDispatcher::getInstance(); $article = new stdClass; $article->text = $text; // disable loadmodule plugin on feed view if ($this->app->document->getType() == 'feed') { $plugin = JPluginHelper::getPlugin('content', 'loadmodule'); if ($this->app->parameter->create($plugin->params)->get('enabled', 1)) { // expression to search for $regex = '/{loadposition\s*.*?}/i'; $article->text = preg_replace($regex, '', $article->text); } } $dispatcher->trigger('onContentPrepare', array($context, &$article, &$registry, 0)); return $article->text; } /** * Returns user group objects. * * @return array * @since 2.0 */ public function getGroups() { if (!isset($this->_groups)) { $this->_groups = $this->app->database->queryObjectList("SELECT id, title AS name FROM #__viewlevels", "id"); } return $this->_groups; } /** * Return user group object. * * @param string $id * * @return object group * @since 2.0 */ public function getGroup($id) { $groups = $this->getGroups(); return isset($groups[$id]) ? $groups[$id] : (object) array('id' => '', 'name' => ''); } /** * Returns current ZOO version. * * @return string version * @since 2.0 */ public function version() { if (empty($this->_version) and $xml = @simplexml_load_file($this->app->path->path('component.admin:zoo.xml')) and ((string) $xml->name == 'ZOO' || (string) $xml->name == 'com_zoo')) { $this->_version = (string) current($xml->xpath('//version')); } return $this->_version; } /** * Build page title from Joomla configuration. * * @param string $title * * @return string title * @since 2.0 */ public function buildPageTitle($title) { $dir = $this->app->system->config->get('sitename_pagetitles', 0); if ($dir == 1) { return JText::sprintf('JPAGETITLE', $this->app->system->config->get('sitename'), $title); } else if ($dir == 2) { return JText::sprintf('JPAGETITLE', $title, $this->app->system->config->get('sitename')); } return $title; } /** * Puts an index.html into given directory * * @param string $dir * @since 2.0 */ public function putIndexFile($dir) { $dir = rtrim($dir, "\\/"); if (!JFile::exists($dir.'/index.html')) { $buffer = ''; JFile::write($dir.'/index.html', $buffer); } } /** * Gets the application groups * * @return array groups * @since 2.0 * * @deprecated 2.5.11 use ApplicationHelper::groups() */ public function getApplicationGroups() { return $this->app->application->groups(); } /** * Gets the application layouts * * @param Application $application The application object * @param string $type_id The id of the type * @param string $layout_type The type of the layout to fetch. Default: all * * @return array layouts * @since 2.0 * * @deprecated 2.5.11 use TypeHelper::layouts() */ public function getLayouts($application, $type_id, $layout_type = '') { return $this->app->type->layouts($application->getType($type_id), $layout_type); } }components/com_zoo/helpers/alphaindex.php000066600000010752150771655450014716 0ustar00app->object->create('AppAlphaindex', array($path)); } } /** * The AppAlphaindex Class. Provides Alphaindex functionality. * * @package Component.Helpers * @since 2.0 */ class AppAlphaindex { /** * App instance * * @var App * @since 2.0 */ public $app; /** * The character index * * @var array * @since 2.0 */ protected $_index = array(); /** * The object key mapping * * @var array * @since 2.0 */ protected $_objects = array(); /** * The "other" character * * @var string * @since 2.0 */ protected $_other = '#'; /** * Class constructor * * @param string $path Path to xml alphaindex definition. * @since 2.0 */ public function __construct($path) { if ($xml = simplexml_load_file($path)) { // add other character if ($xml->attributes()->other) { $this->_other = (string) $xml->attributes()->other; } // add characters foreach ($xml->children() as $option) { if (!in_array((string) $option, $this->_index)) { $key = $option->attributes()->value ? (string) $option->attributes()->value : (string) $option; $this->_index[$key] = (string) $option; } } } } /** * Retrieve character index. * * @param boolean $other Include other character in index * * @return array The index * * @since 2.0 */ public function getIndex($other = false) { $index = $this->_index; $key = $other ? false : array_search($this->_other, $index); if ($key !== false) { unset($index[$key]); } return $index; } /** * Retrieve character for items which are not indexed, usually #. * * @return string The other character * * @since 2.0 */ public function getOther() { return $this->_other; } /** * Retrieve alpha char from value. * * @param string $value The value to look for in the index * * @return string The alpha character * * @since 2.0 */ public function getChar($value) { return isset($this->_index[$value]) ? $this->_index[$value] : ''; } /** * Retrieve objects which match a character in index. * * @param string $char Index character * @param string $class_name Retrieve only objects of a certain class * * @return array The objects * * @since 2.0 */ public function getObjects($char, $class_name = null) { $key = array_search($char, $this->_index); if ($key !== false && isset($this->_objects[$key])) { if ($class_name !== null) { return array_filter($this->_objects[$key], create_function('$object', 'return $object instanceof '.$class_name.';')); } return $this->_objects[$key]; } return array(); } /** * Add objects to index. * * @param array $objects Object array * @param string $property Object property to use for indexing * * @return void * * @since 2.0 */ public function addObjects($objects, $property) { $index = $this->getIndex(); foreach ($objects as $object) { if (isset($object->$property)) { $char = $this->app->string->strtolower($this->app->string->substr($object->$property, 0, 1)); $key = array_search($char, $index); if ($key !== false) { $this->_objects[$key][] = $object; } else { $this->_objects[array_search($this->getOther(), $this->_index)][] = $object; } } } return $this; } /** * Render the alphaindex. * * @param Application The app to use as base for the routes * @return string Alphaindex html * * @since 2.0 */ public function render(Application $app = null) { if (!$app) { $app = $this->app->zoo->getApplication(); } // check if index is empty if (empty($this->_index)) { return ''; } $html = array(); // create html foreach ($this->_index as $key => $char) { if (isset($this->_objects[$key]) && count($this->_objects[$key])) { $html[] = ''.$char.''; } else { $html[] = ''.$char.''; } } return implode("\n", $html); } }components/com_zoo/helpers/comment.php000066600000027670150771655450014252 0ustar00getApplication()->isCommentsEnabled()) { // get application params $params = $this->app->parameter->create($item->getApplication()->getParams()->get('global.comments.')); if ($params->get('twitter_enable') && !function_exists('curl_init')) { $this->app->error->raiseWarning(500, JText::_('To use Twitter, CURL needs to be enabled in your php settings.')); $params->set('twitter_enable', false); } // get active author $active_author = $this->activeAuthor(); // get comment content from session $content = $this->app->system->session->get('com_zoo.comment.content'); $params->set('content', $content); // get comments and build tree $comments = $item->getCommentTree(Comment::STATE_APPROVED); // build captcha $captcha = false; if ($plugin = $params->get('captcha', false) and (!$params->get('captcha_guest_only', 0) or !$this->app->user->get()->id)) { $captcha = JCaptcha::getInstance($plugin); } if ($item->isCommentsEnabled() || count($comments)-1) { // create comments html return $view->partial('comments', compact('item', 'active_author', 'comments', 'params', 'captcha')); } } return null; } /** * Retrieve currently active author object. * * @return CommentAuthor The active author object * * @since 2.0 */ public function activeAuthor() { if (!isset($this->_author)) { // get login (joomla users always win) $login = $this->app->request->getString(self::COOKIE_PREFIX.'login', '', 'cookie'); // get active user $user = $this->app->user->get(); if ($user->id) { // create author object from user $this->_author = $this->app->commentauthor->create('joomla', array($user->name, $user->email, '', $user->id)); } else if ($login == 'facebook' && ($connection = $this->app->facebook->client()) && ($content = $connection->getCurrentUserProfile()) && isset($content->id) && isset($content->name)) { // create author object from facebook user id $this->_author = $this->app->commentauthor->create('facebook', array($content->name, null, null, $content->id)); } else if ($login == 'twitter' && ($connection = $this->app->twitter->client()) && ($content = $connection->get('account/verify_credentials')) && isset($content->screen_name) && isset($content->id)) { // create author object from twitter user id $this->_author = $this->app->commentauthor->create('twitter', array($content->screen_name, null, null, $content->id)); } else { $this->app->twitter->logout(); $this->app->facebook->logout(); // create author object from cookies $cookie = $this->readCookies(); $this->_author = $this->app->commentauthor->create('', array($cookie['author'], $cookie['email'], $cookie['url'])); } } setcookie(self::COOKIE_PREFIX.'login', $this->_author->getUserType(), time() + self::COOKIE_LIFETIME, '/'); return $this->_author; } /** * Retrieve and verify author, email, url from cookie. * * @return array values from cookie * * @since 2.0 */ public function readCookies() { // get cookies $data = array(); foreach (array('hash', 'author', 'email', 'url') as $key) { $data[$key] = $this->app->request->getString(self::COOKIE_PREFIX.$key, '', 'cookie'); } // verify hash if ($this->getCookieHash($data['author'], $data['email'], $data['url']) == $data['hash']) { return $data; } return array('hash' => null, 'author' => null, 'email' => null, 'url' => null); } /** * Render comments and respond form html. * * @param string $author The author name * @param string $email The author email * @param string $url The author url * * @return void * * @since 2.0 */ public function saveCookies($author, $email, $url) { $hash = $this->getCookieHash($author, $email, $url); // set cookies foreach (compact('hash', 'author', 'email', 'url') as $key => $value) { setcookie(self::COOKIE_PREFIX.$key, $value, time() + self::COOKIE_LIFETIME); } } /** * Retrieve hash of author and email. * * @param string $author The author name * @param string $email The author email * @param string $url The author url * * @return string the cookie hash * * @since 2.0 */ public function getCookieHash($author, $email, $url) { // get secret from config $secret = $this->app->system->config->get('config.secret'); return md5($author.$email.$url.$secret); } /** * Match words against comments content, author, URL, Email or IP. * * @param Comment $comment The comment * @param array $words The words to match against * * @return boolean true on match * * @since 2.0 */ public function matchWords($comment, $words) { $vars = array('author', 'email', 'url', 'ip', 'content'); if ($words = explode("\n", $words)) { foreach ($words as $word) { if ($word = trim($word)) { $pattern = '/'.preg_quote($word).'/i'; foreach ($vars as $var) { if (preg_match($pattern, $comment->$var)) { return true; } } } } } return false; } /** * Remove html from comment content * * @param string $content The content * * @return string the filtered content * * @since 2.0 */ public function filterContentInput($content) { // remove all html tags or escape if in [code] tag $content = preg_replace_callback('/\[code\](.+?)\[\/code\]/is', create_function('$matches', 'return htmlspecialchars($matches[0]);'), $content); $content = strip_tags($content); return $content; } /** * Auto linkify urls, emails * * @param string $content The content * * @return string the filtered content * * @since 2.0 */ public function filterContentOutput($content) { $content = ' '.$content.' '; $content = preg_replace_callback('/(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)(?:\([-A-Z0-9+&@#\/%=~_|$?!:;,.]*\)|[-A-Z0-9+&@#\/%=~_|$?!:;,.])*(?:\([-A-Z0-9+&@#\/%=~_|$?!:;,.]*\)|[A-Z0-9+&@#\/%=~_|$])/ix', array($this->app->comment, 'makeURLClickable'), $content); $content = preg_replace("/\s([a-zA-Z][a-zA-Z0-9\_\.\-]*[a-zA-Z]*\@[a-zA-Z][a-zA-Z0-9\_\.\-]*[a-zA-Z]{2,6})([\s|\.|\,])/i"," $1$2", $content); $content = $this->app->string->substr($content, 1); $content = $this->app->string->substr($content, 0, -1); return nl2br($content); } /** * Makes the url clickable (only used as callback internally) * * @param array $matches The url matches * * @return string the wrapped url * * @since 2.0 */ protected function makeURLClickable($matches) { $url = $original_url = $matches[0]; if (empty($url)) { return $url; } // Prepend scheme if URL appears to contain no scheme (unless a relative link starting with / or a php file). if (strpos($url, ':') === false && substr($url, 0, 1) != '/' && substr($url, 0, 1) != '#' && !preg_match('/^[a-z0-9-]+?\.php/i', $url)) { $url = 'http://' . $url; } return " $original_url"; } /** * Check if comment is spam using Akismet. * * @param Comment $comment The Comment object * @param string $api_key The Akismet API key * * @return void * * @since 2.0 */ public function akismet($comment, $api_key = '') { // load akismet class $this->app->loader->register('Akismet', 'libraries:akismet/akismet.php'); // check comment $akismet = new Akismet(JURI::root(), $api_key); $akismet->setCommentAuthor($comment->author); $akismet->setCommentAuthorEmail($comment->email); $akismet->setCommentAuthorURL($comment->url); $akismet->setCommentContent($comment->content); // set state if ($akismet->isCommentSpam()) { $comment->state = Comment::STATE_SPAM; } } /** * Check if comment is spam using Mollom. * * @param Comment $comment The Comment object * @param string $public_key The Mollom public key * @param string $private_key The Mollom private key * * @return void * * @since 2.0 */ public function mollom($comment, $public_key = '', $private_key = '') { // check if curl functions are available if (!function_exists('curl_init')) return; // load mollom class $this->app->loader->register('Mollom', 'libraries:mollom/mollom.php'); // set keys and get servers Mollom::setPublicKey($public_key); Mollom::setPrivateKey($private_key); Mollom::setServerList(Mollom::getServerList()); // check comment $feedback = Mollom::checkContent(null, null, $comment->content, $comment->author, $comment->url, $comment->email); // set state if ($feedback['spam'] != 'ham') { $comment->state = Comment::STATE_SPAM; } } /** * Send notification email * * @param Comment $comment The Comment object * @param array $recipients The recipients email addresses (email => name) * @param string $layout The layout * * @return void * * @since 2.0 */ public function sendNotificationMail($comment, $recipients, $layout) { // workaround to make sure JSite is loaded $this->app->loader->register('JSite', 'root:includes/application.php'); // init vars $item = $comment->getItem(); $website_name = $this->app->system->config->get('sitename'); $comment_link = $this->_getURL($this->app->route->comment($comment, false)); $item_link = $this->_getURL($this->app->route->item($item, false)); $website_link = $this->_getURL('index.php'); // send email to $recipients foreach ($recipients as $email => $name) { if (empty($email) || $email == $comment->getAuthor()->email) { continue; } // build unsubscribe link $unsubscribe_link = JURI::root().'index.php?'.http_build_query(array( 'option' => $this->app->component->self->name, 'controller' => 'comment', 'task' => 'unsubscribe', 'item_id' => $item->id, 'email' => urldecode($email), 'hash' => $this->app->comment->getCookieHash($email, $item->id, '') ), '', '&'); $mail = $this->app->mail->create(); $mail->setSubject(JText::_("Topic reply notification")." - ".$item->name); $mail->setBodyFromTemplate($item->getApplication()->getTemplate()->resource.$layout, compact( 'item', 'comment', 'website_name', 'email', 'name', 'comment_link', 'item_link', 'website_link', 'unsubscribe_link' )); $mail->addRecipient($email); $mail->Send(); } } protected function _getURL($url) { // Get the router. $router = JApplication::getInstance('site')->getRouter(); // Make sure that we have our router if (!$router) { return null; } if ((strpos($url, '&') !== 0) && (strpos($url, 'index.php') !== 0)) { return $url; } // Build route. $uri = $router->build($url); $url = $uri->toString(); if (strpos(JPATH_BASE, 'administrator') !== false) { $url = preg_replace('#\/administrator#', '', $url, 1); } $prefix = JURI::getInstance()->toString(array('host', 'port')); // Make sure our URL path begins with a slash. if (!preg_match('#^/#', $url)) { $url = '/' . $url; } // Build the URL. $url = 'http://' . $prefix . $url; return $url; } } /** * CommentHelperException identifies an Exception in the CommentHelper class * @see CommentHelper */ class CommentHelperException extends AppException {}components/com_zoo/helpers/index.html000066600000000036150771655450014057 0ustar00components/com_zoo/helpers/string.php000066600000004537150771655450014113 0ustar00_call(array($this->_class, $method), $args); } /** * Truncates the input string. * * @param string $text input string * @param int $length the length of the output string * @param string $truncate_string the truncate string * * @return string The truncated string * @since 2.0 */ public function truncate($text, $length = 30, $truncate_string = '...') { if ($text == '') { return ''; } if ($this->strlen($text) > $length) { $length -= min($length, strlen($truncate_string)); $text = preg_replace('/\s+?(\S+)?$/', '', substr($text, 0, $length + 1)); return $this->substr($text, 0, $length).$truncate_string; } else { return $text; } } /** * Sluggifies the input string. * * @param string $string input string * @param bool $force_safe Do we have to enforce ASCII instead of UTF8 (default: false) * * @return string sluggified string * @since 2.0 */ public function sluggify($string, $force_safe = false) { $string = $this->strtolower((string) $string); $string = $this->str_ireplace(array('$',','), '', $string); if ($force_safe) { $string = JFilterOutput::stringURLSafe($string); } else { $string = JApplication::stringURLSafe($string); } return trim($string); } /** * Apply Joomla text filters based on the user's groups * * @param string $string The string to clean * * @return string The cleaned string */ public function applyTextFilters($string) { // Apply the textfilters (let's reuse Joomla's ContentHelper class) if (!class_exists('ContentHelper')) { require_once JPATH_SITE . '/administrator/components/com_content/helpers/content.php'; } return ContentHelper::filterText((string) $string); } }components/com_zoo/helpers/dependency.php000066600000002405150771655450014713 0ustar00app->path->path("component.admin:installation/dependencies.config")) { if ($dependencies = json_decode(file_get_contents($dependencies))) { foreach ($dependencies as $dependency) { $required = $dependency->version; $manifest = $this->app->path->path('root:'.$dependency->manifest); if ($required && is_file($manifest) && is_readable($manifest)) { if ($xml = simplexml_load_file($manifest)) { if (version_compare($required, (string) $xml->version) > 0) { $name = isset($dependency->url) ? "url}\">{$xml->name}" : (string) $xml->name; $this->app->error->raiseNotice(0, sprintf("The %s extension requires an update for the Zoo to run correctly.", $name)); } } } } } } } }components/com_zoo/helpers/commentauthor.php000066600000001672150771655450015467 0ustar00app->loader->register('CommentAuthor', 'classes:commentauthor.php'); } /** * Creates an CommentAuthor instance * * @param string $type Type of CommentAuthor to create * @param array $args Additional arguments to pass to the constructor * * @return CommentAuthor * * @since 2.0 */ public function create($type = '', $args = array()) { return $this->app->object->create(($type ? 'CommentAuthor'.$type : 'CommentAuthor'), $args); } }components/com_zoo/helpers/application.php000066600000005371150771655450015105 0ustar00app->table->application->all(array('order' => 'name')) as $application) { if (!$group || $application->getGroup() == $group) { $applications[$application->id] = $application; } } return $applications; } /** * Get all application groups. * * @return array The application groups * * @since 2.0 */ public function groups() { // get applications $apps = array(); if ($folders = $this->app->path->dirs('applications:')) { foreach ($folders as $folder) { if ($this->app->path->path("applications:$folder/application.xml")) { $apps[$folder] = $this->app->object->create('Application'); $apps[$folder]->setGroup($folder); } } } return $apps; } public function getAlphaIndex($application) { // set alphaindex $alpha_index = $this->app->alphaindex->create($application->getPath().'/config/alphaindex.xml'); // add categories $add_alpha_index = $application->getParams('site')->get('config.alpha_index', 0); if ($add_alpha_index == 1 || $add_alpha_index == 3) { $categories = $application->getCategoryTree(true, $this->app->user->get(), true); $alpha_index->addObjects(array_filter($categories, create_function('$category', 'return $category->id != 0 && $category->totalItemCount();')), 'name'); } // add items if ($add_alpha_index == 2 || $add_alpha_index == 3) { $db = $this->app->database; // get date $date = $this->app->date->create(); $now = $db->Quote($date->toSQL()); $null = $db->Quote($db->getNullDate()); $query = 'SELECT DISTINCT BINARY CONVERT(LOWER(LEFT(name, 1)) USING utf8) letter' .' FROM ' . ZOO_TABLE_ITEM .' WHERE id IN (SELECT item_id FROM ' . ZOO_TABLE_CATEGORY_ITEM . ')' .' AND application_id = '.(int) $application->id .' AND '.$this->app->user->getDBAccessString() .' AND state = 1' .' AND (publish_up = '.$null.' OR publish_up <= '.$now.')' .' AND (publish_down = '.$null.' OR publish_down >= '.$now.')'; $alpha_index->addObjects($db->queryObjectList($query), 'letter'); } return $alpha_index; } } components/com_zoo/helpers/template.php000066600000001503150771655450014406 0ustar00app->loader->register('AppTemplate', 'classes:template.php'); } /** * Get a template instance * * @param array $args Additional constructor arguments * * @return AppTemplate The template */ public function create($args = array()) { $args = (array) $args; return $this->app->object->create('AppTemplate', $args); } }components/com_zoo/helpers/fields/zoosubmission.php000066600000005555150771655450016777 0ustar00app->html->_('behavior.modal', 'a.modal'); $this->app->document->addStylesheet('fields:zoosubmission.css'); $this->app->document->addScript('fields:zoosubmission.js'); // init vars $params = $this->app->parameterform->convertParams($parent); $table = $this->app->table->application; $show_types = (boolean) $node->attributes()->types; // create application/category select $submissions = array(); $types = array(); $app_options = array($this->app->html->_('select.option', '', '- '.JText::_('Select Application').' -')); foreach ($table->all(array('order' => 'name')) as $application) { // application option $app_options[$application->id] = $this->app->html->_('select.option', $application->id, $application->name); // create submission select $submission_options = array(); foreach ($application->getSubmissions() as $submission) { $submission_options[$submission->id] = $this->app->html->_('select.option', $submission->id, $submission->name); if ($show_types) { $type_options = array(); $type_objects = $submission->getSubmittableTypes(); if (!count($type_objects)) { unset($submission_options[$submission->id]); continue; } foreach ($type_objects as $type) { $type_options[] = $this->app->html->_('select.option', $type->id, $type->name); } $attribs = 'data-type="type" data-submission="'.$submission->id.'" data-app="'.$application->id.'" data-control="'.$control_name.'[type]"'; $types[] = $this->app->html->_('select.genericlist', $type_options, $control_name.'[type]', $attribs, 'value', 'text', $params->get('type'), 'submission-type-'.$submission->id); } } if (!count($submission_options)) { unset($app_options[$application->id]); continue; } $attribs = 'data-type="submission" data-app="'.$application->id.'" data-control="'.$control_name.'[submission]"'; $submissions[] = $this->app->html->_('select.genericlist', $submission_options, $control_name.'[submission]', $attribs, 'value', 'text', $params->get('submission'), 'submission-'.$submission->id); } // create html $html[] = '
    '; // create application html $html[] = $this->app->html->_('select.genericlist', $app_options, $control_name.'['.$name.']', 'data-type="application"', 'value', 'text', $value); // create submission html $html[] = '
    '.implode("\n", $submissions).'
    '; // create types html if ($show_types) { $html[] = '
    '.implode("\n", $types).'
    '; } $html[] = '
    '; $javascript = 'jQuery(function($) { jQuery("#'.$name.'").ZooSubmission(); });'; $javascript = "\n"; echo implode("\n", $html).$javascript;components/com_zoo/helpers/fields/global.js000066600000001000150771655450015116 0ustar00/* Copyright (C) YOOtheme GmbH, http://www.gnu.org/licenses/gpl.html GNU/GPL */ jQuery(function(i){i(".field .global").each(function(){var e=i(this).children("input:checkbox:first"),n=i(this).children("div.input:first");n.find("input, select").each(function(){i(this).data("name",i(this).attr("name"))});e.bind("change",function(){if(e.is(":checked")){n.hide()}else{n.slideDown(200)}n.find("input, select").each(function(){i(this).attr("name",e.is(":checked")?"":i(this).data("name"))})}).trigger("change")})});components/com_zoo/helpers/fields/zooplugin.php000066600000001116150771655450016067 0ustar00attributes()->class ? 'class="'.$node->attributes()->class.'"' : 'class="inputbox"'; $options = array($this->app->html->_('select.option', '', '- '.JText::_('Select Plugin').' -')); $folder = (string) $node->attributes()->folder; echo $this->app->html->_('zoo.pluginlist', $options, $control_name.'['.$name.']', $class, 'value', 'text', $value, $control_name.$name, true, $folder); components/com_zoo/helpers/fields/zoolist.php000066600000001343150771655450015546 0ustar00attributes('class') ? $node->attributes('class') : 'inputbox'); printf('');components/com_zoo/helpers/fields/radio.php000066600000001311150771655450015134 0ustar00children() as $option) { // set attributes $id = uniqid('radio-'); $attributes = array('id' => $id, 'type' => 'radio', 'name' => "{$control_name}[{$name}]", 'value' => $option->attributes()->value); // is checked ? if ($option->attributes()->value == $value) { $attributes = array_merge($attributes, array('checked' => 'checked')); } printf(' ', $this->app->field->attributes($attributes), $this->app->field->attributes(array('for' => $id)), JText::_((string) $option)); }components/com_zoo/helpers/fields/zooapplication.css000066600000000541150771655450017076 0ustar00/* Copyright (C) YOOtheme GmbH, http://www.gnu.org/licenses/gpl.html GNU/GPL */ /* * zooapplication */ div.zoo-application { float: left; } div.zoo-application > * { margin-top: 5px; } div.zoo-application > * { float: none; display: block; } div.zoo-application .item input { margin: 0 5px 0 0; } div.zoo-application .hidden { display: none; }components/com_zoo/helpers/fields/zooimage.php000066600000001536150771655450015661 0ustar00app->document->addScript('assets:js/image.js'); // init vars $width = $parent->getValue($name.'_width'); $height = $parent->getValue($name.'_height'); // create image select html $html[] = ''; $html[] = '
    '; $html[] = JText::_('Width').' '; $html[] = JText::_('Height').' '; $html[] = '
    '; echo implode("\n", $html);components/com_zoo/helpers/fields/zoomodule.php000066600000001015150771655450016054 0ustar00attributes()->class ? 'class="'.$node->attributes()->class.'"' : 'class="inputbox"'; $options = array($this->app->html->_('select.option', '', '- '.JText::_('Select Module').' -')); echo $this->app->html->_('zoo.modulelist', $options, $control_name.'['.$name.']', $class, 'value', 'text', $value, $control_name.$name);components/com_zoo/helpers/fields/zooitemauthor.php000066600000004611150771655450016755 0ustar00attributes()->class ? ' class="'.(string) $node->attributes()->class.'"' : ''; $attr .= (string) $node->attributes()->size ? ' size="'.(int) $node->attributes()->size.'"' : ''; // Initialize JavaScript field attributes. $onchange = (string) $node->attributes()->onchange; // Load the modal behavior script. $this->app->html->_('behavior.modal', 'a.modal_'.$name); // Build the script. $script = array(); $script[] = ' function jSelectUser_'.$name.'(id, title) {'; $script[] = ' var old_id = document.getElementById("'.$name.'_id").value;'; $script[] = ' if (old_id != id) {'; $script[] = ' document.getElementById("'.$name.'_id").value = id;'; $script[] = ' document.getElementById("'.$name.'_name").value = title;'; $script[] = ' '.$onchange; $script[] = ' }'; $script[] = ' SqueezeBox.close();'; $script[] = ' }'; // Add the script to the document head. JFactory::getDocument()->addScriptDeclaration(implode("\n", $script)); // Load the current username if available. $username = $value == 'NO_CHANGE' ? JText::_( 'No Change' ) : (($user = $this->app->user->get($value)) && $user->id ? $user->name : JText::_('JLIB_FORM_SELECT_USER')); // Create a dummy text field with the user name. $html[] = '
    '; $html[] = ' '; $html[] = '
    '; // Create the user select button. $html[] = '
    '; $html[] = '
    '; if ((string) $node->attributes()->readonly != 'true') { $html[] = ' '; $html[] = ' '.JText::_('JLIB_FORM_CHANGE_USER').''; } $html[] = '
    '; $html[] = '
    '; // Create the real field, hidden, that stored the user id. $html[] = ''; echo implode("\n", $html);components/com_zoo/helpers/fields/zooitemorderglobal.php000066600000001324150771655450017745 0ustar00app->document->addScript('fields:global.js'); // init vars $id = uniqid('itemorder-'); $global = $parent->getValue((string) $name) === null; // create html echo '
    '; echo ''; echo ''; echo '
    '; echo $this->app->field->render('zooitemorder', $name, $value, $node, compact('control_name', 'parent')); echo '
    '; echo '
    ';components/com_zoo/helpers/fields/index.html000066600000000036150771655450015325 0ustar00components/com_zoo/helpers/fields/zooitemorder.css000066600000001146150771655450016567 0ustar00/* Copyright (C) YOOtheme GmbH, http://www.gnu.org/licenses/gpl.html GNU/GPL */ /* * Item Order Parameter */ #item-order { float: left; } #item-order .type:first-child { padding-top: 0; } #item-order .type { padding: 3px 0; } #item-order label { float: none; } #item-order .chzn-container { margin-top: 5px; } #item-order label { color: #666666; font-size: 11px; font-weight: bold; margin: 5px 5px 3px 5px; display: inline-block; } #item-order select, #item-order input { float: left; margin: 5px 5px 3px 0px; } #item-order .select-message { display: none; } #item-order > div { clear: both; }components/com_zoo/helpers/fields/list.php000066600000001203150771655450015011 0ustar00', $this->app->field->attributes(array('name' => "{$control_name}[{$name}]"))); foreach ($node->children() as $option) { // set attributes $attributes = array('value' => $option->attributes()->value); // is checked ? if ($option->attributes()->value == $value) { $attributes['selected'] = 'selected'; } printf('', $this->app->field->attributes($attributes), JText::_((string) $option)); } printf('');components/com_zoo/helpers/fields/zoolayout.php000066600000003176150771655450016116 0ustar00attributes()->class ? 'class="'.$node->attributes()->class.'"' : 'class="inputbox"'; $constraint = (string) $node->attributes()->constraint; // get renderer $renderer = $this->app->renderer->create('item')->addPath($parent->layout_path); // if selectable types isn't specified, get all types if (empty($parent->selectable_types)) { $parent->selectable_types = array(''); foreach (JFolder::folders($parent->layout_path.'/'.$renderer->getFolder().'/item') as $folder) { $parent->selectable_types[] = $folder; } } // get layouts $layouts = array(); foreach ($parent->selectable_types as $type) { $path = 'item'; $prefix = 'item.'; if (!empty($type) && $renderer->pathExists($path.DIRECTORY_SEPARATOR.$type)) { $path .= DIRECTORY_SEPARATOR.$type; $prefix .= $type.'.'; } foreach ($renderer->getLayouts($path) as $layout) { $metadata = $renderer->getLayoutMetaData($prefix.$layout); if (empty($constraint) || $metadata->get('type') == $constraint) { $layouts[$layout] = $metadata->get('name'); } } } // create layout options $options = array($this->app->html->_('select.option', '', JText::_('Item Name'))); foreach ($layouts as $layout => $layout_name) { $text = $layout_name; $val = $layout; $options[] = $this->app->html->_('select.option', $val, $text); } echo $this->app->html->_('select.genericlist', $options, $control_name.'['.$name.']', $class, 'value', 'text', $value, $control_name.$name);components/com_zoo/helpers/fields/text.php000066600000000674150771655450015035 0ustar00 'text', 'name' => "{$control_name}[{$name}]", 'value' => $value, 'class' => isset($class) ? $class : ''); printf('', $this->app->field->attributes($attributes, array('label', 'description', 'default')));components/com_zoo/helpers/fields/spacer.php000066600000000357150771655450015324 0ustar00app->document->addScript('fields:global.js'); // init vars $id = uniqid('listglobal-'); $global = $parent->getValue((string) $name) === null; ?>
    '; ?> '.JText::_('Global').''; ?>
    app->field->render('list', $name, $value, $node, compact('control_name', 'parent')); ?>
    components/com_zoo/helpers/fields/radioglobal.php000066600000001303150771655450016316 0ustar00app->document->addScript('fields:global.js'); // init vars $id = uniqid('radioglobal-'); $global = $parent->getValue((string) $name) === null; ?>
    '; ?> '.JText::_('Global').''; ?>
    app->field->render('radio', $name, $value, $node, compact('control_name', 'parent')); ?>
    components/com_zoo/helpers/fields/textarea.php000066600000000771150771655450015664 0ustar00attributes()->class) ? (string) $node->attributes()->class : ''; printf('', $this->app->field->attributes($attributes, array('label', 'description', 'default')), $value);components/com_zoo/helpers/fields/textglobal.php000066600000001310150771655450016202 0ustar00app->document->addScript('fields:global.js'); // init vars $id = uniqid('radiotext-'); $global = $parent->getValue((string) $name) === null; // create html echo '
    '; echo ''; echo ''; echo '
    '; echo $this->app->field->render('text', $name, $value, $node, compact('control_name', 'parent')); echo '
    '; echo '
    ';components/com_zoo/helpers/fields/zooapplication.php000066600000010376150771655450017104 0ustar00app->system->language->load('com_zoo'); $this->app->html->_('behavior.modal', 'a.modal'); $this->app->document->addStylesheet('fields:zooapplication.css'); $this->app->document->addScript('fields:zooapplication.js'); // init vars $params = $this->app->parameterform->convertParams($parent); $table = $this->app->table->application; // set modes $modes = array(); if ($node->attributes()->allitems) { $modes[] = $this->app->html->_('select.option', 'all', JText::_('All Items')); } if ($node->attributes()->categories) { $modes[] = $this->app->html->_('select.option', 'categories', JText::_('Categories')); } if ($node->attributes()->types) { $modes[] = $this->app->html->_('select.option', 'types', JText::_('Types')); } if ($node->attributes()->items) { $modes[] = $this->app->html->_('select.option', 'item', JText::_('Item')); } // create application/category select $cats = array(); $types = array(); $options = array($this->app->html->_('select.option', '', '- '.JText::_('Select Application').' -')); foreach ($table->all(array('order' => 'name')) as $application) { // application option $options[] = $this->app->html->_('select.option', $application->id, $application->name); // create category select if ($node->attributes()->categories) { $attribs = 'class="category app-'.$application->id.($value != $application->id ? ' hidden' : null).'" data-category="'.$control_name.'[category]"'; $opts = array(); if ($node->attributes()->frontpage) { $opts[] = $this->app->html->_('select.option', '', '• '.JText::_('Frontpage')); } $cats[] = $this->app->html->_('zoo.categorylist', $application, $opts, ($value == $application->id ? $control_name.'[category]' : null), $attribs, 'value', 'text', $params->get('category')); } // create types select if ($node->attributes()->types) { $opts = array(); foreach ($application->getTypes() as $type) { $opts[] = $this->app->html->_('select.option', $type->id, $type->name); } $attribs = 'class="type app-'.$application->id.($value != $application->id ? ' hidden' : null).'" data-type="'.$control_name.'[type]"'; $types[] = $this->app->html->_('select.genericlist', $opts, $control_name.'[type]', $attribs, 'value', 'text', $params->get('type'), 'application-type-'.$application->id); } } // create html $html[] = '
    '; $html[] = $this->app->html->_('select.genericlist', $options, $control_name.'['.$name.']', 'class="application"', 'value', 'text', $value); // create mode select if (count($modes) > 1) { $html[] = $this->app->html->_('select.genericlist', $modes, $control_name.'[mode]', 'class="mode"', 'value', 'text', $params->get('mode')); } // create categories html if (!empty($cats)) { $html[] = '
    '.implode("\n", $cats).'
    '; } // create types html if (!empty($types)) { $html[] = '
    '.implode("\n", $types).'
    '; } // create items html $link = ''; if ($node->attributes()->items) { $field_name = $control_name.'[item_id]'; $item_name = JText::_('Select Item'); if ($item_id = $params->get('item_id')) { $item = $this->app->table->item->get($item_id); $item_name = $item->name; } $link = $this->app->link(array('controller' => 'item', 'task' => 'element', 'tmpl' => 'component', 'func' => 'selectZooItem', 'object' => $name), false); $html[] = '
    '; $html[] = ''; $html[] = ''.JText::_('Select').''; $html[] = ''; $html[] = '
    '; } $html[] = '
    '; $javascript = 'jQuery(function($) { jQuery("#'.$name.'").ZooApplication({ url: "'.$link.'", msgSelectItem: "'.JText::_('Select Item').'" }); });'; $javascript = "\n"; echo implode("\n", $html).$javascript; components/com_zoo/helpers/fields/zoofeed.js000066600000000436150771655450015325 0ustar00/* Copyright (C) YOOtheme GmbH, http://www.gnu.org/licenses/gpl.html GNU/GPL */ jQuery(function(i){i("div.zoo-feed").each(function(){var n=i(this).find("div.input");var d=i(this).find("input:radio");if(d.first().is(":checked"))n.hide();d.bind("change",function(){n.slideToggle()})})});components/com_zoo/helpers/fields/zooitemorder.php000066600000010025150771655450016562 0ustar00app->document->addStylesheet('fields:zooitemorder.css'); $this->app->document->addScript('fields:zooitemorder.js'); // init vars $params = $this->app->parameterform->convertParams($parent); $item_order = (array) $params->get((string) $name, array('_itemname')); $html = array(); $html[] = '
    '; $html[] = ''.JText::_('Please select application first').''; // add types $html[] = '
    '; if ($node->attributes('apps') || @$node->attributes()->apps) { $applications = $this->app->application->getApplications(); } else if ($group = $this->app->request->getString('group', false)) { $applications = array($this->app->object->create('Application')->setGroup($group)); } else { $applications = array($this->app->zoo->getApplication()); } foreach ($applications as $application) { $types = $application->getTypes(); // add core elements $core = $this->app->object->create('Type', array('_core', $application)); $core->name = JText::_('Core'); array_unshift($types, $core); $html[] = '
    '; foreach ($types as $type) { if ($type->identifier == '_core') { $elements = $type->getCoreElements(); $options = array(); } else { $elements = $type->getElements(); $options = array($this->app->html->_('select.option', false, '- '.JText::_('Select Element').' -')); } // filter orderable elements $elements = array_filter($elements, create_function('$element', 'return $element->getMetaData("orderable") == "true";')); $value = false; foreach ($elements as $element) { if (in_array($element->identifier, $item_order)) { $value = $element->identifier; } $options[] = $this->app->html->_('select.option', $element->identifier, ($element->config->name ? $element->config->name : $element->getMetaData('name'))); } if ($type->identifier == '_core' && ($node->attributes('add_default') || @$node->attributes()->add_default)) { array_unshift($options, $this->app->html->_('select.option', '', JText::_('default'))); } $id = $control_name.$name.$application->id.$type->identifier; $html[] = '
    '; $html[] = $this->app->html->_('select.genericlist', $options, "{$control_name}[{$name}][]", 'class="element"', 'value', 'text', $value, $id); $html[] = ''; $html[] = '
    '; if ($type->identifier == '_core') { $html[] = '- '.JText::_('JOR').' -'; } } $html[] = '
    '; } $html[] = '
    '; $html[] = '
    '; $id = "{$control_name}[{$name}][_reversed]"; $html[] = "'; $html[] = ''; $html[] = '
    '; if ($node->attributes('random') || @$node->attributes()->random) { $html[] = '
    '; $id = "{$control_name}[{$name}][_random]"; $html[] = "'; $html[] = ''; $html[] = '
    '; } $html[] = '
    '; $id = "{$control_name}[{$name}][_alphanumeric]"; $html[] = "'; $html[] = ''; $html[] = '
    '; $html[] = '
    '; $html[] = "\n"; echo implode("\n", $html);components/com_zoo/helpers/fields/zooitemorder.js000066600000002474150771655450016420 0ustar00/* Copyright (C) YOOtheme GmbH, http://www.gnu.org/licenses/gpl.html GNU/GPL */ (function(t){var e=function(){};t.extend(e.prototype,{name:"ZooItemOrder",initialize:function(e){var i=this;this.input=e;this.application=t("body").find(".zoo-application select.application");if(this.application.length){e.find("select.element, input:checkbox").each(function(){t(this).data("_name",t(this).attr("name"))});this.application.bind("change",function(){i.refresh()});this.refresh()}},refresh:function(){var e=this.application.val();e?this.input.find(".select-message").hide().nextAll().show():this.input.find(".select-message").show().nextAll().hide();this.input.find(".apps .app").each(function(){var i=t(this);i.find("select.element, input:checkbox").attr("name",function(){return e&&i.hasClass(e)?t(this).data("_name"):""});e&&i.hasClass(e)?i.show():i.hide()})}});t.fn[e.prototype.name]=function(){var i=arguments;var n=i[0]?i[0]:null;return this.each(function(){var a=t(this);if(e.prototype[n]&&a.data(e.prototype.name)&&n!="initialize"){a.data(e.prototype.name)[n].apply(a.data(e.prototype.name),Array.prototype.slice.call(i,1))}else if(!n||t.isPlainObject(n)){var o=new e;if(e.prototype["initialize"]){o.initialize.apply(o,t.merge([a],i))}a.data(e.prototype.name,o)}else{t.error("Method "+n+" does not exist on jQuery."+e.name)}})}})(jQuery);components/com_zoo/helpers/fields/zooaccesslevel.php000066600000001571150771655450017067 0ustar00attributes()->class ? 'class="'.$node->attributes()->class.'"' : 'class="inputbox"'; $attr .= ((string) $node->attributes()->disabled == 'true') ? ' disabled="disabled"' : ''; $attr .= (string) $node->attributes()->size ? ' size="'.(int) $node->attributes()->size.'"' : ''; $attr .= ((string) $node->attributes()->multiple == 'true') ? ' multiple="multiple"' : ''; // Initialize JavaScript field attributes. $attr .= (string) $node->attributes()->onchange ? ' onchange="'.(string) $node->attributes()->onchange.'"' : ''; echo $this->app->html->_('zoo.accesslevel', array(), $control_name.'['.$name.']', $attr, 'value', 'text', $value, $control_name.$name);components/com_zoo/helpers/fields/hidden.php000066600000000615150771655450015277 0ustar00 'hidden', 'name' => "{$control_name}[{$name}]", 'value' => $value); printf('', $this->app->field->attributes($attributes, array('description', 'default')));components/com_zoo/helpers/fields/zoosubmission.css000066600000000447150771655450016773 0ustar00/* Copyright (C) YOOtheme GmbH, http://www.gnu.org/licenses/gpl.html GNU/GPL */ /* * zoosubmission */ div.zoo-submission { float: left; } div.zoo-submission > * { margin-top: 5px; } div.zoo-submission select { display: block; float: none; } div.zoo-submission .hidden { display: none; }components/com_zoo/helpers/fields/zoofeed.php000066600000002076150771655450015502 0ustar00app->document->addScript('fields:zoofeed.js'); ?>
    app->html->_('select.booleanlist', $control_name.'['.$name.']', null, $value); ?>
    '.JText::_('Feed title').''; ?> app->html->_('control.text', $control_name.'[feed_title]', $parent->getValue('feed_title'), array('id' => 'feed-title')); ?>
    '.JText::_('Alternate feed link').''; ?> app->html->_('control.text', $control_name.'[alternate_feed_link]', $parent->getValue('alternate_feed_link'), array('id' => 'alternate-feed-link')); ?>
    components/com_zoo/helpers/fields/zoocalendar.php000066600000000716150771655450016347 0ustar00attributes()->class ? (string) $node->attributes()->class : 'inputbox'; ?>
    app->html->_('zoo.calendar', $value, $control_name.'['.$name.']', uniqid('calendar-'), compact('class'), true); ?>
    components/com_zoo/helpers/fields/zoofeedglobal.php000066600000001273150771655450016661 0ustar00app->document->addScript('fields:global.js'); // init vars $id = uniqid('feed-'); $global = $parent->getValue((string) $name) === null; ?>
    '; ?> '.JText::_('Global').''; ?>
    app->field->render('zoofeed', $name, $value, $node, compact('control_name', 'parent')); ?>
    components/com_zoo/helpers/fields/zoosubmission.js000066600000003704150771655450016616 0ustar00/* Copyright (C) YOOtheme GmbH, http://www.gnu.org/licenses/gpl.html GNU/GPL */ (function(t){var e=function(){};t.extend(e.prototype,{name:"ZooSubmission",initialize:function(e){var n=this;this.input=e;this.app=e.find('[data-type="application"]');this.submissions=e.find('[data-type="submission"]');this.types=e.find('[data-type="type"]');this.setValues();this.app.bind("change",function(){n.setValues()});this.submissions.bind("change",function(){n.setValues()});e.delegate("select","change",function(){t(this).closest("div.content").css("height","")});t(e.closest("form")).find("input[id$=params_type]:hidden, input[id$=params_submission]:hidden").each(function(){t(this).closest(".control-group").remove().end().remove()})},setValues:function(){var e=this.app.val();if(e){var n=null;this.submissions.each(function(){var a=t(this);if(a.data("app")==e){a.removeClass("hidden").attr("name",a.data("control")).next(".chzn-container").removeClass("hidden");n=a.val()}else{a.addClass("hidden").attr("name","").next(".chzn-container").addClass("hidden")}});this.types.each(function(){var a=t(this);if(a.data("app")==e&&a.data("submission")==n){a.removeClass("hidden").attr("name",a.data("control")).next(".chzn-container").removeClass("hidden")}else{a.addClass("hidden").attr("name","").next(".chzn-container").addClass("hidden")}})}else{this.input.find('[data-type="submission"], [data-type="type"]').each(function(){t(this).addClass("hidden").attr("name","").next(".chzn-container").addClass("hidden")})}}});t.fn[e.prototype.name]=function(){var n=arguments;var a=n[0]?n[0]:null;return this.each(function(){var i=t(this);if(e.prototype[a]&&i.data(e.prototype.name)&&a!="initialize"){i.data(e.prototype.name)[a].apply(i.data(e.prototype.name),Array.prototype.slice.call(n,1))}else if(!a||t.isPlainObject(a)){var s=new e;if(e.prototype["initialize"]){s.initialize.apply(s,t.merge([i],n))}i.data(e.prototype.name,s)}else{t.error("Method "+a+" does not exist on jQuery."+e.name)}})}})(jQuery);components/com_zoo/helpers/type.php000066600000010511150771655450013553 0ustar00id != $type->identifier) { // check identifier $tmp_identifier = $type->identifier; // build resource $resource = $type->getApplication()->getResource().'types/'; $i = 2; while ($this->app->path->path($resource.$tmp_identifier.'.config')) { $tmp_identifier = $type->identifier.'-'.$i++; } $type->identifier = $tmp_identifier; } return $type; } /** * Sanatize positions config file (after renaming or deleting a type) * * @param string $path Path to renderer * @param Type $type The type to sanatize * @param boolean $delete if set to true, type will be removed * * @since 2.0 */ public function sanatizePositionsConfig($path, $type, $delete = false) { // get renderer $renderer = $this->app->renderer->create('item')->addPath($path); // get group $group = $type->getApplication()->getGroup(); // rename folder if special type if ($renderer->pathExists('item'.DIRECTORY_SEPARATOR.$type->id)) { $folder = $path.DIRECTORY_SEPARATOR.$renderer->getFolder().DIRECTORY_SEPARATOR.'item'.DIRECTORY_SEPARATOR; if ($delete) { JFolder::delete($folder.$type->id); } else { JFolder::move($folder.$type->id, $folder.$type->identifier); } } // get positions and config $config = $renderer->getConfig('item'); $params = $config->get($group.'.'.$type->id.'.'); if (!$delete) { $config->set($group.'.'.$type->identifier.'.', $params); } $config->remove($group.'.'.$type->id.'.'); $renderer->saveConfig($config, $path.'/renderer/item/positions.config'); } /** * Copy positions config file * * @param string $id the old type id * @param string $path Path to renderer * @param Type $type The type to copy * * @since 2.0 */ public function copyPositionsConfig($id, $path, $type) { // get renderer $renderer = $this->app->renderer->create('item')->addPath($path); // get group $group = $type->getApplication()->getGroup(); $original = $type->getApplication()->getType($id); $element_mapping = array_combine(array_keys($type->elements), array_keys($original->elements)); // rename folder if special type if ($renderer->pathExists('item'.DIRECTORY_SEPARATOR.$id)) { $folder = $path.DIRECTORY_SEPARATOR.$renderer->getFolder().DIRECTORY_SEPARATOR.'item'.DIRECTORY_SEPARATOR; JFolder::copy($folder.$id, $folder.$type->id); } // get positions and config $config = $renderer->getConfig('item'); $params = $config->get($group.'.'.$id.'.'); // match new element ids to prev ids if ($element_mapping) { foreach ($params as $layout => $positions) { foreach ($positions as $position => $elements) { foreach ($elements as $i => $element_config) { foreach ($type->elements as $elem_id => $element) { if (isset($element_mapping[$elem_id]) && $element_config['element'] == $element_mapping[$elem_id]) { $params[$layout][$position][$i]['element'] = $elem_id; } } } } } } $config->set($group.'.'.$type->id.'.', $params); $renderer->saveConfig($config, $path.'/renderer/item/positions.config'); } /** * Returns layouts for a type of an app. * * @param Type $type * @param string $layout_type * * @return array The layouts * @since 2.0 */ public function layouts($type, $layout_type = '') { $result = array(); // get template if ($template = $type->getApplication()->getTemplate()) { // get renderer $renderer = $this->app->renderer->create('item')->addPath($template->getPath()); $path = 'item'; $prefix = 'item.'; if ($renderer->pathExists($path.DIRECTORY_SEPARATOR.$type->id)) { $path .= DIRECTORY_SEPARATOR.$type->id; $prefix .= $type->id.'.'; } foreach ($renderer->getLayouts($path) as $layout) { $metadata = $renderer->getLayoutMetaData($prefix.$layout); if (empty($layout_type) || ($metadata->get('type') == $layout_type)) { $result[$layout] = $metadata; } } } return $result; } }components/com_zoo/helpers/element.php000066600000005251150771655450014230 0ustar00loader->register('Element', 'elements:element/element.php'); } /** * Returns an array of all Elements. * * @return array elements * * @since 2.0 */ public function getAll(){ $elements = array(); foreach ($this->app->path->dirs('elements:') as $type) { if ($type != 'element' && is_file($this->app->path->path("elements:$type/$type.php"))) { if ($element = $this->create($type)) { if ($element->getMetaData('hidden') != 'true') { $elements[] = $element; } } } } return $elements; } /** * Creates element of given type * * @param string $type The type to create * * @return Element the created element * * @since 2.0 */ public function create($type) { // load element class $elementClass = 'Element'.$type; if (!class_exists($elementClass)) { $this->app->loader->register($elementClass, "elements:$type/$type.php"); } if (!class_exists($elementClass)) { return false; } $testClass = new ReflectionClass($elementClass); if ($testClass->isAbstract()) { return false; } return new $elementClass($this->app); } /** * Separates the passed element values with a separator * * @param string $separated_by The separator * @param array $values the values to separate * * @return string The imploded string * * @since 2.0 */ public function applySeparators($separated_by, $values) { if (!is_array($values)) { $values = array($values); } $separator = ''; $tag = ''; $enclosing_tag = ''; if ($separated_by) { if (preg_match('/separator=\[(.*)\]/U', $separated_by, $result)) { $separator = $result[1]; } if (preg_match('/tag=\[(.*)\]/U', $separated_by, $result)) { $tag = $result[1]; } if (preg_match('/enclosing_tag=\[(.*)\]/U', $separated_by, $result)) { $enclosing_tag = $result[1]; } } if (empty($separator) && empty($tag) && empty($enclosing_tag)) { $separator = ', '; } if (!empty($tag)) { foreach ($values as $key => $value) { $values[$key] = sprintf($tag, $values[$key]); } } $value = implode($separator, $values); if (!empty($enclosing_tag)) { $value = sprintf($enclosing_tag, $value); } return $value; } }components/com_zoo/helpers/validator.php000066600000001655150771655450014570 0ustar00app->loader->register('AppValidator', 'classes:validator.php'); } /** * Creates a validator instance * * @param string $type Validator type * * @return AppValidator */ public function create($type = '') { $args = func_get_args(); $type = array_shift($args); $class = 'AppValidator'.$type; // load class $this->app->loader->register($class, 'classes:validator.php'); return $this->app->object->create($class, $args); } }components/com_zoo/helpers/category.php000066600000007427150771655450014423 0ustar00 category ids cache // refreshes after one hour automatically $this->_cache = $app->cache->create($app->path->path('cache:') . '/item_category', true, 3600, 'apc'); if ($this->_cache && !$this->_cache->check()) { $this->_cache = null; } } /** * Method to retrieve item's related category ids. * * @param int $item_id The items id * @param boolean $published Include published categories only * * @return array category ids * * @since 2.0 */ public function getItemsRelatedCategoryIds($item_id, $published = false) { $key = $item_id.'_'.$published; if ($this->_cache && $result = $this->_cache->get($key)) { return $result; } // select item to category relations $query = 'SELECT b.id' .' FROM '.ZOO_TABLE_CATEGORY_ITEM.' AS a' .' JOIN '.ZOO_TABLE_CATEGORY.' AS b ON a.category_id = b.id' .' WHERE a.item_id='.(int) $item_id .($published == true ? ' AND b.published = 1' : '') .' UNION SELECT 0' .' FROM '.ZOO_TABLE_CATEGORY_ITEM.' AS a' .' WHERE a.item_id='.(int) $item_id.' AND a.category_id = 0'; $result = $this->app->database->queryResultArray($query); if ($this->_cache) { $this->_cache->set($key, $result); $this->_cache->save(); } return $result; } /** * Method to add category related items. * * @param Item $item The item * @param array $categories The category ids * * @return boolean true on success * * @since 2.0 */ public function saveCategoryItemRelations($item, $categories) { //init vars $db = $this->app->database; if (!is_array($categories)) { $categories = array($categories); } // trigger an event to let 3rd party extend the category list $this->app->event->dispatcher->notify($this->app->event->create($item, 'item:beforeSaveCategoryRelations', array('categories' => &$categories))); $categories = array_unique($categories); // delete category to item relations $query = "DELETE FROM ".ZOO_TABLE_CATEGORY_ITEM ." WHERE item_id=".(int) $item->id; // execute database query $db->query($query); // Generate the sql query for the categories $query_string = '(%s,'.(int) $item->id.')'; $category_strings = array(); foreach ($categories as $category) { if (is_numeric($category)) { $category_strings[] = sprintf($query_string, $category); } } // add category to item relations // insert relation to database if (!empty($category_strings)) { $query = "INSERT INTO ".ZOO_TABLE_CATEGORY_ITEM ." (category_id, item_id) VALUES ".implode(',', $category_strings); // execute database query $db->query($query); } $this->clearItemCategoryCache(); return true; } /** * Method to delete category related items. * * @param int $category_id The category id * * @return int number of affected rows * * @since 2.0 */ public function deleteCategoryItemRelations($category_id) { // delete category to item relations $query = "DELETE FROM ".ZOO_TABLE_CATEGORY_ITEM ." WHERE category_id = ".(int) $category_id; // execute database query $result = $this->app->database->query($query); $this->clearItemCategoryCache(); return $result; } /** * Method to clear the item category cache * * @since 2.6.5 */ public function clearItemCategoryCache() { if ($this->_cache) { $this->_cache->clear()->save(); } } }components/com_zoo/helpers/renderer.php000066600000024217150771655450014410 0ustar00app->path->register($this->app->path->path('classes:renderer'), 'renderer'); } /** * Creates a Renderer instance * * @param string $type Renderer type * @param array $args Additional arguments for the constructor * @return AppRenderer * @since 2.0 */ public function create($type = '', $args = array()) { // load renderer class $class = $type ? $type.'Renderer' : 'AppRenderer'; if ($type) { $this->app->loader->register($class, 'renderer:'.strtolower($type).'.php'); } // prepend app array_unshift($args, $this->app); return $this->app->object->create($class, $args); } } /** * The general class for rendering objects. * * @package Component.Helpers * @since 2.0 */ class AppRenderer { /** * The path helper * @var PathHelper */ protected $_path; /** * The layout paths * @var array */ protected $_layout_paths; /** * The current layout * @var string */ protected $_layout; /** * The base folder * @var string */ protected $_folder = 'renderer'; /** * The separator for layout paths * @var string */ protected $_separator = '.'; /** * The extension type of the layouts * @var string */ protected $_extension = '.php'; /** * The metafile name * @var string */ protected $_metafile = 'metadata.xml'; /** * App instance * * @var App * @since 2.0 */ public $app; /** * Maximum recursion depth */ const MAX_RENDER_RECURSIONS = 100; /** * Class constructor * * @param App $app The app instance * @param PathHelper|null $path The path helper to use * @since 2.0 */ public function __construct($app, $path = null) { $this->_layout_paths = array(); $this->_path = $path ? $path : $app->object->create('PathHelper', array($app)); } /** * Render objects using a layout file. * * @staticvar int $count * * @param string $layout Layout name. * @param array $args Arguments to be passed to into the layout scope. * * @return string The rendered output * @since 2.0 */ public function render($layout, $args = array()) { // prevent render to recurse indefinitely static $count = 0; $count++; if ($count < self::MAX_RENDER_RECURSIONS) { // render layout if ($__layout = $this->_getLayoutPath($layout)) { // import vars and layout output extract($args); ob_start(); include($__layout); $output = ob_get_contents(); ob_end_clean(); $count--; return $output; } $count--; // raise warning, if layout was not found JError::raiseWarning(0, 'Renderer Layout "'.$layout.'" not found. ('.$this->app->utility->debugInfo(debug_backtrace()).')'); return null; } // raise warning, if render recurses indefinitly JError::raiseWarning(0, 'Warning! Render recursed indefinitly. ('.$this->app->utility->debugInfo(debug_backtrace()).')'); return null; } /** * Gets the layout path for the given layout * * @param string $layout * * @return string The layout path * @since 2.0 */ protected function _getLayoutPath($layout) { if (!isset($this->_layout_paths[$layout])) { // init vars $parts = explode($this->_separator, $layout); $this->_layout = preg_replace('/[^A-Z0-9_\.-]/i', '', end($parts)); $this->_layout_paths[$layout] = $this->_path->path(implode('/', $parts).$this->_extension); } return $this->_layout_paths[$layout]; } /** * Add layout path(s) to renderer. * * @param array|string $paths * * @return self * @since 2.0 */ public function addPath($paths) { $paths = (array) $paths; foreach ($paths as $path) { $path = rtrim($path, "\\/").'/'; $this->_path->register($path.$this->_folder); } return $this; } /** * Retrieve an array of layout filenames. * * @param string $dir * @return array the layout files * @since 2.0 */ public function getLayouts($dir) { // find layouts in path(s) $layouts = $this->_path->files($dir, false, '/'.preg_quote($this->_extension).'$/i'); return array_map(create_function('$layout', 'return basename($layout, "'.$this->_extension.'");'), $layouts); } /** * Retrieve metadata array of a layout. * * @param string $layout * * @return array The layouts metadata * @since 2.0 */ public function getLayoutMetaData($layout) { // init vars $metadata = $this->app->object->create('AppData'); $parts = explode($this->_separator, $layout); $name = array_pop($parts); if ($file = $this->_path->path(implode(DIRECTORY_SEPARATOR, $parts).'/'.$this->_metafile)) { if ($xml = simplexml_load_file($file)) { foreach ($xml->children() as $child) { $attributes = $child->attributes(); if ($child->getName() == 'layout' && (string) $attributes->name == $name) { foreach ($attributes as $key => $attribute) { $metadata[$key] = (string) $attribute; } $metadata['layout'] = $layout; $metadata['name'] = (string) $child->name; $metadata['description'] = (string) $child->description; break; } } } } return $metadata; } /** * Retrieve the renderers folder. * * @return string The folder * @since 2.0 */ public function getFolder() { return $this->_folder; } /** * Retrieve paths where to find the layout files. * * @param string $dir * @return string The full path * @since 2.0 */ protected function _getPath($dir = '') { return $this->_path->path($dir); } } /** * The base class for rendering positions based on config files. * * @package Component.Helpers * @since 2.0 */ abstract class PositionRenderer extends AppRenderer { /** * The config data * @var AppParameter */ protected $_config; /** * The config file * @var string */ protected $_config_file = 'positions.config'; /** * The positions file * @var string */ protected $_xml_file = 'positions.xml'; /** * Retrieve positions of a layout. * * @param string $dir point separated path to layout, last part is layout * * @return array The positions array * @since 2.0 */ public function getPositions($dir) { // init vars $positions = array(); $parts = explode('.', $dir); $layout = array_pop($parts); $path = implode('/', $parts); // parse positions xml if ($xml = simplexml_load_file($this->_getPath($path.'/'.$this->_xml_file))) { if ($pos = current($xml->xpath('positions[@layout="'.$layout.'"]'))) { $positions['name'] = ($name = current($pos->xpath('name')) ? (string) $name : $layout); $positions['positions'] = array(); foreach ($pos->xpath('position[@name]') as $position) { $name = (string) $position->attributes()->name; $positions['positions'][$name] = (string) $position; } } } return $positions; } /** * Retrieve position configuration. * * @param string $dir path to config file * * @return AppParameter * @since 2.0 */ public function getConfig($dir) { // config file if (empty($this->_config)) { if ($file = $this->_path->path($dir.'/'.$this->_config_file)) { $content = file_get_contents($file); } else { $content = null; } $this->_config = $this->app->parameter->create($content); } return $this->_config; } /** * Save position configuration. * * @param AppParameter|string $config Configuration * @param string $file File to save configuration * * @return boolean * * @throws PositionRendererException * @since 2.0 */ public function saveConfig($config, $file) { if (JFile::exists($file) && !is_writable($file)) { throw new PositionRendererException(sprintf('The config file is not writable (%s)', $file)); } if (!JFile::exists($file) && !is_writable(dirname($file))) { throw new PositionRendererException(sprintf('Could not create config file (%s)', $file)); } // Joomla 1.6 JFile::write expects $buffer to be reference $config_string = (string) $config; return JFile::write($file, $config_string); } /** * Checks if a path exists * * @param string $dir The path to check * @return boolean * @since 2.0 */ public function pathExists($dir) { return (bool) $this->_getPath($dir); } /** * Check if any of the positions from a layout generates some output * * @param string $dir Point separated path to layout, last part is layout * @param Item $item The Item to be checked (default: null) * * @return boolean If any of the positions generates some kind of output * * @since 3.0.4 */ public function checkPositions($dir, $item = null) { $positions = $this->getPositions($dir); if (isset($positions['positions']) && is_array($positions['positions'])) { // set item $this->_item = isset($this->_item) ? $this->_item : $item; // set layout if (!isset($this->_layout)) { $parts = explode('.', $dir); $this->_layout = array_pop($parts); } // proceede with checking foreach ($positions['positions'] as $position => $title) { if ($this->checkPosition($position)) { return true; } } } return false; } /** * Check if a position generates some output * * @param string $position The name of the position to check * * @return boolean If the position generates some kind of output * * @since 2.0 */ public abstract function checkPosition($position); /** * Render the output of the position * * @param string $position The name of the position to render * @param array $args The list of arguments to pass on to the layout * * @return string The html code generated * * @since 2.0 */ public abstract function renderPosition($position, $args = array()); } /** * PositionRendererException identifies an Exception in the PositionRenderer class * @see PositionRenderer */ class PositionRendererException extends AppException {}components/com_zoo/helpers/facebook.php000066600000004172150771655450014351 0ustar00app->zoo->getApplication(); } // get comment params $params = $this->app->parameter->create()->loadArray($application ? $application->getParams()->get('global.comments.') : array()); if (!function_exists('curl_init')) { return null; } // load facebook classes $this->app->loader->register('Facebook', 'libraries:facebook/facebook.php'); $access_token = null; if (isset($_SESSION['facebook_access_token'])) { $access_token = $_SESSION['facebook_access_token']; } // Build FacebookOAuth object with client credentials. return new Facebook($this->app, array('app_id' => $params->get('facebook_app_id'), 'app_secret' => $params->get('facebook_app_secret'), 'access_token' => $access_token)); } /** * Get Facebook Fields. * * @param string $fb_uid Facebook user id * @param array $fields Fields to acquire * @param Application The application to get params from * * @return array The fields * @since 2.0 */ public function fields($fb_uid, $fields = null, $application = null) { try { $connection = $this->client($application); if ($connection) { $infos = $connection->getProfile($fb_uid); if (is_object($infos)) { if (is_array($fields)) { return array_intersect_key((array) $infos, array_flip($fields)); } else { return (array) $infos; } } } } catch (Exception $e) { } } /** * Logout from Facebook. * * @return self * @since 2.0 */ public function logout() { // remove access token from session $_SESSION['facebook_access_token'] = null; return $this; } } components/com_zoo/helpers/menu.php000066600000002520150771655450013537 0ustar00app->loader->register('AppTree', 'classes:tree.php'); $this->app->loader->register('AppMenu', 'classes:menu.php'); } /** * Gets the AppMenu instance * * @param string $name Menu name * @return AppMenu * @since 2.0 */ public function get($name) { if (isset(self::$_menus[$name])) { return self::$_menus[$name]; } self::$_menus[$name] = $this->app->object->create('AppMenu', array($name)); return self::$_menus[$name]; } /** * Gets the active site menu */ public function getActive() { if ($this->_active === null) { if ($menu = $this->app->system->application->getMenu('site') and $menu instanceof JMenu) { $this->_active = $menu->getActive(); } } return $this->_active; } }components/com_zoo/helpers/route.php000066600000033013150771655450013732 0ustar00get('cache_routes', false)) { // get route cache // refreshes after one hour automatically $this->_cache = $app->cache->create($app->path->path('cache:') . '/routes', true, 3600, 'apc'); if (!$this->_cache || !$this->_cache->check()) { $this->_cache = null; } else { $this->_find(null, null); $key = json_encode($this->_menu_items); if (!$this->_cache->get($key)) { $this->_cache->clear()->set($key, true)->save(); } } } if ($app->request->getCmd('task') == 'category' || $app->request->getCmd('view') == 'category') { $this->_category_id = (int) $app->request->getInt('category_id', (method_exists($app->system->application, 'getParams') ? $app->system->application->getParams()->get('category') : null)); } if ($menu_item = $app->menu->getActive()) { $this->_active_menu_item_id = $menu_item->id; } } /** * Gets this route helpers link base * * @return string the link base * @since 2.0 */ public function getLinkBase() { return 'index.php?option='.$this->app->component->self->name; } /** * Gets route to alphaindex * * @param int $application_id * @param string $alpha_char * * @return string the route * @since 2.0 */ public function alphaindex($application_id, $alpha_char = null) { $key = $this->_active_menu_item_id.'-alphaindex-'.$application_id.'_'.$alpha_char; if ($this->_cache && $link = $this->_cache->get($key)) { return $link; } // build frontpage link $link = $this->getLinkBase().'&task=alphaindex&app_id='.$application_id; $link .= $alpha_char !== null ? '&alpha_char='.$alpha_char : ''; if ($menu_item = $this->_find('frontpage', $application_id) or $menu_item = $this->app->menu->getActive()) { $link .= '&Itemid='.$menu_item->id; } // store link for future lookups if ($this->_cache) { $this->_cache->set($key, $link)->save(); } return $link; } /** * Gets route to category * * @param Category $category * @param boolean $route If it should be run through JRoute::_() * @param int $force_id * * @return string the route * @since 2.0 */ public function category($category, $route = true, $force_id = 0) { $key = $this->_active_menu_item_id.'-category-'.$category->application_id.'_'.$category->id.'_'.$route.'_'.$force_id; if ($this->_cache && $link = $this->_cache->get($key)) { return $link; } if (!$force_id && $this->app->request->getBool('f') && $this->app->request->getString('category_id') == $category->id) { $force_id = $this->app->request->getInt('Itemid'); } $itemid = null; $this->app->table->application->get($category->application_id)->getCategoryTree(true); // Priority 1: direct link to category if ($menu_item = $this->_find('category', $category->id)) { $link = $menu_item->link; $itemid = $menu_item->id; } else { // build category link $link = $this->getLinkBase().'&task=category&category_id='.$category->id; // Priority 2: find in category path if ($menu_item = $this->_findInCategoryPath($category)) { $itemid = $menu_item->id; } else { // Priority 3: link to frontpage || Priority 4: current item id if ($menu_item = $this->_find('frontpage', $category->application_id) or $menu_item = $this->app->menu->getActive()) { $itemid = $menu_item->id; } } } if ($force_id && $force_id != $itemid) { $itemid = $force_id; $link .= '&f=1&task=category&category_id='.$category->id; } if ($itemid) { $link .= '&Itemid='.$itemid; } if ($route) { $link = JRoute::_($link); } // store link for future lookups if ($this->_cache) { $this->_cache->set($key, $link)->save(); } return $link; } /** * Get route to comment * * @param Comment $comment * @param boolean $route If it should be run through JRoute::_() * * @return string the route * @since 2.0 */ public function comment($comment, $route = true) { return $this->item($comment->getItem(), $route).'#comment-'.$comment->id; } /** * Get route to feed * * @param Category $category The category to show the feeds for * @param string $feed_type The type of the feed * * @return string The route * * @since 2.0 */ public function feed($category, $feed_type) { $key = $this->_active_menu_item_id.'-feed-'.$category->id.'_'.$feed_type; if ($this->_cache && $link = $this->_cache->get($key)) { return $link; } // build feed link $link = $this->getLinkBase().'&task=feed&app_id='.$category->application_id.'&category_id='.$category->id.'&format=feed&type='.$feed_type; if ($menu_item = $this->_find('frontpage', $category->application_id) or $menu_item = $this->app->menu->getActive()) { $link .= '&Itemid='.$menu_item->id; } // store link for future lookups if ($this->_cache) { $this->_cache->set($key, $link)->save(); } return $link; } /** * Gets route to frontpage * * @param int $application_id * * @return string the route * @since 2.0 */ public function frontpage($application_id) { $key = $this->_active_menu_item_id.'-frontpage-'.$application_id; if ($this->_cache && $link = $this->_cache->get($key)) { return $link; } // Priority 1: direct link to frontpage if ($menu_item = $this->_find('frontpage', $application_id)) { return $menu_item->link.'&Itemid='.$menu_item->id; } // build frontpage link $link = $this->getLinkBase().'&task=frontpage'; // Priority 2: current item id if ($menu_item = $this->app->menu->getActive()) { $link .= '&Itemid='.$menu_item->id; } // store link for future lookups if ($this->_cache) { $this->_cache->set($key, $link)->save(); } return $link; } /** * Get route to item * * @param Item $item * @param boolean $route If it should be run through JRoute::_() * * @return string the route * @since 2.0 */ public function item($item, $route = true) { $category_id = $this->_category_id; $key = $this->_active_menu_item_id.'-item-'.$item->application_id.'_'.$category_id.'_'.$item->id.'_'.$route; if ($this->_cache && $cached = $this->_cache->get($key)) { return $cached; } // Priority 1: direct link to item if ($menu_item = $this->_find('item', $item->id)) { $link = $menu_item->link.'&Itemid='.$menu_item->id; } else { $itemid = null; // build item link $link = $this->getLinkBase().'&task=item&item_id='.$item->id; // are we in category view? $this->app->table->application->get($item->application_id)->getCategoryTree(true); $categories = null; if ($category_id) { $categories = array_filter($item->getRelatedCategoryIds(true)); $category_id = in_array($category_id, $categories) ? $category_id : null; } if (!$category_id) { $primary_id = $item->getPrimaryCategoryId(); // Priority 2: direct link to primary category if ($primary_id && $menu_item = $this->_find('category', $primary_id)) { $itemid = $menu_item->id; // Priority 3: find in primary category path } else if ($primary_id and $primary = $item->getPrimaryCategory() and $menu_item = $this->_findInCategoryPath($primary)) { $itemid = $menu_item->id; } else { $categories = is_null($categories) ? array_filter($item->getRelatedCategoryIds(true)) : $categories; foreach ($categories as $category) { // Priority 4: direct link to any related category if ($menu_item = $this->_find('category', $category)) { $itemid = $menu_item->id; break; } } if (!$itemid) { $categories = $item->getRelatedCategories(true); foreach ($categories as $category) { // Priority 5: find in any related categorys path if ($menu_item = $this->_findInCategoryPath($category)) { $itemid = $menu_item->id; break; } } } // Priority 6: link to frontpage if (!$itemid && $menu_item = $this->_find('frontpage', $item->application_id)) { $itemid = $menu_item->id; } } } elseif ($category_id != $item->getPrimaryCategoryId()) { $link .= '&category_id='.$category_id; } if ($itemid) { $link .= '&Itemid='.$itemid; // Priority 7: current item id } else if ($menu_item = $this->app->menu->getActive()) { $link .= '&Itemid='.$menu_item->id; } } if ($route) { $link = JRoute::_($link); } // store link for future lookups if ($key && $this->_cache) { $this->_cache->set($key, $link)->save(); } return $link; } /** * Get route to mysubmissions view * * @param Submission $submission * * @return string the route * @since 2.0 */ public function mysubmissions($submission) { $link = $this->getLinkBase().'&view=submission&layout=mysubmissions&submission_id='.$submission->id; if ($menu_item = $this->app->menu->getActive()) { $link .= '&Itemid='.$menu_item->id; } return $link; } /** * Get route to submission view * * @param Submission $submission * @param string $type_id * @param string $hash * @param int $item_id * @param string $redirect * * @return string the route * @since 2.0 */ public function submission($submission, $type_id, $hash = null, $item_id = 0, $redirect = null) { $hash = empty($hash) ? $this->app->submission->getSubmissionHash($submission->id, $type_id, $item_id) : $hash; $redirect = !empty($redirect) ? '&redirect='.urlencode($redirect) : ''; $item_id = !empty($item_id) ? '&item_id='.$item_id : ''; $link = $this->getLinkBase().'&view=submission&layout=submission&submission_id='.$submission->id.'&type_id='.$type_id.$item_id.'&submission_hash='.$hash.$redirect; if ($menu_item = $this->app->menu->getActive()) { $link .= '&Itemid='.$menu_item->id; } return $link; } /** * Get route to tag view * * @param int $application_id * @param string $tag * @param int $force_id * * @return string the route * @since 2.0 */ public function tag($application_id, $tag, $force_id = 0) { $key = $this->_active_menu_item_id.'-tag-'.$application_id.'_'.$tag.'_'.$force_id; if ($this->_cache && $link = $this->_cache->get($key)) { return $link; } if (!$force_id && $this->app->request->getBool('f') && $this->app->request->getString('tag') == $tag) { $force_id = $this->app->request->getInt('Itemid'); } // build tag link $link = $this->getLinkBase().'&task=tag&tag='.$tag.'&app_id='.$application_id; // Priority 1: link to frontpage || Priority 2: current item id $item_id = ''; if ($menu_item = $this->_find('frontpage', $application_id) or $menu_item = $this->app->menu->getActive()) { if ($force_id && $force_id != $menu_item->id) { $item_id = '&Itemid='.$force_id; $link .= '&f=1&task=tag&tag='.$tag.'&app_id='.$application_id; } else { $item_id = '&Itemid='.$menu_item->id; } } $link .= $item_id; // store link for future lookups if ($this->_cache) { $this->_cache->set($key, $link)->save(); } return $link; } /** * Finds the category in the pathway * * @param Category $category * @return stdClass menu item * @since 2.0 */ protected function _findInCategoryPath($category) { foreach ($category->getPathway() as $id => $cat) { if ($menu_item = $this->_find('category', $id)) { return $menu_item; } } } /** * Finds a menu item by its type and id in the menu items * * @param string $type * @param string $id * * @return stdClass menu item * @since 2.0 */ protected function _find($type, $id) { if ($this->_menu_items == null) { $menu_items = $this->app->system->application->getMenu('site')->getItems('component_id', JComponentHelper::getComponent('com_zoo')->id); $menu_items = $menu_items ? $menu_items : array(); $this->_menu_items = array_fill_keys(array('frontpage', 'category', 'item', 'submission', 'mysubmissions'), array()); foreach ($menu_items as $menu_item) { switch (@$menu_item->query['view']) { case 'frontpage': $this->_menu_items['frontpage'][$this->app->parameter->create($menu_item->params)->get('application')] = $menu_item; break; case 'category': $this->_menu_items['category'][$this->app->parameter->create($menu_item->params)->get('category')] = $menu_item; break; case 'item': $this->_menu_items['item'][$this->app->parameter->create($menu_item->params)->get('item_id')] = $menu_item; break; case 'submission': $this->_menu_items[(@$menu_item->query['layout'] == 'submission' ? 'submission' : 'mysubmissions')][$this->app->parameter->create($menu_item->params)->get('submission')] = $menu_item; break; } } } return @$this->_menu_items[$type][$id]; } public function clearCache() { if ($this->_cache) { $this->_cache->clear()->save(); } } } components/com_zoo/helpers/editor.php000066600000003322150771655450014062 0ustar00_asset_id)) { $this->_asset_id = $this->app->database->queryResult('SELECT id FROM #__assets WHERE name = '.$this->app->database->quote($this->app->component->self->name)); } $asset = $this->_asset_id; } if ($author === null) { $author = $this->app->user->get()->id; } return $this->app->system->editor->display($name, $content, $width, $height, $col, $row, $buttons, $id, $asset, $author); } }components/com_zoo/helpers/twitter.php000066600000004462150771655450014304 0ustar00app->zoo->getApplication(); } // get comment params $params = $this->app->parameter->create()->loadArray($application ? $application->getParams()->get('global.comments.') : array()); if (!function_exists('curl_init')) { return null; } // load twitter classes $this->app->loader->register('TwitterOAuth', 'libraries:twitter/twitteroauth.php'); $oauth_token = null; $oauth_token_secret = null; if (isset($_SESSION['twitter_oauth_token'], $_SESSION['twitter_oauth_token_secret'])) { $oauth_token = $_SESSION['twitter_oauth_token']; $oauth_token_secret = $_SESSION['twitter_oauth_token_secret']; } // Build TwitterOAuth object with client credentials. return new TwitterOAuth($params->get('twitter_consumer_key'), $params->get('twitter_consumer_secret'), $oauth_token, $oauth_token_secret); } /** * Get Twitter Fields. * * @param string $t_uid Twitter user id * @param array $fields Fields to acquire * @param Application The application to get params from * * @return array The fields * @since 2.0 */ public function fields($t_uid, $fields = null, $application = null) { try { $connection = $this->client($application); if ($connection) { $infos = $connection->get('users/show.json?user_id='.$t_uid.'&include_entities=true'); if (is_object($infos)) { if (is_array($fields)) { return array_intersect_key((array) $infos, array_flip($fields)); } else { return (array) $infos; } } } } catch (Exception $e) {} } /** * Logout from Twitter. * * @return self * @since 2.0 */ public function logout() { // remove access token from session $_SESSION['twitter_oauth_token'] = null; $_SESSION['twitter_oauth_token_secret'] = null; return $this; } } components/com_zoo/helpers/html.php000066600000060054150771655450013545 0ustar00= 2) { $func = array_pop($parts); $file = array_pop($parts); if (in_array($file, array('zoo', 'control')) && method_exists($this, $func)) { array_shift($args); return call_user_func_array(array($this, $func), $args); } } return call_user_func_array(array('JHTML', '_'), $args); } /** * Get zoo datepicker. * * @param string $value The value * @param string $name The html name * @param string $id The html id * @param string|array $attribs The html attributes * @param boolean $time * * @return string datepicker html output * @since 2.0 */ public function calendar($value, $name, $id, $attribs = null, $time = false) { if (!defined('ZOO_CALENDAR_SCRIPT_DECLARATION')) { define('ZOO_CALENDAR_SCRIPT_DECLARATION', true); $this->app->document->addScript('assets:js/date.js'); $translations = array( 'closeText' => 'Done', 'currentText' => 'Today', 'dayNames' => array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'), 'dayNamesMin' => array('Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'), 'dayNamesShort' => array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'), 'monthNames' => array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'), 'monthNamesShort' => array('JANUARY_SHORT', 'FEBRUARY_SHORT', 'MARCH_SHORT', 'APRIL_SHORT', 'MAY_SHORT', 'JUNE_SHORT', 'JULY_SHORT', 'AUGUST_SHORT', 'SEPTEMBER_SHORT', 'OCTOBER_SHORT', 'NOVEMBER_SHORT', 'DECEMBER_SHORT'), 'prevText' => 'Prev', 'nextText' => 'Next', 'weekHeader' => 'Wk', 'appendText' => '(yyyy-mm-dd)' ); foreach ($translations as $key => $translation) { $translations[$key] = is_array($translation) ? array_map(array('JText', '_'), $translation) : JText::_($translation); } $timepicker_translations = array_map(array('JText', '_'), array( 'currentText' => 'Now', 'closeText' => 'Done', 'timeOnlyTitle' => 'Choose Time', 'timeText' => 'Time', 'hourText' => 'Hour', 'minuteText' => 'Minute', 'secondText' => 'Second' )); $javascript = 'jQuery(function($) { $("body").Calendar({ translations: '.json_encode($translations).', timepicker_translations: '.json_encode($timepicker_translations).' }); });'; $this->app->document->addScriptDeclaration($javascript); } if (is_array($attribs)) { $attribs = JArrayHelper::toString($attribs); } $data = $time ? ' data-timepicker="timepicker"' : ''; return '' .''; } /** * Get image resource info. * * @param string $image the image path * @param int $width the image width * @param int $height the image height * * @return array|null image info * @since 2.0 */ public function image($image, $width = null, $height = null) { $resized_image = $this->app->zoo->resizeImage(JPATH_ROOT.'/'.$image, $width, $height); $inner_path = $this->app->path->relative($resized_image); $path = JPATH_ROOT.'/'.$inner_path; if (is_file($path) && $size = getimagesize($path)) { $info['path'] = $path; $info['src'] = JURI::root().$inner_path; $info['mime'] = $size['mime']; $info['width'] = $size[0]; $info['height'] = $size[1]; $info['width_height'] = sprintf('width="%d" height="%d"', $info['width'], $info['height']); return $info; } return null; } /** * Returns category select list html string. * * @param Application $application The application object * @param array $options The options * @param string $name The hmtl name * @param string|array $attribs The html attributes * @param string $key * @param string $text * @param string $selected The selected value * @param string $idtag * @param boolean $translate * @param string $category The category id to build the select list for * * @return string category select list html * @since 2.0 */ public function categoryList($application, $options, $name, $attribs = null, $key = 'value', $text = 'text', $selected = NULL, $idtag = false, $translate = false, $category = 0, $prefix = '- ', $spacer = '.   ', $indent = '  ') { // set options settype($options, 'array'); reset($options); // get category tree list $list = $this->app->tree->buildList($category, $application->getCategoryTree(), array(), $prefix, $spacer, $indent); // create options foreach ($list as $category) { $options[] = $this->_('select.option', $category->id, $category->treename); } return $this->_('zoo.genericlist', $options, $name, $attribs, $key, $text, $selected, $idtag, $translate); } /** * Returns edit row html string. * * @param string $name The hmtl name * @param string $value The hmtl value * * @return string the editor row html output * @since 2.0 */ public function editRow($name, $value) { $html[] = "\t\n"; $html[] = "\t\t$name\n"; $html[] = "\t\t$value\n"; $html[] = "\t\n"; return implode("\n", $html); } /** * Returns the country select list * * @param array $countries Countries * @param string $name The hmtl name * @param string $selected The selected value * @param boolean $multiselect Show as multiselect * * @return string the country select list html output * @since 2.0 */ public function countrySelectList($countries, $name, $selected, $multiselect) { $options = array(); if (!$multiselect) { $options[] = $this->app->html->_('select.option', '', '-'.JText::_('Select Country').'-'); } foreach ($countries as $key => $country) { $options[] = $this->app->html->_('select.option', $key, JText::_($country)); } $attribs = $multiselect ? 'size="'.max(min(count($options), 10), 3).'" multiple="multiple"' : ''; return $this->app->html->_('select.genericlist', $options, $name, $attribs, 'value', 'text', $selected); } /** * Returns layout select list html string. * * @param Type $type The type object * @param string $layout_type The layout type filter * @param array $options The options * @param string $name The hmtl name * @param array|string $attribs The html attributes * @param string $key * @param string $text * @param string $selected The selected value * @param string $idtag * @param boolean $translate * * @return string the layout select list html output * @since 2.0 */ public function layoutList($type, $layout_type, $options, $name, $attribs = null, $key = 'value', $text = 'text', $selected = NULL, $idtag = false, $translate = false) { // set options settype($options, 'array'); reset($options); $layouts = $this->app->type->layouts($type, $layout_type); foreach ($layouts as $layout => $metadata) { $options[] = $this->_('select.option', $layout, $metadata->get('name')); } return $this->_('select.genericlist', $options, $name, $attribs, $key, $text, $selected, $idtag, $translate); } /** * Returns type select list html string. * * @param Application $application The Application object * @param array $options The options * @param string $name The html name * @param array|string $attribs The html attributes * @param string $key * @param string $text * @param string $selected The selected value * @param string $idtag * @param boolean $translate * @param array $filter The type filter * * @return string the type select list html output * @since 2.0 */ public function typeList($application, $options, $name, $attribs = null, $key = 'value', $text = 'text', $selected = null, $idtag = false, $translate = false, $filter = array()) { // set options settype($options, 'array'); reset($options); foreach ($application->getTypes() as $type) { if (empty($filter) || in_array($type->id, $filter)) { $options[] = $this->_('select.option', $type->id, JText::_($type->name)); } } return $this->_('select.genericlist', $options, $name, $attribs, $key, $text, $selected, $idtag, $translate); } /** * Returns module select list html string. * * @param array $options The options * @param string $name The html name * @param array|string $attribs The html attributes * @param string $key * @param string $text * @param string $selected The selected value * @param string $idtag * @param boolean $translate * @param boolean $published * * @return string the module select list html output * @since 2.0 */ public function moduleList($options, $name, $attribs = null, $key = 'value', $text = 'text', $selected = null, $idtag = false, $translate = false, $published = false) { // set options settype($options, 'array'); reset($options); // get modules $modules = $this->app->module->load($published); if (count($modules)) { foreach ($modules as $module) { $options[] = $this->app->html->_('select.option', $module->id, $module->title.' ('.$module->position.')'); } return $this->_('select.genericlist', $options, $name, $attribs, $key, $text, $selected, $idtag, $translate); } return JText::_("There are no modules to choose from."); } /** * Returns plugin select list html string. * * @param array $options The options * @param string $name The html name * @param array|string $attribs The html attributes * @param string $key * @param string $text * @param string $selected The selected value * @param string $idtag * @param boolean $translate * @param string $folder The folder path to filter plugins by * @param boolean $enabled Show selected plugins only * * @return string the plugin select list html output * @since 2.0 */ public function pluginList($options, $name, $attribs = null, $key = 'value', $text = 'text', $selected = null, $idtag = false, $translate = false, $folder = false, $enabled = true) { // set options settype($options, 'array'); reset($options); $plugins = JPluginHelper::getPlugin($folder); if (count($plugins)) { foreach ($plugins as $plugin) { if ($enabled && JPluginHelper::isEnabled($plugin->type, $plugin->name)) { $plugin_name = 'plg_'.$plugin->type.'_'.$plugin->name; JFactory::getLanguage()->load($plugin_name.'.sys', JPATH_ADMINISTRATOR); $options[] = $this->app->html->_('select.option', $plugin->name, $plugin_name); } } return $this->_('select.genericlist', $options, $name, $attribs, $key, $text, $selected, $idtag, $translate); } return JText::_("There are no plugins to choose from."); } /** * Returns author select list html string. * * @param array $options The options * @param string $name The html name * @param array|string $attribs The html attributes * @param string $key * @param string $text * @param string $selected The selected value * @param string $idtag * @param boolean $translate * @param boolean $show_registered_users Show registered users only * * @return string the author select list html output * @since 2.0 */ public function authorList($options, $name, $attribs = null, $key = 'value', $text = 'text', $selected = null, $idtag = false, $translate = false, $show_registered_users = true) { $query = 'SELECT DISTINCT u.id AS value, u.name AS text' .' FROM #__users AS u' .' WHERE u.block = 0' .($show_registered_users ? '' : ' AND u.gid > 18'); return $this->queryList($query, $options, $name, $attribs, $key, $text, $selected, $idtag, $translate); } /** * Returns item author select list html string. * * @param array $options The options * @param string $name The html name * @param array|string $attribs The html attributes * @param string $key * @param string $text * @param string $selected The selected value * @param string $idtag * @param boolean $translate * * @return string the item author select list html output * @since 2.0 */ public function itemAuthorList($options, $name, $attribs = null, $key = 'value', $text = 'text', $selected = null, $idtag = false, $translate = false) { $query = 'SELECT DISTINCT u.id AS value, u.name AS text' .' FROM '.ZOO_TABLE_ITEM.' AS i' .' JOIN #__users AS u ON i.created_by = u.id'; return $this->queryList($query, $options, $name, $attribs, $key, $text, $selected, $idtag, $translate); } /** * Returns item select list html string. * * @param Application $application The Application object * @param array $options The options * @param string $name The html name * @param array|string $attribs The html attributes * @param string $key * @param string $text * @param string $selected The selected value * @param string $idtag * @param boolean $translate * * @return string the item select list html output * @since 2.0 */ public function itemList($application, $options, $name, $attribs = null, $key = 'value', $text = 'text', $selected = null, $idtag = false, $translate = false) { // set options settype($options, 'array'); reset($options); $query = 'SELECT DISTINCT c.item_id as value, a.name as text' .' FROM '.ZOO_TABLE_COMMENT.' AS c' .' LEFT JOIN '.ZOO_TABLE_ITEM.' AS a ON c.item_id = a.id' .' WHERE a.application_id = '.(int) $application->id .' ORDER BY a.name'; $rows = $this->app->database->queryAssocList($query); foreach ($rows as $row) { $options[] = $this->_('select.option', $row['value'], $row['text']); } return $this->_('select.genericlist', $options, $name, $attribs, $key, $text, $selected, $idtag, $translate); } /** * Returns user access select list. * * @param array $options The options * @param string $name The html name * @param array|string $attribs The html attributes * @param string $key * @param string $text * @param string $selected The selected value * @param string $idtag * @param boolean $translate * @param array $exclude Access level ids to exclude * * @return string the user access list html output * @since 2.0 */ public function accessLevel($options, $name, $attribs = 'class="inputbox"', $key = 'value', $text = 'text', $selected = null, $idtag = false, $translate = false, $exclude = array()) { // set options settype($options, 'array'); reset($options); // set exclude $exclude = (array) $exclude; reset($exclude); $groups = $this->app->zoo->getGroups(); foreach ($exclude as $key) { unset($groups[$key]); } foreach ($groups as $group) { $options[] = $this->_('select.option', $group->id, JText::_($group->name), $key, $text); } if (!isset($groups[$selected])) { $selected = $this->app->joomla->getDefaultAccess(); } return $this->_('select.genericlist', $options, $name, $attribs, $key, $text, $selected, $idtag, $translate); } /** * Returns comment author select list html string. * * @param Application $application The Application object * @param array $options The options * @param string $name The html name * @param array|string $attribs The html attributes * @param string $key * @param string $text * @param string $selected The selected value * @param string $idtag * @param boolean $translate * * @return string the comment author select list html output * @since 2.0 */ public function commentAuthorList($application, $options, $name, $attribs = null, $key = 'value', $text = 'text', $selected = null, $idtag = false, $translate = false) { $query = "SELECT DISTINCT c.author AS value, c.author AS text" ." FROM ".ZOO_TABLE_COMMENT." AS c" .' LEFT JOIN '.ZOO_TABLE_ITEM.' AS a ON c.item_id = a.id' ." WHERE c.author <> ''" ." AND a.application_id = ".$application->id ." ORDER BY c.author"; return $this->queryList($query, $options, $name, $attribs, $key, $text, $selected, $idtag, $translate); } /** * Returns select list html string. * * @param string $query The database query * @param array $options The options * @param string $name The html name * @param array|string $attribs The html attributes * @param string $key * @param string $text * @param string $selected The selected value * @param string $idtag * @param boolean $translate * * @return string select list html output * @since 2.0 */ public function queryList($query, $options, $name, $attribs = null, $key = 'value', $text = 'text', $selected = null, $idtag = false, $translate = false) { // set options settype($options, 'array'); reset($options); $options = array_merge($options, $this->app->database->queryObjectList($query)); return $this->_('select.genericlist', $options, $name, $attribs, $key, $text, $selected, $idtag, $translate); } /** * Wrapper for Joomla 1.5/1.6 * * @param array $data * @param string $name The html name * @param array|string $attribs The html attributes * @param string $optKey * @param string $optText * @param string $selected The selected value * @param string $idtag * @param boolean $translate * * @return string generic list html output * @since 2.0 */ public function genericList($data, $name, $attribs = null, $optKey = 'value', $optText = 'text', $selected = null, $idtag = false, $translate = false) { $attributes['list.attr'] = $attribs; $attributes['id'] = $idtag; $attributes['list.translate'] = $translate; $attributes['option.key'] = $optKey; $attributes['option.text'] = $optText; $attributes['list.select'] = $selected; $attributes['option.text.toHtml'] = false; return $this->app->html->_('select.genericlist', $data, $name, $attributes); } //****************************** //* ZOO Controls * //****************************** /** * Get array list * * @param array $array * @param array $options * @param string $name The html name * @param array|string $attribs The html attributes * @param string $key * @param string $text * @param string $selected The selected value * @param string $idtag * @param boolean $translate If the text should be translated. * * @return string array list html output * * @return type */ public function arrayList($array, $options, $name, $attribs = null, $key = 'value', $text = 'text', $selected = null, $idtag = false, $translate = false) { // set options settype($options, 'array'); reset($options); $options = array_merge($options, $this->listOptions($array)); return $this->_('select.genericlist', $options, $name, $attribs, $key, $text, $selected, $idtag, $translate); } /** * Returns select option as JHTML compatible array. * * @param array $array * @param string $value * @param string $text * * @return array * @since 2.0 */ public function listOptions($array, $value = 'value', $text = 'text') { $options = array(); if (is_array($array)) { foreach ($array as $val => $txt) { $options[] = $this->_('select.option', strval($val), $txt, $value, $text); } } return $options; } /** * Returns directory select html string. * * @param string $directory * @param string $filter * @param string $name * @param string $value * @param array|string $attribs * * @return string directory select list html output * @since 2.0 */ public function selectdirectory($directory, $filter, $name, $value = null, $attribs = null) { // get directories $options = array($this->app->html->_('select.option', '', '- '.JText::_('Select Directory').' -')); $dirs = $this->app->path->dirs($directory, true, $filter); natsort($dirs); foreach ($dirs as $dir) { $options[] = $this->app->html->_('select.option', $dir, $dir); } return $this->app->html->_('select.genericlist', $options, $name, $attribs, 'value', 'text', $value); } /** * Returns form textarea html string. * * @param string $name * @param string $value * @param array|string $attribs * * @return string form textarea html output * @since 2.0 */ public function textarea($name, $value = null, $attribs = null) { if (is_array($attribs)) { $attribs = JArrayHelper::toString($attribs); } $value = htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); // convert
    tags so they are not visible when editing $value = str_replace('
    ', "\n", $value); return "\n\t\n"; } /** * Returns form text input html string. * * @param string $name * @param string $value * @param array|string $attribs * * @return string form text input html output * @since 2.0 */ public function text($name, $value = null, $attribs = null) { $value = htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); return $this->input('text', $name, $value, $attribs); } /** * Returns form input html string. * * @param string $type * @param string $name * @param string $value * @param array|string $attribs * * @return string form input html output * @since 2.0 */ public function input($type, $name, $value = null, $attribs = null) { if (is_array($attribs)) { $attribs = JArrayHelper::toString($attribs); } return "\n\t\n"; } /** * Generates a yes/no radio list. * * @param string $name The value of the HTML name attribute * @param array $attribs Additional HTML attributes for the tag * @param mixed $optKey The key that is selected * @param string $optText The name of the object variable for the option value * @param string $selected The name of the object variable for the option text * @param boolean $idtag Value of the field id or null by default * @param boolean $translate True if options will be translated * * @return string HTML for the select list * * @since 11.1 */ public function radiolist($data, $name, $attribs = null, $optKey = 'value', $optText = 'text', $selected = null, $idtag = false, $translate = false) { reset($data); $html = ''; if (is_array($attribs)) { $attribs = JArrayHelper::toString($attribs); } $id_text = $idtag ? $idtag : $name; foreach ($data as $obj) { $k = $obj->$optKey; $t = $translate ? JText::_($obj->$optText) : $obj->$optText; $id = (isset($obj->id) ? $obj->id : null); $extra = ''; $extra .= $id ? ' id="' . $obj->id . '"' : ''; if (is_array($selected)) { foreach ($selected as $val) { $k2 = is_object($val) ? $val->$optKey : $val; if ($k == $k2) { $extra .= ' selected="selected"'; break; } } } else { $extra .= ((string) $k == (string) $selected ? ' checked="checked"' : ''); } $html .= "\n\t" . '' . "\n\t" . ''; } $html .= "\n"; return $html; } }components/com_zoo/helpers/field.php000066600000003726150771655450013667 0ustar00app->path->register($this->app->path->path('helpers:fields'), 'fields'); } /** * Render a field like text, select or radio button * * @param string $type The type of the field * @param string $name The name of the field * @param mixed $value The value of the field * @param object $node The node * @param array $args The arguments to pass on to the field layout * * @return string The html output * * @since 2.0 */ public function render($type, $name, $value, $node, $args = array()) { if (empty($type)) return; // set vars $args['name'] = $name; $args['value'] = $value; $args['node'] = $node; $__file = $this->app->path->path("fields:$type.php"); if ($__file != false) { // render the field extract($args); ob_start(); include($__file); $output = ob_get_contents(); ob_end_clean(); return $output; } return 'Field Layout "'.$type.'" not found. ('.$this->app->utility->debugInfo(debug_backtrace()).')'; } /** * Create html attribute string from array * * @param array $attributes The attributes * @param array $ignore The attributes to ignore * * @return string the attribute string * * @since 2.0 */ public function attributes($attributes, $ignore = array()) { $attribs = array(); $ignore = (array) $ignore; foreach ($attributes as $name => $value) { if (in_array($name, $ignore)) continue; $attribs[] = sprintf('%s="%s"', $name, htmlspecialchars($value)); } return implode(' ', $attribs); } }components/com_zoo/helpers/cache.php000066600000012751150771655450013645 0ustar00app->object->create('AppApcCache', array(md5($file), $lifetime)); } else { $cache = $this->app->object->create('AppCache', array($file, $hash, $lifetime)); $this->app->zoo->putIndexFile(dirname($file)); } return $cache; } } /** * The cache class. * * @package Component.Helpers * @since 2.0 */ class AppCache { /** * Path to cache file * * @var string * @since 2.0 */ protected $_file = 'config.txt'; /** * Path to cache file * * @var array * @since 2.0 */ protected $_items = array(); /** * marks cache dirty * * @var boolean * @since 2.0 */ protected $_dirty = false; /** * The cached items * * @var boolean * @since 2.0 */ protected $_hash = true; /** * Class constructor * * @param string $file Path to cache file * @param boolean $hash Wether the key should be hashed * @param int $lifetime The values lifetime * @since 2.0 */ public function __construct($file, $hash = true, $lifetime = null) { // if cache file doesn't exist, create it if (!JFile::exists($file)) { JFolder::create(dirname($file)); $buffer = ''; JFile::write($file, $buffer); } // set file and parse it $this->_file = $file; $this->_hash = $hash; $this->_parse(); // clear out of date values if ($lifetime) { $lifetime = (int) $lifetime; $remove = array(); foreach ($this->_items as $key => $value) { if ((time() - $value['timestamp']) > $lifetime) { $remove[] = $key; } } foreach ($remove as $key) { unset($this->_items[$key]); } } } /** * Check if the cache file is writable and readable * * @return boolean If the cache can be used * * @since 2.0 */ public function check() { return is_readable($this->_file) && is_writable($this->_file); } /** * Get a cache content * * @param string $key The key * * @return mixed The cache content * * @since 2.0 */ public function get($key) { if ($this->_hash) $key = md5($key); if (!array_key_exists($key, $this->_items)) return null; return $this->_items[$key]['value']; } /** * Set a cache content * * @param string $key The key * @param mixed $value The value * * @return AppCache $this for chaining support * * @since 2.0 */ public function set($key, $value) { if ($this->_hash) $key = md5($key); if (array_key_exists($key, $this->_items) && @$this->_items[$key]['value'] == $value) return $this; $this->_items[$key]['value'] = $value; $this->_items[$key]['timestamp'] = time(); $this->_dirty = true; return $this; } /** * Parse the cache file * * @return AppCache $this for chaining support * * @since 2.0 */ protected function _parse() { $content = file_get_contents($this->_file); if (!empty($content)) { $items = json_decode($content, true); if (is_array($items)) { $this->_items = $items; } } return $this; } /** * Save the cache file if it was changed * * @return AppCache $this for chaining support * * @since 2.0 */ public function save() { //ini_set('memory_limit', '600M'); if ($this->_dirty) { $data = json_encode($this->_items); JFile::write($this->_file, $data); } return $this; } /** * Clear the cache file * * @return AppCache $this for chaining support */ public function clear() { $this->_items = array(); $this->_dirty = true; return $this; } } /** * Cache class with alternative PHP cache (APC) storage. * * @author */ class AppApcCache { /** * @var string $_prefix */ protected $_prefix; protected $_lifetime = false; /** * Constructor. * * @param string $prefix The prefix for cache index keys. */ public function __construct($prefix = null, $lifetime = null) { $this->_prefix = $prefix === null ? md5(__FILE__) : $prefix; $this->_lifetime = $lifetime; } public function get($id) { if ($data = apc_fetch(sprintf('%s-%s', $this->_prefix, $id))) { if ($entry = @unserialize($data) and is_array($entry)) { if ($this->_lifetime && (time() - $entry['time']) > $this->_lifetime) { return null; } return $entry['data']; } } return null; } public function set($id, $data) { apc_store(sprintf('%s-%s', $this->_prefix, $id), serialize(array('data' => $data, 'time' => time()))); return $this; } public function clear() { $cache = new APCIterator('user', '/^'.preg_quote($this->_prefix, '/').'-/'); foreach ($cache as $entry) { apc_delete($entry['key']); } return $this; } public function check() { return true; } public function save() { return $this; } } /** * AppCacheException identifies an Exception in the AppCache class * @see AppCache */ class AppCacheException extends AppException {}components/com_zoo/helpers/tree.php000066600000004517150771655450013542 0ustar00app->object->create($classname); $root->id = 0; $root->name = 'ROOT'; $root->alias = '_root'; $objects[0] = $root; foreach ($objects as $object) { // set parent and child relations if (isset($object->$parent_property, $objects[$object->$parent_property])) { $object->setParent($objects[$object->$parent_property]); $objects[$object->$parent_property]->addChild($object); } } if ($max_depth) { foreach ($objects as $object) { if (count($object->getPathway()) > $max_depth) { $object->getParent()->removeChild($object); $object->setParent($objects[0]); $objects[0]->addChild($object); } } } return $objects; } /** * Build tree list which reflects the tree structure. * * @param string|int $id Object id to start * @param array $objects Objects collection * @param array $list Tree list return value * @param string $prefix Sublevel prefix * @param string $spacer Spacer * @param string $indent Indent * @param int $level Start level * @param int $maxlevel Maximum level depth * * @return array Tree list * @since 2.0 */ public function buildList($id, $objects, $list = array(), $prefix = '|_ ', $spacer = '.      ', $indent = '', $level = 0, $maxlevel = 9999) { if (isset($objects[$id]) && $level <= $maxlevel) { foreach ($objects[$id]->getChildren() as $child) { // set treename $id = $child->id; $list[$id] = $child; $list[$id]->treename = $indent.($indent == '' ? $child->name : $prefix.$child->name); $list = $this->buildList($id, $objects, $list, $prefix, $spacer, $indent.$spacer, $level + 1, $maxlevel); } } return $list; } }components/com_zoo/helpers/install.php000066600000012766150771655450014256 0ustar00getGroup(); if ($this->_applicationExists($group)) { throw new InstallHelperException('Delete existing applications first.'); } if (!($directory = $this->app->path->path("applications:$group")) || !JFolder::delete($directory)) { throw new InstallHelperException('Unable to delete directory: (' . $directory . ')'); } } /** * Checks if application exists * * @param string $group * @return boolean * @since 2.0 */ protected function _applicationExists($group) { $result = $this->app->table->application->first(array('conditions' => 'application_group = '.$this->app->database->Quote($group))); return !empty($result); } /** * Installs an Application from a user upload. * * @param array $userfile The userfile to install from * @return int 2 = update, 1 = install * * @throws InstallHelperException * @since 2.0 */ public function installApplicationFromUserfile($userfile) { // Make sure that file uploads are enabled in php if (!(bool) ini_get('file_uploads')) { throw new InstallHelperException('Fileuploads are not enabled in php.'); } // If there is no uploaded file, we have a problem... if (!is_array($userfile) ) { throw new InstallHelperException('No file selected.'); } // Check if there was a problem uploading the file. if ($userfile['error'] || $userfile['size'] < 1) { throw new InstallHelperException('Upload error occured.'); } // Temporary folder to extract the archive into $tmp_directory = $this->app->path->path('tmp:').'/'; $archivename = $tmp_directory.$userfile['name']; if (!JFile::upload($userfile['tmp_name'], $archivename)) { throw new InstallHelperException("Could not move uploaded file to ($archivename)"); } // Clean the paths to use for archive extraction $extractdir = $tmp_directory.uniqid('install_'); jimport('joomla.filesystem.archive'); // do the unpacking of the archive if (!JArchive::extract($archivename, $extractdir)) { throw new InstallHelperException("Could not extract zip file to ($tmp_directory)"); } return $this->installApplicationFromFolder($extractdir); } /** * Installs an Application from a folder. * * @param string $folder The application folder * * @return int 2 = update, 1 = install * * @throws InstallHelperException * @since 2.0 */ public function installApplicationFromFolder($folder) { $folder = rtrim($folder, "\\/") . '/'; if (!($manifest = $this->findManifest($folder))) { throw new InstallHelperException('No valid xml file found in the directory'); } $group = $this->getGroup($manifest); if (empty($group)) { throw new InstallHelperException('No app group in application.xml specified.'); } $update = false; $write_directory = $this->app->path->path('applications:').'/'.$group.'/'; if (JFolder::exists($write_directory)) { $files = $this->app->filesystem->readDirectoryFiles($folder.'types/', '', '/\.config$/', false); foreach ($files as $file) { if (JFile::exists($write_directory.'types/'.$file)) { JFile::delete($folder.'types/'.$file); } } $files = $this->app->filesystem->readDirectoryFiles($folder, '', '/(positions\.(config|xml)|metadata\.xml)$/', true); foreach ($files as $file) { if (JFile::exists($write_directory.$file)) { JFile::delete($folder.$file); } } $update = true; } if (!JFolder::copy($folder, $write_directory, '', true)) { throw new InstallHelperException('Unable to write to folder: ' . $write_directory); } $applications = $this->app->application->groups(); $application = isset($applications[$group]) ? $applications[$group] : null; // trigger installed event $this->app->event->dispatcher->notify($this->app->event->create($application, 'application:installed', compact('update'))); return $update ? 2 : 1; } /** * Reads application group from manifest * * @param SimpleXMLElement $manifest * @return string group * @since 2.0 */ public function getGroup(SimpleXMLElement $manifest) { return (string) $manifest->group; } /** * Reads version from manifest * * @param SimpleXMLElement $manifest * @return string version * @since 2.0 */ public function getVersion(SimpleXMLElement $manifest) { return (string) $manifest->version; } /** * Finds manifest in path * * @param string $path * @return SimpleXMLElement|false * @since 2.0 */ public function findManifest($path) { $path = rtrim($path, "\\/") . '/'; foreach ($this->app->filesystem->readDirectoryFiles($path, $path, '/\.xml$/', false) as $file) { if (($xml = simplexml_load_file($file)) && $this->isManifest($xml)) { return $xml; } } return false; } /** * Checks if xml is manifest * * @param SimpleXMLElement $xml * * @return boolean * * @since 2.0 */ public function isManifest(SimpleXMLElement $xml) { return $xml->getName() == 'application'; } } /** * InstallHelperException identifies an Exception in the InstallHelper class * @see InstallHelper */ class InstallHelperException extends AppException {}components/com_zoo/helpers/update.php000066600000022674150771655450014071 0ustar00getRequiredUpdates(); return !empty($updates); } /** * Return required update versions. * * @return array versions of required updates * @since 2.0 */ public function getRequiredUpdates() { // get current version $current_version = $this->getVersion(); // find required updates if ($files = $this->app->path->files('updates:', false, '/^\d+.*\.php$/')) { $files = array_map(create_function('$file', 'return basename($file, ".php");'), array_filter($files, create_function('$file', 'return version_compare("'.$current_version.'", basename($file, ".php")) < 0;'))); usort($files, create_function('$a, $b', 'return version_compare($a, $b);')); } return $files; } /** * Get preupdate notifications. * * @return array messages * @since 2.0 */ public function getNotifications() { // check if update is required if (!$this->required()) { return $this->_createResponse('No update required.', false, false); } // get current version $current_version = $this->getVersion(); $notifications = array(); // find and run the next update foreach ($this->getRequiredUpdates() as $version) { if ((version_compare($version, $current_version) > 0)) { $class = 'Update'.str_replace('.', '', $version); $this->app->loader->register($class, "updates:$version.php"); if (class_exists($class)) { // make sure class implemnts iUpdate interface $r = new ReflectionClass($class); if ($r->isSubclassOf('iUpdate') && !$r->isAbstract()) { // run the update $notification = $r->newInstance()->getNotifications($this->app); if (is_array($notification)) { $notifications = array_merge($notifications, $notification); } } } } } return $notifications; } /** * Performs the next update. * * @return array response * @since 2.0 */ public function run() { // check if update is required if (!$this->required()) { return $this->_createResponse('No update required.', false, false); } // get current version $current_version = $this->getVersion(); // find and run the next update $updates = $this->getRequiredUpdates(); foreach ($updates as $version) { if ((version_compare($version, $current_version) > 0)) { $class = 'Update'.str_replace('.', '', $version); $this->app->loader->register($class, "updates:$version.php"); if (class_exists($class)) { // make sure class implemnts iUpdate interface $r = new ReflectionClass($class); if ($r->isSubclassOf('iUpdate') && !$r->isAbstract()) { try { // run the update $r->newInstance()->run($this->app); } catch (Exception $e) { return $this->_createResponse("Error during update! ($e)", true, false); } // set current version $version_string = $version; if (!$required = count($updates) > 1) { if (($xml = simplexml_load_file($this->app->path->path('component.admin:zoo.xml'))) && (string) $xml->name == 'ZOO') { $version_string = (string) $xml->version; } } $this->setVersion($version); return $this->_createResponse('Successfully updated to version '.$version_string, false, $required); } } } } return $this->_createResponse('No update found.', false, false); } /** * Drops and recreates all ZOO database table indexes. * * @since 2.0 */ public function refreshDBTableIndexes() { // sanatize table indexes if ($this->app->path->path('component.admin:installation/index.sql')) { $db = $this->app->database; // read index.sql $buffer = JFile::read($this->app->path->path('component.admin:installation/index.sql')); // Create an array of queries from the sql file jimport('joomla.installer.helper'); $queries = JInstallerHelper::splitSql($buffer); if (!empty($queries)) { foreach ($queries as $query) { // replace table prefixes $query = $db->replacePrefix($query); // parse table name preg_match('/ALTER\s*TABLE\s*`(.*)`/i', $query, $result); if (count($result) < 2) { continue; } $table = $result[1]; // check if table exists if (!$db->queryResult('SHOW TABLES LIKE '.$db->Quote($table))) { continue; } // get existing indexes $indexes = $db->queryObjectList('SHOW INDEX FROM '.$table); // drop existing indexes $removed = array(); foreach ($indexes as $index) { if (in_array($index->Key_name, $removed)) { continue; } if ($index->Key_name != 'PRIMARY') { $db->query('DROP INDEX '.$index->Key_name.' ON '.$table); $removed[] = $index->Key_name; } } // add new indexes $db->query($query); } } } } /** * Gets the current version from versions table. * * @return string version * @since 2.0 */ public function getVersion() { $cache = $this->getCache(); if (!$version = $cache->get('zoo_version')) { // make sure versions table is present $this->app->database->query('CREATE TABLE IF NOT EXISTS '.ZOO_TABLE_VERSION.' (version varchar(255) NOT NULL) ENGINE=MyISAM;'); $version = $this->app->database->queryResult('SELECT version FROM '.ZOO_TABLE_VERSION); } $cache->set('zoo_version', $version)->save(); return $version; } /** * Writes the current version in versions table. * * @param string $version * * @since 2.0 */ public function setVersion($version) { // remove previous versions $this->app->database->query('TRUNCATE TABLE '.ZOO_TABLE_VERSION); // set version $this->app->database->query('INSERT INTO '.ZOO_TABLE_VERSION.' SET version='.$this->app->database->Quote($version)); $this->getCache()->clear()->save(); } /** * Creates an response * * @param string $message * @param string $error * @param boolean $continue * * @return array response * @since 2.0 */ protected function _createResponse($message, $error, $continue) { $message = JText::_($message); return compact('message', 'error', 'continue'); } /** * Outputs a message if there is a new update available. * * @since 2.0 */ public function available() { // check for updates if ($xml = @simplexml_load_file($this->app->path->path('component.admin:zoo.xml'))) { // update check if ($url = (string) current($xml->xpath('//updateUrl'))) { // create check url $url = sprintf('%s?application=%s&version=%s&format=raw', $url, 'zoo_j17', urlencode(current($xml->xpath('//version')))); // only check once a day $hash = md5($url.date('Y-m-d')); $cache = $this->getCache(); $check = $cache->get('check'); $data = $cache->get('data'); $prev_message = @$data['message']; if ($check != $hash) { if ($request = $this->app->http->get($url)) { $check = $hash; $data = json_decode($request['body'], true); } if ($prev_message != @$data['message']) { $cache->set('hideUpdateNotification', false); } } // decode response and set message if (!$cache->get('hideUpdateNotification') && @$data['status'] == 'update-available') { $close = $this->app->joomla->version->isCompatible('3.2') ? '' : ''; $close = sprintf($close, $this->app->link(array('controller' => 'manager', 'task' => 'hideUpdateNotification', 'format' => 'raw'), false)); $this->app->system->application->enqueueMessage(@$data['message'].$close, 'notice'); } $cache->set('check', $check)->set('data', $data)->save(); } } } /** * Hides the update notifications for this session * * @since 2.0 */ public function hideUpdateNotification() { $this->getCache()->set('hideUpdateNotification', true)->save(); } /** * Returns cache * * @return AppCache The update cache * @since 2.0 */ protected function getCache() { if (empty($this->_cache)) { $this->_cache = $this->app->cache->create($this->app->path->path('cache:') . '/zoo_update_cache'); if (!$this->_cache->check()) { $this->app->system->application->enqueueMessage('Cache not writeable please update the file permissions!', 'warning'); } } return $this->_cache; } } /** * Update interface * * @package Component.Helpers * @since 2.0 */ interface iUpdate { /** * Get preupdate notifications. * * @param Application $app The application to get the notifications from * @return array messages * @since 2.0 */ public function getNotifications($app); /** * Performs the update. * * @param Application $app The application to get the notifications from * @return boolean true if updated successful * @since 2.0 */ public function run($app); } /** * UpdateAppException identifies an Exception in the UpdateHelper class * @see UpdateHelper */ class UpdateAppException extends AppException {}components/com_zoo/helpers/googlemaps.php000066600000006763150771655450014745 0ustar00 $regs[1], 'lng' => $regs[2]); } } // use geocode to translate location return $this->geoCode($location, $cache); } /** * Geocode an address * * @param string $address The address to locate * @param string $cache The cache to lock in * * @return array coordinates * @since 2.0 */ public function geoCode($address, $cache = null) { // use cache result if ($cache !== null && $value = $cache->get($address)) { if (preg_match('/^([-]?(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+)),\s?([-]?(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+))$/i', $value, $regs)) { return array('lat' => $regs[1], 'lng' => $regs[2]); } } // query google maps geocoder and parse result $result = $this->queryGeoCoder($address); $coordinates = null; if (isset($result->status)) { switch ($result->status) { case 'OVER_QUERY_LIMIT': throw new GooglemapsHelperException("Google Geocoding API error: You are over your quota."); case 'ZERO_RESULTS': throw new GooglemapsHelperException("Google Geocoding API error: Couldn't find passed in address ($address)."); case 'REQUEST_DENIED': throw new GooglemapsHelperException("Google Geocoding API error: The request was denied."); case 'INVALID_REQUEST': throw new GooglemapsHelperException("Google Geocoding API error: The request was invalid."); case 'OK': if (isset($result->results) && $result = array_pop($result->results)) { if (isset($result->geometry->location->lat, $result->geometry->location->lng)) { $coordinates['lat'] = $result->geometry->location->lat; $coordinates['lng'] = $result->geometry->location->lng; } } // cache geocoder result if ($cache !== null && $coordinates !== null) { $cache->set($address, $coordinates['lat'].",".$coordinates['lng']); } } } return $coordinates; } /** * Query the Geocoder for an address * * @param string $address The address to locate * * @return array result array * @since 2.0 */ public function queryGeoCoder($address) { // query use http helper $response = $this->app->http->get(sprintf('http://maps.google.com/maps/api/geocode/json?address=%s&sensor=false', urlencode($address))); if (isset($response['body'])) { return json_decode($response['body']); } return null; } } /** * GooglemapsHelperException identifies an Exception in the GooglemapsHelper class * @see GooglemapsHelper */ class GooglemapsHelperException extends AppException {}components/com_zoo/helpers/parameterform.php000066600000020754150771655450015450 0ustar00app); return $this->app->object->create('AppParameterForm', $args); } /** * Convert params to AppData * * @param JParameter|AppParameterForm|array $params * @return AppData the converted params * @since 2.0 */ public function convertParams($params = array()) { if ($params instanceof AppParameterForm) { $params = $params->getValues(); } return $this->app->data->create($params); } } /** * Render parameter XML as HTML form. * * @package Component.Helpers * @since 2.0 */ class AppParameterForm { /** * App instance * * @var App * @since 2.0 */ public $app; /** * Array of values * * @var array */ protected $_values = array(); /** * The xml params object array, with each group as array key. * @var array */ protected $_xml; /** * Class constructor * * @param App $app The app instance * @param string|SimpleXMLElement $xml The xml file path or the xml string or the SimpleXMLElement * @since 2.0 */ public function __construct($app, $xml = null) { // init vars $this->app = $app; $this->loadXML($xml); } /** * Retrieve a form value * * @param string $name * @param mixed $default * * @return mixed * @since 2.0 */ public function getValue($name, $default = null) { if (isset($this->_values[$name])) { return $this->_values[$name]; } return $default; } /** * Set a form value * * @param string $name * @param mixed $value * * @return self * @since 2.0 */ public function setValue($name, $value) { $this->_values[$name] = $value; return $this; } /** * Retrieve form values * * @return array * @since 2.0 */ public function getValues() { return $this->_values; } /** * Set form values * * @param array $values * * @return self * @since 2.0 */ public function setValues($values) { $this->_values = (array) $values; return $this; } /** * Add a directory to search for field types * * @param string $path * * @return self * @since 2.0 */ public function addElementPath($path) { $this->app->path->register($path, 'fields'); return $this; } /** * Return number of params to render * * @param string $group Parameter group * * @return int Parameter count * @since 2.0 */ public function getParamsCount($group = '_default') { if (!isset($this->_xml[$group]) || !count($this->_xml[$group]->children())) { return false; } return count($this->_xml[$group]->children()); } /** * Get the number of params in each group * * @return array Array of all group names as key and parameter count as value * @since 2.0 */ public function getGroups() { if (!is_array($this->_xml)) { return false; } $results = array(); foreach ($this->_xml as $name => $group) { $results[$name] = $this->getParamsCount($name); } return $results; } /** * Sets the xml for a group * * @param SimpleXMLElement $xml * @since 2.0 */ public function setXML($xml) { if ($xml instanceof SimpleXMLElement) { if ($group = (string) $xml->attributes()->group) { $this->_xml[$group] = $xml; } else { $this->_xml['_default'] = $xml; } if ($path = (string) $xml->attributes()->addpath) { $this->addElementPath(JPATH_ROOT.$path); } } } /** * Loads an xml file or formatted string and parses it * * @param string|SimpleXMLElement $xml The xml file path or the xml string or an SimpleXMLElement * * @return boolean true on success * @since 2.0 */ public function loadXML($xml) { $element = false; if ($xml instanceof SimpleXMLElement) { $element = $xml; } // load xml file or string ? if ($element || ($element = @simplexml_load_file($xml)) || ($element = simplexml_load_string($xml))) { if (isset($element->params)) { foreach ($element->params as $param) { $this->setXML($param); } return true; } } return false; } /** * Adds an xml file or formatted string and parses it * * @param string|SimpleXMLElement $xml The xml file path or the xml string or an SimpleXMLElement * * @return boolean true on success * @since 2.0 */ public function addXML($xml) { $element = false; if ($xml instanceof SimpleXMLElement) { $element = $xml; } // load xml file or string ? if ($element or $element = @simplexml_load_file($xml) or $element = simplexml_load_string($xml)) { if (isset($element->params)) { foreach ($element->params as $params) { $group = $params->attributes()->group ? (string) $params->attributes()->group : '_default'; if (!isset($this->_xml[$group])) { $this->_xml[$group] = new SimpleXMLElement(''); } foreach ($params->param as $param) { // Avoid parameters in the same group with the same name $existing_params = $this->_xml[$group]->children(); foreach ($existing_params as $existing_param) { // If it exists already ( Skip array params, they can have the same name ) if (((string) $existing_param->attributes()->name == (string) $param->attributes()->name)) { // remove the old and let it add the new $dom = dom_import_simplexml($existing_param); $dom->parentNode->removeChild($dom); continue; } } $this->_appendSimpleXMLElement($this->_xml[$group], $param); } if ($path = (string) $params->attributes()->addpath) { $this->addElementPath(JPATH_ROOT.$path); } } return true; } } return false; } /** * Get the xml for a specific group or all groups * * @param string $group * @return SimpleXMLElement|array|false Array of groups or the xml for a group * @since 2.0 */ public function getXML($group = null) { if (!$group) { return $this->_xml; } if (isset($this->_xml[$group])) { return $this->_xml[$group]; } return false; } /** * Render parameter HTML form * * @param string $control_name The name of the control, or the default text area if a setup file is not found * @param string $group Parameter group * * @return string HTML output * @since 2.0 */ public function render($control_name = 'params', $group = '_default') { if (!isset($this->_xml[$group])) { return false; } $html = array('
      '); // add group description if ($description = (string) $this->_xml[$group]->attributes()->description) { $html[] = '
    • '.JText::_($description).'
    • '; } // add params foreach ($this->_xml[$group]->param as $param) { // init vars $type = (string) $param->attributes()->type; $name = (string) $param->attributes()->name; $value = $this->getValue((string) $param->attributes()->name, (string) $param->attributes()->default); $field = '
      '.$this->app->field->render($type, $name, $value, $param, array('control_name' => $control_name, 'parent' => $this)).'
      '; if ($type != 'hidden') { $html[] = '
    • '; $output = ' '; if ((string) $param->attributes()->label != '') { $attributes = array('for' => $control_name.$name); if ((string) $param->attributes()->description != '') { $attributes['class'] = 'hasTip'; $attributes['title'] = JText::_($param->attributes()->label).'::'.JText::_($param->attributes()->description); } $output = sprintf('', $this->app->field->attributes($attributes), JText::_($param->attributes()->label)); } $html[] = "
      $output
      "; $html[] = $field; $html[] = '
    • '; } else { $html[] = $field; } } $html[] = '
    '; return implode("\n", $html); } protected function _appendSimpleXMLElement($parent, $child) { if (strlen(trim((string) $child)) == 0) { $xml = $parent->addChild($child->getName()); foreach ($child->children() as $child_xml) { $this->_appendSimpleXMLElement($xml, $child_xml); } } else { $xml = $parent->addChild($child->getName(), (string) $child); } foreach ($child->attributes() as $n => $v) { $xml->addAttribute($n, $v); } } }components/com_zoo/helpers/module.php000066600000007375150771655450014075 0ustar00app->database; $query = "SELECT id, title, module, position, content, showtitle, params, published" ." FROM #__modules AS m" ." LEFT JOIN #__modules_menu AS mm ON mm.moduleid = m.id" ." WHERE " ."m.".$this->app->user->getDBAccessString(); // Fetch only published modules if ($published) { // get date $date = $this->app->date->create(); $now = $db->Quote($date->toSQL()); $null = $db->Quote($db->getNullDate()); $query .= " AND published = 1" . " AND (publish_up = ".$null." OR publish_up <= ".$now.")" . " AND (publish_down = ".$null." OR publish_down >= ".$now.")"; } $query .= " AND m.client_id = 0" ." ORDER BY position, ordering"; $db->setQuery($query); $modules = $db->loadObjectList('id'); foreach ($modules as $module) { $file = $module->module; $custom = $this->app->string->substr($file, 0, 4) == 'mod_' ? 0 : 1; $module->user = $custom; $module->name = $custom ? $module->title : $this->app->string->substr($file, 4); $module->style = null; $module->position = $this->app->string->strtolower($module->position); } return $modules; } /** * Enable Joomla module. * * @param string $module * @param string $position * @param int $menuid * * @since 2.0 */ public function enable($module, $position, $menuid = 0) { $query = "UPDATE #__modules, (SELECT MAX(ordering) +1 as ord FROM #__modules WHERE position = '$position') tt" ." SET published = 1, position = '$position', ordering = tt.ord" ." WHERE module = '$module'"; $this->app->database->query($query); $query = "INSERT IGNORE #__modules_menu" ." SET menuid = $menuid, moduleid = (SELECT id FROM #__modules WHERE module = '$module')"; $this->app->database->query($query); $query = "UPDATE #__extensions, (SELECT MAX(ordering) +1 as ord FROM #__modules WHERE position = '$position') tt" ." SET enabled = 1, ordering = tt.ord" ." WHERE element = '$module'"; $this->app->database->query($query); } /** * Get items from ZOO module params. * * @param AppData $params Module Parameter * @return array Items */ public function getItems($params) { $items = array(); if ($application = $this->app->table->application->get($params->get('application', 0))) { // set one or multiple categories $category = (int) $params->get('category', 0); if ($params->get('subcategories')) { $categories = $application->getCategoryTree(true); if (isset($categories[$category])) { $category = array_merge(array($category), array_keys($categories[$category]->getChildren(true))); } } // get items if ($params->get('mode') == 'item') { if (($item = $this->app->table->item->get($params->get('item_id'))) && $item->isPublished() && $item->canAccess()) { $items[] = $item; } } else if ($params->get('mode') == 'types') { $items = $this->app->table->item->getByType($params->get('type'), $application->id, true, null, $params->get('order', array('_itemname')), 0, $params->get('count', 4)); } else { $items = $this->app->table->item->getByCategory($application->id, $category, true, null, $params->get('order', array('_itemname')), 0, $params->get('count', 4)); } } return $items; } }components/com_zoo/helpers/alias.php000066600000006310150771655450013665 0ustar00_helper[$name])) { if (!$table = $this->app->table->$name) { throw new AliasHelperException(sprintf('Table class (%s) not found', $name)); } $this->_helper[$name] = $this->app->object->create('AppAlias', array($this->app, $table)); } return $this->_helper[$name]; } } class AppAlias { /** * Reference to the global App object * * @var App * @since 1.0.0 */ public $app; /** * Contains an instance of an AppTable object * * @var AppTable * @since 2.0 */ protected $_table; public function __construct($app, $table) { $this->app = $app; $this->_table = $table; } /** * Translate object id to alias. * * @param string $id The object id * * @return string|null The object alias if found * * @since 2.0 */ public function translateIDToAlias($id) { if (!is_numeric($id)) { return null; } if ($this->_table->has($id)) { return $this->_table->get($id)->alias; } // init vars $db = $this->app->database; // search alias $query = 'SELECT alias' .' FROM '.$this->_table->name .' WHERE id = '.$db->Quote($id) .' LIMIT 1'; return $db->queryResult($query); } /** * Translate object alias to id. * * @param string $alias The object alias * * @return string The object id if found, or 0 * * @since 2.0 */ public function translateAliasToID($alias) { // init vars $db = $this->app->database; // search alias $query = 'SELECT id' .' FROM '.$this->_table->name .' WHERE alias = '.$db->Quote($alias) .' LIMIT 1'; return $db->queryResult($query); } /** * Get unique object alias. * * @param string $id The object id * @param string $alias The object alias * * @return string The unique object alias string * * @since 2.0 */ public function getUniqueAlias($id, $alias = '') { if (empty($alias) && $id) { $alias = $this->string->sluggify($this->_table->get($id)->name); } if (!empty($alias)) { $new_alias = $alias; while ($this->checkAliasExists($new_alias, $id)) { $new_alias = JString::increment($new_alias, 'dash'); } return $new_alias; } return $alias; } /** * Method to check if an alias already exists. * * @param string $alias The object alias * @param string $id The object id * * @return string The object id if found, or 0 * * @since 2.0 */ public function checkAliasExists($alias, $id = 0) { $xid = intval($this->translateAliasToID($alias)); if ($xid && $xid != intval($id)) { return true; } return false; } } /** * AliasHelperException identifies an Exception in the AliasHelper class * @see AliasHelper */ class AliasHelperException extends AppException {}components/com_zoo/partials/index.html000066600000000036150771655450014234 0ustar00components/com_zoo/partials/_menu.php000066600000004601150771655450014055 0ustar00app->menu->get('nav') ->addFilter(array('ZooMenuFilter', 'activeFilter')) ->addFilter(array('ZooMenuFilter', 'nameFilter')) ->addFilter(array('ZooMenuFilter', 'versionFilter')) ->applyFilter(); echo ''; /* Class: ZooMenuFilter Filter for menu class. */ class ZooMenuFilter { public static function activeFilter(AppMenuItem $item) { // init vars $id = ''; $app = App::getInstance('zoo'); $application = $app->zoo->getApplication(); $controller = $app->request->getWord('controller'); $task = $app->request->getWord('task'); $classes = array(); // application context if (!empty($application)) { $id = $application->id.'-'.$controller; } // application configuration if ($controller == 'configuration' && $task) { if (in_array($task, array('importfrom', 'import', 'importcsv', 'importexport'))) { $id .= '-importexport'; } else { $id .= '-'.$task; } } // new application if ($controller == 'new') { $id = 'new'; } // application manager if ($controller == 'manager') { $id = 'manager'; if (in_array($task, array('types', 'addtype', 'edittype', 'editelements', 'assignelements', 'assignsubmission'))) { $id .= '-types'; } elseif ($task) { $id .= '-'.$task; } } // save current class attribute $class = $item->getAttribute('class'); if (!empty($class)) { $classes[] = $class; } // set active class if ($item->getId() == $id || $item->hasChild($id, true)) { $classes[] = 'active'; } // replace the old class attribute $item->setAttribute('class', implode(' ', $classes)); } public static function nameFilter(AppMenuItem $item) { if ($item->getId() != 'new' && $item->getId() != 'manager') { $item->setName(htmlspecialchars($item->getName(), ENT_QUOTES, 'UTF-8')); } } public static function versionFilter(AppMenuItem $item) { $app = App::getInstance('zoo'); if ($item->getId() == 'manager') { if ($version = $app->zoo->version()) { $item->setAttribute('data-zooversion', $version); } } } }components/com_zoo/partials/_message.php000066600000000277150771655450014542 0ustar00

    components/com_tags/tags.xml000066600000002734150771655450012236 0ustar00 com_tags Joomla! Project December 2013 (C) 2005 - 2014 Open Source Matters. All rights reserved. http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL admin@joomla.org www.joomla.org 3.1.0 COM_TAGS_XML_DESCRIPTION controller.php index.html metadata.xml newsfeeds.php router.php helpers models views language/en-GB.com_tags.ini tags.php config.xml controller.php index.html controllers helpers models views language/en-GB.com_tags.ini language/en-GB.com_tags.sys.ini com_tags components/com_tags/tables/tag.php000066600000012255150771655450013313 0ustar00loadArray($array['params']); $array['params'] = (string) $registry; } if (isset($array['metadata']) && is_array($array['metadata'])) { $registry = new JRegistry; $registry->loadArray($array['metadata']); $array['metadata'] = (string) $registry; } if (isset($array['urls']) && $array['urls']) { $registry = new JRegistry; $registry->loadArray($array['urls']); $array['urls'] = (string) $registry; } if (isset($array['images']) && is_array($array['images'])) { $registry = new JRegistry; $registry->loadArray($array['images']); $array['images'] = (string) $registry; } return parent::bind($array, $ignore); } /** * Overloaded check method to ensure data integrity. * * @return boolean True on success. * * @since 3.1 * @throws UnexpectedValueException */ public function check() { // Check for valid name. if (trim($this->title) == '') { throw new UnexpectedValueException(sprintf('The title is empty')); } if (empty($this->alias)) { $this->alias = $this->title; } $this->alias = JApplication::stringURLSafe($this->alias); if (trim(str_replace('-', '', $this->alias)) == '') { $this->alias = JFactory::getDate()->format("Y-m-d-H-i-s"); } // Check the publish down date is not earlier than publish up. if ((int) $this->publish_down > 0 && $this->publish_down < $this->publish_up) { throw new UnexpectedValueException(sprintf('End publish date is before start publish date.')); } // Clean up keywords -- eliminate extra spaces between phrases // and cr (\r) and lf (\n) characters from string if (!empty($this->metakey)) { // Only process if not empty // Define array of characters to remove $bad_characters = array("\n", "\r", "\"", "<", ">"); // Remove bad characters $after_clean = JString::str_ireplace($bad_characters, "", $this->metakey); // Create array using commas as delimiter $keys = explode(',', $after_clean); $clean_keys = array(); foreach($keys as $key) { if (trim($key)) { // Ignore blank keywords $clean_keys[] = trim($key); } } // Put array back together delimited by ", " $this->metakey = implode(", ", $clean_keys); } // Clean up description -- eliminate quotes and <> brackets if (!empty($this->metadesc)) { // Only process if not empty $bad_characters = array("\"", "<", ">"); $this->metadesc = JString::str_ireplace($bad_characters, "", $this->metadesc); } return true; } /** * Overriden JTable::store to set modified data and user id. * * @param boolean $updateNulls True to update fields even if they are null. * * @return boolean True on success. * * @since 3.1 */ public function store($updateNulls = false) { $date = JFactory::getDate(); $user = JFactory::getUser(); if ($this->id) { // Existing item $this->modified_time = $date->toSql(); $this->modified_user_id = $user->get('id'); } else { // New tag. A tag created and created_by field can be set by the user, // so we don't touch either of these if they are set. if (!(int) $this->created_time) { $this->created_time = $date->toSql(); } if (empty($this->created_user_id)) { $this->created_user_id = $user->get('id'); } } // Verify that the alias is unique $table = JTable::getInstance('Tag', 'TagsTable'); if ($table->load(array('alias' => $this->alias)) && ($table->id != $this->id || $this->id == 0)) { $this->setError(JText::_('COM_TAGS_ERROR_UNIQUE_ALIAS')); return false; } return parent::store($updateNulls); } /** * Method to delete a node and, optionally, its child nodes from the table. * * @param integer $pk The primary key of the node to delete. * @param boolean $children True to delete child nodes, false to move them up a level. * * @return boolean True on success. * * @since 3.1 * @see http://docs.joomla.org/JTableNested/delete */ public function delete($pk = null, $children = false) { $return = parent::delete($pk, $children); if ($return) { $helper = new JHelperTags; $helper->tagDeleteInstances($pk); } return $return; } } components/com_tags/tables/index.html000066600000000037150771655450014017 0ustar00 components/com_tags/views/tag/view.html.php000066600000006414150771655450015113 0ustar00form = $this->get('Form'); $this->item = $this->get('Item'); $this->state = $this->get('State'); $this->canDo = JHelperContent::getActions('com_tags'); $this->assoc = $this->get('Assoc'); $input = JFactory::getApplication()->input; // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $input->set('hidemainmenu', true); $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 3.1 * * @return void */ protected function addToolbar() { $user = JFactory::getUser(); $userId = $user->get('id'); $isNew = ($this->item->id == 0); $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); // Need to load the menu language file as mod_menu hasn't been loaded yet. $lang = JFactory::getLanguage(); $lang->load('com_tags', JPATH_BASE, null, false, true) || $lang->load('com_tags', JPATH_ADMINISTRATOR . '/components/com_tags', null, false, true); // Load the tags helper. require_once JPATH_COMPONENT . '/helpers/tags.php'; // Get the results for each action. $canDo = $this->canDo; $title = JText::_('COM_TAGS_BASE_' . ($isNew?'ADD':'EDIT') . '_TITLE'); // Prepare the toolbar. JToolbarHelper::title($title, 'tag tag-' . ($isNew?'add':'edit') . ($isNew?'add':'edit')); // For new records, check the create permission. if ($isNew) { JToolbarHelper::apply('tag.apply'); JToolbarHelper::save('tag.save'); JToolbarHelper::save2new('tag.save2new'); } // If not checked out, can save the item. elseif (!$checkedOut && ($canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_user_id == $userId))) { JToolbarHelper::apply('tag.apply'); JToolbarHelper::save('tag.save'); if ($canDo->get('core.create')) { JToolbarHelper::save2new('tag.save2new'); } } // If an existing item, can save to a copy. if (!$isNew && $canDo->get('core.create')) { JToolbarHelper::save2copy('tag.save2copy'); } if (empty($this->item->id)) { JToolbarHelper::cancel('tag.cancel'); } else { if ($this->state->params->get('save_history', 0) && $user->authorise('core.edit')) { JToolbarHelper::versions('com_tags.tag', $this->item->id); } JToolbarHelper::cancel('tag.cancel', 'JTOOLBAR_CLOSE'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_COMPONENTS_TAGS_MANAGER_EDIT'); JToolbarHelper::divider(); } } components/com_tags/views/tag/tmpl/edit.php000066600000004421150771655450015073 0ustar00state->get('params'); $params = $params->toArray(); ?>
    'details')); ?>
    form->getControlGroup('description'); ?>
    components/com_tags/views/tag/tmpl/edit_metadata.php000066600000001551150771655450016734 0ustar00
    form->getLabel('metadesc'); ?>
    form->getInput('metadesc'); ?>
    form->getLabel('metakey'); ?>
    form->getInput('metakey'); ?>
    form->getGroup('metadata') as $field): ?>
    hidden): ?> label; ?>
    input; ?>
    components/com_tags/views/tag/tmpl/index.html000066600000000037150771655450015431 0ustar00 components/com_tags/views/tag/tmpl/edit_options.php000066600000003763150771655450016656 0ustar00 'collapse0')); $fieldSets = $this->form->getFieldsets('params'); $i = 0; foreach ($fieldSets as $name => $fieldSet) : $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_TAGS_'.$name.'_FIELDSET_LABEL'; echo JHtml::_('bootstrap.addSlide', 'categoryOptions', JText::_($label), 'collapse' . $i++); if (isset($fieldSet->description) && trim($fieldSet->description)) : echo '

    '.$this->escape(JText::_($fieldSet->description)).'

    '; endif; ?> form->getFieldset($name) as $field) : ?>
    label; ?>
    input; ?>
    form->getLabel('note'); ?>
    form->getInput('note'); ?>
    form->getLabel('tag_layout'); ?>
    form->getInput('tag_layout'); ?>
    form->getLabel('tag_link_class'); ?>
    form->getInput('tag_link_class'); ?>
    components/com_tags/views/tags/view.html.php000066600000011400150771655450015265 0ustar00state = $this->get('State'); $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); TagsHelper::addSubmenu('tags'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } // Preprocess the list of items to find ordering divisions. foreach ($this->items as &$item) { $this->ordering[$item->parent_id][] = $item->id; } // Levels filter. $options = array(); $options[] = JHtml::_('select.option', '1', JText::_('J1')); $options[] = JHtml::_('select.option', '2', JText::_('J2')); $options[] = JHtml::_('select.option', '3', JText::_('J3')); $options[] = JHtml::_('select.option', '4', JText::_('J4')); $options[] = JHtml::_('select.option', '5', JText::_('J5')); $options[] = JHtml::_('select.option', '6', JText::_('J6')); $options[] = JHtml::_('select.option', '7', JText::_('J7')); $options[] = JHtml::_('select.option', '8', JText::_('J8')); $options[] = JHtml::_('select.option', '9', JText::_('J9')); $options[] = JHtml::_('select.option', '10', JText::_('J10')); $this->f_levels = $options; $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 3.1 */ protected function addToolbar() { $state = $this->get('State'); $canDo = JHelperContent::getActions('com_tags'); $user = JFactory::getUser(); // Get the toolbar object instance $bar = JToolBar::getInstance('toolbar'); JToolbarHelper::title(JText::_('COM_TAGS_MANAGER_TAGS'), 'tags'); if ($canDo->get('core.create')) { JToolbarHelper::addNew('tag.add'); } if ($canDo->get('core.edit')) { JToolbarHelper::editList('tag.edit'); } if ($canDo->get('core.edit.state')) { JToolbarHelper::publish('tags.publish', 'JTOOLBAR_PUBLISH', true); JToolbarHelper::unpublish('tags.unpublish', 'JTOOLBAR_UNPUBLISH', true); JToolbarHelper::archiveList('tags.archive'); } if ($canDo->get('core.admin')) { JToolbarHelper::checkin('tags.checkin'); } if ($state->get('filter.published') == -2 && $canDo->get('core.delete')) { JToolbarHelper::deleteList('', 'tags.delete', 'JTOOLBAR_EMPTY_TRASH'); } elseif ($canDo->get('core.edit.state')) { JToolbarHelper::trash('tags.trash'); } // Add a batch button if ($user->authorise('core.create', 'com_tags') && $user->authorise('core.edit', 'com_tags') && $user->authorise('core.edit.state', 'com_tags')) { JHtml::_('bootstrap.modal', 'collapseModal'); $title = JText::_('JTOOLBAR_BATCH'); // Instantiate a new JLayoutFile instance and render the batch button $layout = new JLayoutFile('joomla.toolbar.batch'); $dhtml = $layout->render(array('title' => $title)); $bar->appendButton('Custom', $dhtml, 'batch'); } if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_tags'); } JToolbarHelper::help('JHELP_COMPONENTS_TAGS_MANAGER'); JHtmlSidebar::setAction('index.php?option=com_tags&view=tags'); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_PUBLISHED'), 'filter_published', JHtml::_('select.options', JHtml::_('jgrid.publishedOptions'), 'value', 'text', $this->state->get('filter.published'), true) ); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_ACCESS'), 'filter_access', JHtml::_('select.options', JHtml::_('access.assetgroups'), 'value', 'text', $this->state->get('filter.access')) ); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_LANGUAGE'), 'filter_language', JHtml::_('select.options', JHtml::_('contentlanguage.existing', true, true), 'value', 'text', $this->state->get('filter.language')) ); } /** * Returns an array of fields the table can be sorted by * * @return array Array containing the field name to sort by as the key and display text as value * * @since 3.0 */ protected function getSortFields() { return array( 'a.lft' => JText::_('JGRID_HEADING_ORDERING'), 'a.state' => JText::_('JSTATUS'), 'a.title' => JText::_('JGLOBAL_TITLE'), 'a.access' => JText::_('JGRID_HEADING_ACCESS'), 'language' => JText::_('JGRID_HEADING_LANGUAGE'), 'a.id' => JText::_('JGRID_HEADING_ID') ); } } components/com_tags/views/tags/tmpl/default.php000066600000023510150771655450015755 0ustar00get('id'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $ordering = ($listOrder == 'a.lft'); $canOrder = $user->authorise('core.edit.state', 'com_tags'); $saveOrder = ($listOrder == 'a.lft' && $listDirn == 'asc'); if ($saveOrder) { $saveOrderingUrl = 'index.php?option=com_tags&task=tags.saveOrderAjax'; JHtml::_('sortablelist.sortable', 'categoryList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true); } $sortFields = $this->getSortFields(); ?>
    sidebar)): ?>
    sidebar; ?>
    pagination->getLimitBox(); ?>
    items)) : ?>
    items as $i => $item) : $orderkey = array_search($item->id, $this->ordering[$item->parent_id]); $canCreate = $user->authorise('core.create', 'com_tags'); $canEdit = $user->authorise('core.edit', 'com_tags'); $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id')|| $item->checked_out == 0; $canChange = $user->authorise('core.edit.state', 'com_tags') && $canCheckin; // Get the parents of item for sorting if ($item->level > 1) { $parentsStr = ""; $_currentParentId = $item->parent_id; $parentsStr = " ".$_currentParentId; for ($j = 0; $j < $item->level; $j++) { foreach ($this->ordering as $k => $v) { $v = implode("-", $v); $v = "-" . $v . "-"; if (strpos($v, "-" . $_currentParentId . "-") !== false) { $parentsStr .= " " . $k; $_currentParentId = $k; break; } } } } else { $parentsStr = ""; } ?>
    ', 'a.ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING'); ?> state->get('list.direction'), $this->state->get('list.ordering')); ?>
    pagination->getListFooter(); ?>
    id); ?> published, $i, 'tags.', $canChange);?> level > 0): ?> —', $item->level - 1) ?> checked_out) : ?> editor, $item->checked_out_time, 'tags.', $canCheckin); ?> escape($item->title); ?> escape($item->title); ?> note)) : ?> escape($item->alias));?> escape($item->alias), $this->escape($item->note));?> escape($item->access_title); ?> language == '*') : ?> language_title ? $this->escape($item->language_title) : JText::_('JUNDEFINED'); ?> id; ?>
    loadTemplate('batch'); ?>
    components/com_tags/views/tags/tmpl/index.html000066600000000037150771655450015614 0ustar00 components/com_tags/views/tags/tmpl/default_batch.php000066600000002547150771655450017125 0ustar00state->get('filter.published'); ?> components/com_tags/views/tags/index.html000066600000000037150771655450014640 0ustar00 components/com_tags/views/index.html000066600000000037150771655450013702 0ustar00 components/com_tags/index.html000066600000000037150771655450012545 0ustar00 components/com_tags/config.xml000066600000024306150771655450012544 0ustar00
    components/com_tags/controller.php000066600000003000150771655450013435 0ustar00input->get('view', 'tags'); $layout = $this->input->get('layout', 'default'); $id = $this->input->getInt('id'); // Check for edit form. if ($view == 'tag' && $layout == 'edit' && !$this->checkEditId('com_tags.edit.tag', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_tags&view=tags', false)); return false; } parent::display(); return $this; } } components/com_tags/controllers/tag.php000066600000003167150771655450014411 0ustar00authorise('core.create', 'com_tags')); } /** * Method to check if you can edit a record. * * @param array $data An array of input data. * @param string $key The name of the key for the primary key. * * @return boolean * * @since 3.1 */ protected function allowEdit($data = array(), $key = 'id') { // Since there is no asset tracking and no categories, revert to the component permissions. return parent::allowEdit($data, $key); } /** * Method to run batch operations. * * @param object $model The model. * * @return boolean True if successful, false otherwise and internal error is set. * * @since 3.1 */ public function batch($model = null) { JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Set the model $model = $this->getModel('Tag'); // Preset the redirect $this->setRedirect('index.php?option=com_tags&view=tags'); return parent::batch($model); } } components/com_tags/controllers/index.html000066600000000037150771655450015113 0ustar00 components/com_tags/controllers/tags.php000066600000002626150771655450014573 0ustar00 true)) { $model = parent::getModel($name, $prefix, $config); return $model; } /** * Rebuild the nested set tree. * * @return boolean False on failure or error, true on success. * * @since 3.1 */ public function rebuild() { JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); $this->setRedirect(JRoute::_('index.php?option=com_tags&view=tags', false)); $model = $this->getModel(); if ($model->rebuild()) { // Rebuild succeeded. $this->setMessage(JText::_('COM_TAGS_REBUILD_SUCCESS')); return true; } else { // Rebuild failed. $this->setMessage(JText::_('COM_TAGSS_REBUILD_FAILURE')); return false; } } } components/com_tags/access.xml000066600000001313150771655450012531 0ustar00
    components/com_tags/tags.php000066600000001201150771655450012211 0ustar00input; if (!JFactory::getUser()->authorise('core.manage', 'com_tags')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } $task = $input->get('task'); $controller = JControllerLegacy::getInstance('Tags'); $controller->execute($input->get('task')); $controller->redirect(); components/com_tags/helpers/html/index.html000066600000000037150771655450015153 0ustar00 components/com_tags/helpers/index.html000066600000000037150771655450014207 0ustar00 components/com_tags/helpers/tags.php000066600000002607150771655450013666 0ustar00/language $lang->load($component, JPATH_BASE, null, false, true) || $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component), null, false, true); } } } } } components/com_tags/models/tag.php000066600000024762150771655450013332 0ustar00id)) { if ($record->published != -2) { return; } return parent::canDelete($record); } } /** * Method to test whether a record can have its state changed. * * @param object $record A record object. * * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. * * @since 3.1 */ protected function canEditState($record) { return parent::canEditState($record); } /** * Method to get a table object, load it if necessary. * * @param string $type The table name. Optional. * @param string $prefix The class prefix. Optional. * @param array $config Configuration array for model. Optional. * * @return JTable A JTable object * * @since 3.1 */ public function getTable($type = 'Tag', $prefix = 'TagsTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @return void * * @since 3.1 */ protected function populateState() { $app = JFactory::getApplication('administrator'); $parentId = $app->input->getInt('parent_id'); $this->setState('tag.parent_id', $parentId); // Load the User state. $pk = $app->input->getInt('id'); $this->setState($this->getName() . '.id', $pk); // Load the parameters. $params = JComponentHelper::getParams('com_tags'); $this->setState('params', $params); } /** * Method to get a tag. * * @param integer $pk An optional id of the object to get, otherwise the id from the model state is used. * * @return mixed Tag data object on success, false on failure. * * @since 3.1 */ public function getItem($pk = null) { if ($result = parent::getItem($pk)) { // Prime required properties. if (empty($result->id)) { $result->parent_id = $this->getState('tag.parent_id'); } // Convert the metadata field to an array. $registry = new JRegistry; $registry->loadString($result->metadata); $result->metadata = $registry->toArray(); // Convert the images field to an array. $registry = new JRegistry; $registry->loadString($result->images); $result->images = $registry->toArray(); // Convert the urls field to an array. $registry = new JRegistry; $registry->loadString($result->urls); $result->urls = $registry->toArray(); // Convert the created and modified dates to local user time for display in the form. $tz = new DateTimeZone(JFactory::getApplication()->getCfg('offset')); if ((int) $result->created_time) { $date = new JDate($result->created_time); $date->setTimezone($tz); $result->created_time = $date->toSql(true); } else { $result->created_time = null; } if ((int) $result->modified_time) { $date = new JDate($result->modified_time); $date->setTimezone($tz); $result->modified_time = $date->toSql(true); } else { $result->modified_time = null; } } return $result; } /** * Method to get the row form. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return mixed A JForm object on success, false on failure * * @since 3.1 */ public function getForm($data = array(), $loadData = true) { $jinput = JFactory::getApplication()->input; // Get the form. $form = $this->loadForm('com_tags.tag', 'tag', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } $user = JFactory::getUser(); if (!$user->authorise('core.edit.state', 'com_tags' . $jinput->get('id'))) { // Disable fields for display. $form->setFieldAttribute('ordering', 'disabled', 'true'); $form->setFieldAttribute('published', 'disabled', 'true'); // Disable fields while saving. // The controller has already verified this is a record you can edit. $form->setFieldAttribute('ordering', 'filter', 'unset'); $form->setFieldAttribute('published', 'filter', 'unset'); } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * * @since 3.1 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_tags.edit.tag.data', array()); if (empty($data)) { $data = $this->getItem(); } $this->preprocessData('com_tags.tag', $data); return $data; } /** * Method to preprocess the form. * * @param JForm $form A JForm object. * @param mixed $data The data expected for the form. * @param string $group The name of the plugin group to import. * * @return void * * @see JFormField * @since 3.1 * @throws Exception if there is an error in the form event. */ protected function preprocessForm(JForm $form, $data, $group = 'content') { // Trigger the default form events. parent::preprocessForm($form, $data, $group); } /** * Method to save the form data. * * @param array $data The form data. * * @return boolean True on success. * * @since 3.1 */ public function save($data) { $dispatcher = JEventDispatcher::getInstance(); $table = $this->getTable(); $input = JFactory::getApplication()->input; $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState($this->getName() . '.id'); $isNew = true; // Include the content plugins for the on save events. JPluginHelper::importPlugin('content'); // Load the row if saving an existing tag. if ($pk > 0) { $table->load($pk); $isNew = false; } // Set the new parent id if parent id not matched OR while New/Save as Copy . if ($table->parent_id != $data['parent_id'] || $data['id'] == 0) { $table->setLocation($data['parent_id'], 'last-child'); } if (isset($data['images']) && is_array($data['images'])) { $registry = new JRegistry; $registry->loadArray($data['images']); $data['images'] = (string) $registry; } if (isset($data['urls']) && is_array($data['urls'])) { $registry = new JRegistry; $registry->loadArray($data['urls']); $data['urls'] = (string) $registry; } // Alter the title for save as copy if ($input->get('task') == 'save2copy') { list($title, $alias) = $this->generateNewTitle($data['parent_id'], $data['alias'], $data['title']); $data['title'] = $title; $data['alias'] = $alias; } // Bind the data. if (!$table->bind($data)) { $this->setError($table->getError()); return false; } // Bind the rules. if (isset($data['rules'])) { $rules = new JAccessRules($data['rules']); $table->setRules($rules); } // Check the data. if (!$table->check()) { $this->setError($table->getError()); return false; } // Trigger the onContentBeforeSave event. $result = $dispatcher->trigger($this->event_before_save, array($this->option . '.' . $this->name, &$table, $isNew)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } // Store the data. if (!$table->store()) { $this->setError($table->getError()); return false; } // Trigger the onContentAfterSave event. $dispatcher->trigger($this->event_after_save, array($this->option . '.' . $this->name, &$table, $isNew)); // Rebuild the path for the tag: if (!$table->rebuildPath($table->id)) { $this->setError($table->getError()); return false; } // Rebuild the paths of the tag's children: if (!$table->rebuild($table->id, $table->lft, $table->level, $table->path)) { $this->setError($table->getError()); return false; } $this->setState($this->getName() . '.id', $table->id); // Clear the cache $this->cleanCache(); return true; } /** * Method rebuild the entire nested set tree. * * @return boolean False on failure or error, true otherwise. * * @since 3.1 */ public function rebuild() { // Get an instance of the table object. $table = $this->getTable(); if (!$table->rebuild()) { $this->setError($table->getError()); return false; } // Clear the cache $this->cleanCache(); return true; } /** * Method to save the reordered nested set tree. * First we save the new order values in the lft values of the changed ids. * Then we invoke the table rebuild to implement the new ordering. * * @param array $idArray An array of primary key ids. * @param integer $lft_array The lft value * * @return boolean False on failure or error, True otherwise * * @since 3.1 */ public function saveorder($idArray = null, $lft_array = null) { // Get an instance of the table object. $table = $this->getTable(); if (!$table->saveorder($idArray, $lft_array)) { $this->setError($table->getError()); return false; } // Clear the cache $this->cleanCache(); return true; } /** * Method to change the title & alias. * * @param integer $parent_id The id of the parent. * @param string $alias The alias. * @param string $title The title. * * @return array Contains the modified title and alias. * * @since 3.1 */ protected function generateNewTitle($parent_id, $alias, $title) { // Alter the title & alias $table = $this->getTable(); while ($table->load(array('alias' => $alias, 'parent_id' => $parent_id))) { $title = ($table->title != $title) ? $title : JString::increment($title); $alias = JString::increment($alias, 'dash'); } return array($title, $alias); } } components/com_tags/models/index.html000066600000000037150771655450014030 0ustar00 components/com_tags/models/fields/index.html000066600000000037150771655450015276 0ustar00 components/com_tags/models/forms/index.html000066600000000037150771655450015156 0ustar00 components/com_tags/models/forms/tag.xml000066600000015755150771655450014473 0ustar00
    components/com_tags/models/tags.php000066600000020132150771655450013500 0ustar00context; $search = $this->getUserStateFromRequest($context . '.search', 'filter_search'); $this->setState('filter.search', $search); $level = $this->getUserStateFromRequest($context . '.filter.level', 'filter_level', 0, 'int'); $this->setState('filter.level', $level); $access = $this->getUserStateFromRequest($context . '.filter.access', 'filter_access', 0, 'int'); $this->setState('filter.access', $access); $published = $this->getUserStateFromRequest($context . '.filter.published', 'filter_published', ''); $this->setState('filter.published', $published); $language = $this->getUserStateFromRequest($context . '.filter.language', 'filter_language', ''); $this->setState('filter.language', $language); // Load the parameters. $params = JComponentHelper::getParams('com_tags'); $this->setState('params', $params); // List state information. parent::populateState('a.lft', 'asc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. * * @return string A store id. * @since 3.1 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.published'); $id .= ':' . $this->getState('filter.language'); return parent::getStoreId($id); } /** * Method to create a query for a list of items. * * @return string * * @since 3.1 */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); $user = JFactory::getUser(); // Select the required fields from the table. $query->select( $this->getState( 'list.select', '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' ) ); $query->from('#__tags AS a') ->where('a.alias <> ' . $db->quote('root')); // Join over the language $query->select('l.title AS language_title') ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); // Join over the users for the checked out user. $query->select('uc.name AS editor') ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); // Join over the users for the author. $query->select('ua.name AS author_name') ->join('LEFT', '#__users AS ua ON ua.id = a.created_user_id') ->select('ug.title AS access_title') ->join('LEFT', '#__viewlevels AS ug on ug.id = a.access'); // Filter on the level. if ($level = $this->getState('filter.level')) { $query->where('a.level <= ' . (int) $level); } // Filter by access level. if ($access = $this->getState('filter.access')) { $query->where('a.access = ' . (int) $access); } // Implement View Level Access if (!$user->authorise('core.admin')) { $groups = implode(',', $user->getAuthorisedViewLevels()); $query->where('a.access IN (' . $groups . ')'); } // Filter by published state $published = $this->getState('filter.published'); if (is_numeric($published)) { $query->where('a.published = ' . (int) $published); } elseif ($published === '') { $query->where('(a.published IN (0, 1))'); } // Filter by search in title $search = $this->getState('filter.search'); if (!empty($search)) { if (stripos($search, 'id:') === 0) { $query->where('a.id = ' . (int) substr($search, 3)); } elseif (stripos($search, 'author:') === 0) { $search = $db->quote('%' . $db->escape(substr($search, 7), true) . '%'); $query->where('(ua.name LIKE ' . $search . ' OR ua.username LIKE ' . $search . ')'); } else { $search = $db->quote('%' . $db->escape($search, true) . '%'); $query->where('(a.title LIKE ' . $search . ' OR a.alias LIKE ' . $search . ' OR a.note LIKE ' . $search . ')'); } } // Filter on the language. if ($language = $this->getState('filter.language')) { $query->where('a.language = ' . $db->quote($language)); } // Add the list ordering clause $listOrdering = $this->getState('list.ordering', 'a.lft'); $listDirn = $db->escape($this->getState('list.direction', 'ASC')); if ($listOrdering == 'a.access') { $query->order('a.access ' . $listDirn . ', a.lft ' . $listDirn); } else { $query->order($db->escape($listOrdering) . ' ' . $listDirn); } //echo nl2br(str_replace('#__','jos_',$query)); return $query; } /** * Method override to check-in a record or an array of record * * @param mixed $pks The ID of the primary key or an array of IDs * * @return mixed Boolean false if there is an error, otherwise the count of records checked in. * * @since 12.2 */ public function checkin($pks = array()) { $pks = (array) $pks; $table = $this->getTable(); $count = 0; if (empty($pks)) { $pks = array((int) $this->getState($this->getName() . '.id')); } // Check in all items. foreach ($pks as $pk) { if ($table->load($pk)) { if ($table->checked_out > 0) { // Only attempt to check the row in if it exists. if ($pk) { $user = JFactory::getUser(); // Get an instance of the row to checkin. $table = $this->getTable(); if (!$table->load($pk)) { $this->setError($table->getError()); return false; } // Check if this is the user having previously checked out the row. if ($table->checked_out > 0 && $table->checked_out != $user->get('id') && !$user->authorise('core.admin', 'com_checkin')) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_CHECKIN_USER_MISMATCH')); return false; } // Attempt to check the row in. if (!$table->checkin($pk)) { $this->setError($table->getError()); return false; } } $count++; } } else { $this->setError($table->getError()); return false; } } return $count; } /** * Method to get a table object, load it if necessary. * * @param string $type The table name. Optional. * @param string $prefix The class prefix. Optional. * @param array $config Configuration array for model. Optional. * * @return JTable A JTable object * * @since 3.1 */ public function getTable($type = 'Tag', $prefix = 'TagsTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } } components/com_plugins/plugins.xml000066600000002042150771655450013474 0ustar00 com_plugins Joomla! Project April 2006 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_PLUGINS_XML_DESCRIPTION config.xml controller.php index.html plugins.php controllers helpers models views language/en-GB.com_plugins.ini language/en-GB.com_plugins.sys.ini components/com_plugins/views/plugins/view.html.php000066600000006224150771655450016543 0ustar00items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } // Check if there are no matching items if (!count($this->items)) { JFactory::getApplication()->enqueueMessage( JText::_('COM_PLUGINS_MSG_MANAGE_NO_PLUGINS'), 'warning' ); } $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { $canDo = JHelperContent::getActions('com_plugins'); JToolbarHelper::title(JText::_('COM_PLUGINS_MANAGER_PLUGINS'), 'power-cord plugin'); if ($canDo->get('core.edit')) { JToolbarHelper::editList('plugin.edit'); } if ($canDo->get('core.edit.state')) { JToolbarHelper::publish('plugins.publish', 'JTOOLBAR_ENABLE', true); JToolbarHelper::unpublish('plugins.unpublish', 'JTOOLBAR_DISABLE', true); JToolbarHelper::checkin('plugins.checkin'); } if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_plugins'); } JToolbarHelper::help('JHELP_EXTENSIONS_PLUGIN_MANAGER'); JHtmlSidebar::setAction('index.php?option=com_plugins&view=plugins'); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_PUBLISHED'), 'filter_enabled', JHtml::_('select.options', PluginsHelper::publishedOptions(), 'value', 'text', $this->state->get('filter.enabled'), true) ); JHtmlSidebar::addFilter( JText::_('COM_PLUGINS_OPTION_FOLDER'), 'filter_folder', JHtml::_('select.options', PluginsHelper::folderOptions(), 'value', 'text', $this->state->get('filter.folder')) ); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_ACCESS'), 'filter_access', JHtml::_('select.options', JHtml::_('access.assetgroups'), 'value', 'text', $this->state->get('filter.access')) ); $this->sidebar = JHtmlSidebar::render(); } /** * Returns an array of fields the table can be sorted by * * @return array Array containing the field name to sort by as the key and display text as value * * @since 3.0 */ protected function getSortFields() { return array( 'ordering' => JText::_('JGRID_HEADING_ORDERING'), 'enabled' => JText::_('JSTATUS'), 'name' => JText::_('JGLOBAL_TITLE'), 'folder' => JText::_('COM_PLUGINS_FOLDER_HEADING'), 'element' => JText::_('COM_PLUGINS_ELEMENT_HEADING'), 'access' => JText::_('JGRID_HEADING_ACCESS'), 'extension_id' => JText::_('JGRID_HEADING_ID') ); } } components/com_plugins/views/plugins/tmpl/default.php000066600000020011150771655450017214 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $canOrder = $user->authorise('core.edit.state', 'com_plugins'); $saveOrder = $listOrder == 'ordering'; if ($saveOrder) { $saveOrderingUrl = 'index.php?option=com_plugins&task=plugins.saveOrderAjax&tmpl=component'; JHtml::_('sortablelist.sortable', 'articleList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); } $sortFields = $this->getSortFields(); ?>
    sidebar)) : ?>
    pagination->getLimitBox(); ?>
    items as $i => $item) : $ordering = ($listOrder == 'ordering'); $canEdit = $user->authorise('core.edit', 'com_plugins'); $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; $canChange = $user->authorise('core.edit.state', 'com_plugins') && $canCheckin; ?>
    ', 'ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING'); ?>
    pagination->getListFooter(); ?>
    extension_id); ?> enabled, $i, 'plugins.', $canChange); ?> checked_out) : ?> editor, $item->checked_out_time, 'plugins.', $canCheckin); ?> name; ?> name; ?> escape($item->folder);?> escape($item->element);?> escape($item->access_level); ?> extension_id;?>
    components/com_plugins/views/plugins/tmpl/index.html000066600000000037150771655450017062 0ustar00 components/com_plugins/views/plugins/index.html000066600000000037150771655450016106 0ustar00 components/com_plugins/views/index.html000066600000000037150771655450014425 0ustar00 components/com_plugins/views/plugin/view.html.php000066600000003444150771655450016361 0ustar00state = $this->get('State'); $this->item = $this->get('Item'); $this->form = $this->get('Form'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { JFactory::getApplication()->input->set('hidemainmenu', true); $canDo = JHelperContent::getActions('com_plugins'); JToolbarHelper::title(JText::sprintf('COM_PLUGINS_MANAGER_PLUGIN', JText::_($this->item->name)), 'power-cord plugin'); // If not checked out, can save the item. if ($canDo->get('core.edit')) { JToolbarHelper::apply('plugin.apply'); JToolbarHelper::save('plugin.save'); } JToolbarHelper::cancel('plugin.cancel', 'JTOOLBAR_CLOSE'); JToolbarHelper::divider(); // Get the help information for the plugin item. $lang = JFactory::getLanguage(); $help = $this->get('Help'); if ($lang->hasKey($help->url)) { $debug = $lang->setDebug(false); $url = JText::_($help->url); $lang->setDebug($debug); } else { $url = null; } JToolbarHelper::help($help->key, false, $url); } } components/com_plugins/views/plugin/tmpl/edit.php000066600000011357150771655450016347 0ustar00fieldsets = $this->form->getFieldsets('params'); ?>
    'general')); ?>
    item->xml) : ?> item->xml->description) : ?>

    item->xml) { echo ($text = (string) $this->item->xml->name) ? JText::_($text) : $this->item->name; } else { echo JText::_('COM_PLUGINS_XML_ERR'); } ?>

    form->getValue('folder'); ?> / form->getValue('element'); ?>
    item->xml->description); $this->fieldset = 'description'; $long_description = JLayoutHelper::render('joomla.edit.fieldset', $this); if(!$long_description) { $truncated = JHtmlString::truncate($short_description, 550, true, false); if(strlen($truncated) > 500) { $long_description = $short_description; $short_description = JHtmlString::truncate($truncated, 250); if($short_description == $long_description) { $long_description = ''; } } } ?>

    fieldset = 'basic'; $html = JLayoutHelper::render('joomla.edit.fieldset', $this); echo $html ? '
    ' . $html : ''; ?>
    form->getLabel('ordering'); ?>
    form->getInput('ordering'); ?>
    form->getLabel('folder'); ?>
    form->getInput('folder'); ?>
    form->getLabel('element'); ?>
    form->getInput('element'); ?>
    fieldsets = array(); $this->ignore_fieldsets = array('basic', 'description'); echo JLayoutHelper::render('joomla.edit.params', $this); ?>
    components/com_plugins/views/plugin/tmpl/index.html000066600000000037150771655450016677 0ustar00 components/com_plugins/views/plugin/tmpl/edit_options.php000066600000002425150771655450020116 0ustar00fieldsets as $name => $fieldset) { if (!isset($fieldset->repeat) || isset($fieldset->repeat) && $fieldset->repeat == false) { $label = !empty($fieldset->label) ? JText::_($fieldset->label, true) : JText::_('COM_PLUGINS_' . $fieldset->name . '_FIELDSET_LABEL', true); $optionsname = 'options-' . $fieldset->name; echo JHtml::_('bootstrap.addTab', 'myTab', $optionsname, $label); if (isset($fieldset->description) && trim($fieldset->description)) { echo '

    ' . $this->escape(JText::_($fieldset->description)) . '

    '; } $hidden_fields = ''; foreach ($this->form->getFieldset($name) as $field) { if (!$field->hidden) { ?>
    label; ?>
    input; ?>
    input; } } echo $hidden_fields; echo JHtml::_('bootstrap.endTab'); } } components/com_plugins/views/plugin/index.html000066600000000037150771655450015723 0ustar00 components/com_plugins/index.html000066600000000037150771655450013270 0ustar00 components/com_plugins/config.xml000066600000000537150771655450013267 0ustar00
    components/com_plugins/plugins.php000066600000001132150771655450013462 0ustar00authorise('core.manage', 'com_plugins')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } $controller = JControllerLegacy::getInstance('Plugins'); $controller->execute(JFactory::getApplication()->input->get('task')); $controller->redirect(); components/com_plugins/controller.php000066600000003113150771655450014165 0ustar00input->get('view', 'plugins')); $view = $this->input->get('view', 'plugins'); $layout = $this->input->get('layout', 'default'); $id = $this->input->getInt('extension_id'); // Check for edit form. if ($view == 'plugin' && $layout == 'edit' && !$this->checkEditId('com_plugins.edit.plugin', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_plugins&view=plugins', false)); return false; } parent::display(); } } components/com_plugins/controllers/plugin.php000066600000000714150771655450015652 0ustar00 components/com_plugins/controllers/plugins.php000066600000001714150771655450016036 0ustar00 true)) { $model = parent::getModel($name, $prefix, $config); return $model; } } components/com_plugins/access.xml000066600000001010150771655450013246 0ustar00
    components/com_plugins/helpers/index.html000066600000000037150771655450014732 0ustar00 components/com_plugins/helpers/plugins.php000066600000005050150771655450015127 0ustar00getQuery(true) ->select('DISTINCT(folder) AS value, folder AS text') ->from('#__extensions') ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) ->order('folder'); $db->setQuery($query); try { $options = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage()); } return $options; } public function parseXMLTemplateFile($templateBaseDir, $templateDir) { $data = new JObject; // Check of the xml file exists $filePath = JPath::clean($templateBaseDir . '/templates/' . $templateDir . '/templateDetails.xml'); if (is_file($filePath)) { $xml = JInstaller::parseXMLInstallFile($filePath); if ($xml['type'] != 'template') { return false; } foreach ($xml as $key => $value) { $data->set($key, $value); } } return $data; } } components/com_plugins/models/plugin.php000066600000021330150771655450014564 0ustar00getItem(); $folder = $item->folder; $element = $item->element; } else { $folder = JArrayHelper::getValue($data, 'folder', '', 'cmd'); $element = JArrayHelper::getValue($data, 'element', '', 'cmd'); } // These variables are used to add data from the plugin XML files. $this->setState('item.folder', $folder); $this->setState('item.element', $element); // Get the form. $form = $this->loadForm('com_plugins.plugin', 'plugin', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } // Modify the form based on access controls. if (!$this->canEditState((object) $data)) { // Disable fields for display. $form->setFieldAttribute('ordering', 'disabled', 'true'); $form->setFieldAttribute('enabled', 'disabled', 'true'); // Disable fields while saving. // The controller has already verified this is a record you can edit. $form->setFieldAttribute('ordering', 'filter', 'unset'); $form->setFieldAttribute('enabled', 'filter', 'unset'); } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * @since 1.6 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_plugins.edit.plugin.data', array()); if (empty($data)) { $data = $this->getItem(); } $this->preprocessData('com_plugins.plugin', $data); return $data; } /** * Method to get a single record. * * @param integer The id of the primary key. * * @return mixed Object on success, false on failure. */ public function getItem($pk = null) { $pk = (!empty($pk)) ? $pk : (int) $this->getState('plugin.id'); if (!isset($this->_cache[$pk])) { $false = false; // Get a row instance. $table = $this->getTable(); // Attempt to load the row. $return = $table->load($pk); // Check for a table object error. if ($return === false && $table->getError()) { $this->setError($table->getError()); return $false; } // Convert to the JObject before adding other data. $properties = $table->getProperties(1); $this->_cache[$pk] = JArrayHelper::toObject($properties, 'JObject'); // Convert the params field to an array. $registry = new JRegistry; $registry->loadString($table->params); $this->_cache[$pk]->params = $registry->toArray(); // Get the plugin XML. $path = JPath::clean(JPATH_PLUGINS.'/'.$table->folder.'/'.$table->element.'/'.$table->element.'.xml'); if (file_exists($path)) { $this->_cache[$pk]->xml = simplexml_load_file($path); } else { $this->_cache[$pk]->xml = null; } } return $this->_cache[$pk]; } /** * Returns a reference to the a Table object, always creating it. * * @param type The table type to instantiate * @param string A prefix for the table class name. Optional. * @param array Configuration array for model. Optional. * @return JTable A database object */ public function getTable($type = 'Extension', $prefix = 'JTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @return void * @since 1.6 */ protected function populateState() { // Execute the parent method. parent::populateState(); $app = JFactory::getApplication('administrator'); // Load the User state. $pk = $app->input->getInt('extension_id'); $this->setState('plugin.id', $pk); } /** * @param object A form object. * @param mixed The data expected for the form. * @return mixed True if successful. * @throws Exception if there is an error in the form event. * @since 1.6 */ protected function preprocessForm(JForm $form, $data, $group = 'content') { jimport('joomla.filesystem.path'); $folder = $this->getState('item.folder'); $element = $this->getState('item.element'); $lang = JFactory::getLanguage(); // Load the core and/or local language sys file(s) for the ordering field. $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('element')) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) ->where($db->quoteName('folder') . ' = ' . $db->quote($folder)); $db->setQuery($query); $elements = $db->loadColumn(); foreach ($elements as $elementa) { $lang->load('plg_'.$folder.'_'.$elementa.'.sys', JPATH_ADMINISTRATOR, null, false, true) || $lang->load('plg_'.$folder.'_'.$elementa.'.sys', JPATH_PLUGINS.'/'.$folder.'/'.$elementa, null, false, true); } if (empty($folder) || empty($element)) { $app = JFactory::getApplication(); $app->redirect(JRoute::_('index.php?option=com_plugins&view=plugins', false)); } $formFile = JPath::clean(JPATH_PLUGINS . '/' . $folder . '/' . $element . '/' . $element . '.xml'); if (!file_exists($formFile)) { throw new Exception(JText::sprintf('COM_PLUGINS_ERROR_FILE_NOT_FOUND', $element . '.xml')); } // Load the core and/or local language file(s). $lang->load('plg_'.$folder.'_'.$element, JPATH_ADMINISTRATOR, null, false, true) || $lang->load('plg_'.$folder.'_'.$element, JPATH_PLUGINS.'/'.$folder.'/'.$element, null, false, true); if (file_exists($formFile)) { // Get the plugin form. if (!$form->loadFile($formFile, false, '//config')) { throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); } } // Attempt to load the xml file. if (!$xml = simplexml_load_file($formFile)) { throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); } // Get the help data from the XML file if present. $help = $xml->xpath('/extension/help'); if (!empty($help)) { $helpKey = trim((string) $help[0]['key']); $helpURL = trim((string) $help[0]['url']); $this->helpKey = $helpKey ? $helpKey : $this->helpKey; $this->helpURL = $helpURL ? $helpURL : $this->helpURL; } // Trigger the default form events. parent::preprocessForm($form, $data, $group); } /** * A protected method to get a set of ordering conditions. * * @param object A record object. * @return array An array of conditions to add to add to ordering queries. * @since 1.6 */ protected function getReorderConditions($table) { $condition = array(); $condition[] = 'type = '. $this->_db->quote($table->type); $condition[] = 'folder = '. $this->_db->quote($table->folder); return $condition; } /** * Override method to save the form data. * * @param array The form data. * @return boolean True on success. * @since 1.6 */ public function save($data) { // Load the extension plugin group. JPluginHelper::importPlugin('extension'); // Setup type $data['type'] = 'plugin'; return parent::save($data); } /** * Get the necessary data to load an item help screen. * * @return object An object with key, url, and local properties for loading the item help screen. * @since 1.6 */ public function getHelp() { return (object) array('key' => $this->helpKey, 'url' => $this->helpURL); } /** * Custom clean cache method, plugins are cached in 2 places for different clients * * @since 1.6 */ protected function cleanCache($group = null, $client_id = 0) { parent::cleanCache('com_plugins'); } } components/com_plugins/models/index.html000066600000000037150771655450014553 0ustar00 components/com_plugins/models/fields/pluginordering.php000066600000002675150771655450017577 0ustar00form->getValue('folder'); // Build the query for the ordering list. $query = $db->getQuery(true) ->select(array($db->quoteName('ordering', 'value'), $db->quoteName('name', 'text'), $db->quoteName('type'), $db->quote('folder'), $db->quote('extension_id'))) ->from($db->quoteName('#__extensions')) ->where('(type =' . $db->quote('plugin') . 'AND folder=' . $db->quote($folder) . ')') ->order('ordering'); return $query; } /** * Retrieves the current Item's Id. * * @return integer The current item ID */ protected function getItemId() { return (int) $this->form->getValue('extension_id'); } } components/com_plugins/models/fields/index.html000066600000000037150771655450016021 0ustar00 components/com_plugins/models/forms/index.html000066600000000037150771655450015701 0ustar00 components/com_plugins/models/forms/plugin.xml000066600000002515150771655450015727 0ustar00
    components/com_plugins/models/plugins.php000066600000015535150771655450014761 0ustar00getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $accessId = $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', null, 'int'); $this->setState('filter.access', $accessId); $state = $this->getUserStateFromRequest($this->context . '.filter.enabled', 'filter_enabled', '', 'string'); $this->setState('filter.enabled', $state); $folder = $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', null, 'cmd'); $this->setState('filter.folder', $folder); $language = $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', ''); $this->setState('filter.language', $language); // Load the parameters. $params = JComponentHelper::getParams('com_plugins'); $this->setState('params', $params); // List state information. parent::populateState('folder', 'asc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string A prefix for the store id. * * @return string A store id. */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.access'); $id .= ':' . $this->getState('filter.state'); $id .= ':' . $this->getState('filter.folder'); $id .= ':' . $this->getState('filter.language'); return parent::getStoreId($id); } /** * Returns an object list * * @param string The query * @param int Offset * @param int The number of records * @return array */ protected function _getList($query, $limitstart = 0, $limit = 0) { $search = $this->getState('filter.search'); $ordering = $this->getState('list.ordering', 'ordering'); if ($ordering == 'name' || (!empty($search) && stripos($search, 'id:') !== 0)) { $this->_db->setQuery($query); $result = $this->_db->loadObjectList(); $this->translate($result); if (!empty($search)) { foreach ($result as $i => $item) { if (!preg_match("/$search/i", $item->name)) { unset($result[$i]); } } } $direction = ($this->getState('list.direction') == 'desc') ? -1 : 1; JArrayHelper::sortObjects($result, $ordering, $direction, true, true); $total = count($result); $this->cache[$this->getStoreId('getTotal')] = $total; if ($total < $limitstart) { $limitstart = 0; $this->setState('list.start', 0); } return array_slice($result, $limitstart, $limit ? $limit : null); } else { if ($ordering == 'ordering') { $query->order('a.folder ASC'); $ordering = 'a.ordering'; } $query->order($this->_db->quoteName($ordering) . ' ' . $this->getState('list.direction')); if ($ordering == 'folder') { $query->order('a.ordering ASC'); } $result = parent::_getList($query, $limitstart, $limit); $this->translate($result); return $result; } } /** * Translate a list of objects * * @param array The array of objects * @return array The array of translated objects */ protected function translate(&$items) { $lang = JFactory::getLanguage(); foreach ($items as &$item) { $source = JPATH_PLUGINS . '/' . $item->folder . '/' . $item->element; $extension = 'plg_' . $item->folder . '_' . $item->element; $lang->load($extension . '.sys', JPATH_ADMINISTRATOR, null, false, true) || $lang->load($extension . '.sys', $source, null, false, true); $item->name = JText::_($item->name); } } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.extension_id , a.name, a.element, a.folder, a.checked_out, a.checked_out_time,' . ' a.enabled, a.access, a.ordering' ) ) ->from($db->quoteName('#__extensions') . ' AS a') ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')); // Join over the users for the checked out user. $query->select('uc.name AS editor') ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); // Join over the asset groups. $query->select('ag.title AS access_level') ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); // Filter by access level. if ($access = $this->getState('filter.access')) { $query->where('a.access = ' . (int) $access); } // Filter by published state $published = $this->getState('filter.enabled'); if (is_numeric($published)) { $query->where('a.enabled = ' . (int) $published); } elseif ($published === '') { $query->where('(a.enabled IN (0, 1))'); } // Filter by state $query->where('a.state >= 0'); // Filter by folder. if ($folder = $this->getState('filter.folder')) { $query->where('a.folder = ' . $db->quote($folder)); } // Filter by search in name or id $search = $this->getState('filter.search'); if (!empty($search)) { if (stripos($search, 'id:') === 0) { $query->where('a.extension_id = ' . (int) substr($search, 3)); } } return $query; } } components/com_cache/cache.xml000066600000001735150771655450012450 0ustar00 com_cache Joomla! Project April 2006 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_CACHE_XML_DESCRIPTION cache.php config.xml controller.php index.html models views language/en-GB.com_cache.ini language/en-GB.com_cache.sys.ini components/com_cache/views/purge/view.html.php000066600000002332150771655450015562 0ustar00addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { //JHtmlSidebar::addEntry(JText::_('COM_CACHE_BACK_CACHE_MANAGER'), 'index.php?option=com_cache', false); JToolbarHelper::title(JText::_('COM_CACHE_PURGE_EXPIRED_CACHE'), 'lightning purge'); JToolbarHelper::custom('purge', 'delete.png', 'delete_f2.png', 'COM_CACHE_PURGE_EXPIRED', false); JToolbarHelper::divider(); if (JFactory::getUser()->authorise('core.admin', 'com_cache')) { JToolbarHelper::preferences('com_cache'); JToolbarHelper::divider(); } JToolbarHelper::help('JHELP_SITE_MAINTENANCE_PURGE_EXPIRED_CACHE'); } } components/com_cache/views/purge/tmpl/default.php000066600000001577150771655450016257 0ustar00
    sidebar; ?>

    components/com_cache/views/purge/tmpl/index.html000066600000000037150771655450016105 0ustar00 components/com_cache/views/purge/index.html000066600000000037150771655450015131 0ustar00 components/com_cache/views/index.html000066600000000037150771655450014007 0ustar00 components/com_cache/views/cache/view.html.php000066600000003361150771655450015506 0ustar00data = $this->get('Data'); $this->client = $this->get('Client'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { JToolbarHelper::title(JText::_('COM_CACHE_CLEAR_CACHE'), 'lightning clear'); JToolbarHelper::custom('delete', 'delete.png', 'delete_f2.png', 'JTOOLBAR_DELETE', true); JToolbarHelper::divider(); if (JFactory::getUser()->authorise('core.admin', 'com_cache')) { JToolbarHelper::preferences('com_cache'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_SITE_MAINTENANCE_CLEAR_CACHE'); JHtmlSidebar::setAction('index.php?option=com_cache'); JHtmlSidebar::addFilter( // @todo We need an actual label here '', 'filter_client_id', JHtml::_('select.options', CacheHelper::getClientOptions(), 'value', 'text', $this->state->get('clientId')) ); } } components/com_cache/views/cache/tmpl/default.php000066600000004522150771655450016171 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?>
    sidebar; ?>
    data as $folder => $item) : ?>
    pagination->getListFooter(); ?>
    group; ?> count; ?> size*1024); ?>
    components/com_cache/views/cache/tmpl/index.html000066600000000037150771655450016026 0ustar00 components/com_cache/views/cache/index.html000066600000000037150771655450015052 0ustar00 components/com_cache/index.html000066600000000037150771655450012652 0ustar00 components/com_cache/config.xml000066600000001106150771655450012642 0ustar00
    components/com_cache/controller.php000066600000004761150771655450013561 0ustar00input->get('view', 'cache'); $vFormat = $document->getType(); $lName = $this->input->get('layout', 'default', 'string'); // Get and render the view. if ($view = $this->getView($vName, $vFormat)) { switch ($vName) { case 'purge': break; case 'cache': default: $model = $this->getModel($vName); $view->setModel($model, true); break; } $view->setLayout($lName); // Push document object into the view. $view->document = $document; // Load the submenu. CacheHelper::addSubmenu($this->input->get('view', 'cache')); $view->display(); } } public function delete() { // Check for request forgeries JSession::checkToken() or jexit(JText::_('JInvalid_Token')); $cid = $this->input->post->get('cid', array(), 'array'); $model = $this->getModel('cache'); if (empty($cid)) { JError::raiseWarning(500, JText::_('JERROR_NO_ITEMS_SELECTED')); } else { $model->cleanlist($cid); } $this->setRedirect('index.php?option=com_cache&client=' . $model->getClient()->id); } public function purge() { // Check for request forgeries JSession::checkToken() or jexit(JText::_('JInvalid_Token')); $model = $this->getModel('cache'); $ret = $model->purge(); $msg = JText::_('COM_CACHE_EXPIRED_ITEMS_HAVE_BEEN_PURGED'); $msgType = 'message'; if ($ret === false) { $msg = JText::_('COM_CACHE_EXPIRED_ITEMS_PURGING_ERROR'); $msgType = 'error'; } $this->setRedirect('index.php?option=com_cache&view=purge', $msg, $msgType); } } components/com_cache/cache.php000066600000001065150771655450012433 0ustar00authorise('core.manage', 'com_cache')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } $controller = JControllerLegacy::getInstance('Cache'); $controller->execute(JFactory::getApplication()->input->get('task')); $controller->redirect(); components/com_cache/helpers/index.html000066600000000037150771655450014314 0ustar00 components/com_cache/helpers/cache.php000066600000002574150771655450014103 0ustar00 components/com_cache/models/cache.php000066600000007171150771655450013722 0ustar00getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', 0, 'int'); $this->setState('clientId', $clientId == 1 ? 1 : 0); $client = JApplicationHelper::getClientInfo($clientId); $this->setState('client', $client); parent::populateState('group', 'asc'); } /** * Method to get cache data * * @return array */ public function getData() { if (empty($this->_data)) { $cache = $this->getCache(); $data = $cache->getAll(); if ($data != false) { $this->_data = $data; $this->_total = count($data); if ($this->_total) { // Apply custom ordering $ordering = $this->getState('list.ordering'); $direction = ($this->getState('list.direction') == 'asc') ? 1 : -1; jimport('joomla.utilities.arrayhelper'); $this->_data = JArrayHelper::sortObjects($data, $ordering, $direction); // Apply custom pagination if ($this->_total > $this->getState('list.limit') && $this->getState('list.limit')) { $this->_data = array_slice($this->_data, $this->getState('list.start'), $this->getState('list.limit')); } } } else { $this->_data = array(); } } return $this->_data; } /** * Method to get cache instance * * @return object */ public function getCache() { $conf = JFactory::getConfig(); $options = array( 'defaultgroup' => '', 'storage' => $conf->get('cache_handler', ''), 'caching' => true, 'cachebase' => ($this->getState('clientId') == 1) ? JPATH_ADMINISTRATOR . '/cache' : $conf->get('cache_path', JPATH_SITE . '/cache') ); $cache = JCache::getInstance('', $options); return $cache; } /** * Method to get client data * * @return array */ public function getClient() { return $this->getState('client'); } /** * Get the number of current Cache Groups * * @return int */ public function getTotal() { if (empty($this->_total)) { $this->_total = count($this->getData()); } return $this->_total; } /** * Method to get a pagination object for the cache * * @return integer */ public function getPagination() { if (empty($this->_pagination)) { $this->_pagination = new JPagination($this->getTotal(), $this->getState('list.start'), $this->getState('list.limit')); } return $this->_pagination; } /** * Clean out a cache group as named by param. * If no param is passed clean all cache groups. * * @param String $group */ public function clean($group = '') { $cache = $this->getCache(); $cache->clean($group); } public function cleanlist($array) { foreach ($array as $group) { $this->clean($group); } } public function purge() { $cache = JFactory::getCache(''); return $cache->gc(); } } components/com_messages/tables/message.php000066600000006005150771655450015031 0ustar00user_id_from); if (empty($user->id)) { $this->setError(JText::_('COM_MESSAGES_ERROR_INVALID_FROM_USER')); return false; } $user = new JUser($this->user_id_to); if (empty($user->id)) { $this->setError(JText::_('COM_MESSAGES_ERROR_INVALID_TO_USER')); return false; } if (empty($this->subject)) { $this->setError(JText::_('COM_MESSAGES_ERROR_INVALID_SUBJECT')); return false; } if (empty($this->message)) { $this->setError(JText::_('COM_MESSAGES_ERROR_INVALID_MESSAGE')); return false; } return true; } /** * Method to set the publishing state for a row or list of rows in the database * table. The method respects checked out rows by other users and will attempt * to checkin rows that it can after adjustments are made. * * @param mixed An optional array of primary key values to update. If not * set the instance property value is used. * @param integer The publishing state. eg. [0 = unpublished, 1 = published] * @param integer The user id of the user performing the operation. * @return boolean True on success. * @since 1.6 */ public function publish($pks = null, $state = 1, $userId = 0) { $k = $this->_tbl_key; // Sanitize input. JArrayHelper::toInteger($pks); $state = (int) $state; // If there are no primary keys set check to see if the instance key is set. if (empty($pks)) { if ($this->$k) { $pks = array($this->$k); } // Nothing to set publishing state on, return false. else { $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); return false; } } // Build the WHERE clause for the primary keys. $where = $k.' IN ('.implode(',', $pks).')'; // Update the publishing state for rows with the given primary keys. $this->_db->setQuery( 'UPDATE '.$this->_db->quoteName($this->_tbl). ' SET '.$this->_db->quoteName('state').' = '.(int) $state . ' WHERE ('.$where.')' ); try { $this->_db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } // If the JTable instance value is in the list of primary keys that were set, set the instance. if (in_array($this->$k, $pks)) { $this->state = $state; } $this->setError(''); return true; } } components/com_messages/tables/index.html000066600000000037150771655450014670 0ustar00 components/com_messages/layouts/index.html000066600000000037150771655450015116 0ustar00 components/com_messages/layouts/toolbar/index.html000066600000000037150771655450016560 0ustar00 components/com_messages/layouts/toolbar/mysettings.php000066600000001101150771655450017473 0ustar00 components/com_messages/views/messages/view.html.php000066600000004634150771655450017022 0ustar00items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.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')) { JToolbarHelper::addNew('message.add'); } if ($canDo->get('core.edit.state')) { JToolbarHelper::divider(); JToolbarHelper::publish('messages.publish', 'COM_MESSAGES_TOOLBAR_MARK_AS_READ'); JToolbarHelper::unpublish('messages.unpublish', 'COM_MESSAGES_TOOLBAR_MARK_AS_UNREAD'); } if ($state->get('filter.state') == -2 && $canDo->get('core.delete')) { JToolbarHelper::divider(); JToolbarHelper::deleteList('', 'messages.delete', 'JTOOLBAR_EMPTY_TRASH'); } elseif ($canDo->get('core.edit.state')) { JToolbarHelper::divider(); JToolbarHelper::trash('messages.trash'); } //JToolbarHelper::addNew('module.add'); 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'); if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_messages'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_COMPONENTS_MESSAGING_INBOX'); } } components/com_messages/views/messages/tmpl/default.php000066600000010531150771655450017476 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?>
    sidebar)) : ?>
    sidebar; ?>
    items)) : ?>
    items as $i => $item) : $canChange = $user->authorise('core.edit.state', 'com_messages'); ?>
    pagination->getListFooter(); ?>
    message_id); ?> escape($item->subject); ?> state, $i, $canChange); ?> user_from; ?> date_time, JText::_('DATE_FORMAT_LC2')); ?>
    components/com_messages/views/messages/tmpl/index.html000066600000000037150771655450017336 0ustar00 components/com_messages/views/messages/index.html000066600000000037150771655450016362 0ustar00 components/com_messages/views/message/view.html.php000066600000003451150771655450016633 0ustar00form = $this->get('Form'); $this->item = $this->get('Item'); $this->state = $this->get('State'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } parent::display($tpl); $this->addToolbar(); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { if ($this->getLayout() == 'edit') { JToolbarHelper::title(JText::_('COM_MESSAGES_WRITE_PRIVATE_MESSAGE'), 'envelope-opened new-privatemessage'); JToolbarHelper::save('message.save', 'COM_MESSAGES_TOOLBAR_SEND'); JToolbarHelper::cancel('message.cancel'); JToolbarHelper::help('JHELP_COMPONENTS_MESSAGING_WRITE'); } else { JToolbarHelper::title(JText::_('COM_MESSAGES_VIEW_PRIVATE_MESSAGE'), 'envelope inbox'); $sender = JUser::getInstance($this->item->user_id_from); if ($sender->authorise('core.admin') || $sender->authorise('core.manage', 'com_messages') && $sender->authorise('core.login.admin')) { JToolbarHelper::custom('message.reply', 'redo', null, 'COM_MESSAGES_TOOLBAR_REPLY', false); } JToolbarHelper::cancel('message.cancel'); JToolbarHelper::help('JHELP_COMPONENTS_MESSAGING_READ'); } } } components/com_messages/views/message/tmpl/default.php000066600000003133150771655450017313 0ustar00
    item->get('from_user_name');?>
    item->date_time);?>
    item->subject;?>
    item->message; ?>
    components/com_messages/views/message/tmpl/edit.php000066600000003172150771655450016617 0ustar00
    form->getLabel('user_id_to'); ?>
    form->getInput('user_id_to'); ?>
    form->getLabel('subject'); ?>
    form->getInput('subject'); ?>
    form->getLabel('message'); ?>
    form->getInput('message'); ?>
    components/com_messages/views/message/tmpl/index.html000066600000000037150771655450017153 0ustar00 components/com_messages/views/message/index.html000066600000000037150771655450016177 0ustar00 components/com_messages/views/config/view.html.php000066600000001674150771655450016461 0ustar00form = $this->get('Form'); $this->item = $this->get('Item'); $this->state = $this->get('State'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } // Bind the record to the form. $this->form->bind($this->item); parent::display($tpl); } } components/com_messages/views/config/tmpl/default.php000066600000004274150771655450017143 0ustar00
    components/com_messages/views/config/tmpl/index.html000066600000000037150771655450016774 0ustar00 components/com_messages/views/config/index.html000066600000000037150771655450016020 0ustar00 components/com_messages/views/index.html000066600000000037150771655450014553 0ustar00 components/com_messages/index.html000066600000000037150771655450013416 0ustar00 components/com_messages/config.xml000066600000000543150771655450013412 0ustar00
    components/com_messages/messages.xml000066600000002256150771655450013757 0ustar00 com_messages Joomla! Project April 2006 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_MESSAGES_XML_DESCRIPTION language/en-GB.com_messages.ini config.xml controller.php index.html messages.php controllers helpers models tables views language/en-GB.com_messages.ini language/en-GB.com_messages.sys.ini components/com_messages/controller.php000066600000003116150771655450014316 0ustar00input->get('view', 'messages'); $layout = $this->input->get('layout', 'default'); $id = $this->input->getInt('id'); // Check for edit form. if ($view == 'message' && $layout == 'edit' && !$this->checkEditId('com_messages.edit.message', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_messages&view=messages', false)); return false; } // Load the submenu. MessagesHelper::addSubmenu($this->input->get('view', 'messages')); parent::display(); } } components/com_messages/controllers/message.php000066600000002440150771655450016124 0ustar00input->getInt('reply_id')) { $this->setRedirect('index.php?option=com_messages&view=message&layout=edit&reply_id=' . $replyId); } else { $this->setMessage(JText::_('COM_MESSAGES_INVALID_REPLY_ID')); $this->setRedirect('index.php?option=com_messages&view=messages'); } } } components/com_messages/controllers/index.html000066600000000037150771655450015764 0ustar00 components/com_messages/controllers/config.php000066600000004042150771655450015745 0ustar00getModel('Config', 'MessagesModel'); $data = $this->input->post->get('jform', array(), 'array'); // Validate the posted data. $form = $model->getForm(); if (!$form) { JError::raiseError(500, $model->getError()); return false; } $data = $model->validate($form, $data); // Check for validation errors. if ($data === false) { // Get the validation messages. $errors = $model->getErrors(); // Push up to three validation messages out to the user. for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) { if ($errors[$i] instanceof Exception) { $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); } else { $app->enqueueMessage($errors[$i], 'warning'); } } // Redirect back to the main list. $this->setRedirect(JRoute::_('index.php?option=com_messages&view=messages', false)); return false; } // Attempt to save the data. if (!$model->save($data)) { // Redirect back to the main list. $this->setMessage(JText::sprintf('JERROR_SAVE_FAILED', $model->getError()), 'warning'); $this->setRedirect(JRoute::_('index.php?option=com_messages&view=messages', false)); return false; } // Redirect to the list screen. $this->setMessage(JText::_('COM_MESSAGES_CONFIG_SAVED')); $this->setRedirect(JRoute::_('index.php?option=com_messages&view=messages', false)); return true; } } components/com_messages/controllers/messages.php000066600000001723150771655450016312 0ustar00 true)) { $model = parent::getModel($name, $prefix, $config); return $model; } } components/com_messages/messages.php000066600000001167150771655450013746 0ustar00authorise('core.manage', 'com_messages')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } $task = JFactory::getApplication()->input->get('task'); $controller = JControllerLegacy::getInstance('Messages'); $controller->execute(JFactory::getApplication()->input->get('task')); $controller->redirect(); components/com_messages/access.xml000066600000001162150771655450013404 0ustar00
    components/com_messages/helpers/html/index.html000066600000000037150771655450016024 0ustar00 components/com_messages/helpers/html/messages.php000066600000002343150771655450016351 0ustar00 array('trash.png', 'messages.unpublish', 'JTRASHED', 'COM_MESSAGES_MARK_AS_UNREAD'), 1 => array('tick.png', 'messages.unpublish', 'COM_MESSAGES_OPTION_READ', 'COM_MESSAGES_MARK_AS_UNREAD'), 0 => array('publish_x.png', 'messages.publish', 'COM_MESSAGES_OPTION_UNREAD', 'COM_MESSAGES_MARK_AS_READ') ); $state = JArrayHelper::getValue($states, (int) $value, $states[0]); $html = JHtml::_('image', 'admin/'.$state[0], JText::_($state[2]), null, true); if ($canChange) { $html = '' .$html.''; } return $html; } } components/com_messages/helpers/index.html000066600000000037150771655450015060 0ustar00 components/com_messages/helpers/messages.php000066600000003437150771655450015412 0ustar00input; $user = JFactory::getUser(); $this->setState('user.id', $user->get('id')); $messageId = (int) $input->getInt('message_id'); $this->setState('message.id', $messageId); $replyId = (int) $input->getInt('reply_id'); $this->setState('reply.id', $replyId); } /** * Check that recipient user is the one trying to delete and then call parent delete method * * @param array &$pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * * @since 3.1 */ public function delete(&$pks) { $pks = (array) $pks; $table = $this->getTable(); $user = JFactory::getUser(); // Iterate the items to delete each one. foreach ($pks as $i => $pk) { if ($table->load($pk)) { if ($table->user_id_to !== $user->id) { // Prune items that you can't change. unset($pks[$i]); JLog::add(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), JLog::WARNING, 'jerror'); return false; } } else { $this->setError($table->getError()); return false; } } return parent::delete($pks); } /** * Returns a Table object, always creating it. * * @param type The table type to instantiate * @param string A prefix for the table class name. Optional. * @param array Configuration array for model. Optional. * @return JTable A database object * @since 1.6 */ public function getTable($type = 'Message', $prefix = 'MessagesTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Method to get a single record. * * @param integer The id of the primary key. * @return mixed Object on success, false on failure. * @since 1.6 */ public function getItem($pk = null) { if (!isset($this->item)) { if ($this->item = parent::getItem($pk)) { // Prime required properties. if (empty($this->item->message_id)) { // Prepare data for a new record. if ($replyId = $this->getState('reply.id')) { // If replying to a message, preload some data. $db = $this->getDbo(); $query = $db->getQuery(true) ->select('subject, user_id_from') ->from('#__messages') ->where('message_id = '.(int) $replyId); try { $message = $db->setQuery($query)->loadObject(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } $this->item->set('user_id_to', $message->user_id_from); $re = JText::_('COM_MESSAGES_RE'); if (stripos($message->subject, $re) !== 0) { $this->item->set('subject', $re.$message->subject); } } } elseif ($this->item->user_id_to != JFactory::getUser()->id) { $this->setError(JText::_('JERROR_ALERTNOAUTHOR')); return false; } else { // Mark message read $db = $this->getDbo(); $query = $db->getQuery(true) ->update('#__messages') ->set('state = 1') ->where('message_id = '.$this->item->message_id); $db->setQuery($query)->execute(); } } // Get the user name for an existing messasge. if ($this->item->user_id_from && $fromUser = new JUser($this->item->user_id_from)) { $this->item->set('from_user_name', $fromUser->name); } } return $this->item; } /** * Method to get the record form. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * @return JForm A JForm object on success, false on failure * @since 1.6 */ public function getForm($data = array(), $loadData = true) { // Get the form. $form = $this->loadForm('com_messages.message', 'message', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * @since 1.6 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_messages.edit.message.data', array()); if (empty($data)) { $data = $this->getItem(); } $this->preprocessData('com_messages.message', $data); return $data; } /** * Checks that the current user matches the message recipient and calls the parent publish method * * @param array &$pks A list of the primary keys to change. * @param integer $value The value of the published state. * * @return boolean True on success. * * @since 3.1 */ public function publish(&$pks, $value = 1) { $user = JFactory::getUser(); $table = $this->getTable(); $pks = (array) $pks; // Check that the recipient matches the current user foreach ($pks as $i => $pk) { $table->reset(); if ($table->load($pk)) { if ($table->user_id_to !== $user->id) { // Prune items that you can't change. unset($pks[$i]); JLog::add(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), JLog::WARNING, 'jerror'); return false; } } } return parent::publish($pks, $value); } /** * Method to save the form data. * * @param array The form data. * * @return boolean True on success. */ public function save($data) { $table = $this->getTable(); // Bind the data. if (!$table->bind($data)) { $this->setError($table->getError()); return false; } // Assign empty values. if (empty($table->user_id_from)) { $table->user_id_from = JFactory::getUser()->get('id'); } if ((int) $table->date_time == 0) { $table->date_time = JFactory::getDate()->toSql(); } // Check the data. if (!$table->check()) { $this->setError($table->getError()); return false; } // Load the recipient user configuration. $model = JModelLegacy::getInstance('Config', 'MessagesModel', array('ignore_request' => true)); $model->setState('user.id', $table->user_id_to); $config = $model->getItem(); if (empty($config)) { $this->setError($model->getError()); return false; } if ($config->get('locked', false)) { $this->setError(JText::_('COM_MESSAGES_ERR_SEND_FAILED')); return false; } // Store the data. if (!$table->store()) { $this->setError($table->getError()); return false; } if ($config->get('mail_on_new', true)) { // Load the user details (already valid from table check). $fromUser = JUser::getInstance($table->user_id_from); $toUser = JUser::getInstance($table->user_id_to); $debug = JFactory::getConfig()->get('debug_lang'); $default_language = JComponentHelper::getParams('com_languages')->get('administrator'); $lang = JLanguage::getInstance($toUser->getParam('admin_language', $default_language), $debug); $lang->load('com_messages', JPATH_ADMINISTRATOR); $siteURL = JUri::root() . 'administrator/index.php?option=com_messages&view=message&message_id='.$table->message_id; $sitename = JFactory::getApplication()->getCfg('sitename'); $subject = sprintf($lang->_('COM_MESSAGES_NEW_MESSAGE_ARRIVED'), $sitename); $msg = sprintf($lang->_('COM_MESSAGES_PLEASE_LOGIN'), $siteURL); JFactory::getMailer()->sendMail($fromUser->email, $fromUser->name, $toUser->email, $subject, $msg); } return true; } } components/com_messages/models/index.html000066600000000037150771655450014701 0ustar00 components/com_messages/models/fields/index.html000066600000000037150771655450016147 0ustar00 components/com_messages/models/fields/usermessages.php000066600000003350150771655450017372 0ustar00getQuery(true) ->select('id') ->from('#__usergroups'); $db->setQuery($query); try { $groups = $db->loadColumn(); } catch (RuntimeException $e) { JError::raiseNotice(500, $e->getMessage()); return null; } foreach ($groups as $i => $group) { if (JAccess::checkGroup($group, 'core.admin')) { continue; } if (!JAccess::checkGroup($group, 'core.manage', 'com_messages')) { unset($groups[$i]); continue; } if (!JAccess::checkGroup($group, 'core.login.admin')) { unset($groups[$i]); continue; } } return array_values($groups); } /** * Method to get the users to exclude from the list of users * * @return array|null array of users to exclude or null to to not exclude them * @since 1.6 */ protected function getExcluded() { return array(JFactory::getUser()->id); } } components/com_messages/models/forms/message.xml000066600000001260150771655450016177 0ustar00
    components/com_messages/models/forms/index.html000066600000000037150771655450016027 0ustar00 components/com_messages/models/forms/config.xml000066600000001454150771655450016025 0ustar00
    components/com_messages/models/config.php000066600000006277150771655450014676 0ustar00setState('user.id', $user->get('id')); // Load the parameters. $params = JComponentHelper::getParams('com_messages'); $this->setState('params', $params); } /** * Method to get a single record. * * @param integer The id of the primary key. * * @return mixed Object on success, false on failure. */ public function &getItem() { $item = new JObject; $db = $this->getDbo(); $query = $db->getQuery(true) ->select('cfg_name, cfg_value') ->from('#__messages_cfg') ->where($db->quoteName('user_id') . ' = '. (int) $this->getState('user.id')); $db->setQuery($query); try { $rows = $db->loadObjectList(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } foreach ($rows as $row) { $item->set($row->cfg_name, $row->cfg_value); } $this->preprocessData('com_messages.config', $item); return $item; } /** * Method to get the record form. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * @return JForm A JForm object on success, false on failure * @since 1.6 */ public function getForm($data = array(), $loadData = true) { // Get the form. $form = $this->loadForm('com_messages.config', 'config', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } return $form; } /** * Method to save the form data. * * @param array The form data. * @return boolean True on success. */ public function save($data) { $db = $this->getDbo(); if ($userId = (int) $this->getState('user.id')) { $query = $db->getQuery(true) ->delete($db->quoteName('#__messages_cfg')) ->where($db->quoteName('user_id') . '=' . (int) $userId); $db->setQuery($query); try { $db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } if (count($data)) { $query = $db->getQuery(true) ->insert($db->quoteName('#__messages_cfg')) ->columns($db->quoteName(array('user_id', 'cfg_name', 'cfg_value'))); foreach ($data as $k => $v) { $query->values($userId . ', ' . $db->quote($k) . ', ' . $db->quote($v)); } $db->setQuery($query); try { $db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } } return true; } else { $this->setError('COM_MESSAGES_ERR_INVALID_USER'); return false; } } } components/com_messages/models/messages.php000066600000006725150771655450015236 0ustar00getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string'); $this->setState('filter.state', $state); // List state information. parent::populateState('a.date_time', 'desc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string A prefix for the store id. * * @return string A store id. */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.state'); return parent::getStoreId($id); } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); $user = JFactory::getUser(); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.*, ' . 'u.name AS user_from' ) ); $query->from('#__messages AS a'); // Join over the users for message owner. $query->join('INNER', '#__users AS u ON u.id = a.user_id_from') ->where('a.user_id_to = ' . (int) $user->get('id')); // Filter by published state. $state = $this->getState('filter.state'); if (is_numeric($state)) { $query->where('a.state = ' . (int) $state); } elseif ($state === '') { $query->where('(a.state IN (0, 1))'); } // Filter by search in subject or message. $search = $this->getState('filter.search'); if (!empty($search)) { $search = $db->quote('%' . $db->escape($search, true) . '%', false); $query->where('a.subject LIKE ' . $search . ' OR a.message LIKE ' . $search); } // Add the list ordering clause. $query->order($db->escape($this->getState('list.ordering', 'a.date_time')) . ' ' . $db->escape($this->getState('list.direction', 'DESC'))); //echo nl2br(str_replace('#__','jos_',$query)); return $query; } } components/com_sef/uninstall.sql000066600000001734150771655450013126 0ustar00DROP TABLE IF EXISTS `#__sefurls_bak`; RENAME TABLE `#__sefurls` TO `#__sefurls_bak`; DROP TABLE IF EXISTS `#__sefexts_bak`; RENAME TABLE `#__sefexts` TO `#__sefexts_bak`; DROP TABLE IF EXISTS `#__sefmoved_bak`; RENAME TABLE `#__sefmoved` TO `#__sefmoved_bak`; DROP TABLE IF EXISTS `#__sefexttexts_bak`; RENAME TABLE `#__sefexttexts` TO `#__sefexttexts_bak`; DROP TABLE IF EXISTS `#__sefwords_bak`; RENAME TABLE `#__sefwords` TO `#__sefwords_bak`; DROP TABLE IF EXISTS `#__sefurlword_xref_bak`; RENAME TABLE `#__sefurlword_xref` TO `#__sefurlword_xref_bak`; DROP TABLE IF EXISTS `#__sefaliases_bak`; RENAME TABLE `#__sefaliases` TO `#__sefaliases_bak`; DROP TABLE IF EXISTS `#__sef_statistics_bak`; RENAME TABLE `#__sef_statistics` TO `#__sef_statistics_bak`; DROP TABLE IF EXISTS `#__seflog_bak`; RENAME TABLE `#__seflog` TO `#__seflog_bak`; DROP TABLE IF EXISTS `#__sef_subdomains_bak`; RENAME TABLE `#__sef_subdomains` TO `#__sef_subdomains_bak`; components/com_sef/assets/js/infotexts.js000066600000001122150771655450014662 0ustar00function jsToggleInfoText() { // Toggle state jsInfoTextShown = !jsInfoTextShown; // Show/hide div $('jsInfoText').style.display = (jsInfoTextShown ? 'block' : 'none'); // Toggle link text $('jsInfoTextLink').innerHTML = '(' + (jsInfoTextShown ? jsInfoTextHide : jsInfoTextShow) + ')'; // Save new state using AJAX var url = jsInfoTextUrl + '&state=' + (jsInfoTextShown ? '1' : '0'); new Request({ 'url': url, 'method': 'GET', 'onSuccess': function(text, xml) { // Do nothing } }).send(); }components/com_sef/assets/js/index.html000066600000000054150771655450014301 0ustar00components/com_sef/assets/js/crawler.js000066600000015620150771655450014306 0ustar00var jsCrawlerUrlsBatch = 15; var jsCrawlerMaxResponseTime = 30; var jsCrawlerResponseTimer = null; var jsCrawlerLastResponse = 0; var jsCrawlerMaxLevel = 0; var jsCrawlerCurrentUrls = new Array(); var jsCrawlerNextUrls = new Array(); var jsCrawlerCrawledUrls = new Array(); var jsCrawlerCurrentLevel = 0; var jsCrawlerFoundUrls = 0; // Crawler's state // 0 - before started // 1 - running // 2 - finished var jsCrawlerState = 0; var jsCrawlerRequestCancel = false; function jsCrawlerStopResponseTimer() { if (jsCrawlerResponseTimer) { clearInterval(jsCrawlerResponseTimer); } } function jsCrawlerResetResponseTimer() { jsCrawlerStopResponseTimer(); jsCrawlerLastResponse = 0; jsCrawlerResponseTimer = setInterval('jsCrawlerCheckResponseTime()', 1000); jsCrawlerUpdateResponseTime(); } function jsCrawlerCheckResponseTime() { jsCrawlerLastResponse++; jsCrawlerUpdateResponseTime(); if (jsCrawlerLastResponse > jsCrawlerMaxResponseTime) { jsCrawlerRequestCancel = true; jsCrawlerError(); } } function jsCrawlerUpdateResponseTime() { document.id('crawlerResponseTime').innerHTML = jsCrawlerTextResponseTime.replace('%s', jsCrawlerLastResponse); } function jsCrawlerButtonClicked() { if (jsCrawlerState == 0) { jsCrawlerStartCrawl(); } else if (jsCrawlerState == 1) { jsCrawlerCancel(); } else { jsCrawlerFinish(); } } function jsCrawlerStartCrawl() { jsCrawlerState = 1; var root = jsCrawlerRootUrl + document.id('crawlerRootUrl').value; jsCrawlerMaxLevel = document.id('crawlerMaxLevel').value; jsCrawlerCurrentUrls = new Array(root); jsCrawlerFoundUrls = 1; document.id('crawlerRootUrl').disabled = true; document.id('crawlerMaxLevel').disabled = true; //document.id('crawlerButton').disabled = true; document.id('crawlerButton').value = jsCrawlerTextCancel; document.id('crawlerRunningValue').innerHTML = jsCrawlerTextRunning; document.id('crawlerRunningImg').style.display = 'block'; jsCrawlerResetResponseTimer(); jsCrawlerCrawl(0); } function jsCrawlerRecoverCrawl() { jsCrawlerState = 1; jsCrawlerRequestCancel = false; document.id('crawlerButton').value = jsCrawlerTextCancel; document.id('crawlerRunningValue').innerHTML = jsCrawlerTextRunning; document.id('crawlerRunningValue').style.fontWeight = 'normal'; document.id('crawlerRunningValue').style.color = 'black'; document.id('crawlerRunningImg').style.display = 'block'; document.id('crawlerContinueButton').style.display = 'none'; jsCrawlerResetResponseTimer(); jsCrawlerCrawl(jsCrawlerCurrentLevel); } function jsCrawlerFinish() { submitform(); } function jsCrawlerSuccess() { jsCrawlerEnd(); document.id('crawlerRunningValue').innerHTML = jsCrawlerTextSuccess; document.id('crawlerRunningValue').style.fontWeight = 'bold'; document.id('crawlerRunningValue').style.color = 'green'; } function jsCrawlerError() { jsCrawlerEnd(); document.id('crawlerRunningValue').innerHTML = jsCrawlerTextError; document.id('crawlerRunningValue').style.fontWeight = 'bold'; document.id('crawlerRunningValue').style.color = 'red'; document.id('crawlerResponseTime').innerHTML = jsCrawlerTextErrorMsg; document.id('crawlerContinueButton').style.display = 'inline'; } function jsCrawlerCancel() { jsCrawlerRequestCancel = true; jsCrawlerEnd(); document.id('crawlerRunningValue').innerHTML = jsCrawlerTextCancelled; document.id('crawlerRunningValue').style.fontWeight = 'bold'; document.id('crawlerRunningValue').style.color = 'red'; } function jsCrawlerEnd() { jsCrawlerState = 2; jsCrawlerStopResponseTimer(); document.id('crawlerRunningImg').style.display = 'none'; document.id('crawlerResponseTime').innerHTML = ' '; document.id('crawlerButton').value = jsCrawlerTextFinish; //document.id('crawlerButton').disabled = false; } function jsCrawlerCrawl(level) { // Store current level jsCrawlerCurrentLevel = level; // Update counts document.id('crawlerCrawledValue').innerHTML = jsCrawlerCrawledUrls.length; document.id('crawlerUrlsValue').innerHTML = jsCrawlerFoundUrls; // Check cancelled if (jsCrawlerRequestCancel) { return; } // Check level if (level > jsCrawlerMaxLevel) { jsCrawlerSuccess(); return; } // Update level document.id('crawlerLevelValue').innerHTML = level + ' / ' + jsCrawlerMaxLevel; // Prepare URL var url = jsCrawlerScriptUrl; var max = (jsCrawlerCurrentUrls.length < jsCrawlerUrlsBatch) ? jsCrawlerCurrentUrls.length : jsCrawlerUrlsBatch; var crawlUrls = new Array(); for (var i = 0; i < max; i++) { crawlUrls.push(jsCrawlerCurrentUrls[i]); } // Call request new Request.JSON({ 'url': url, 'method': 'POST', 'data': { 'url': crawlUrls }, 'onSuccess': function(data, text) { // Check cancelled if (jsCrawlerRequestCancel) { return; } // Update response timer jsCrawlerResetResponseTimer(); // Move crawled URLs to another array for (var i = 0; i < data.crawled; i++) { var cur = jsCrawlerCurrentUrls.shift(); jsCrawlerCrawledUrls.push(cur); } // Handle found URLs if this is not last level if (level < jsCrawlerMaxLevel) { for (var i = 0; i < data.found.length; i++) { var cur = data.found[i]; // Check if URL has already been crawled or is already scheduled to be crawled if (jsCrawlerCrawledUrls.contains(cur) || jsCrawlerCurrentUrls.contains(cur) || jsCrawlerNextUrls.contains(cur)) { continue; } jsCrawlerNextUrls.push(cur); jsCrawlerFoundUrls++; } } // Check if there are any URLs left for current level if (jsCrawlerCurrentUrls.length > 0) { // Continue with current level jsCrawlerCrawl(level); } else { // No more URLs, continue with next level jsCrawlerCurrentUrls = jsCrawlerNextUrls; jsCrawlerNextUrls = new Array(); jsCrawlerCrawl(level + 1); } }, 'onError': function(text, error) { jsCrawlerError(); }, 'onFailure': function(xhr) { jsCrawlerError(); } }).send(); }components/com_sef/assets/js/words.js000066600000013364150771655450014010 0ustar00// AJAX var jsAjax; function createAjax() { if( jsAjax ) { return; } try { jsAjax = new XMLHttpRequest(); } catch (e){ try { jsAjax = new ActiveXObject("Microsoft.XMLHttp"); } catch (e){ } } } function realLeft(el) { var l = 0; while( el ) { l += el.offsetLeft; el = el.offsetParent; } return l; } function realTop(el) { var t = 0; while( el ) { t += el.offsetTop; el = el.offsetParent; } return t; } function hasClass(el, cl) { return (el.className.indexOf(cl) != -1); } function addClass(el, cl) { if( !hasClass(el, cl) ) { el.className = (el.className + ' ' + cl); } } function removeClass(el, cl) { el.className = el.className.replace(new RegExp('(^|\\s)' + cl + '(?:\\s|$)'),'$1'); } // Autocomplete var timeOut = 250; var textElement = null; var dataElement = null; var timerID = 0; var autoShown = false; var selectedItem = -1; function hideAutoComplete() { if( timerID ) { clearTimeout(timerID); } var ul = $('autocomplete'); if( ul ) { ul.style.display = 'none'; } autoShown = false; } function handleKey(e, fn) { var code; code = e.keyCode; if( autoShown ) { var ul = $('autocomplete'); // Enter if( code == 13 ) { if( selectedItem > -1 ) { ul.childNodes[selectedItem].onmousedown(); hideAutoComplete(); } else { fn(); } return false; } // Tab else if( code == 9 ) { if( selectedItem > -1 ) { ul.childNodes[selectedItem].onmousedown(); hideAutoComplete(); } } // Up or Down arrow else if( code == 38 || code == 40 ) { var newItem = selectedItem; if( code == 38 ) { newItem--; } else { newItem++; } if( newItem < 0 ) { newItem = ul.childNodes.length - 1; } else if( newItem >= ul.childNodes.length ) { newItem = 0; } ul.childNodes[newItem].onmouseover(); } } else { if( code == 13 ) { fn(); return false; } } return true; } function showAutoComplete(el, e, dataEl, controller, task) { if( e.keyCode == 37 || // arrows e.keyCode == 38 || e.keyCode == 39 || e.keyCode == 40 || e.keyCode == 13 || // enter e.keyCode == 33 || // page up e.keyCode == 34 || // page down e.keyCode == 35 || // end e.keyCode == 36 || // home e.keyCode == 45 || // insert e.keyCode == 16 || // shift e.keyCode == 17 || // shift e.keyCode == 20 || // caps lock e.keyCode == 144 ) // num lock { return; } textElement = el; dataElement = $(dataEl); if (dataElement) { dataElement.value = ''; } if( timerID ) { clearTimeout(timerID); } if( el.value.length < 1 ) { hideAutoComplete(); return; } timerID = setTimeout('searchWords(\''+controller+'\', \''+task+'\');', timeOut); } function searchWords(controller, task) { createAjax(); if( !jsAjax ) { return; } try { var params = 'option=com_sef&controller='+controller+'&task='+task+'&tmpl=component&req=' + textElement.value; jsAjax.open('POST', 'index.php', true); jsAjax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;'); jsAjax.onreadystatechange = handleSearch; jsAjax.send(params); } catch (e) { } } function handleSearch() { if( jsAjax.readyState == 4 ) { if( jsAjax.status == 200 ) { try { // Create the response object from JSON syntax var response = eval('(' + jsAjax.responseText + ')'); } catch (e){ return; } showAuto(response); } } } function showAuto(data) { if( data.length == 0 ) { return; } var ul = $('autocomplete'); if( !ul ) { return; } // Remove all the nodes while( ul.childNodes.length > 0 ) { ul.removeChild(ul.childNodes[0]); } selectedItem = -1; // Build new nodes for( var i = 0, n = data.length; i < n; i++ ) { var newLi = document.createElement('li'); newLi.innerHTML = data[i].text; newLi.data = data[i].data; newLi.index = i; newLi.onmouseover = function() { if( selectedItem > -1 ) { removeClass($('autocomplete').childNodes[selectedItem], 'selected'); } addClass(this, 'selected'); selectedItem = this.index; } newLi.onmousedown = function() { textElement.value = this.innerHTML; if( dataElement ) { dataElement.value = this.data; } } ul.appendChild(newLi); } // List position ul.style.left = realLeft(textElement) + 'px'; ul.style.top = (realTop(textElement) + textElement.offsetHeight) + 'px'; ul.style.width = (textElement.clientWidth) + 'px'; ul.style.display = 'block'; autoShown = true; }components/com_sef/assets/js/joomsef.js000066600000010723150771655450014310 0ustar00/**/ var JoomSEF = { txtHomePage: '', ajaxItemTask: function(container, id, task, controller) { var containerId = 'sef_' + container + '_'; JoomSEF.ajaxShowElement(containerId + id, 'working'); if (typeof controller === 'undefined') { controller = null; } if (!controller) { var controllerEl = document.adminForm.controller; if (controllerEl) { controller = controllerEl.value; } } var postData = { option: 'com_sef', task: task, cid: [id], ajax: '1' }; if (controller) postData.controller = controller; new Request.JSON({ url: 'index.php', method: 'POST', data: postData, onSuccess: function(data, text) { for (var i = 0; i < data.length; i++) { JoomSEF.ajaxShowElement(containerId + data[i].id, data[i].newValue); } } }).send(); }, ajaxShowElement: function(containerId, visibleId) { var els = document.getElementById(containerId); if (!els) { return; } var showId = containerId + '_' + visibleId; var nodes = els.childNodes; for (var i = 0; i < nodes.length; i++) { var node = nodes[i]; if (!node.id) { continue; } node.style.display = (node.id == showId) ? 'block' : 'none'; } }, ajaxEditOrigurl: function(id) { var origurl = $('sef_origurl_' + id + '_spn').innerHTML; origurl = origurl.replace(/&/g, '&'); var Itemid = ''; var pos = origurl.indexOf('Itemid='); if (pos >= 0) { Itemid = origurl.substr(pos + 7); origurl = origurl.substr(0, pos - 1); } $('sef_origurl_' + id + '_url').value = origurl; $('sef_origurl_' + id + '_itemid').value = Itemid; JoomSEF.ajaxShowElement('sef_origurl_' + id, 'edit'); }, ajaxEditSefurl: function(id) { var url = $('sef_sefurl_' + id + '_spn').innerHTML; url = url.replace(/^\s+|\s+$/g, ''); // Trim // Handle homepage if (url.substr(0, 1) == '(') { url = ''; } $('sef_sefurl_' + id + '_url').value = url; JoomSEF.ajaxShowElement('sef_sefurl_' + id, 'edit'); }, ajaxSaveOrigurl: function(id) { var containerId = 'sef_origurl_' + id; JoomSEF.ajaxShowElement(containerId, 'working'); var postData = { option: 'com_sef', controller: 'sefurls', task: 'setOrigurl', cid: [id], ajax: '1', origurl: $('sef_origurl_' + id + '_url').value, Itemid: $('sef_origurl_' + id + '_itemid').value }; new Request.JSON({ url: 'index.php', method: 'POST', data: postData, onSuccess: function(data, text) { if (!data.success) { JoomSEF.ajaxShowElement(containerId, 'edit'); alert(data.msg); } else { $('sef_origurl_' + id + '_spn').innerHTML = data.origurl.replace(/&/g, '&'); JoomSEF.ajaxShowElement(containerId, 'txt'); } } }).send(); }, ajaxSaveSefurl: function(id) { var containerId = 'sef_sefurl_' + id; JoomSEF.ajaxShowElement(containerId, 'working'); var postData = { option: 'com_sef', controller: 'sefurls', task: 'setSefurl', cid: [id], ajax: '1', sefurl: $('sef_sefurl_' + id + '_url').value }; new Request.JSON({ url: 'index.php', method: 'POST', data: postData, onSuccess: function(data, text) { if (!data.success) { JoomSEF.ajaxShowElement(containerId, 'edit'); alert(data.msg); } else { $('sef_sefurl_' + id + '_spn').innerHTML = (data.sefurl == '') ? JoomSEF.txtHomePage : data.sefurl; JoomSEF.ajaxShowElement(containerId, 'txt'); } } }).send(); } }; components/com_sef/assets/js/cron.js000066600000004330150771655450013604 0ustar00function jsCronGetRadioValue(radioObj) { if (!radioObj) { return false; } var radioLength = radioObj.length; if (radioLength == undefined) { if (radioObj.checked) return radioObj.value; else return false; } for (var i = 0; i < radioLength; i++) { if (radioObj[i].checked) { return radioObj[i].value; } } return false; } function jsCronSetRadioGroupDisabled(radioObj, state) { if (!radioObj) { return; } var radioLength = radioObj.length; if (radioLength == undefined) { radioObj.disabled = state; } for (var i = 0; i < radioLength; i++) { radioObj[i].disabled = state; } } function jsCronUpdateFields() { if (jsCronGetRadioValue(document.adminForm.cronUpdateUrls) == '1') { // Disable meta tags and sitemap jsCronSetRadioGroupDisabled(document.adminForm.cronUpdateMeta, true); jsCronSetRadioGroupDisabled(document.adminForm.cronUpdateSitemap, true); } else { // Enable meta tags and sitemap jsCronSetRadioGroupDisabled(document.adminForm.cronUpdateMeta, false); jsCronSetRadioGroupDisabled(document.adminForm.cronUpdateSitemap, false); } if (jsCronGetRadioValue(document.adminForm.cronCrawlWeb) == '1') { // Enable max crawl level document.adminForm.cronCrawlMaxLevel.disabled = false; } else { // Disable max crawl level document.adminForm.cronCrawlMaxLevel.disabled = true; } // Enable generate button if at least one option is enabled if ((jsCronGetRadioValue(document.adminForm.cronUpdateUrls) == '1') || (jsCronGetRadioValue(document.adminForm.cronUpdateMeta) == '1') || (jsCronGetRadioValue(document.adminForm.cronUpdateSitemap) == '1') || (jsCronGetRadioValue(document.adminForm.cronUpdateSitemapXml) == '1') || (jsCronGetRadioValue(document.adminForm.cronCrawlWeb) == '1')) { document.adminForm.cronGenerateButton.disabled = false; } else { document.adminForm.cronGenerateButton.disabled = true; } } function jsCronButtonClicked() { Joomla.submitbutton('getfile'); }components/com_sef/assets/images/icon-16-404-logs.png000066600000001624150771655450016272 0ustar00PNG  IHDRa pHYs B4 cHRMz%u0`:o_FIDATx\oU{m|ٱۄ&R ĀwbBbba#)ꀐJ!T)-j#ATJ݀b'MmNl~{;9GlnnJ`J1y޹4M'0ZFB(6MRXksrF>RzRJ(Fqp8|BOOI!DEAxRJh\.G>' C*',@J cjnBV1ejβKqxHhbbR14MIӔXa\םBXk$Ih!Qv7樯X[PJtc̩8%x?uw'U-Oe($ц䩌gy~&b:(>z_j =ق1!F;lj3*2> >![K+s*W>~T7RsR!G Ql@k`ht4w=R'~p:sLZ:>0ЖibΡщy].4@8<=e]VV&)W%'/F+|'}3TeyIENDB`components/com_sef/assets/images/icon-48-info.png000066600000010204150771655450015753 0ustar00PNG  IHDR00WtEXtSoftwareAdobe ImageReadyqe<&IDATxZ[lyϙ](%6.4v iRyK" ZAZE(4}C @hSiQiSNI_T+Vv#Ro"ٝs9K.)I& p/{G{'~/iQuB)ȷ)MR{3ئlgM(ݼA'T-Dq2-5Vv~z#*״ֹj6"%z yC *\e 7m2?l `bFX!ar1x臦dGcA #dQ,;i쾔/9ͺDFgo'⯟833'cXDcA)Hx0Souund/n&btN %h?v> @d,ia"hkiz_xͭo XX5?N/~p"FE-KHA{9_a!f;ȹfI5D$v{kֿO}gIs!rx)Ux ݩEXE\ Qx;^,p՞:kF}CJ;i+; !/f~y'2pT`8WJrSDcBt(lbѠ~Ѕ2D8B?Z]{( NNOVn)0YWSg'jeSp8C۽dh7^UEHϽGZ^Jڐکxlw R%* "e`OE4:"Kod'MuM܄(\reCeEDJJMOAgYIomZRM"}6{:/15gDz^GM@ u[ }qd,w/q${ddzCu {] u IVF˫+W$IƳN殞0PZ9 2ܗ4|oo+Ut}O,G(N>ʍ+D?xkq ^d(DŅaTOߠAHI">2Ahg|!UFA$;6}0P1LLQ tzDum%p\CÕ),7ۜzE^@fhd5K?~]_h'H+92õu#Nk 96˿и,`|{>I GH褐,%}Ae#M0C=ݱ6>q!0j5ÒnS WBq =nŪ)֩}q%(VHoiR81結D:hUxnKUekA4:g-Ԭ_M;Qy;4 ƊY>a,xƼ=nj:@_(divS>*T{R # V"<<+%Xne'\YCXafR@Wa(> eI]|6FB/Vui{@^$@MW[vzm_s?kI'Sf!3/Ma\ !^%2BXC4o=Q(@~>@@@gtF C76`Hye9~96 n]+ljld4ѺPNR$(jw)e௮iU>1~%}_y_ԅ#+*Hײ 㲒xZ}ETD38,JàdRZxQ9D=/0-7/\L#v`ʵl<ivrE*qszKd??־~!K!O, ҂JC rG,rO3V𝮫[Ik#Pnd8uR@,:#WPH-ox><+*S`~|L0)C# (s{/}@+!G`u?0nFLǘvW&[YLau e4mPZBƏ;8ƺvvt i9CP@zZާR >&sUs4(sZjm\ +a %Vq8)±[u+ E_*l[; R> RYGG"8byu] B1x@sS͝`46 ål;o=|Ӄh"TGT]V2u+jJ YH]*Y60ZJBm)PZ9dnX\}zĭnlG׶mkrT*TM%0 P y HXFkY{E0&Cߊp[Ԑ W1Ap{řzZ{K''ml Cj>:~k 3S( ?j *;fԬ:*]v\xhq?41M[#jYPhq?}rI|cE=0Yl? hբ/HdO o-u|I̔jtm7%0Ybg_a|a:e 5ڒ"}|Ъ?rqY?qzو=hQp7CҧujӞɯ>>ߌӕ\b{$c~Qʇﷱsβbb~jwc+o%^X( 4 PܡsmvS~lRqGҺ+)wbq{aHxuxg^n=G{oou3+zi}XtG1k]wsҝ#,l0kDz=V5^gEmnSپ'4ڣ{ Cj, aZ}|c ȄͪTCHA# N3p >Y]=#FCIS!f)]瑠,Z(OC/b+%knsZwtZ? e^}}"۽ȟ*eꑿ㴟C`{O :t?j߿'wdG Cg~{b0$!IENDB`components/com_sef/assets/images/icon-16-statistics.png000066600000001615150771655450017213 0ustar00PNG  IHDRa pHYs   cHRMz%u0`:o_FIDATxڤk\e{;{gI:4JŅE.\ -t#ԝۮJ݉TA&Hqaj ͘ĘɗLޙ.Rgsx8xHӔ#56q>{nXJ/TSraCJWeR e:ҕ+|~|o'H) 4M2[6yM?RrųCo~-.)0 ~ΔӅ 6f,_Q.*J i0҄`E5 M8"lv{w8lxX)I!}8ZJAV#7VcH) PHSu{UnmSӬ:G;΅jy\0Ӱ:PeZŲl2gq>งvnnUNNȵPo޸q׶4MT8|sO SLȑVk>8>ϛӜ\4M -=\ 90$.gt72IENDB`components/com_sef/assets/images/icon-48-update.png000066600000010731150771655450016307 0ustar00PNG  IHDR00WsRGBbKGD pHYs  tIME tEXtCommentCreated with GIMPW4IDATh՚y\U?WK];t: $VDd(qtdzFs#.GD(z<b$!{;[uUu;N%@8Ǫ;U;[fܴoŋ j,%,A7_=*!qͲE%Ғ);߫^(dR9krDkc[qӟ u5r%.Luȏ6`%˕whR+Uqߌ@ۆ۫◅7sr|n_6lD:C:/ɗ>oLxy->ڐh\v?l~o*Ko]oY+"*Q&"&m%׎< v l`:}*Zzl Y<̞w~7@XUVu6k OMglDȏDH$@8\q/|3(G<HeOgsz}3Wh׻nj:?vY ^W͓/$o'e,`fV" %@ [HdK>zIrf_%]WM_sApt&K"MIPrZТ$%C]C ۙ;Rqm>LM[ ](Ŷ$K `2l’ BErM.RZ,o/.B)Mdql.GnzsN|^fq#`>O7\%I@<9L%W3\EWӣHYe9 OccY-]=ߟ5Jt^vEhvvog}Ԇ9kw+,!$ujg"u.f Jhc(*8_ <4JiGT9++[~3;Xb-:[j G@Jw:r`xc[C /HbAYҶv?YY,Y%;WaħNz͡7Do Hm$Z2_jbb7ڸ]8Pʑ̴1\\>1{W #N,lgCސ?mmgxΆW106]CC*,i,y.}t>t7/#nѪHcce>ܶhĆ_ZژO\(ff{bq|ٕ͑x85QH(z;Ó!:7t ;fUYH"}$#4xV[W.CG*xߓkaG߻#1އU6@y kv8vپ IőHvi#;Jw3좽%{pB`KH3[g24Ֆ+LL:<+XV@c$6)+F#\5f!]O,RbI./:U'Imh#Mw.!婵5!o*3KK4n~@]u1!к|} L im:A:y{kh!)6a:AZ alf9dBK;Z&FWxϖsd10Of|Gyg.ΆٴZr%~/Ӹ(mٹEOkNn5-u=kk\h E1I.'bAKt+R{,H1sL5TRHK1# xlGڦq;j(UQkDQ,M[2<3.8 J('hC30Di}WR%hcpeh2L %̤xb D#K5w NAމ2\R2QN`!/82J2SiiHM)Ltxh7EV,#s AU((sۋ![i5jBkAju"d Ntv 6KnJ씳N3ĚW1 DzhM;A89+u^`Mj+4Sxl2siKK@j=_m$Œiq5\=DMx}^p 'ZT@[7`9V&3N~+~OuLjPݼOML@J82[QAIDC#h-I) ,oB(+]p4gVڏ@܂ D98+YLr ez\ f3Jh499y,qrr/)˿{~ܳAOycd:ǒ1&IM|7|ceb̾nC[Bt/aYsos-PhLrNѲ~^tqཀ/;]R#7mݱ?:[t ;p>)f sq\+kI0(7BAԺ; '7`@b8+Hm?4Օk[邷[l3MT_:X\4FwTcSK!Fʫ8|9n<=P`8Ny3u$ 2Rvx乻??~³_w]P]_WΟ|[ÿZUq!#k۶Dtwv=:Pm>w=pM:)ߒ=CO>%p*.>!Kej,ǎ0]@bѢ ióoeXu^R䪫>SO)y_>,K RJ̘iM&M9>t64|;+Mg;_ݷ|럿,p.{ԗ%G thu}X,z.wnSuu-[MUb̓ۻ_<9?|A5 y __[V*1)~}rpQuu-[MKg T1H~i )ČlR+BA;Q[)%m 'ԕsZe?s,4p]b]'4)]ǰmdDz3gbX6@vlom.t/m'bˍZ"ORTzȿ3_Bʤ35)%B@k{#^kȤW򛱎 1MشCC,?gsvp[7-F8J)ql6H`"0g|oosUׇdg~R׸Z jW<;FenooϞ:_cD")Sv{LFAUp[{8eY>0=;&> )8 H'(R|SR-W*[ D8h_?,nL42|?%^ӧOi*ni!vؤ.H#T{].m _Q{O r/I|^ejoT"1;xӷm)kq2F#<⯴ht7׏/X>|4!^0m#Y7)-HK Gm uh4z!E+]uGstGQͤ𺦽 RZjr9|շ&Gs34[$V\Kr*t=D,fF 4TU%ht9_nj=}Z+)'>?gG{wڙnXE0H&&pEQ HbDB7`AthTbdt66 uP TD"QS74b72K\#7& p]/P^WB"ꬋ~S8KB-ape-*=2n!)RU"A֜UU!lEY5PJj!بD?7Kb:EYtm`Yij_*Wd8pB!E;C} ŬbQ_\{BKDx3L@"{;/!77g1 w.*НNCKѪp9x'e͹"򬺇#{dt@XP@XHԐI)Nu=٧Ҿ< Zm)5/*/%7_۵ϬEO1 '\<ZvާDN IENDB`components/com_sef/assets/images/uninstall.png000066600000102235150771655450015660 0ustar00PNG  IHDR szzsBIT|d pHYs  ~tEXtSoftwareMacromedia Fireworks 8hxtEXtCreation Time12/04/055prVWxі0cR*XĝRrwN^]|$i㽃G p/3N_W:EqFԤTH? <_>1>e͙Oܑ^]6q/<rDCڃ N @Uf_HmkBF)3 mkTSx]YsƖƱ%ɭüjjjˣ$bJbʖA,jӍ[bXDc, ٹ{6z<ԆNsz&=+OTloR>C>ns?¯Dy W(rwzx|ǟK8~ǯtRM{tm'ƨ1i'th<A鎽G'mŽ}@v:xC1^tn{{Tvu;}Vgw!G~8VciDNtMĠ u(tVXLs`2MORP)Ç"\T?Gcqc:CHg !!dNoL 8aݰ:Pç>h׿A~(Z6ZCP %_z3/8p3V>\Y9Wp@7"J >_)W`j|jFnTS>lՌak IDsr\K3, mX]2.Cn4'B2zIYY~q:ƳbHqT5PQ-fb'dSĉj@%u+ehj4@/3LkWkTgqށ-STLp:24r|c{'AOɧwAc9Avn"E/Mw _wYc93ch涝% d Jre2j CƆ2#@06wPǁ(ȑ4M"hՇh2Ia4@Ix5y53 Lv$&8Ŕ#TR(ΥgZ`FC=;1ًZf{fg9_<]=Y5HWi%U(Ԣ\a8K©x ɟ'c8m8]Grp5]dMʠQ4*FeШ9y!U!>S\}\.%,Dψ^u`La09 &G1ܤ>rDRr+:h(d* 96אLlSFWĒ҉31|3F&?^Yp b&+cju:Յڐ爘a2Xm0`]u?8 > nǤⴓ:($R7Rt)}&$žJJB(E8Lc[ʩbw 6ONa@6:w=bF||G͈OM 7º Η)Ƃ<2=hZRd0gNQ;mYAIcoHo%戰?gdV~1!36X$(ŽGbp 2YT6qϗ=a_)Dtx( ͵ C28NkR=:5l귌Wka0uTT[7?h±IpŐ Zaܺk$VsyH`̿n>|dI|׾"u& eԐa6Kgך|QG2Es;aϙ th_CezZe}|[UXJ6;@Iֺ΍ui)) gu[\\3P!ZD L19.Pߑ8*gMƈ8qAU$|i3!0]'#1ɷȇLsh#jKY"iL;KEjeAbԊ/ YQ߁:$]Yнl(: !|z<#}˓-T|L$Rky `+V9hSwzNA\?\u0Ґ*aVC>(,u(4N8Žh+tn1\+σBso-˲ 9̃D׋i-od8 MI-TƐ68C+0Bpȇ.w&lB6]3#[ri M> cx+$t¶RUl)[(ՖBsDOCI\o].X2*kgߟ;I;bSBnYD8iN 4i3nh3{^NX+ΰQkFlB55嚤&A5 #\o#S>7|>Wxğhw~fXQ4RU+XԇG+y ζGzSufJRYH~ga6`(*U vڢ`gE1\7kAoÆk *HI;2wt5MXuܼG[hQ#G 8u1chZޥkK{I#FPnr(M…=4SG ǐóPzC8$g=ڂ35F\/8?zͥEZy}| R5_7賕C÷9*ӟ질?W)u-NC@R־f=u|&IFT3&E͘]NܝE]_x_/{\G0aG ʷh3oA7^9r0}7IY^yFld3cS'n2y)7|c-mSvߗ!hvt#9z9pCy OR/'Jކo=c(9l9ɘ7%R>~`ioGqaRHpŬ#P7$wWHW~VHߑw|>9o= ̮*~ ׬zWp=nfe!,#hxOvv; ݑ6MH&#R^w>MNxJg^ h<[<Ѧ^NX+ΰv'C,Ex ys?yׅs}7 xRGs|n4;OGNnu 16KUpn$v ;K߶[Tp ㉅;s(>{t clܾc+:6I`>vm{ulv?›7kGnPINgmjߣX32=>2'k5xxv}GdžB1\ptܢM;o=wA:Ї/ {+vITCbCc:GQG6ZgWjlfMI4)3%ktl56Hj:xεWW7k.YOSjq BnHf 9]WA\\Lf[xilϣTs1H QlHاEt(SAZ_Y X mkBT~qx Pl;ݣmX;ѬqۍGD6h[Q@b DTAѠQ@p7O_c Arbk(کA{|P;E]CW-juo6#Hc ԥ=:T*C*P2Wsk>5Q<ǮSh&Clʲ㕿J8MRJonj8A_ޥ#*T}rߣrݬr7|j/NGT][x{DO,YӶqPfE!TρP2F՞U@c2 /RSZC'0^pܱbtޔ챮K< )WCR!w w3*T՗&<Ɛ4L G;vxwp':;zͩXD۔:r C]]4kPj'[]yrmn豮[5FRЗ_|批uvzVs=u hKɃfهۆm ,% 󢸸htWz}@bBZX 48KX+̡JSqDvWfY'l_Hϻm?H(iUW(陙DEEcPk~Y0qܿ?j+u7XY{aMllFL,zZUc1޽Yس..gG-j~g-6eflbmy|dqUZ{-,40iG9A\}OM!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!׿7E)dvAmkBT~dx}LeS4ӴTЖZFR _QKD֔td(LEEpTFDTji%7?㳳=YE*ZbW"J:/RKb(DE[24SEC:9EWGڏ}c3HF݌f)I TzER!;nitgu9RwȜq3[Z(-ҍYf(Eb~MhA~8k{84GVxϕ>5uOb&Kb 77}o\nn:;ƚܚWRBKfL߯'ejotǷOu39l3!y̹ofӹ |NMg6 |b`yM_4g=%ߧu{MUFg4XΙЗz:F'?isf=0oWIị҈6x|w;6jY:.Y+oVvo*ǨU*eieNjXZC1S`LqiS]T;1EȰ)[l>7L8l'HNQsƋƚݻQ79cz}n)3h鱟>SI>ږSppNbqTOPS?si1Ȧ緳koiG汓 VgGpY:~gCubtoeӺ)9-Uΐ[yR =PEMy/͐vn& mkBTWx흍8 FSHI!)$FRHnw HYx3ꇤsaaaaxIǏ'U{o_ھgW9 o'GW {>~Jlo߾)*/N\ϱov[iZ_ձaJΝ/:6O- 92b?Tlk%?_21B sY5>:>c=1Ow y^- ڶ,XzusM#גU]>H_yYv!ۉ_mi Rus]Xm_g)YY)m]y,m z1aaaxEߓGקo/Y\k6xjgH|yu.\aæM&wk#ϐ$?]Mo\Ⱦ,/ڥQ@~6s?)}, l gX #vQg Bٙ^uのuhm?}{].~}v_J;xogJY]޳@.)oqC?}>@Xߘ'-(W? źvƔOʙRv[K?[A}?-wmՑ}g\=c}M ggg DŽ-B^k_g?F? v0||؎=ǧHPgs/hؑI t~{n^}ZyD5XWvO)"c0vY Z|~_%/,p\ɹyΰZ/;/xs_9?Pܯ5ݻ\[y|č8gʱL{? 0 0 _k3>z_\S |<)b|7aaaxn.ta?l^Cvkؽ#~e)3<3^kdlc&jK+o"e<.ʞ`^(3zu l+6v<ï k7]/lc[`On}򚄫 G뎱zt^v2)?;Wmr5ocIz?Ozx{&!ez."ѯ 1Gg{+ҏlw<=}GݽFƨ^)zIpG K֜{{e G12ۭqiumf>.}~a? 0 0 [u+7Svq֭y΅ ?ނ}XwŶv?ߩDZۓ-q/?߳=<~#>Fk"qzrQo 9r,nY[;o:)@-`ק-7({߯S@µK9֠ɸ>:n3 _[_*mtcmC>qSL=<6;ǫsaaa{xˌ\ފpx?0׋#5zяc]x^l򼠕(f:~٣^lin59W~\;?vn6erUbS~v^U O7O(|;+SG4|?f*?rW~2oNٟS9~daևmH6mX[J~s.ym4ٶO|Bd/b5ɿyU? 0 0 0 0 0 0 0.P~*1@G\⟿KrKXs2(ߥ纎J8'>X@▼QQbqwx b)_K|v 1M6kee-2Ǜ59?K^E~9ϱQﱮYF8N?~;:=J<-tĒyNAgC \NXKs)'^Kg\~2}6}Գ)n]Or^j~"{p29w6/.z-v:+M{WJYZ굢`% Ҥl9ힶկ#OUz+U?;sd~vND7*.Y+v:ye;8}~|+ÑޅN9}{Bƞ#txխsXɿkSV/uJ=o G<ջL'L:D]6jfgLz/+ؽ[{rCMYq~[{yy czA;w9zszWHVax3 %mkBTx흍) q ĉ8D^>׻gI@XjjgiЃ`0 `0 ?ϟ|:seQ3|ӧO|:2|.};7eGFO6_Qv]T]^ˮg{>pjzkuo{yye?{-x/ D:3D&򈼹e^Hyi#/OGzϪ߯_~ :sMe#M3Y#=2 QЙ[\s=E8}E>GȩT ڲTg-}VfoSVwzV}./>~!?U1<#}=F[ ~QڋBN..+푹^edLo+[\-k dW(}6q$#?z6Bөi?L7!3O_Q}Пuo[=tkȋM!'}/Ƈdr2_Cﲨ: `0 :8o=+8-4}۞cĥXdq{bUq©ήm!ƶg*ΪU\z[GA=^+ru{LV U?)V>ғ)x|Yҁgi\yi^cUo*= !TY?rfgWsʽVn*VX#=Fϫ+[F~yH\L~[O҇h5ݵTow|Sfӟ+);F;:x )/OS yUo2e)Ve3'wgGg=J^`0  ľu kU,Ksؑ5nY,bXw{ w&3QהNQev ]ƷgcH˞i{A3I8hwduwUIWq8I>+@pQşGcZ\ƪUߝ]/:3d;ɫ:gB9R|GW~w2;fzt|+i5nΟgZY|<1NyŬ|E7k?z/k><=Α}N΅>uWydʬdz `0 *\?W8GY:Dgcg< 2+'W6qn؟{ru"wU쏘~c#T?+y{Q,,^qF/Xv8.֩g3}ȸOP ~n%hUG4(_sn|W}Tg&x^c,Fѭ+ <#+}/Uw8BRh_|33!mr\7U9m({ѝpvew[xG]߱?g;,nҽow8]וb?OV=Z_#ve?vN_WrYLo;1g9pV^G~>[_vNOS3 `0Q[ veO\k^8֔v<Zbz\Opbn$~}oz3ј mK vU]^iNWA#x딫jt q :E= z%օq)CcYEqyRG-+u (K\hP'*^ء^q=m=y|Kvūe\rȊ4={W1;=ݷxp;o@>ȘT\Ԏ+C=*ɫ|GJOCW]x1.ﵠ9_Eб Vq)v(ʑ}[GwǺ{-oSdו_˞׃2;iT&w*w:g׭SOsj%Z[~_˯d֮+w]7 `0]kIu+eL]ւoA^;=GR?v쯱;<y o$N1紈=:ߥPVu< <&3KyC/4r)i=*/|Ύ^]QNН1qGw>ù{ ?Kv:A}E:_n+{u=rq͓̳]>>d}+|L01`0 leg:׺񶊝`W,3O?]\9P~[kOWiGc~)-<w.3q}'vuw$Vnv(r52S;Wk_Kϔ8B/hEՠ'9w?K;x:x<|@cϽVyc@ۖSw8Bq]=2lBe6V}eR( VeZT4ade2ޒ+nYBTqSߔ<[&=f[|szP)G}{Zׅ3n7jpWwftEw[ǽ;`l? `0 `0 `{~i`oLy>uoi\qK|}7Svu9G쯿c¾#>,jow{ՆݲL=mW2u_8دjo?kD߱mw>#}E:OۡO;y`$jwymkBT6x횉m0]HI!)$FR?6c>>~sm+vuՑνYu8uN?WP>1JsWiV_uKEϸ/rˆ_gKW]ױEYcl,[TYHT}xL#}A GV7^}>iҞ-i;}LJX&TP3T#ߨgJl e'=?͘ona|7>?ǐU%;/mN/IfQփz{G}?v✽3X~j{zTAO^ʰ>?sy|G)PU{ ..T}6ڳ-F`p]k߅~b  О$wݓٱ|sCoA+q3lOx@(0a+? T,_7s\Ϙ^Bl1)C+k(FyN"8dPC_9>O0&l4Im+nwGrŰ)/tihf ѸX>E)<,6s45zb?J\<OM%O#(76:= ӋYAƒH Ls6MXBcX&ǘJte. 3.je(??Lj=%wZizFTx$kP8Em jAOހ>~؆B9 ֤8UKCvjbL Cy ;mj P. DkwUE€3ܨ8xUJs\ɟ+;}sFQ(KIXݛƨ 1 +KdX];Jģcx$D׷X`i @l̏rnm$^9΄zBGϞQ=nfkDe; <a>,⢞jk0B[p($Ǡp4 nq`XƓ vϵ.xHnorJ5Hu뇗 f a[Z:>36[g RL؍?( &w.7C#~B{] UW 71jk~ecGrD.=K@WDZM0倐0\xvqNZ ># BE )&yA}t?B Ym(WIpɱ |2+\2 )l8tl@Z.Be񅋍RSƃm>dIl'N adĢG3%#)?$s _5=YBR#-k"qGP-e"f%֩-ϓ378M9ϊ,_*n;HEBƱcl~ ˝[/sagIE2,z1t:kLș壋G){7ond{@rP>kwk׽ #kXfyEAB9uM4P=_lgW؇N#_nGpp ,ZUu6ȓVӰ0EK7*|]{75F\ԶzQz! uH>upT٣o3P)[^6` -d&*=%fY<^ط`_6|h3ء>2 Pq7ώ ,NsjF=B` 큳CiU)R鐏@LҮǧmb<2FHRqùFXi䎲OmGA}:*u f:@ʫRH.66jcGOpO- 6HKJU:Jǃv,3DZEƮqq7p?ȌK%ȧ$;?Qr6pP7`a^=R_)m>D3#£ _' Iɭu͋C-Rne㯄ssL<ȭ/R)|Lt_1Lk=rr 4/gEr~PnB[\g[{gYvRW' {Fem1{ wL;7&$xc0 n&u@5sCCձm8Heft x{q(aтa?Q%l4ςxmWI׆GC1kQ3iJh,KRO`ʲ4)%b6B8\pe;u)ko)#WSncRx{[sXv195_0Kՙ7>Tp5ٴl3S"؝LX睫[5m Q="u}pϘ*xbՉ#iM+@Z! Ϯ~jYݬ$?5mtu] %@݅:4h8ۃtu3; ΑO1A/r R*5i&j#Y2:$Z(ad@>'z L뇶6Z8|`6"X1_z' F-я?X^ A:?1;h/KVB' vOnFS ƤQ{=kh7MwXQp\v͓O/. N3HKRlK"q^Wh1wt h@3e6N|I;y?8t[[! $,ήLe"z%IކAkRl!3u8ځy?_W)AbCO!rza5Sn֗#<43y6"R߃CQ&>[# BHǽ{vekOTlq(UH͵h ݔ8,@tՂL{p/*L"d_y k,4 G̖bD>,.ok"D;|7[.DCA#ilϟI֬Dq]+eE _-- ڰc^Lq1~CCC9gNH8BkhJ#Z-`VoMa 9r$պZ-hkh ?C$ ^tď9d(8P݅]ڶw[wl;dn׆oKd Hބ(DInI M_(5)6H/Y1 QRk,nXHʉ?>df&6^EJmt{CCc`0ʅv5x<\9Yc}106"״!֏9dl:' 1H"z'7QqɌ#KR./CVgQȬ\ `?d1yuM6Ƶ8ZX]8^pwQE &1frRKi$GݜЕh3'{;;~FK37ku<pdʎ+C RMzƏ7)nҀ lEGyl:̑IoBS%|ЕsTulebA}Aʹ10A{KʘӺtjdLI=r PRg_LbR Şl?␔)![Fo wi&k^CV(t@pW2{hxHGRn͉eCbxԉ6GQd27\ثdS=\Ff*0ۣOP5(rZߙxQZ>~GAeN-jY7Ҿn;n?ӹ"Px}/NW:݊&׾:x" ꭥу;R펔 c䛅љElmG§a= h¨BG_uYnZ쫭FYs U"zM&:Gnu.DX5Xn;}ԫ%XO?~2&Frjj8 yA*W I9/ub)Zl: s 85J>~iI3Yԕ;:#hELם[ROd^GA˩f~Y!En0~/A Km>^WYq"<цF*c:xw|͞w%ehRgd9̕v3v Dgh>>?3hYDkgC(ʹƒԕSԜ| 2Q94(?OGQ34 fccPopTYaW(>@tX4`LGٞpɄaŰl\[9c26U M6f,'C4i?W~psϠ?kAKrŵk@I|>^xs?\`,D̒5W^w DMXf_8<%|8_왉pP1Wlm߃f?4:́_Ԕv M;k:p_sj؎qw]$F}y ,b'N=o0, ~M YR46+!}@~ujctCP.Y(x׎z?70WXFܣo3z0c8RGg0 TU򄽻w"/4֏CQ`[{Ocn]+{{ N!33+5]qpj' r9FDȬ)~: 9Gmx2-?sraG"yvUpa;Ră A\& ?#n 0eed~oq嶭!!DzP^H)>oȑ.ļԶ=Hy7S-M ?8ycߧq|#5"2Б lm#UeΤVbM͘jAc7Z ]> 4gb s 2WRsKg6 's8qzTT[R[w)I95xWj #!nN+zPڔ KgTE,?{^RDݥ=Ru^zîc&D'i74SJߔ&HUG[crͦ<׿~4}څh;lpAZ%XZ;tQ?yk1+Ƴu6[ Dc4Ɯ*dB#!}e>samhG3c^8u9󼵕⸈߂UyB;f "Yi=D =4&|C3g]~WgjhSIXU"1A5Fr4{AljwTt6</N \Rta| i>T.Wo>>xϯY{緷m,J{gg}v~)]s!?wXGFl!7U|Cnfﳅ:.@mq%臔Ru?.:aBֺE#Gg'yXDuSWNJD)21ѵVagWPqȒ s?¶@g")s\T{f3go^w:^"{d#!φt},nyWFKv„X4|VB~,˘_&fjp/WԍwaO H 3I`u1ͤ+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_Wݚw) IDATXip]eg.ɽI/mC% 3! @ Ց GGpFq#udRV ])t MiZڛf9sVh|}>NP@$jA`dh4ʎ;H&Gx%l^ގLLL`vyRu]4MCBj088H᭷4Msmr8B * iZ}$IA@u p׺~~>u[n|A_I>'RVQx<^! P,T*ȲLKKKD"! `bZ}}}ׯoxg9z(a 2HQ)=ϣP(`6d4uUU*6۽h4`*Μ9$I^w!Ar466ֆ$IxJ{e(>r@UU-Zaض$IJ6exxu9s&\pA0y8Ti+q/=s]H$0 ˲(Jض,̚5|ߧZRT*۩8$ѣG>}zY\FEt]窫PU5L$D"2Z 4I.8\]ijj'd88( 5]L&) x?1JLYV4M4M(XD" 8qǏ3<<8 2RpUUeY4mݼyۙ1c+iUVjOsjHiCbll EQPH$aJ%,4Ml& C֬YêUbxGw^d̀ۜZه$scEQ0 A, M}F:::yImMfQ Ɯx}8Cb̙#Ba6+^s~yVEQTU0 DQD"d2dY& z6qCֹ8o$I(Bڊ`YjZF>5א~gK.kD4!276~ǰ6.rrYϧȪ+#EQp]t:(_ :|abG5XXGM\>aJ3#XǂVSD"dY烦iP uH$x/b%ȕQ# C@axB_Fg>?AD?>T Er!RN:;;/-L -(:U:[37|O\L&s6TS̱cPnk(iA"{̸Rxm?`Y`9xێmes gF:}v i(, PTXr%x,˔e|IZ[[*sN@]`w/ɂ B+ 8.Q';=pۗO ˲dHRb1`ٲeqV^ @Tb3{lf}[i_{!XPujA']/@VzjY?rҥKYx1ap%сy000@,]wu{u_-AkSI T6cb\ϻ  !'?{ٹI>_裏/ ɲ 7܀i<ĪU[~S$g? ? }1l^EƁ,1_<|hjZ݃8۷ɫlbrrҿ+_;>'ѩzSzO,3/"Aq_i9`Idh '{;;n۶|>ʕ+H/KO=؜"lx\x9֛&iw+nX8~;l _OvݒψV޻;$㌝XIENDB`components/com_sef/assets/images/icon-48-404-logs.png000066600000006775150771655450016313 0ustar00PNG  IHDR00WsRGBbKGDC pHYs B4tIME _ }IDATh՚y\}?fgetJ+ K$H^Q*pRE le'2$T)L(# Vjv;3;{ݝ?`vu]驮߷o71I?U__"n3̖R^*\(k0xB )A.766r#cǎRͲZV`ݲ,cL1B,ShTo{纮XE?|)%B2Lnxxc6]WW׫*m۶۶Ummm}F-H$"]ŶmlF19Bl6R u+0Nd1k]]]O !Eؾ}{+VBD^pQ!&}`ttt[t7R!T,| jSD"qʼn'vo۶ rLg/9~0 C%e]}h4}-Zbرw.@oH)/ @5X8xW!q0$ϣq,YI)e1G h{jr8q={p1>RJ8Rʖ;w6H1ÅBAygU?AP4B0 +fkk+---|ݻwsaDf͚5KRcBA !*zisM6!'xL&8.j<3d7#ajZvhppcժUK$xcD"d", g{{Eòe*(ymFAUNm:u]33 Ĺ. h Ð PJ!a|_N)UAPyznlذa>m#l)I6>Yֺ bLbU, ۞qΚ7Y3_Yc, !DhM|ŋ?S&^kuLC\ak'$'H\}fL 0.BSf~st>7- {Y~oo-{x+Rj[lΎ$>l^Ǘn_W^!jwLe|#L|=z|kVcqfqԤw澟o47  VYK|Ի(CC!TX`O?I~iۤc w}Eg$|wќ& y ZϦ!jӛ,` ܁$/t'QڠMg!qXYFR8Z5 ıc*^:|矏rmע- %z6ۗq:P-Xc)Ey_،XXV+?֤!AV|q3[9CBK-8Ѹ䞛ud2d!\HGkJ~Ǽ_W+n^1Ջ~VUbǎK˗/fNϰWșZO5* g<ѠT2Ϛuyts,[~M)-۶$²iIxht^ RJtc#,:RmU<58'\4y|4xNa mٹ4{{4W/jf֖?|ZJJ/s;xxSC`#zm8o7`aMg-:6,kbs<|x~ٜF?n(! [n(1'˳3tHU89fd ϖ΋?{1_P޾Og4S[c],:β2 5\?p:ֆ5d'r~kq{)N O08Ar:6"tѨBkՓ܏،O$5#_Kѵ0A` HOI"wBh(P|{a+BeN w+ePu%R1rΦа'ǟsNJ"f3goMrr$J` b(Q,m[T|I/toW8F`4h(^8⅞LIHXQYBTzp?ß"H1|>ϐ8# f3D)6(HXB+ړ/9b"C{sc@*t ˲D^6q>{cý#q%SPHpߦe+"|󳝠5IaL7j*)¹uBs)q0,&X8,!#24T+.aQk TXFR``xRR]!Gpu]׎pP[8l (9څuX/^o䟶DClKbAw^?k|\s $ R)f7\??:Bc Gh\HTQRt^}8B_A,S%-a/XO^ԳeYaXI><$jvX`aa 8-/9/}dK - W7a)Cs*?Iax^DJc/:jt\1:w"T KZXZaKc;=Hs !)viB"E-Psl _0;w|@=/J`Rz[%Jƍ/n:y344drl6TJI)m<qh$ƢY?߷YQъl> 2AC*]lO{h7n˃N+te jjB#dڼysҥK;jjj:<}8 H`YNRv27y,fwRsZ)wi R@wqIf=|_jq<.[{wCww2`tΌLykv̙3g R9mHމDDSkͭqb'NgRçSG>QE1&Hp!iӦ%S@00%:_ SrU&Y\u#mԸM|,N}}hll$o߾?_"z?Us-ƹ W]<)a۶]-5Kv8ibb-ORH2q48UvJD{A D4͸oP$IENDB`components/com_sef/assets/images/icon-32-yahoo.png000066600000003277150771655450016144 0ustar00PNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<aIDATxWilUE澽PH-4QA ~`?\b54D1FEbq"B"۲}m_v}K_[mo9|;eB\cG܊yk_v.M76b6<̍`ׁ ܫ't;SJfWȗ˖/fynܺs59[?,8^PY'/p8Z̕O/=qC`69Ӥh 9!tSohYР.9 CdLOr3 .Sv4˴HxnE#q ^vȗH$x4#1uԪC`qD}X,0pvEE \X( CG<A꿬Ĩ٥cs6'c~Lϡ1 <ڍS:^7py]^‘Gqp>ÀIO, 1RX9w57U8zT.|+}$ܥ avlWvDGbʖExZjHpTN;ފł.Ei)`5,^##j 6tb q SX 䂡 C{\65ލf(-ߵ"ՇWxUnXpM҅/χ{ GFx`: +Ӳ Q332 1 cTWTݪkޢ\t&]r>Ϯ{<Ʀ͚ekn (,`!JB ØYR)8}.Jܸq%L/$9j'~iSK9H}2ڒPצ9wmhܰeX}-)5&RR3s0)7+Ƹ6kwǻ'T|iu JkK߱|9R2s265& e"HZ׉[C+4,ʄeLWTecZ͸*='ً_7Ah/= v2 T "YE1 e}ZҰIm~al{u8uy5:W)mqamR d d<)l||Vmj@|,[tQdӁ߰p Qb|ܶV}߫0e,)9.`B$!t:@7vOG͊*(轈v4,'MODT3KNn5"p⣡l?z:ϑA;.8=N<Ӈ'{TP}Z@Vg%>995xw,dI})=gfS15e2P2THFduֵ[(*"vNୱM奷"LTDduDumv $J N܃$x6ȌʵOV a6zrw( QlGrWxrJ[(:q֏*  Z#JS%Ibi??쒑%S%m.5K d~kh};<_Yݝ(ُaZ7Gk0WGq{i,-Un[F"8_3H&('^P?R[PjL  V\Z'y{a9jX@S:Lq!ft}8v!@ؕbI\i =`[@GhtByV'/v{4=mPM||3GQq|\GrXYh;.`f2Ţ.Xs EJA @3IENDB`components/com_sef/assets/images/down.png000066600000000166150771655450014616 0ustar00PNG  IHDR2=IDATxڍA A+fVTUfs `1 n ^'K Pܽ_ 6IENDB`components/com_sef/assets/images/reload_f2.png000066600000004667150771655450015516 0ustar00PNG  IHDR szzbKGD pHYsnu>tIME)N DIDATxڭk]Wu{=>;g<3#8+NI"TQDJ-_CT (jc<}9{~8qI֗k I/;ӟNj#N,1;GG՚5y*gS.5sۀ|]}[KfLݜ CO o.6vi" k2S3k vґ _٭Wr#E>x!O-_тTa%ZB& I q\}US0ӀƟQѽZ!{*Y(9 P`ACT裯DzTxOvnk}hlEb*N 7;:ߕw>1q^A%ǒ(eh{ ϤTֆ ߝ\%~:,K3+֛5x~K$}rA\=_پ0ЊB" cE3H '(e!;ۛ+}pϞFK[cg[>VTy=ޝU \^t _I>(Dil)ۆ䇥'0C}=ݙ|&ZZJ__aXJ4ÇGG_?/綇 S9ЧeLe57GRWf v0"&%%VuٿgSI|@ EBQF1ҷ12m3T>Wz>8vOTF#é[˛XR08ơ6Ss(qmj| Ɓ8ЄqD+ZP`@A@^kxggOgNwo꣯V.[ӊ"Q؄J#Q.ӕI` h^'¯V+MG:I2H{. %8$<{ !WKԙIH֘\g4|s\ (QDEDhz-/`PAƩZ,.eeX=FjZ@!ߛ l6%1,ֹRXaR$6XEF_6ϷPxg:;JKXY%E|o[1҂JC%&#ο/6khB(֫1KVS~z9LJ4x|@*!w&]8F D;HF\ +Y`?;;SJA)5B bm@*D,.Uo61f-ߗA`^H"EJ{'O,hE!+h-RXf'(0wHt~4 FJc;qms,<ƄFsU4>5Z0Fk6X+bcbEn }Md.;}(*ilҶ ;;H RA5B)9OfυNf%uuSz\Ʊ,j&I/!>{' յ_7}+.9 or\[/NXxׁ~h@oOGn0%nj6`#K7X:S?b}+j·K٬O>)66fBB ҀH!,Z5~s;7LϟKGzAFFƑ6 %p<\&=\wfrco_~ <}7Li~1@JeKΞ/pŊ~(tF/m>4)%JkV.+9鉕oE'm\H]1Qtw[' Fkٍ\֏%0vӔV8"Hf6 ֫^VqmiUA*i5IENDB`components/com_sef/assets/images/ajax-loader-small.gif000066600000003311150771655450017120 0ustar00GIF89aԔ```@@@DDDnnnܤ$$$(((000666>>>jjjrrrŠPPP^^^:::\\\|||ↆhhhfffFFF xxx֮ƼzzzLLLRRRZZZbbbBBB<<B;>CD ;+F &03 8<݄!'14,< "PF`! ,;WX []<U Y-\$_&JOSHTJ^*\GP2 #7HKQ:6L=FF'MijNA:bIT@?R/D924I ::/E`ӃA&V,ZJCaTT9Ij! , i^,CK jl8^ghQCRk "dNJnj2H0T.-435GЄ`eC6:f:=σG5AT770/6@C(CBA;@/܆F r Z@! ,?(N!lG9'g[jNJA#HlF=B]ON*#F`8"p A/`9"07qE "T=36n F o)! ,aoe&? +qe4H2D< @33 %F8<;J @@ce[l>8TBjuaB7KAǐ0Cv^ ur6b?ՅY)3T3+'s 6F0:.ntn830֭! ,0@9(+ATA8cJq >`GT6:"VVA6@>/B4eb= oRTD3>hF^M'0F7BLd63Ӑ]jl7ۅ&NG+TTc1SOJvwn\-Yr;"0:TD AB8Q"6/37;(I@0=:GJ73QfA6D,<3e34.1&2*^Z\3#*N DK$+C9 \T6Jc -:gY(DZe u,AKXqoPt2Q=FAl!+ OjLM^aG1N\@ÕA;components/com_sef/assets/images/icon-16-301-redirects.png000066600000001571150771655450017307 0ustar00PNG  IHDRa pHYs B4 cHRMz%u0`:o_FIDATxdMoTeGft:231`0X 5qOpe&ĘX! 6i(2m;{BjV: ѣTy Bjݭ[GYYQlcw92 OP8ZXh{5\Y5oO^>v޽Vс@!'?Z*]ߕ*IttV ! A/Zv Ժe p8‡r "ȫϟZjd#Rr$ x (%`"0}~an}t򕭝 <:u8p1Y&Zg>S;gLg'Yb³w3-q͋!"zi>.]>zg j@꩙CFbC4e;Wxri~gӘOv6uQxt`;H0ٞ]XwimbWu|bKcN+?oo,6hZeg딣-FyO.cF׵(Ǧ|P&"+md1DQa F'%-aU+mEz1N87.kDPx (M wÓbq,wuZ2>Zy ZF$ \!L֜I V-"8<'CQJiW%nh[O.= (@%ÝVFBx(A9%nCw}\cIENDB`components/com_sef/assets/images/icon-48-error-logs.png000066600000005200150771655450017113 0ustar00PNG  IHDR00WbKGDtIME8Ai "IDAThyT_t0# QDe 5ј7]bߦ "(w &Bb%`Fd(aQP{{^zR5^{wϹwo9Ng(OTKSuiʨDNY~;*g7ϻ8h3fwsoc׸a)9[?ts_?4ii2ylܯ[yO)}ΤmY'WVF+k?0jM4nXOSSD!Jb#3aPEy;/<M{eYI@H]D L$C àUK"ĸai E))%D YnK^[iNaҤI/J8L*9k痻9~|%|lY;w~Bnd2ضʕoֶϽtv.iHLâcK,㕿O+@(J%G !>6,aT0 f]1 5Y2t:qnF^c]ĝE0{0PJ~SO=$뢵f!bUhJ6ep@˲0 4Tx2I::sÐO 4! >Xm܉*'KVXft:HP01M ) 0L,Ʋ!AK i??UH&9{p]!J)F0~.24UUD+6RʽgSiABiĝ3s\sy* ͜1˖2n8lkbHPi!@HZkI(2M\%N0`F :yrw4p@x=v,dN m0 8(\! X\g„Vzo<ģEwa@)d&'HaW J|(QJ+\7K&%ɐfZ1Qq+OB002s0LРV hU0lT*MavPA'I$ض\Z&I')$y21 LT\ QO$wqˡV^txOmTTaZg]Xo>+hA"H (/zlaP H%Ix{{|͒fHg$SI8T )%D"RdbPJ)6on"s39 XkCZ|裵 X@q&1Mׁ__}~1i+kF7iK!$RhCUܭY!'UEo.ZyY k?d{[;M2ZI*¶l,4\)|E"::Yx1diD"}lnֲ&\7˜g#./3n8&< iH @ B"YZz-&N1L:P(D$؂oKϚɧH$׿W3~8(v6_#2n$Iټe37Vr%R=ƴ>sr4P2ӧkVUrDZcv{zhi]GNuu5O&z*r3BH) }%ķ̙ Va1Z[Һ 'ڡD"U "NS;uK0LAP(rOve@|`MMMІV|4'@48N _Lo (ekS@aY e+T)6ZI:?((e0 #ՍblJVa1eIg)?+d:}5Z ~./ɚK^~hcq]eזqڙg^~$ΌiVS^?<2?hbr`K/.a!%@}>SI)rݟ}P@kf{?+Bf<ϳ}ٜ/Pp {۶!3?/PːS;w8Ann6[ˬCܵi=(y;}Ƕёpb_pCqf,xx>Cپcxr#`/{*>^nyMagpأRһ! SNr |6ظM\P%KW)9d 9/&lIENDB`components/com_sef/assets/images/delete_f2.png000066600000003413150771655450015476 0ustar00PNG  IHDR D+tEXtCreation TimeMon 2 Aug 2004 14:46:37 -0000vjtIME / pHYs  ~gAMA aPLTEƭ֥֖}oL9{qsֽΌ&#seW~AJsZNuuksUbR4& gRV)ޜ)R{{ZcoRbk{{됈%Ӊ#ޜ1scZcc絥s19kkc`{s G7BJZk ƽĜޔ1ޥBcck{sΥ֙<~GkBZkscƽm?<ޥJRRJBޜJZޥ9ޥRcޜ9s{{ޔ)Bk9cBkJsRsZR{kJkcs=V.WBkZ{kcRs޵ZJZc猵c1Z)Rބk֥JRRsR{-R)J!J!BJscZbbpRޭNZ9cBcJksVĶm/PSb{ٻor D5k *i\n6hoܴyVT/N70ad+͵Ӛ3kjI/D##UӔf+̜5k͛f)PAOO/ Ή=K&M45@w}tnOO#:KmbtbRzz\ެ.U k,Ѷ͵7lj6mimkmfdȨSpXҲ*^.&ee e55b |!RU ʅEje!yB i@E"2 S-+;'=X89/ߕA#,<"Ԣcllc SR 8=, V8gE])!h:.{:Z}:1r[P$|=;i+9 ipT"XJi g* !'91:va*; lN lfPEP@W9_*<۩ XLP8&X‘-l[C5P2_ Tʞ}x @ }`UI|7X{4YD:U;㰌UL b ]Ґ³i'vd<#(rԸ*#-#ri6ztIME bя pHYs  ~gAMA aIPLTEֽέΌs{{JJsJJss{kk91!1)))BB119)kBBƌss9)R!9)ΌRRB)J{BB)kccsBJ{{{ƜZ1Rk{Z!BJ)!kck{{11!))ƥcBskR!J1{11{)cckƄƌR9k9B)!9!RR1)B!cRZZJΌJ))!sZk1c)Z)!֥{{ތc{sZc1)RRZRkc)ssRs99B9J!1JJ9Zc9)1!BBZ1B!kBJ1)ZBkZZZZ9!c)!B)JƭZB9s99cZcsJZB{kRBks)cJckJBZRkJJBBJBsBJ9!kkJ91){B!91Ƶss9)kkn?@tRNS@fIDATx}SW`m)4"Zh օMBb'B A4UjUW@[Ľ~KDxOsNw{?gѯaL|z; }7~3щo%8 %^6u DRM|Lv7O{s#8* CÁ֮GnE1 =A`G} ;MKP,}W1~߸)>9: %hH DQO:1'W)З$IEe ǝȀ'.SS>J~KjH׶c;yWE\r!O,|h/.ǎH-:ySr8T-DOMҠG2C4A̵a>/huI FB{ZG#G8.P,\{Q`{\v ۱S0ÔpАcض=M7AXM rPԲ@؈m]0!74|erWIk hK$好@Mм,y:żxdzd4M -C(3N `Ϝ5[=3gɚ[m̘ZTi%RSzhܓ'O %4?mM3i:΄P!IENDB`components/com_sef/assets/images/icon-48-url-edit.png000066600000007560150771655450016560 0ustar00PNG  IHDR00WsRGBbKGD pHYs B4tIME ':IDAThk\e9/3=d2!Q# 1uYE~`-JikYRª[Z."A F@erL&t缗gfz&=1Z~t=>?C/ndEףZ[z@8@a-Y0$sF'UJ2۾Sco{/u|bŲf6% i>{t? Dy{ n=w-Iozn* b-`Ӫ -InM` X}IN Jet5S#?vMmwߐHmxqHRp%)4cV&; G`YrQ(OAV"?:ySp][_WnMu,T%`i*ڮ$ 6LqUoKT&?yuTFe-3}N߸ͫ>Wo}Le8W KXLG:Ά Rآo6RulNYBg/;X[jӪOs7Y{\=V T@jA`$7XI,#U|E.<1p81yi t_w-]]{˷Z{s%MlNص9<dϪcy \)di*v}Bei'3qBy}C\߉ם[oO&}CcE@ ,Q`}Wlj\<7I',4٬Hpώ6hm]+I:CI:(Ys@pT){y;`?8y.IV}?rM\YOS2 | w%-2{=Nv,oh64;yV7/Il -D2Ѣby_j,ڛÓA/ ¶.Ns OW.]Ev$9K/Has@j֯jwTʂP*0^{" j 4 77uM3,Kx&^)Wa`P 1EL*j/D ڊִgd^z AX6 ߘiL »:Ⱥt>pEJx˖5y 5??o^Fܙ'w K25> 1'\0m{ebLJ5 Oyz)x.xDLg6Bv%E_8dB 9]!3/n&*|t<_2z4J\]{5,K%oQ'j3i/$cz툿͆Y^ }>*zRU|#*!8-Kw!Z e *U5Fצ^6fq/X*\a OI7E@(?| epl QCKۈҴ0kP00ecOyOcy yb %O'/c{_CFWɆ9 i>qfA,Q-Oy~/8pvQRn˲WdϪ{ ]d/j58cj=ן0]S4q V}_#եH^ TI.QUp7F_G˰wד`0N8tYIqUe].&z`BN8vO4Bȶ"Cu1ITl{P%bԩ::0˱'(zҡ1f~{EFDa8좜4$'kjD:%"qYv*SjzBDh(\ġa@KO,nҘG4:7K*JMX=xl H. |0.;+Z kj`Lؘ* Ԥ~Hi@{2i_5_2?ŞJSHze7#u'~Žl4c!rфb^(m<~kmt )qBZIzL }"=4pIEe1%V\£AvzJO9 OV ^A~}9:_%Qf~7±3494[uRMk)2|Mi@*# w=^-I_~܂ձgo2 mxjWNg\ PqK0BQ¡ ocpE͏ <-*.䮜n{匫 %8uѧh)]UxRҀ_{8HlQ`GS yaL9m2<-j[kP :] I79Oh(d'1nDcG`ٍjT.:6QHґ'"\)ar0[ffkXinɟC rixv/T*.yx㖉 :|V?TU?.x8SUlgYu޲=K`AUO!HtS%]쟗qi*P} * 7do'm*swl* u8 M޾/tt_~sx[yC{$!Pc1d O`هJ 9 SۋaaUAB` TbvJ6ZvxCDV1mZ 3@?q,>Š t9t%A~,HkU E` OT*~Ƚ74hf E?Z-o?1f EV@@ G+ۇo}6~B$]р=?so͋ࠂMhݛ*o?|4M(lM;NWώPh\ y_.=H@V83B18__y})yb@Z(j[2ĩjU=^&(s l ⬦ɲyї%_Ofg`#ZN8[k\_+n5 KEeW qDQTR{b, qC<]Lo G D$| BA$h .'8]! :*ƮP[z7~/ek^IENDB`components/com_sef/assets/images/icon-48-update-tags.png000066600000014671150771655450017252 0ustar00PNG  IHDR00W pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxy\uz[/%-#b cfl M196;1^%n[c|E0$$FlYz{n$a$>:Uuu}u})OyS?tvv "H]nZ]WVW+ 7y4UEP(3a,y"V@`Tzq7L\[t] ~X|lxx ټOonnu2\3z{{$>QǝWƮ5ݴ_3L-Wjښĺ>Ss$ ,RCFU4.KU?_xbN)R*yli[##D֚F#aQ\G\|>O>GDHRL>}}}Lǘ}qn%YR4cFV>oE \{uA姺gl=1'[Zn-,lGDT*fIRh{x;NaTBeDl`;'sˬ,==]8/X2iD֮ e_,d4V((rP,R%kd-/;F cq]^s_%cSS+:gt*1>B\Y6$U,vFkǰ`Q(P(H$P*]ĕBfivxӌX1lI.ҿl d!Y{Y]η{JS454PT}Ruj0;l,Cj,AiEb~woޗS:!tM~b7B xA'SZGjylᨘV}bAv\vmcS-X%Wjůİ%YR@+$2:=ޅxE N^`+eT+WSswsWPhelt!+s׺R滬qLzM5XxqRjމ.[:]?a⣐ KhxJUax ڊ2"+n*MWc/碖L#r< R)$1ױa?+]i$߄]MGz yc}_?@Wg`e9jV`j3_0]hZ`fZ4|`:sq=PZUH8bquȿfY;άcj*iO| ><z=x/;y;Sϥ pޣsyǟ%~a#%͖`$kC<)7PAYּep0>3Oab-+(Bk} ;x6gEd2*`Oe;+LkcN?+ QA^q+u:M0v}gGܘKQpDOXk=%!BŶ W}뛔g'nm?6K5F.j8O;Dk"D '!ĂϹr{\Û;/LnLw{3nsR ѯp7`^e~!'"JX-!| c4ߌ:'\\DaWX*h^Mʪ -60D "r ;cŲ3qj&<8/*h'DNnU1`Oy7_YߒU +u~tE7||}| pZh٧L`Nk8 Ƙhg]oՏS8TZ-ܷ!DR"=Xa'?:;F IENDB`components/com_sef/assets/images/icon-10-blank.png000066600000007027150771655450016105 0ustar00PNG  IHDR ? pHYs  ~ OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FPLTE)AX۫qst VUxUUUwv@j=qMMMޤaaa3fƈU|||ݚ%Bl`|1\{H|̼]r\\\kkk-JdJl-Nnֽĵǎ΋999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~ tRNS, IDATxbd&8(v&AH  5FڄIENDB`components/com_sef/assets/images/download_f2.png000066600000004352150771655450016046 0ustar00PNG  IHDR szzIDATxil\{9glN8Y " %,I!R EmůR%*UHEVVD@,BI$$N<3sνa'H.|q{~Sޯx[(Օ;6 nhp~çq/h&=bw;~{b(^JEOE5RG/a"ĝ`߹|OݦHH_1u?v85);SL!U8 .Hӣҳgο |—?_Km<]m). _[6҈tmw,:͂yM`+D_Pwތm9U x9?B)=}b*;˦M~tih0R((K%&& rr5ANϐ:^`2[W=SѲdб%#?QTMSQt@"ql@O%xzXK6s?EGa$7TeAs(޾zؔJuf2_i}ׇCBLE0h"ple9aC(ΚQOМzu3\ͨliK7rjdAʟvqREUBA6kw*P&,i,,k_%Q3/,uIh5,\ãGuӧs IJ$^DB.aTUw s2;([(V<ȔP,*4UUp0 Rv̛ TDІ㖥/oT۞^8."TTx DZ,>`KK0dBLDJu":;ٶ5t`ܵxOOh`<|(4= {Ŷض:4UUB.Dq=bA4MöUH&s9z{ٱM(o9V]vM$ ˚Wso]{]O^wݍ74bƲkHLSR(fa2tH%ɜ>Dzd/t>m>SUUKcC-v)мx=5Q?*^`| ٹcӭUVF"`Y5mt:06ԅj;ONaz#TTFX{+hQ }}FFN%/V[wC7㖖X  N\c8q(A&[Tq -X/:+uS/7ӳ[톅G|oyꫯ3,`&Tqѩ&D%мEN}ٙ=66(RG#@f5VnC/oh`ǏܺX*ɤ'9}<w&w}<8?hY>`2@8P jWnp~mW]ծJ.D?xg{9>{,J@$`s9a)om]yk7 s(;C@sϹ!pf_\ "_Ϸq鷊IENDB`components/com_sef/assets/images/icon-16-docs.png000066600000001463150771655450015752 0ustar00PNG  IHDRa pHYs   cHRMz%u0`:o_FIDATxtk\e;ɝI2' iE…P7qFq!E{7*( A7͐I2L3:.ƴ聳<<_XY\_[_+_G*RqejL!xx4"* k.-R.\^zՙvjuc׭AxtR)@}3s^yVoi}.hkg㵗|rP5Wq훞NS@$.tXY(d6FLƇLCɘ rւRتp^Gdou֣Y !` Sت:>@yv.#QǗ1Be9P\EOw8d/ku2B(_JAWɈ&6IxLc3X\? 9n'bKLXc0BNnNCUIڨQK#t` Z|("B- >;{rh {O!Aġw;jvϮmGdis,>x|P٠s@T$ 5tc^oi1D`|{ڇs纭gWV; O:ksYc6}7>j(k?۩wҗ>H\Ց/>==ښ+r]rR׬\<toaTI5FI$ % a).A7 M-&{u<3֫ף 9H27:BinyjD D"ULE -/B%6zvfpe9x;!!"|(v[ CQQT=:tcHAmBY(Q%]b ׈y,@34AHbRv]#->(Ķ%&x|`ja9+3nѡ˼?uOǹJ(.`.BЩLF5%J!+ }PyDFiqs6-eKrQei4)KmO;NI-۷?ѽMvf^P \ZkO3@ۆR7qt˃7BY< O)-`и%T”F˳N)*ǒZզ>g'foS>g)ѵ'23vjxz{nDA?+8#3P817@}@ $&,Uɻjz.FČ?2 D]l7e5@Hϗz)M^̌=Dy +G?]O6{?hW {7ǣl(Ry*fS7 "W#UzB'Y+Kqc,»e1P)eR**^ rw$c iW&.e2#| ԘzK>^Won:} gg]."X(H ! J!,J GEi5_o$;vebrҦ'm/'P/]5k_}]睮$V a" 8@EyI+g6r+ͷ;H|| iC)w/i!Poܺz @[Ӑf x~t^ ܀4B.& lDzc#@s}%ʃPp̚^OPW [I-Xz)a(zNE`Z璗 ]Өh2b(eUT|񹔆5i` @Ģ >dxS 4;$\r L9v>|"{i*k%Hfrk>?$0--{ϲ+̒,a7_ye=}lٕBZI∺? |@:+Re\rt0s9̎Xf\v\WΣnl0'/ rs0h2,`fXg1/<\`c٬0^4,neyZטMsegLF~兂ND6O4 ܵf!f%"v 'PEDfn-쇇o^t_i9%]DhL+jxS=TbSjƙ1ha*L*a[}|S" wv^ 5p3܀%ʰ{h9޴sCMMQH>o!_huC}=I">*#Ir+13I5y[[ĕy3AŬ\x#Wb"zFM~|W]IN/0BJ&C Moj4xa"c:,m/?{yS]RyQ'XƯ4:E/*y(0GLzE5ɡ|+w";rthdZBe7˖4t~eRsq,Oݧ)TЧh.rL}E9Ֆ>>@jDm<|,+H(&A/M@Q2\AݲŜ2ʸ7T5KqX;wd;?庹M! ]~ isRtl;z:U/Iij+x7]&kBh.Ϝ̵f_JC^V-j:m C>=MIz4*HY0IR*4*ў GrҶ]'U3N?UP9lTb"H7аs])O 5l(y0SIqT S4ZX2r'|~t_ƕ^3 cN]O k K( EQ|MQV$(%|;̚ xM^{SgHF>/KPvފmДA2H]ܶ~Ne-c,*=+j=+TBv:c idsXd4P&(O@ ^%״s{7>ͯ_ aeAқ8x!Nf6-/?8ŎM$K%ߤ"dz9<{xll BI'{ٓ+SVs+x<Б\ɲs-fzaaNsgs-}+pi|h^KGYRCey[h{?"keХo%)hR n2ܑ4ux|MKęC膠+CJ/St]CG ?|ϯG槯hV4۸瓏PW¾O' b|FB#Ijd)c9^ºa@|#{οl\-M;hBGЄ@W]佢5+AG䥰J{&w1499z/CIp3G/_HÅ9*/;f:"ԕJ j"\4@ 8mhp81iФ+jq`Vz =~=w;cew_oj <櫕_.)۟n"6O'ɫi3O@S d\Д&=4%1DiK#qma_"arr̨ͱdGf?Zu,wL/Fv?ޯuޫ Ga^2?Zo=2iAVͼkp p~/ᡝd*Yz0-؉ά%~vGnxfB&l_W5_0B_@riMJt',άYաM/Bێ 9&ӈ,+*94(>ۤՉ5\`kk0f0]omg){"u*ʹW~~QzuKoQbNO+XP FɌҒy}.R^sF}ex ݌ŪرkmW p:K@&۵)jbiZ2#;Ǝ; U5g͟]m~~*yzІv  `Ͳ[W\"kDEEH?J*Fv-zn"ːu_O. >x4K?J%o.]T)`Fjd"{ƍ'O<~8w^V^^|)kllZGa--Ϸ5..+[juEUKn3fZt4>,I%`DH<"_GyyyFWWEuw2hoogݻ{MV0ވb≤5hI$T]8gXz^%zzz>jmm;}n>y$("=|_pxph$:ʢz2|_SR1%La0YM2 >/hwoo0|x*\ &!UKE*y$@B8/ldd{.jGݗ=yfUguP;wNٟi8{50nPoe-.1Zq;wg= QZv:]a,Ϯ\g!9þa#׊L3)1&˗/03>?k֬6mʕ+Ϙ1`0@gA?e Nvْ aKZZZ|zB+k.[bjxdI~~ li #VZ\xDSHÐN^\Nrya/&|D<(s-_[ϯQ2 Kd B-yp8c  Dz{{+<ZS;^x;/8qb >}yFb٪IK$:~ lٲe<ެuց~`NUx/L֭Κ5kv#_x6oWFanR)O|3bHyK.-+x4i%P1uFIENDB`components/com_sef/assets/images/icon-16-url-edit.png000066600000001714150771655450016546 0ustar00PNG  IHDRa pHYs B4 cHRMz%u0`:o_FRIDATxLKh\e{G+mM4XӇPKZIb.]7"(.ܸJ]НP1Q J0Vlb$&ivc&;s]L ~s6,QB).p)V]:"zcmnLt rz1 `դ+ZG}XK>$WG97͆nksU,'}2hCį{x#3}GP/&( ̇^  ]|3*a@T6 k:>A_wD`gڅR6 ѼϽ݆+䍁0!ͣ1djs?ͅG6Q}84Y@O|_,d7 )_zQO,# WJԛ.H x)rB,hI3у@ʖM$+2Cf26N)Qtw69{]\ٺjdfV p.phH j![_~2{whc* AA*dZZ;mr5ôl%0ֵ|y2v-c ˆCw/VD 0& D{z$d:)?ֶ=\VwUgX1m!I`0ֺ%9(y.i3 h+Rp*_sԪ?{>5D۫6U\r % 틭ދWY]j^,?ޗ2d|ǣO6cQ21$q5E^jΦ]c6-n/kWhtYx=Q@IKnsi.z!)+G8E\ZޤيEZ'KgL^[P݈<)b6dzbȖ)U~LjPQק .Q6IR y'!>W {WFoHU?.ӥJykNuKt(' iut7{kr߱jeT %4􍤾`[ ű(gc?/b+4"teP\n~~qfpN]z!5DO1{BiJ3Ki8{=oۮer%:5^L"ȸ@ĕF.7{T.( +%f>{N]fOF8b sB9n90K O{!bZYR,uwYy72H €޹zA 1U?OsS1W ,tō"40H@J;WΈq$(U.~Q4.d{Dip#7n %/"qmoWkGnz1Sf@W3Ka{A{ =:M/^NHq N+mLN.'qn޲J6p.>?>L!R n`@HE 4LU$ bp)ڿsjLxsyI!. 4m(D3L.nϗ,j2rvx(25,HD?)rRu;'mh][}`<)ϼt^[RyrFQ3~e"Jt( hųiPfP"ccCDK 90^&`uฝR _j:}Gs^|wΐ]B]`-(Xg~PXRJ9z5 7%\2Y.`*{0Em 5B Ms#bhHNY@σlcCKkd])!!XaYˌ}JuH3 3=Tq- coW~my{1s_Ag!g>҉ EI?!\g9uM)V!93 |E, #c3)Ba!sŒSK4C&R/븛O(qH\elpв|y8wS2zrG9$PN%gو"}H01? %V$X뵉RQ8oziG;Mz(Y>l+mZz:3dsߢb>Xd|; ܸ'~,Ӎ(~ _JXpA_Yh\ڛK%xRecaǺP3'x3o І螝yOGfkĄ}}glRg`ngKf|V>_ĵ 3?M`vGF߽7vJOXBQ^0 0 Su(4]syvnCT~g>SUK;Y/(Éy4vTH*SwF~bK06 Q2ThhzNEi $ ߳vX[D y>)%u/O׈}u&TRz#6 v\unTZ^FÅsiL0æ'3F%o⑞ХwTamLTre f!-l/t}dflu2;e߷"F >($)Bm*)9Xh^?lF^Ңk}]=]k>xGG d B&\55VN(7buɶb‡wu^i6u*9>0̛z>b ̂y2}k'G :zKS$s1H,4Hq Ϭˉ2d>l>pp4Xk=v31QкF"T Cc)O+H]?wן~Nr -wގ1,fG1AvkGڧ՛ob8H2Ѕ]b82v֜Dic.u4Ml +pyG=fc(?^[o\Խsggtkv6Jvzl;>]3Wo P&#]幡 @~H_;]y+z|J{2RGSvkMo9Ev.5]D71)}Fh^ϧ;oݳ`2leZVFr+2֐H)wʯ׋N烼+e2d%ϲg=PqT2|Mx A=h_>k2 ݬWխׇYX0 vu^ZxtQmJVG3HΈT6 ,~#6=hF-4?7xV\@^V׳x6"2I^h Vx~ek8NE>V0\:Aj|JrCsuC}X|z1!b õ\,nϯ KZ3jvZJ$8țJ/예/煊ڼ(2ۙQ K(:P%8Ua2z%!XڵA`5F ohīF*FmAa }4Flc9v\Tlyͩ0B!(o %,@!5_A>f]$2t )}_tK"&j~components/com_sef/assets/images/icon-16-sefcpanel.png000066600000002233150771655450016756 0ustar00PNG  IHDR(-S pHYs  ~ cHRMz%u0`:o_FPLTE5Rnwdy垳Lit⯻[rkCa~}놛֤ŞA[uk`v捜j~RkzUtΚ3{\o[B@6c+v/kE&HIENDB`components/com_sef/assets/images/icon-48-edit.png000066600000007176150771655450015763 0ustar00PNG  IHDR00WsRGBbKGD pHYs  tIME,M%V IDATh՚o$}?^m7dsYIP 9 HrȂ_ t/r!ʼn&%$(k8í^Ȫ!)r-zo}-+ŷ~w!Zk3ߥNZk:I$ɮ#O'IBꭷx<ռH7xc^u/~rqCk͉(~90.ODQzѻ/qӶm˶mq^VR?y.PPq|>oxw5.nu>aT*.!\|>h4b8R,١X,Qv~%q[LS(DQDnjF#8F)t:%"fJ)a޹qZVe^9BA\P(VEe1e$ R|>0jOE!`4j|N^g8l63TU,qrܷnee !O.RqV00 #0Ķm(bss0 Bm˲  .~Zh4bwwbHڵkʙb 83WWWq4Zc=yr\.IM/eaf`i8Je9Rd2?O+IjPJafFH)ZSy1RJE)Eb2P({.Jui$ J5GGGYqLPu]fSVwI:!6Mvꅞh44h6 Matڌu|>Hq+ ž)^ʢ=]qa\ȑx$D$, loo3L2V,zJ%ǡ`&kkkSK}֧]c&YtTN4x(4,)bYZ-ye)%Y(9<~݅2Egmp}uJ͍q.LW !! >|q4S|yQ!X,f6 +K !-@s}/Q?,fg}[e׸(]i#9)Jt:\}Z)m!$ *ϐ%>%f_x-k/grm5+++=0LR23ER2 TO;'M$a0d>e{i^ƕOfJ,iRhU0 VTaYާ39_cVodլP(dIAh=`&, #0, reVVVm۶Q7!7aq凨kK,0SjeӽRD tw OzUNCZeX0OX,~xQGL뿏iCa62V<|58ξ# Y/?  l$ J)J%* ׊1'L3`JoXfgǀp0drd2ƍ4 0Rœ®++6zl*X,( af/cjh40Mv0M ˲R" !Q1J8^fb6cU KkDQL>_4M{!Dpe8VlDe0 #< )Ocu<\LS>cݻ{rDTLI.b", z޽{?}wѣGyիx<>{@o4j$Tz $=O:R^$AW}w |ͫZegg< }B)꘭ eY0tLDjFy|+йpIENDB`components/com_sef/assets/images/icon.png000066600000001337150771655450014600 0ustar00PNG  IHDRasRGBbKGD pHYs  tIME8Raz_IDAT8ˍoLa;(A  +QK${+KlX""J#QmOrzswKU*;ЩyuZ"`{/㎎Y̵/sεuww-XD*G!9]3`fe)Ÿ⮕ܪ_fjcoʍ<$ R'h|rIKT]*J<37BΎ5GIO\:Vfp\*nxdzz욆ܬ' /WO,>/lX,l6)*"H Iqv s)dl=QT~Xֿ? h Bh<25m)y/ط޾>T[+PU\ [q4YH:{)~XLSDfaYDD~ lLS#sΞ9=<{ZU56-R""Aw;Ƈ04͈$f-4$ *!,c@( Ԍ߾e/2qو({O:;ZƯvO`΁a$IqcqPB^io3< =< wuOZ IENDB`components/com_sef/assets/images/icon-16-info.png000066600000001652150771655450015755 0ustar00PNG  IHDRa pHYs   cHRMz%u0`:o_F0IDATx4kec>vv&IäӦIiB5ZAxP DxDԃ("XĪPil6Jɦ~zh|?xGpS mxOO|<z;MN=H ȝ;17;8XE!s&jV߯wX=ӟ@nzgOFTg$3ĉkFR~Z?[@qiB]\8~<C>/!ʭU˩#S;b>& I?afzaS9CEEѓ, Y-x(`x+5cw?Jf^Y2Tt깥;7oYJ*)48.qIajHc:ّB#EFasCdy6XpV#Bx(~ w> NF"vOچN&q&4ՄAAg3hcй)9RJr(x V)AXeA!PRPt}.Ew5VZ$)BȪ@ ~C",*ӧZ֫9HeJٮ/&G'?wh[f76(iqdƒ[p$٫~.n\l(3ڴ({&|fGrOH'y?oz͕im!8 yhW׆KjV(\GyYg| ((L:aڌ&;NP:i5 sb?+@ ̃Ǥv~Um\q%69O$W:hIENDB`components/com_sef/assets/images/icon-48-clear.png000066600000005310150771655450016110 0ustar00PNG  IHDR00WsRGBbKGD pHYs B4tIME 'M  HIDAThyƟs-wfg0XѦZ.ƈm,(Z iNI6DH.i5)֥V4bcMIF0l,̝~pJY{o<>ـ?!߬r_<($ ` ^ÚWK vG^xvu5w3o|7%Z_P+>VRM/*`w:B{5%˿nofO,l&nzD H+`2Di<oDLcoAݣ +@9cg/p%QCŪj&GZ 85`}&vCi̚yVRV9s֖Vs{fBXQV1Jbf46$a`@hڏ7zW챙Wϋz>?$VJinG'%Xw=HHP '])]qD{+c1O`0zI}i,Dˊ ,?5}@%CY銵WvJ&O@ky>Q+\H ugeaap?@%%q_8~p'8O+B,!g))0s=.}dxkcqwܵ ÄFI#1܄l8 l-$|$Mօ嗂PQw LR]=sYuÏYTӚYOF0ӄZ"8~f}z`ٲeFhOW}8r]G:d.€ xk Z|ZJ<]xezB6&36`0TUWEQU^nlssJ{iU~P,Te@ReA筮z~HDUeCa  C# V)Mib}i}di|jƪ03MAZsj(Bmu jb-6e)bAZw O_V5cUAp JzH8 E(]oruf+y.oݺF\ruN!6a"{[i{hQ3 buD"s(͡Vn2fQ0*0-f0qtda$;>6{aa@r#4(CnE%9TN7iW}ARd` ZqV) :w!H!` Dr7(˗CN:շ$:AԝǺ&GvSY$iyR-` Ca*F 9YGk +ڹ;+B9+绽BKRo y ׸Nd!6h%LCo[p1@ЊY ۈ2A1ָϓ; .9K[J[ÑY!4($PJ s6t" h%s #4h.VFgOЍ 6eb|X3G3ޖFxݯԪ= Ĩı=z!!WCI+c `2BLPV1㟻{F`qV>t^GA%7J9 _@Ч@b0gxBO>?5ךi|}[.[XjvVr 'γ+ŵ1hLDH tLpqY]k?KP;}_?)i+}_6Koc͙4FH8-51- E\iٯëidCO晘6+/@2AL='LVWg-ƉR>ThXIENDB`components/com_sef/assets/images/icon-16-manage-tags.png000066600000006366150771655450017215 0ustar00PNG  IHDRa pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F!IDATxē9hTa޾=$jЍWX!"F!`!7bBFmj,,b%YRHP+ %AXM{,6GL33!c Z #r9sVuR,)\ipePTpPd8s Sژ# #*c[inFb>zi"BgwbvMr;0NąWiOolA:a@+ %\'R:$q $qvHm4O(- (B m.mހqt>X`-qJa0N H\wJmm'VD<м,&˴7`q#R1@s"c'zvOLL&S)zfH%E= |=ٽTaxx)|>dQ +,\1>?߹o?T*68/NMa80:H$bN 3" q3t: pqBf Wy3e= ͲK\w6ϳx7gH*w27O WW+oBЊ{qBHpO I@p{-)YLDrya?3LPK-Wf K]Z9|即2,;f (;R2sp¤d2intIENDB`components/com_sef/assets/images/icon-48-manage-sitemap.png000066600000011223150771655450017712 0ustar00PNG  IHDR00WsRGBbKGD pHYs B(xtIME.̕~uIDAThy\}?ޛcgvvgՅ q,ˮqbIBʼnb!&`A$[+i3ocf.;'W{{]߯^poGmޢU q!^@h$2pv R{4Cp䦫,7/o$hk  p*]f4;?c3L=W'kFHwBa˻/.؃㹤sUI%Jr+NhE93H;]Zd7@wy͖ć6&_ PBr["2D"8NZσ,\ދb|݌LIWo}ev@_V/cEFBτ|'Z ͍Q"T 8i Vzi{Hģ8OP&ov=:+괫Is.Νxkhk֯?xX,x1GL%DksX$TB&WmmdK6&N/UX4YKhlJr=(ZzH'jkw["w辉*Gx1 ^ +6hI2$\Ét'N2~U ]IV5}f3W*Ӡ5:iK}W"p֍rDI9(K뷜͒vb02[A!ƲL{z'6o'lt50DW+~!-_X?ST}D.+{&^՝?Γu-2N [JzU<.Y? wn'c ؎ ZbS+~ӺP~=oY yGZ K022FjJޫcEw+_~9,B\t*Vi JS8n~v3||<] hRgXaVVx}w-JqnZ3DL|FH]'2=, TMܰy-/z#q}ʶKqBJEVH#LPL#$ qd~#( V 6^.=o-'$r#1yeh@iqӒbǡ,o]"] pp[x>/q<{P\?OzNĉhy0NW,+/Heɒ ǚ٠0Ŷ9X=-aQt$nqS)΁L5q-W86:87fI R{*M8NeL OTSY^a4lX 74)U%qN@cXna?g^q}Ǜ\_8\'u']p#ɜfxD[Ă{ญi mᡗsɬfMּ:\f`k6sJUfr-NC!]M]5ϧ#FU!ٍ Xĺ%K3].?x08-gdǔս4L|1 !02Jv 91:gq B͗Vo3RB4ѝl qn6],M=ңo׵3tQ/û_>o㑽ӵ*Q+C״jSLjAjZ'Hƣ\8p)S"F8KZ )6АqhKwvQqjJm[KA[4Zz(+̗lnC?]Duu&D 9s0,`έ$ksrtO0Sk׳(m!ˤ3;O㵡 |meS9l})屒՛h[RցkLt݅}1C T,n08QOad©2& 6EY̾]#T3hF:3 d5 43+4o-8 s>8.od/P>aⵗs~e^g?*ˬb&HM<Ý|yʎMo@OTh ~i״s6vOexL T4FCtb4MO1>EG][_U'w> D.::ht jZܴ?Klug[/88 {NdICHX(2qg:hUr8b@lZ~,! $F }\j0'Z+(hB_@ڊ֯}&c:$2.]CY#M@;4@I$hhCuQΠSGQ5d/6UW:$.ZCl,p Qzn)$~S0R w qPk.?gP[oj{Q8#9ʐAy lXbUSɔ󙒐 *n/qKkf[?}o7S.Ob(iBP[gYCCi67W0! 1m<\EgpDG:G0Az-OE[7~ V#_$_JdO \%ys)!*M"*(q#5hu~$N{uE41|QZdcq4ؘCewsO#6QÃ~w}jtM@o7x>B*j{Ei[#E<1O8 (2S= PJF.M6 sGm9G-$b{UA|`R\:\ŢelPBx^(\MG[^\{nFc(b9k%X⣫0EYG4H0ȹ'drLCi=rfјW8P7Z4\\eƅM B#$4EeQ=%_j&^^4?u>cj ˺,mh7|fK1Kz@c<%b׉8IK]`y˅%A65JuȤ&d5 A_bWOzW/?ɞ؎:{v5~r=ڨ+П. ^rQ;z8}4~>)8Oh͂"eeZS|zl6.$vyc 9 B>ɽ^Hyfˌ=)~DΣ;EUC%V+வGl%chھu-s*&Q`}4ScH>T.tHIB )83&4ʢ` Q%Y;׶lD2ŞC2?y'wz-uBj:W? Ӹ@c{A`tNˋ<<[;OS7ش<ƚ'x]X&NoZNŴᅡ?k=0wMsC}h`K#d[LA~ChL*úye8<e0o(nZV=+{>V.tS\hz R8җEɳ7)\WL8-VHBax/(L0ⅣX:߁:$1w_y=>hve {>q/W&^v Md^=<$rhe:<.)<0.jV2ҶңCתkXT_,(/S% O䋛, f7^G'KX]&Z k2#Hsv0~rI;ve}멡UU5s)E! W^hæ9YƱ'H) sF1}"imE'A+puvNP?P Dgñu}s(-6q\0D> RhV(C)lo]M=?"zNL+0L2Y?tCF{irv3x%BHch#Ot?ѥfLR~?cr#'~iƺ>)b^C)3+) |DaoP|s3%%>*"Et0;r"PvY*0>;TjL#ށ/|sႵw #aG4&Մs eE7Kt8}jL'Ee8@CUƪ0!J(+!]hlSzyjO5wƲl>u|WZ6 { ⸎ ,ўa]RҜKyr3]E& *6HQ[lf " CFrQNR㍝vS]']kk3 p ﬛.XY["#ҳV77zO,Q7fsDE$ 'vxTj=I3ҟ=&sYzjY`dZYIENDB`components/com_sef/assets/images/install.png000066600000100431150771655450015311 0ustar00PNG  IHDR szzsBIT|d pHYs  ~tEXtSoftwareMacromedia Fireworks 8hxtEXtCreation Time12/04/05!prVWxr@J&ljBbİU[a S6>׾ξPgu9 ·_/A1ʘZsi43JL)d1,ڷJQ)\jttFjh)6xJ(ڃRRwM$6 ?`2X˲Q X~$nX%VLB{ mKH()%k+e'     S؋{̙z{3>\kՎm^# zo:C}0~Hk?XZӳuoR?c=h~,6:G~p\}9NK'۪6QA𨾬 (l_CWEԟ^Yťfh?"G9?ugy-0p;Yy;,tBL0RlɃ';硃RiLf_GMs[ ^g:{0G3BЊ2|nf{R/Cl2N^;!"Q}.Φxx^+-y2 8^8Ź v1̽L +CH"}Qk1'Os/,8! lUXгPAkl!xgԁ%pKKw ^0jYs\}̽O&xK쀄P,KQ~2[?AAAAAAA?taHmkBF)3mkTSx]YsƖƱ%[r+0/b(x ʖAljK<,9tck4@ذ5Y:zպv6x2Ué쬻M[V9l{SC޴}:>^{;mjl(CU)=e|O|vx|5P j4(~d9;ؓ1nZCldvf-{N;TgP+*v :?:-SqڽɴYr>CXq_pw P T .zfL1[Yh:94- MAӜŎNV@hZfeGljr@q@m]VZ)g.vnqimq%[j?-kQͳ6wԟ[#aG[Egc˧6t#AY(\RLa6WTg4bY !NJGU%-E-`rLIipP 8g,|m8]q^Ә邻fI˦2hTʠQ4*FAšŸނ7(ECF PbD;zF:CHg !!d"qOPe#)@jM> E( ϥԛ|; ErV3r;jʐ$B@$9>rFn, mT]1.Cn Br+dϊdZ m(薟SFn@E[Dj(R-nCL5Ӛճņѳ8Fo\Kѩ *&xY4^G_;>ߣ$j+A>P8Aצ]H~R¯URcfܶlSnj##?$ 9,[N'rp|پ7"C0 "͘O:w=,Bx0F6fed9)LI:t^|3ƹ1P<ݓdA--C3 Jf d Jre2j CƆ2#@0􄡌6PLJ(I4M"hջh2Ia9AQipXɑWW3 f|0=y)])4=*Ź2,WKh ?204} QKlOz ١82\$1| JOc2XyR2rWhAc-132c6vr.d'H=pg%1ܥ ygϮwMR\iJRBO˽4=_ox&1.~Z|rtuDi2։dZ&0(7;ᔝxGΟ!`` )tj9>px>)~G|*Ko.3 fR80F~}8E<'BOM1_wZ7h[ ^gyfLStF BSjCt6Ȼ:yIDU4?O!MQx@sGV~!;ilb0qY=έ^[='yGre25#8>\(?)Nfe2 kq ֤z d2%|-׹RiPFo=TKp!T*Jo{oX 7$X‹}0f} d?| m1B|s42DfA0%4Ԑa6c&O 7k,"ZnB(7萧VYyDȴLxOR~ÎPsc]gCJ zb-m]:c.݌tgJK۞erU$2e=)@ ;359.kĭD4Ë' 9;6_wNȘLq|JP2b;7zO( c~F b&ivoyb(s<#dHhs*O~وI-~>d|p_ˬRȶ|,8JV6E埴GV|Y }ZrΡExBUftzYY^^vK~jMЋl6j)#FFh?R*${u@ >iR|_y S|=Z)ak'!lMO~srm_Тk)~?Mձ)K};g] Z!|͢V3yn5NŔRrݬi3o% c& Q4aq;qn'Fӆͺ6LL+)kUc5Eh^7F䥗P7'Ita3V)+$^XҐdN3_n{^};D5Ǥ~ ~NyqQg{=v_!S<ڴ! _7{F}^s5L: ~TEW~.OxlDPҏEg5m{FGe|Aß;s3r s|~-$rx b ]qVY(i?MOo'B身 #vJ=| {&qIC**ha|CxE_C+P߷wG`q{rF6#hВ*T#ᑇ~H~L8| ƣ1~rJ Uѽ:I҂1GRBB*/<^_M|LˤXJsZ(כn+ølGvwuV5z"ƾ}6H[E8a\ULsؚw\{eǯU>[ _|ғG-_qjORZﳟ">zxյ4; JYJPgR$.xK=,,1c0zDRs2#.esq{ʄ⾫~ ng]oY1 ŎY➘\=‘>tw]vP/37%@{y\ϻAgؤ=\lNgHr]WӹA&UúgxeI C7Ca1$Z6\G[Du=#?Lʀ6y e\GZxOe=_q{DѤ Kk:46o'ieX߃yeY.!3 ~mrMFd(s^VX&qo8s6>mE݁?LGQc̀(; IsQg\CU,l~W1R٤~~lL G+TG{4kީ$ %{ fq2xkPQm3&~wqa/ׁSZk3kE 7qt?2IEEXP$O%JpdN~R~-OWJG9YPh–o<-h/_ч=C(%ZdV^\F,]^V3&!y͘]ϝ_.H/lolri=#ѽ3 4™OԠ,hŠ &Ӫt#߫"2z&Ď#>q]rb󡫉~dAQ%w^|Įee]L~ mل]͢Ry-Y&uD4kd+-V!doW!G ĥĦ/VqSj6_cvacEIG**dA{{Gh'|r"np/93FYYViIIW3/z^C{?@o.*ce$ϫw|,!e ߯@c4K&CNj2MI=({r){Q%n$Mb޻p^|qWPv$שz;v}})yFc?چU[7%U\\q߿@Ÿxvdz;ik;z:o߬Ӌdb<mk{ >MOSxʠ5bC}4m0jNMgXg){K~9 uvˁOЋa{2{#ӣbn4;N;Gn^v16GUpހ$N ;KvTp1 ?'S K}=aEb8Pݯvclܾc]6+6I`>vm[umv08› WkǤnPINfgjЧXw32;>2ok2ͨXB (;x>5xxN{CdžB1\ptܦͺoݝ}Ї/ {U+vITCbCc GQGf]Ԥb:W1X#a桙쀜Cktz~b @c=P{xl߾aORa7݄-+k\mMo*Uj]5>&8wH%mkBSx]N0Æ WM- 2*5X|DZ=fLc(F? hҶ BLrGpodgd/e>f 9]WA\\Lf[xilϣTs1H QlHاEt(SAZ_Y X mkBT~qx Pl;ݣmX;ѬqۍGD6h[Q@b DTAѠQ@p7O_c Arbk(کA{|P;E]CW-juo6#Hc ԥ=:T*C*P2Wsk>5Q<ǮSh&Clʲ㕿J8MRJonj8A_ޥ#*T}rߣrݬr7|j/NGT][x{DO,YӶqPfE!TρP2F՞U@c2 /RSZC'0^pܱbtޔ챮K< )WCR!w w3*T՗&<Ɛ4L G;vxwp':;zͩXD۔:r C]]4kPj'[]yrmn豮[5FRЗ_|批uvzVs=u hKɃfهۆm ,% 󢸸htWz}@bBZX 48KX+̡JSqDvWfY'l_Hϻm?H(iUW(陙DEEcPk~Y0qܿ?j+u7XY{aMllFL,zZUc1޽Yس..gG-j~g-6eflbmy|dqUZ{-,40iG9A\}OM!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!׿7E)dvA mkBTWx흍8 FSHI!)$FRHnw HYx3ꇤsaaaaxIǏ'U{o_ھgW9 o'GW {>~Jlo߾)*/N\ϱov[iZ_ձaJΝ/:6O- 92b?Tlk%?_21B sY5>:>c=1Ow y^- ڶ,XzusM#גU]>H_yYv!ۉ_mi Rus]Xm_g)YY)m]y,m z1aaaxEߓGקo/Y\k6xjgH|yu.\aæM&wk#ϐ$?]Mo\Ⱦ,/ڥQ@~6s?)}, l gX #vQg Bٙ^uのuhm?}{].~}v_J;xogJY]޳@.)oqC?}>@Xߘ'-(W? źvƔOʙRv[K?[A}?-wmՑ}g\=c}M ggg DŽ-B^k_g?F? v0||؎=ǧHPgs/hؑI t~{n^}ZyD5XWvO)"c0vY Z|~_%/,p\ɹyΰZ/;/xs_9?Pܯ5ݻ\[y|č8gʱL{? 0 0 _k3>z_\S |<)b|7aaaxn.ta?l^Cvkؽ#~e)3<3^kdlc&jK+o"e<.ʞ`^(3zu l+6v<ï k7]/lc[`On}򚄫 G뎱zt^v2)?;Wmr5ocIz?Ozx{&!ez."ѯ 1Gg{+ҏlw<=}GݽFƨ^)zIpG K֜{{e G12ۭqiumf>.}~a? 0 0 [u+7Svq֭y΅ ?ނ}XwŶv?ߩDZۓ-q/?߳=<~#>Fk"qzrQo 9r,nY[;o:)@-`ק-7({߯S@µK9֠ɸ>:n3 _[_*mtcmC>qSL=<6;ǫsaaa{xˌ\ފpx?0׋#5zяc]x^l򼠕(f:~٣^lin59W~\;?vn6erUbS~v^U O7O(|;+SG4|?f*?rW~2oNٟS9~daևmH6mX[J~s.ym4ٶO|Bd/b5ɿyU? 0 0 0 0 0 0 0.P~*1@G\⟿KrKXs2(ߥ纎J8'>X@▼QQbqwx b)_K|v 1M6kee-2Ǜ59?K^E~9ϱQﱮYF8N?~;:=J<-tĒyNAgC \NXKs)'^Kg\~2}6}Գ)n]Or^j~"{p29w6/.z-v:+M{WJYZ굢`% Ҥl9ힶկ#OUz+U?;sd~vND7*.Y+v:ye;8}~|+ÑޅN9}{Bƞ#txխsXɿkSV/uJ=o G<ջL'L:D]6jfgLz/+ؽ[{rCMYq~[{yy czA;w9zszWHVax3 %mkBTx흍) q ĉ8D^>׻gI@XjjgiЃ`0 `0 ?ϟ|:seQ3|ӧO|:2|.};7eGFO6_Qv]T]^ˮg{>pjzkuo{yye?{-x/ D:3D&򈼹e^Hyi#/OGzϪ߯_~ :sMe#M3Y#=2 QЙ[\s=E8}E>GȩT ڲTg-}VfoSVwzV}./>~!?U1<#}=F[ ~QڋBN..+푹^edLo+[\-k dW(}6q$#?z6Bөi?L7!3O_Q}Пuo[=tkȋM!'}/Ƈdr2_Cﲨ: `0 :8o=+8-4}۞cĥXdq{bUq©ήm!ƶg*ΪU\z[GA=^+ru{LV U?)V>ғ)x|Yҁgi\yi^cUo*= !TY?rfgWsʽVn*VX#=Fϫ+[F~yH\L~[O҇h5ݵTow|Sfӟ+);F;:x )/OS yUo2e)Ve3'wgGg=J^`0  ľu kU,Ksؑ5nY,bXw{ w&3QהNQev ]ƷgcH˞i{A3I8hwduwUIWq8I>+@pQşGcZ\ƪUߝ]/:3d;ɫ:gB9R|GW~w2;fzt|+i5nΟgZY|<1NyŬ|E7k?z/k><=Α}N΅>uWydʬdz `0 *\?W8GY:Dgcg< 2+'W6qn؟{ru"wU쏘~c#T?+y{Q,,^qF/Xv8.֩g3}ȸOP ~n%hUG4(_sn|W}Tg&x^c,Fѭ+ <#+}/Uw8BRh_|33!mr\7U9m({ѝpvew[xG]߱?g;,nҽow8]וb?OV=Z_#ve?vN_WrYLo;1g9pV^G~>[_vNOS3 `0Q[ veO\k^8֔v<Zbz\Opbn$~}oz3ј mK vU]^iNWA#x딫jt q :E= z%օq)CcYEqyRG-+u (K\hP'*^ء^q=m=y|Kvūe\rȊ4={W1;=ݷxp;o@>ȘT\Ԏ+C=*ɫ|GJOCW]x1.ﵠ9_Eб Vq)v(ʑ}[GwǺ{-oSdו_˞׃2;iT&w*w:g׭SOsj%Z[~_˯d֮+w]7 `0]kIu+eL]ւoA^;=GR?v쯱;<y o$N1紈=:ߥPVu< <&3KyC/4r)i=*/|Ύ^]QNН1qGw>ù{ ?Kv:A}E:_n+{u=rq͓̳]>>d}+|L01`0 leg:׺񶊝`W,3O?]\9P~[kOWiGc~)-<w.3q}'vuw$Vnv(r52S;Wk_Kϔ8B/hEՠ'9w?K;x:x<|@cϽVyc@ۖSw8Bq]=2lBe6V}eR( VeZT4ade2ޒ+nYBTqSߔ<[&=f[|szP)G}{Zׅ3n7jpWwftEw[ǽ;`l? `0 `0 `{~i`oLy>uoi\qK|}7Svu9G쯿c¾#>,jow{ՆݲL=mW2u_8دjo?kD߱mw>#}E:OۡO;y`$jwymkBT6x횉m0]HI!)$FR?6c>>~sm+vuՑνYu8uN?WP>1JsWiV_uKEϸ/rˆ_gKW]ױEYcl,[TYHT}xL#}A GV7^}>iҞ-i;}LJX&TP3T#ߨgJl e'=?͘ona|7>?ǐU%;/mN/IfQփz{G}?v✽3X~j{zTAO^ʰ>?sy|G)PU{ ..T}6ڳ-F`p]k߅~b  О$wݓٱ|sCoA+q3lOx@(0a+? T,_7s\Ϙ^Bl1)C+k(FyN"8dPC_9>O0&l4Im+nwGrŰ)/tihf ѸX>E)<,6s45zb?J\<OM%O#(76:= ӋYAƒH Ls6MXBcX&ǘJte. 3.je(??Lj=%wZizFTx$kP8Em jAOހ>~؆B9 ֤8UKCvjbL Cy ;mj P. DkwUE€3ܨ8xUJs\ɟ+;}sFQ(KIXݛƨ 1 +KdX];Jģcx$D׷X`i @l̏rnm$^9΄zBGϞQ=nfkDe; <a>,⢞jk0B[p($Ǡp4 nq`XƓ vϵ.xHnorJ5Hu뇗 f a[Z:>36[g RL؍?( &w.7C#~B{] UW 71jk~ecGrD.=K@WDZM0倐0\xvqNZ ># BE )&yA}t?B Ym(WIpɱ |2+\2 )l8tl@Z.Be񅋍RSƃm>dIl'N adĢG3%#)?$s _5=YBR#-k"qGP-e"f%֩-ϓ378M9ϊ,_*n;HEBƱcl~ ˝[/sagIE2,z1t:kLș壋G){7ond{@rP>kwk׽ #kXfyEAB9uM4P=_lgW؇N#_nGpp ,ZUu6ȓVӰ0EK7*|]{75F\ԶzQz! uH>upT٣o3P)[^6` -d&*=%fY<^ط`_6|h3ء>2 Pq7ώ ,NsjF=B` 큳CiU)R鐏@LҮǧmb<2FHRqùFXi䎲OmGA}:*u f:@ʫRH.66jcGOpO- 6HKJU:Jǃv,3DZEƮqq7p?ȌK%ȧ$;?Qr6pP7`a^=R_)m>D3#£ _' Iɭu͋C-Rne㯄ssL<ȭ/R)|Lt_1Lk=rr 4/gEr~PnB[\g[{gYvRW' {Fem1{ wL;7&$xc0 n&u@5sCCձm8Heft x{q(aтa?Q%l4ςxmWI׆GC1kQ3iJh,KRO`ʲ4)%b6B8\pe;u)ko)#WSncRx{[sXv195_0Kՙ7>Tp5ٴl3S"؝LX睫[5m Q="u}pϘ*xbՉ#iM+@Z! Ϯ~jYݬ$?5mtu] %@݅:4h8ۃtu3; ΑO1A/r R*5i&j#Y2:$Z(ad@>'z L뇶6Z8|`6"X1_z' F-я?X^ A:?1;h/KVB' vOnFS ƤQ{=kh7MwXQp\v͓O/. N3HKRlK"q^Wh1wt h@3e6N|I;y?8t[[! $,ήLe"z%IކAkRl!3u8ځy?_W)AbCO!rza5Sn֗#<43y6"R߃CQ&>[# BHǽ{vekOTlq(UH͵h ݔ8,@tՂL{p/*L"d_y k,4 G̖bD>,.ok"D;|7[.DCA#ilϟI֬Dq]+eE _-- ڰc^Lq1~CCC9gNH8BkhJ#Z-`VoMa 9r$պZ-hkh ?C$ ^tď9d(8P݅]ڶw[wl;dn׆oKd Hބ(DInI M_(5)6H/Y1 QRk,nXHʉ?>df&6^EJmt{CCc`0ʅv5x<\9Yc}106"״!֏9dl:' 1H"z'7QqɌ#KR./CVgQȬ\ `?d1yuM6Ƶ8ZX]8^pwQE &1frRKi$GݜЕh3'{;;~FK37ku<pdʎ+C RMzƏ7)nҀ lEGyl:̑IoBS%|ЕsTulebA}Aʹ10A{KʘӺtjdLI=r PRg_LbR Şl?␔)![Fo wi&k^CV(t@pW2{hxHGRn͉eCbxԉ6GQd27\ثdS=\Ff*0ۣOP5(rZߙxQZ>~GAeN-jY7Ҿn;n?ӹ"Px}/NW:݊&׾:x" ꭥу;R펔 c䛅љElmG§a= h¨BG_uYnZ쫭FYs U"zM&:Gnu.DX5Xn;}ԫ%XO?~2&Frjj8 yA*W I9/ub)Zl: s 85J>~iI3Yԕ;:#hELם[ROd^GA˩f~Y!En0~/A Km>^WYq"<цF*c:xw|͞w%ehRgd9̕v3v Dgh>>?3hYDkgC(ʹƒԕSԜ| 2Q94(?OGQ34 fccPopTYaW(>@tX4`LGٞpɄaŰl\[9c26U M6f,'C4i?W~psϠ?kAKrŵk@I|>^xs?\`,D̒5W^w DMXf_8<%|8_왉pP1Wlm߃f?4:́_Ԕv M;k:p_sj؎qw]$F}y ,b'N=o0, ~M YR46+!}@~ujctCP.Y(x׎z?70WXFܣo3z0c8RGg0 TU򄽻w"/4֏CQ`[{Ocn]+{{ N!33+5]qpj' r9FDȬ)~: 9Gmx2-?sraG"yvUpa;Ră A\& ?#n 0eed~oq嶭!!DzP^H)>oȑ.ļԶ=Hy7S-M ?8ycߧq|#5"2Б lm#UeΤVbM͘jAc7Z ]> 4gb s 2WRsKg6 's8qzTT[R[w)I95xWj #!nN+zPڔ KgTE,?{^RDݥ=Ru^zîc&D'i74SJߔ&HUG[crͦ<׿~4}څh;lpAZ%XZ;tQ?yk1+Ƴu6[ Dc4Ɯ*dB#!}e>samhG3c^8u9󼵕⸈߂UyB;f "Yi=D =4&|C3g]~WgjhSIXU"1A5Fr4{AljwTt6</N \Rta| i>T.Wo>>xϯY{緷m,J{gg}v~)]s!?wXGFl!7U|Cnfﳅ:.@mq%臔Ru?.:aBֺE#Gg'yXDuSWNJD)21ѵVagWPqȒ s?¶@g")s\T{f3go^w:^"{d#!φt},nyWFKv„X4|VB~,˘_&fjp/WԍwaO H 3I`u1ͤ+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_Wݚw) IDATX}uoLLL˾d7B^v!.`"p Y^"uhxjKR!"o 9HHȚKyn@-N*}u?q C6ǚz Cl/Cs Jyl7o+a 7ܻ$-1;`"_䪌քFCzfNzow>P LR.R|gW7Mÿ\ǐj jtI(&cwM F]J}rQ\Pc7o6ѽ } qo%X)H|,9i!غ0@@Ъ3$On%NjS?{pIך; ,iBѓPJA% N I  3>31/UA!u(9ځz#TJ8 $PɃ2=6EE+s:X*@&O}m0ta@( >RD?`ޫ:{/V!U B"i2\b|4L᎛-;hGvXL|\:$;~ AlU,v'~&^7O;Ս? Jb97iV].!? 88 F`HaΚWZ"D4sLۮݻ>ɋnHm㈸]4-GѲxX?~:+PyE@ fAK8C3|R)ĻȒBӳM_CWӗg} *mb;"ә%O5RK/#UFyH.e_ޗ7e,ѕ, }R7s]LuDuwlwOĦ \yKk5DQ'oNW]3IZ4C|Vød}KƇ>7a:#일q9 ի\}+X!ܞ8_>s_9oPC<e[tE^ji&B&EZ򾾾X^rYvptA8H{]0l*=+)YƫNs_+$y#XW0KErC?#"066mC:`TP((Ȳ(d2pdHB2UH2'H`b1)A\K;9lCm( h}70KElFu{#:>_W6U}Gx{8YOP*TCMɓ͹UP8DѣFcS39q\2nA`WHP _qP%JZm@"ZaSOpM`Ke" --"$A 3=8iLbsw\Y`'2["̏H ݋ܐ9.&N6U rvlC5 ۶d2Y pA;wقر:uvVg7/z(઎fzV^]_e<~+],;Gd 11645cǶGYg_{8Mj{~Ws+* Õ+}ّpa_[/Z[WO4I&A#׮Y̜Ǝϴ|) C! {>{9ov=IENDB`components/com_sef/assets/images/icon-48-url-update.png000066600000011057150771655450017111 0ustar00PNG  IHDR00WsRGBbKGD pHYs B4tIME $IDAThyt?w]ro@B DDRm]jn鱝ӣRΔֺ֎X "{!ܬw_y{Hv̛;=7ye/~~ϼii*~Z5C P8('+5;fKוtX7MT4?1 ƭ8[LQ5 8RZt&ya!~B fndmQC@JnXe}*6]"q]@S]bz3T<hB~ͺ $mTYX'Śy̮Qp3o]LG*̚Db:u iBx\ZЛLi~%Mu}˵m]I6a9(-ΞgL N~sDp3A˾4X1?k'Z+++K~-qv&I9UE̫b=l*Gs( E¢:XBWga"}Rn,@}ֶ +zUI;l:By-^>&ޞ$qY&(-ҙYAJŝ5&$5pdU?s?8*&M=r&I[g/p;Eيڐs kCC]ёb[w~͇L+vX͆1U >qN9/IۏRL*S~ |n-֙wG8,9})!g+("oB}w\(PW`*^e8㐳GGQ[+J'C(Ŝ"ZϠȥ5u4-#//uQXskQ"\P4U '0ek*ZƁQE֖ybY]*TyQD:Mҏ%|zI5>bҢ95h:qK7@%⟗H1!"HY vze3 FnQ<2ꗳ̽YH%PHRfVanoom deRE꩗=ڵ!7{,kCd@ AOܦDK|k~aqW0=lz~OshlF}VhoXwzk+W`:. <h`q=BK s57hCh7sZU~T}q$ņQ:h:hZ^˳"tD@!x;|: 9zi z_1Ef 8a7>^/bPmN{W!Jemq祵D{g@IP2#+#*RU ǣm&?ˋNl`Kpk-7~.];m4l=(L~_,Bj E!/m2fG8 xb) I³C"cq]$ܱg3q Gtxykl߲Ꮟ'rkNdb(iSS> DJP{摛?;ɦvr X`f{:Y,  ߸d#1m4]3'Ϙ"s I3Sy*?V M (4 k)'ͥV ~uBEB%Y6K` xHM@{^IӲDG鱢$]) $BR(hs\,]z>[_Khy|rKpok i)KA$I,v'hI2ΨA+ CSB B9jf}|/E5z x9|~3<^Ú-/^'۲RJ:=Ȅݲ*)D |Cu .$:"})"~|E>H!ٕ̮fjKd ,YXD롻xٴw3 j7q|W 6L2uɚٜ ']ԧ7G<ӚC9n050D~044.eKNIHNeƍq{[45q^}SK@-96d]LŴf&.Gf;<ޭkwU'PMI4!ёh8$&хdh*,KxyIe?Mֱ`s|\8:t=/>#S܊7bҙUznvkYu%?ѵ2gghON~,#4i-.b݋ |u 67к]] +YM( #z+G N괍-[hW;t,EeDS*ƈ xz#%0X|9=~ͦM7OHvFGPd6r;oX<8Ew-Yx/_7ʼf;m2/K]ABZh24+]It S!lGBg'=hBG J_ V;82)I@ki*prZ~xdNj`z!(!4eIM9H(0@#}&ꦤa7LItD*#]}׿:b_7w%jv IG^骸d?dJukDSB˂Vy.bZH %|9߁mY9IdQy:hl{ >؉T&-7z$Η]~eM;~S=gر+Kwofge/>-$*$9,[Q)ӊ9uC^l9=(St3j&S$ g=<{`WhK*rͳU_}^b[tWB}uU#4 S6hVTYhte au̟߽plpYv8}FbW Jeu"Ù\** K` q$_zuC*HQ\ 5MOqesr9ҹ8#=7V=4jS4-ɶWHG½rT<"eƩ, rx3pp<@~o⚢ڏdW}zEMH {ttl!kpUN,Ɛ\Eڗ`bζH=[ uL_s?4q°:AOS3D3  1ZsO,Ziud@g76n{Zz3';D0ڇ4Sһ(H .$ZrCQwF`vz({9j"1Jk-/2>̞ u1H|@*G{7 DF6gp WtA1N( Vʻ?*Ay-0z$t >ڸǟs)an~dJC>IENDB`components/com_sef/assets/images/icon-16-sefconfig.png000066600000000727150771655450016767 0ustar00PNG  IHDR(-SsBITO`PLTE Ůʨuɗ;ֽۿ̵(߹Rǟڲk ⽵޽߹Yʝ tRNS_ pHYs  ~tEXtSoftwareMacromedia Fireworks 8hxtEXtCreation Time02/15/06jIDAT]0 C. *9k!Bj @-g .`b r0ILc EU)Pun~Q| /0"0ͻã.֬l]e{k%tz1z)&ԫ v{pIENDB`components/com_sef/assets/images/icon-16-help.png000066600000001751150771655450015752 0ustar00PNG  IHDRa pHYs   cHRMz%u0`:o_FoIDATx4KO\e@ǼÔ@@C)Zc&n$,4Q&GqXݘmRXSJPKZ030{{:G'GS&x*& '4)jm{sytCb(kp1QRm;L$OB|ʖC>t۹|Yg GM$ܻL-BMXՒˏJ@lm0^5vڄ:!z_r&;;3? ?Tl:ݶXX)g:,Ec8Gshb@J=Ȯd*8տd` TcUsy4_GiW]7|/vwuu7xzH@5䡭>zLwtyW@{w7_nn09o+gYF HV\_twi"V:LHJ[,{B<&_33Қ E1vZ 14MP]qʦ50 $`H% fnvզ6BkC8+Q ;>JdN,U" Bb!d\9 lU=#╩ GF-;.[O ]ۣX)ڐ.KY4RױJ+7iN„Ź19)a'HfC'agG|`v|:&먿s:{_Ե~Q>ͫߔ{K@@"@<`W^ioI̊ŭ5 Gs|T /(ftLR]8#?Q)M37-Vl%IENDB`components/com_sef/assets/images/icon-48-docs.png000066600000006303150771655450015755 0ustar00PNG  IHDR00WtEXtSoftwareAdobe ImageReadyqe< eIDATxYi\W=onwkl;v 8ddF hw4$ fĠh4`LH!Nӻ{z۽{_<Ǒozk6x'o&w!plk\sϢ*|}ކi :g5X~";:Yc0ҏ+&P[ Za4\~GA'8~gq]*jҘg"Iҳʘ,ѣAkLKp(Z *U K!$T7$6 >-^oԨҞr<8A."M͙Fy)دBInNV{-bH grf6[Ԗ׀lMЗy0aZV:xD}$ XBGb9;c D~~*.0V{!}"m1(i\Tښ!!-tsmvð Nv赾Nɡ(9D8I,[sJPTNq0UEK0q$VBFIˉ"[nB.^X ӝχ?"S3^,ROI$љhTq$v(f=lx!}#cM(ݏaṚ)` Cn@l,5C"KxX{uG {_෗8[F*OD~QEC$cg'GC;Gpv U:s˘k (mjkha\35qXP-NE[>v!gv"2bU©(/|Z|@IYzcg9w{_*O¡.-JWgb;X6IUdK0N oH2 J&l7#YY,My| ט/aET(_|F<Aҋb|xqϬ@RoIxqK36 ɒD#lr*7L^WvTuC 95PI#FDС"͡ EjۙZSJBVNXϓg~"s#6N蚮%6j6[27Ê{S#QpXJHA넍 8V#@PD`hk2k)8IY7Sh*JiP1;սG )@xȟ/@;<;a:rlQ$A&*T(R4pRrk!vi\mR_[cxQX[#R58! P2;򒡬)ZU 6X?orCU.v3,:nrL+ZCŷ\^g2fIBp<~I5cca"2ҪQv[$9UW' ZLVg0*Q-˕e7VZlU],\Edd,RFiN=,#4k'7ߒ8zNwU`Mo3O}Ӽb^Qu/XfjIme5SC ˞kYFD$Qk[yZ;ϝnT͛]W2ĎSsޙ?|3Fi5nme6%Ybj;=/I j緵_m֬-_ՠZaP Dl k2ǬV䯞.}}VFh7'iJVgX|[x`q_-6qEz|[}y>ٰ֭͟nOqH s*եEzKIPK) ǁ8ékvKC ֝vat6_XÐf)UVU3şou|"SF&cG>_|ު]; +xiF6gK梲+6-_[9S"bKPeRp}< ?~gΜعIB BO:'OoQ؂F(yIENDB`components/com_sef/assets/images/box.png000066600000023406150771655450014441 0ustar00PNG  IHDRxy8wsRGBbKGD pHYs  tIME "86 IDATxyp}?u`'Io.ۉ('U;ޭMRIm7&T8JʱdŲX$K%Q):H g0gw @ Eupfg~OP83@16!AcLb'`a!1!D;r.?}+p09rGx1!DIc̯:.ď 1<+"|1>[O}ѧƘ_$,qcYDHzm4Zo|Zkic_c>>K_^ d8?8pmBb֚ںZ*[O& 6z295ĤO1m[MgGpl{Kb7K^Rrzֆh4ξv3c[î_笒} !c~Y{MkkRb:}J/K)I iI355-lm;RPzg9w|11}`Y[^ZQ|νJ)wjjWCe m21Hd h61XE"SSRmzO}ZwtvvxM7B=Q'qo&p'v @ !1?chH&imiޚ=$TwF%-7~7lcL;q۶illlIuv1h<OillLr> D"Ըꍰ~}%kq"A~_?>D݊uozJ͚/4h c )s sxM l{ Mr#q1dݾ\6h ! !+jK$q m8B.G8[F_E0e! DWv25دR5S{^U%Yzw56`6Tz7]T@+9ѭqϵYo蕁BbIǦBx7_@aԦ譱s$ɻ)R`Ybv),bN8 ȵ'^jNm0 6h[[FZk^8ywGFRڀ@ !$1+%#8CĮAhBHz,iXҡI`K]CJ`d{ ޲&&kx;?< M6 Ԙz]J_>Ap#+RdaT/ۏocLiFA(,[df<ӵwUlX64LݽO}x;Z_0$U UմFOk߼Oe ~nMŏx6>vNI*BUY˅UbEtoʧVZ'N-o^y6V5Lf]=@w~=v6 u&2T5蛭&˶fC ND*7a4БO_O.+TϜ{ӃXVqO tu/.달Tnw1D#Q&_ _s $th@хgz_/!FQla:7copd}6;>wpOyܾL`h "L~zRlp ɟ*Y%Ó<{+ UP7UUv&w&??d3H!εd9p?UW>﷐.P/oWdi֘`>֚ep%J{+NCSߢqQn8,f&?#7~]Z񹃿Ooӭw2Eъh32Ek WwkwIUZŸKzQ_= { Lʱ)2BɎٖtnqܚ';#^TcǽlLHd& JqeYNor-BH{CF|rb*7co%y7]P  J ~oZqYՂ|vH)}CSaf,isz(o _BBpd"s[҅W*3 ͶAVe@Bٍ1XVOmTPa%;8X %sr[dX{{Zs[/bX'$xSu6 ]I~c/GgWڲXV hzopaO"kŶm[\NɡkB`YN%R &3x1ĒNՋGҊ|Vq g\L*58=}}QddE Uotlq\}CDޝ]dLqZ"?_3GoSPrE<6;BMta.]\;ؾcudyOR%qnљ91 EE Q`-ʼnW(xsd)fXᦰj圗=;[B}۶159IP`n.ŋd3slMkk+mo hr V|ѩy}(=lsC2r-? M}K 癞&N)rr{󘚜u=8mX\y.E: Pbp{ ˼>uW- vZ!_851H)C0-lF 18$*EEkC{{;g֡V뫞ض͕k1y\n{n::O:&j(B7(]R zԐGM2YrE( dLRHS950Ekڍ!RND:hP{LJPc۔ k{><#53PǶl^]k`pK_ad Ύi] M37vkZDm!HPW[G>Immx XvE6%. k0Ydc2>*'WXSl|<=TPBUiK},d/PCH"W.MF:%Xk A۲Ţ464F[G  " ax!X(5zmmV|X4u|BU U+Zx0nl1Hˢfx:FwP(gO5ʥ.>,D0F"455m6zz{imk&@J"Fihldfz*6pbp1ŢZ>9@PfS `Q9.~D"tuvgr\`xdL&KQ(Dļ׾^"aPʣfv,7Ϝ%_cyK奐%좿>䘗rrb5qjk=r,ƀj%YbZ{Qq,8NPJ:m!CTFxT68h4Fww7{v&&VSinn O^Sj 9E=399a%˶a}twO$zUZ&Y˦gÈ6G˶ɝȷpU8 6>$D"AΝD}KN2dppKHSAeȩhuS3TV`8\?J-pւiinag_{H4R !'j05&o{B!86wZYM&X|5h޼t5 J޲-X]K7!,ۦ{^I^8/Zd6 xo7pa94K#LOM&%c3Fp\lhy˽͚X4ZC*7G!N!,Kfz =Ph,ؼ{hhl(b#^g~z.\dbmS)9n0njkkor GMZKc453Syj< u 󽸙Z F8wbW.Dy*~ {{(ͭ--\#Jz.:<Ѳ$q'}C]2Ix8ڐXkNpf!\?o%H󂩷q1 J&ۻ>88=ݽtuu(hml )d8tvͲ!oaJѱ87VPs}(455sˁ[ޱ=K Bi! A6G) l߻ecձjljbOpfMEQQB(lۦR􍛉U֚Mh L֪Ց *CF0Q E>';B: BDٱ؀1j{cp]?3*(F{5؂8W"sų9-<+6+ j#;CHEm]r-&*&|s<⸊\^Zp!;CKjBwYs-MıMScg8u A[6Zw6y>]-?eJ3|F϶ :l߾LmGPJσmzҊ9g~@W@rat sq;whii rң{ܥv_]ʿlab~* 6|F3z ߿{PHT0ia"BY)G-WmLp8+T$c{V FӏL+&헛)EhuM[NEZƶrشR"Y\J h7RbYj¦<~%@GO.x'-b]z;hin^pzZݞUBfgg9q8T^n=xf-6e03=ͩS;۶Z/11<*rjfcEt'&|m-iV*܃J?RHړBKq567Ѽb3 "-d6}LfTh9s$>(Es=x vҗ]-'Nc?`6Bo?m~w~[Ȝ牁ՆccO_6f_J- Vq/עSn>q]wޓ(pL L:ͣ}th| |BHFGyI H)[]0*4R%7 e*7ĪzkI"˴cG4z 'N-rs6=rev[0)((%J'OVX_3XRb 6SƲa6Z^t5A2.=MiTDXRBvl7d߾bk=E78U,e|a]}(ry"֊|>%603=VtUi8BWey\&니UU;G`31ʳzw]-1375iLl)nm"HFCBb{ w 実.MzDFu)+\*K155TtPJ180Xϟ `vzT* $ROPgc2K_j7C2ڎ1!bcwsb 2QƔwKtyBR=޷ˣy1;;; |^122(gL~EsӃVPհgΜ ]u/_||> {MiSVһs'0[4/8aZҶm[Hͦb#qUm()- ֑)~szIDAT 5jj⨚.F^dܭQZwc$B=MMI*߅.D"~ss <ףhikm-oA5d_LIkkh,( Cu 'VD8/0^FQ^L⬭geiluNJ*xW9 H)l' 4tD"DQ &Zf*tp"ܥ=!Y__^taے&DʠJ5ҔKDD$bX h4Tӑcv5DGɇ* 1ؾE"}uN*ȫhb55h?ye c(o&PD|Y|o D_% )V 8%' ;W=(VT:s*ynJ)u}`XSo$Yiz*k-jh]PaVeJ)FJ)FGǍ1v6{:Ţ7*M0]~W|Eyv }磔eq×.= "h$l {@.MS'݈6%[q=T*tNd}᝷w?K~u]{-:CiWMn ۶Ź3gFs̫| z##""_( ˟0~JoE7BQH)y7'|G''Kvv`ͤR2/v65?Ea1mSuIc4\θEW!I=7xK_MgJ^ TLj O^ٶlKkۡDm|H)E:3WCes-ͺƫbSz>7J)!ҥK}/^. m045425ǎ;^WL%mRHQ,&:OE,ߘ'[ڔp4Ik T}ߜċ?<݃tJO/~G>v/ڽޮm cD)[*yA)eR/t雇ngP%E XW|v}~};; K2#{эLeY ##_{u'^;v;ScJ6w1=c*ߜu|={knllr0l雙/^z+ώ]{vzjX,v~pd8Ppi<{h!m] I'n A\.ͥKtj3sse ! K*AK}eh,s"z۲['BhCԳgI)R1`۶bgw/y`IIENDB`components/com_sef/assets/images/icon-48-cron.png000066600000010325150771655450015765 0ustar00PNG  IHDR00WbKGDtIME 9wIDAThݙy\}?ケg^%JZ.t $0PFHƆSl]8&!E9v 0cd]PG|Ra!!t[siϙݝuwx33 I*yUz޼~~~VT󓄬4W )JK^c !#Bȣn^Foۼf#5s7rql2:kn.6wq$*}U `i0Fc*=N.1@fଊ?;H)λCg =IZ}֚D\"`& 3!!@D*#"hc1~Us`ʹw\ox:-~ɇSxk7o|^l} $5>2mWZp= )%mcKF+\PJa>:C$ؿ3L&!%AXOѿ3xE~&͒dHҐ%#GбbhYۅiXE49wײWWi; `/N+Eo~&6 "X2{z0dJ)R$cp۴^Nu[ kWp{sc.1[4fښF;@w9w*.Fu­ +EƖ0jχ}?=USm4ZkV$ ǩ|i]KfA>l\Nުsʝ&j0~_ۯ)fF'LoI3gQӱb@K(¸.FR}e{&m,iaYVl[65T/bC$ N='cNػb]Vxg}E̹ݏ|u#5 ]ʓVȂx)-Hi ug!tA:T-]vg|w溛k䫇U+j`ohNa ]&\W" `[6eWH) eO.8Nf`mn?647Z11}$.VGaO0*x+({ߒ4RHH) D.Zx3}'9HmNf ,}{e! ^>?H0</mpW}˔CM@ +?'hcH $!X 3z ({+E)|^t9?i/.c P&u+a%Kݧ(-$InH!ڵRmn~XDG;+N`IeT?,}?ey ۹k9slTecrʠRp˲PЩF81L6%V:\< rml∙)4e @ (5oǗ_K2k*WUi!,'ZV ky! HD/`4i[$AGX${Y(_~cw 9mƭy.P9,IQpFI(zY];ۤ Bz@ccYsh &G2cITBB>ŪU+&T;/ͷvՓ˕ j(x\^Nń2~ȎM &!JJZj+| ,dm:hB/5K.!ʖf>,IIFa MQ=l:gXF D@A(W!}Ც !;Xpc76vjXL[SZ9])st#2{oeTa[hmB aBH.dņMgu':;J00uw|./**ԭKP^)FƎFI^$^ɧCA:䒓]Ԡ-i=~ضEhjj⹭Q 5['91}ص{OE'Wa1z@$"y1à*r֠!P]u0a Vn<\bxt ɌzhںZjc>oYֵ7s0:ELJ0PCmΜ!8 m&B#@hg=|?moYiFJ.:hE ذ@Ri"=qgkuU1z_UEuLRO a ~5*ziiA(*xPXUBI8 I ! F!PCı -F}0}gl-| KTE%ѥjH1!4BHYޣF㉾D]] .!}q'KsOf#Kߌ:lDx&Gl~јHRCZ kZJ։RnaŝR.ZuMh#&ҾGf0}H!xL܍31A Z/2B*enpW)":v|?`V(52gΫ5W\/e#'CďSRc8Z*euBO|ў~|Ar+.݄uۈu 3 j =a`t6 i.tIv7q}WJaNw}@Vtͬ$R~4|Kq<_cw؜BnCB(7>^ti>~+/2έ^'U?N`%zbR[7"N80]aJgS`7_% ](t_k;Wl{B/Gn͜]\=o#q1G#u4zܠ>PNi*ͤVNH`>MۚL DqeOXS2m nrmQnhmfu0 yD+0:Ǝz1uPVFr)d,q:AˉtDΣw!4gN97Roe%78?k.iӴti~llr_ 9N9Of<0|5h@H 8E'1>8p0ioeo M-ߺ/*\Ѻbi\cF8os9ȏ# N0c}gL|"WW: ./a=V_:r hk\4/X"lۀ&Ol?fl:wX.{;ES):'&L|Ѭҕ-_D\XKc Xu0ߏt,owqsYrIR\w cYΨa{ Քsi @3EY})KU!y,t0&`2ɛ#)w^kgJ^.. / Pee iGa.)_(ӂފ(Aʏp=L0IENDB`components/com_sef/assets/images/icon-32-clear.png000066600000004002150771655450016076 0ustar00PNG  IHDR szz pHYs B4 cHRMz%u0`:o_FIDATxė[lzw8c;@HHR *(i( J@H>TBU(D@AҨEHQ67ā4NI\ٙ98&N-}n5 ޹'8r1Swl iVš9b@Hp@kp+DW򙶅?F%d}]Bsrg ;.pdKhHË/ "}YTmG8;~5b(fK90Ll? (dkj5ml w?&݇?DoH˜= n hn͞?W)%W4ܡq8+/Ţu3_\mhA6kT[c)R?P< f.]cz{Z Bʠ)-Y̌0FLjH^ }JJh1+:NBJ%W_\Ӓc#=YCU?FKqr'{)G}?x"V=R_ߍOӳӬ\uf bum478='{\&Wuq,zezzV KW5\{W1ms9|8^Olʷj 92#A'V=D]>nZ[}q7ea{}g.mN . }g 1pޞG(.G~XrY9 /T)FǶ$CXf 59uc;J26rJvsj"*Ë 4_@Wח ( Q"VBE 5_B ~%aQbyt-JFxMy+Z!aa"X&<t+Q_`umұQ|_McZ9e y,ۢF97xhbQ> / =P=R y!ugc[U"T,}9" QuGJrUJ!aU&}WXT_tJj2j>fmk|)PA3LR#LT=A%"-X8c(ig{ T$sXFjǢe?^kD)bB:1L:~BP2Os/^xpl ZhB UM-c6*QfD6y!B! D 5J5^%ya[8) t-^X?y$,fY!^ n1`WwͩNhO ~: ]кj#"0$ ?ڏaY ;i0̀Ѵsf€}U ?{66}jػoFH#Vj9{Ii]H`WU>Ųr\&w|\1 `e]XTI=Wn[fmMM`ΣmPѸ ¼R'53S.|G5aPM }X~3?[u}p||=d8Hۉ% \F d&G0g&N}H\$PT`w=t-z/#NDk0GQ_aiɻ^ ꂱR,~3'6W1av+'ř|օi4 ԗIb22%0A+jt@+{w͹1gcKg 7IENDB`components/com_sef/assets/images/icon-16-apply.png000066600000000725150771655450016147 0ustar00PNG  IHDRaIDATx^O`g&ɶiMA.<RêW+ |=EV²tZI2cH/.{c^yIUq0N:)Sa@iH'ӷ7|vY߬\t>15ZI@(Jo]qï\&8T| w'_&9\>tk9tU!{txm~1n7ۖi&lE{9^Ɯo, V?h%ɏT6R@o)1N+MbH FxH5\]<Ĩ 2QĄ)z6 A"DuWH/KÃ痽߶1NIIENDB`components/com_sef/assets/images/icon-48-url-user.png000066600000010554150771655450016606 0ustar00PNG  IHDR00WsRGBbKGDC pHYs B4tIME 6g6cIDAThy]u?{[; dA D 0P (baQ)u kPQ(ѱpu-' & 1a Y$ݤӝN˽;ǽN@Gu~={~_ޗC/\z%U؊o4ޢPcr}<.F?oߛh[ːoYu5AMƶJBPx.p{q *SՑ?!?5-4F/~ (Ȗ|ʌ\lRwdu5R xghTFE~?)Ҷ~˒ol|#7G#鼋Rmu{4'#l^VO3"Q"(,Kgknű"g|1G~Wqig߹/T^?b)hNFX煁"6 ذ+ɅKcڸO]/ҀnQ G}_.{@{q)i})(U)Vǹ~cŪ(ES-1xp 7_Eܙ?%qm ˮA{H]63N-/ojPBŇؖ"Iwcwm:W9 Z}v)o(4 ߀//䫆 ._յҟu98R;cEKX0,xoX|8(F)5#ő^S|+aٛgS/a(^4mne VhMٔ=C"|/ӹCr3']ID8&ڒ"E7>Vx/~Ʃzfzc w|t+bţIB@[f,k}(7]܈kae[ {Jˈ5[Z嫚VGmG7/g"d>^ׅCXvdwl9-֋︪*kʸ=* @x%5JQ#ɫXsf>h. yD{>BS cvy;xQޠ{Zʨ,]@,0Q)\-7qhģ3s-P }}(s$[/Z*VuiH$~ɢ)CG>zHHSi5h[m7oO ?^A^,pˏq2SNJϱcA#!:H&1tUkWYy߉u & >ycɀB(îCGE`j ny|>۸g}|l H6 >L-,Ɂ.y=MF%, OG~H}*bXD\D4"s2,R|%DqyzWO %Ba#&C}s[S<N~*Jdژ57ҳMgm ehIXl8#ͥ;({ta=h {V B]T4)K6ow=I`qF Ʊ,_G)%Z3Pd)yW01˲n9@pg2NS,Y=B,i=qjeއbmMD!\±Q``-{>o]"略.MpZAssZj1O2.Xy U@%T*PAL R.wcw_sc&Rؑeema+m0Ԃ6h>)ΧJJT"*ҀTC*)r*PRh ==2]c/>a:eSu={^5 L!+1Xb Vc`+B<̠s4Hܴc"iMwl1.b\PQjɏ=z=nTKC:>*5UldEC)kqS ;oq:braț4 i3\.cL1U(^%[)O|e՘X?(`$"A6 Q 9=/쮳)tJɆKߡS˜2Y@p|0]pNy#uv14YAie4xX&h` 2bFccx ʼni$Ȧr~6)ޗʮT*!uM]n5&\ D=-'Mz2]lÚ5Ŋ%RA%Z`$;>Bq(5z,TBT6c%|7HMww|b6vNJ?y]lsQ "(ePF)2J "kVXCeTT8$A)!Ųlh񫸕>UPJP _$}ت}hd=@Duc띘ѥ/1t?iW l_ "avQ YM0NyUuu U#ZYϢ5E%hњLtzm@=ƗAr'#zO+fݹ`+tù ڦQ>O>+jOTrcX95Egc5x>Kµ H%؍0~g:t`DaǷ0;8o>/fټOh00 ,j%hƕxI 0のb܌E_?gҭ m v*F4@ٝd wϪ|k}M^1@̷6gV&هLVkctXֹ.zjubȑ>z';CLEܝX,M9kD\?{:^Ϫ%]teɕ8:9F~sa0c5˜W8fIXGS5o}vs_QǦIENDB`components/com_sef/assets/images/icon-16-key.png000066600000006620150771655450015612 0ustar00PNG  IHDRa OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD pHYs  ~tIME+6 MLIDAT8˅Iha&&&MjBm j^ " /^j{pCE(ZuC (R!%LCdf&źb~y+PCܟԡD"a/0}*79;]N{tyQx\21Ŧ# Vz=񁾎_iZJI f^Mq焀{~"cUןIiπ Fv!d\lDk<R?ԡ^uW8}o]  @y3J:Yr/\P*␓S87# A-ߥC=30 u >7 Mf.g@DׄLXxLpa @@EcJqwhZM4E!y&L$n $R2:{^fp]?ڝ _ $[) O^KU&gER`FP@!>GM]gzI|dEK咷g^Mr[7RiҀ,e(i:y=t`Ս22w^-mf!v4zW7{IKsX ?TH:ua[C{Q-qU!SΐI1ĩT節e '--QGK)oNf&1D5v{\?wU-Ҙ4IENDB`components/com_sef/assets/images/up.png000066600000000170150771655450014266 0ustar00PNG  IHDR2?IDATxڍ h<si͒)N$ds5Deր;t HIENDB`components/com_sef/assets/images/icon-48-statistics.png000066600000005363150771655450017224 0ustar00PNG  IHDR00WbKGDtIME&$Gg IDATh{pTW?;ټHQ$4@ HuuG[KX`mGG:hөV;Vm@ ! Ivdwsw$HaUg͞s~|s;x&ؼqb"a,Ro ]ׅ5v>sEuc?>꿁 "ꁯmΆs}>_K{(*Rr\:?<̟͛_;Rz=+ozNrFYfMq!R*fEunYfmk׮%a$.-Gr=マ)Ka6dg`= )ecVQ϶ Om[ض5iS'f4U˚]ۋA`0iH) Eu [c&b1O#O@CC#+V`6-*9ɦMwꪫj>;iP(5}dkk{1țtw9Ar8b"O YN!&PE̎yYZ/_^mŚ5Eu~Сvt`El)r6 nx G,ƈx<.C|F@ZBt)E79g{9JKiֆ6/vp@)I8H}%8onW1?SE +{&Xzմĕ+Vz8 J p\͟ϼyXZ**m vxL1Et6FFxw[[uRBI)!fD9._h]⫯lk'&߯O1HY~v] 7s:q*%Ҷ,e!M3)1P;溫viӦ:uSX+#瀴m^9]vdi:9Lbb̫Ί/ەZcaҥ㾟ZueM]EEH!֧;#rI-b ՏڵT0=<FGHnPy`)ws4|ϧaUA MSԠWOr}k+45Y6uF_K_y=}e9#v步UCl0<V8BN[( b3 "ɀeWrzx8D p^I$s1fʕȾI33Zn*6l8B39%8"a4̛j,| ;&X)%y֭Cдuۣ{s9}Mzk(USBG45,i3q\ԗ omӾs'kEu\ ;Bue[L"+& H\ZMIC&H):mɩ+uu$!>̜nC 06n1T$4Y!ʖ%Ek\D_w$a%n0, 9zxwH$Bgg`\H<ǹ^fqExaxf{=|xBE$fkhQN'/ oWiib8ȣz2 J^TO[nش\1>RW]şvtfVb3ގ`c4u-AeNF9._NcmGy0]捻y$ys!7Rp:TVr-7xa+:mmݶ%_e׳`__y=%X* Qv0 Rj+1Nؑ@Ӡan 52)^d. MֻxaNc,ln&ۋ4Mͱݻ)c,/] nDžt0Mz gAss=FJxvx$ <2IM4&oK t]vxC/`b4/[q P`?F >'c six}reRBqSlL7FNKҔ$"jjujjv A,kXЌ )y^}LrޫdgM77e_0k7?<-?4>uڴ3fΚ azd P7A I'B^k(у 6|Q ЯjCuVRicb7 3r)¡?42j- >}i4vޣg/jбVVT~_<.{IENDB`components/com_sef/assets/images/icon-48-support.png000066600000010731150771655450016541 0ustar00PNG  IHDR00WtEXtSoftwareAdobe ImageReadyqe<{IDATxZ{\u>9w{vfgv/!Fa^u R JڤPKmW*%B*RUQD A^{Żޝyosww0!IQ\w|X}~~Ώ__HDBHL&I. JcS<'YIQ*se^k2S=@ ug)x<*x "߀ߑCiw"˂'&fy/U,$>,Eq ]5]D~\DRػA$R$Q&B J[m'%0BVGWc(QWў8ڡ;*ye3FBnRmS>xzg^ ܾA]&Ppxߛq♯ӅٿXϝugϦpCHX#U9ȫM)\g@iVDi=?2 JtS9[zҿй& &3lSiww)tjUzſfPni눝Ï=D@$?@^Ar8Ia;?Gx0M9tnKWt7:6 ] *r'Ykt+):G(P>&,-z"8TA.?C| !| ѬZe7: ##p9>$29p_=Ab(qIjlKhG"E"z|p%4a}^ ;U<8 PQK݆e[ła+J)zM$4f":r) hfHqnwPw`S,T2DuG4\:=!6Q> )Ir=%&QBۮK"Q:~ ґe5F"MnG-G'Ϣ0لԥV$-Rjdh7@m#?@N 7!0^CID/8㺞d(CcFBP:Uz*қoIgΜFbKto5Fc)jQ4d2In ק$Tx4YY8 @`I = , ϧ2QuaaV)pोZuv&ZT.>P֍reD")RX9 Gƚd਱!B39S|oP|/DQNdd>hlbYAC}߃CdPI%-{o2)z4@\pTR%1RH! J/HpXG--wWOƧ×D,,7֨nX6Тsn*qa$ Ì{*MfJˆ2Ed1H6}cץZϣV{gI9BlVؘ8NhFG~H%|dէs z8H#7CBѣԨh(C ߩT>ȋ,6ZeA&$PUj- f/ku`QM <&QWgx6esʥ:E]z)M >C&@5SSFN"#N*S0K9Lt(G*کq#z=h鼫 S%تM7l "zܢ =3hWLh^dTvm3mhk@q p+++5]1+ ɄTVi2rԋAaRE-ȥM6-Tal4=R^VF>V@/5Qp|9^(Dte{.gqq[;sݩ (1Hw|O7}Cۯ k,Ngyn4=oM֚-:Y=r#_=yǝ=#pJBaz4Po[cHvO#7X{RX#0r7~_Y‰cG( ocqODC鑣Gh7ҧ|77<$sxt=&Z$f*=EeF5eT@_bOq JEӻ5M mD gdl&T [xJ+T#ĶWR5QX)+858w|>6FJq&L]S_t؎#غ{8"}U#Vzݗov{_zփ,I\r ½҅Ukł&U|3ؑZyu`%B-,{qwaxdYҡ0rrLk=gv"Bޘ;?y+K?'io}| 0$RIENDB`components/com_sef/assets/images/icon-48-help.png000066600000010475150771655450015762 0ustar00PNG  IHDR00WbKGDtIME .,IDATh{]U}?{s}ΝG ɼ2 y@CDP*u!*hveU Uj K)HDbȃ@2d23y?<;d~kY{w ׯ 0FK͠b2 Bv2x/yr}] _/!#KZ*\Qm4M/qdd<2q8J z}ؘgg, s7e_~_$Tly]>6u820vڔQISUqV-&;twD963J zCK<~k/^esÏ!mBLj>gSxy7.|IJ ?{ב? ntN}]ng(K`Eky,J*:Nyp1@+m>ym9Wî׎{j-o{J\u߿wŜy͒?>32$Ml%$11I y<|?lOW_'[#@~}nݗ*՛}K"yGNimX'H )VrI.gK8Г l:0kGB>h^]nV3z֯Z="dAGӼ3h_G^<϶#q[goNklA-z#)j&e ![D ,I4$0 i"kkB\(IkMؗ[Yax'Ha4p5L&C~ MT9Ga)^<&xI",I}AdlMVG:xf[('l q?,MU!6l!qn:F+s\F;-{OhFQ{NdZHHۂM)AJMHFiP8̲1FD-eMq~oa˲X9u#iIOU_>Xzűk{?UJ]Oo@C)(,EI_d$Kc̫0Ը|BqŞo0 ʄ9Г֫w!jn{kD'+hsj:)Le a KjlSW"fI!%KC\tAa^kDߘ@cICu~{ !H6Bb,m!ir>0 C2ݙ74L^{+kV} j+9Aōw5~׭#p9kcӐR?BuIkub5IO[y7c\Q!zN%*FrM5w [m-7hp{_s,?0[uS\{q6vx~ ~\%9dEkC l6"@HҨg0̕5UӬ7Ŋ;Ӏ/? z~:Wi]\O3&tQoJ*Z`wg8mRrlaVm_oFXd<@ea}ع+[ψ'p< 1/Ac^jjn(SYfRПVT&A ϜO%ZH g4VN趣Y ǃ ;Q}"xk^.O~ xxw(!4I =#,`fE)#YEYIؗVs OS/( e38R#`Gk \ஶ Yy_:Q!%SIF%R"%A%E&H)]M"\<ϫ (oTŧs4_xzW{Wi _|9JcGs2;!ϫ"DXs)FAV  L>lfݣ#qPZQ4E,$ 5R B WH RXx粶G gbgy(B ܺ,I<>({| !1 iH Y0!HM*IFs !VHZ& XxX7.@cU4"BB0uJ`MC Ce@<=!,*u`BK&%ʲb_-h'1FdYDC_ @dZkTBY2z" 48:@wהY;fjsiS8x70Sζ1L)Ni—xm@(HMbQ}B@e {(lSKH}N*&[WIP]SΌ˭ C L)1K)^0hv#k^;C OjsťXWM~qjR'@s%e&v:FPB7\2\XTyRC`Xhc{9ŏJC=]'&?`qQ&MҠ!̲Xh6T$\Jr`ͅ\˗Y&ozC臦.Z~xtmYGl HHUg~X]iry+Ͼn}6Bk+jGHpoOJ29{wvtʄן=UInZRZхt^w*JM6HIAIF9\Lbo*gWyH*}]U, .j*J&S mG(9vw٠avo )/nj7q+>\4Kʧj~SJVO,iULRۛ9:vqhi0šXéόxYe0{c'敛;Ϯι}3w"ġW\5m_*≿j(n䜣/x9(rXG!V]#~(#Ür0;ödmԀ31+cKG߷pNu(4m$#!Cp85Dv&΁ fԚܵ2λ1<1B砃fNb};?JlfS:m]c[\oJ%֨<%ώsEsjY!?2cyʼn!vڼ|,OpG) +dߐJȉ/ݻpsyU W `IfNjٚ{ߴ45TjN":8F )BM ~ԞEGMҤw0C{Y'v~D^&L XZk8P$01禮X%lUv$CE:硔GHBHjb$,)Kbp>zlC{3L.:r\r:SB|@) )k0g\VV^Z3} U^Y.IG" ?َM&k3:(SذrCC?D.=٠7!Pdb$K/M V^ !pSv5|bݵlx:hy1}Q6|&ٙ(^+IENDB`components/com_sef/assets/images/ajax-loader.gif000066600000021123150771655450016013 0ustar00GIF89a ```LLL>>>HHHVVVpppfff444222888BBBtttjjj000***\\\&&&"""~~~RRRzzz  ! NETSCAPE2.0!Created with ajaxload.info! , @pH KAl:"t:JV( lF . t:|-C3z> F.Z? wE"PP P N O M vM MDCك   Cc 0H@͌Z,0HP`xXF "`*V`"@Ca2t`D D,5¤AT!A I.r n @?Y+N<O&,p` ,! , @pH 0Jx @Ĩ@hBtMBC#֦Ofƪ7;yhevw%{Tr"  B` `   ` PS_S RҨQmDCB X`O> =IȀBzq`0Yq1€ 2%bTa*XcFBPd` :a E'K(HH"*E+j\e( Z8SL@vE=A! , @pHp0FHx t:\`.&4bA (F冸D(z-q'7$vB{m%^_6  Ie M  uDž υ evTdSRC#! d` D $~@H8A LT RA*Z8AALD &\ƌ4hX!` L,xU(UXɥ ԪWsaB* Fb*ܴs! , @pH(f$ &Ĩt 4.Xf4t*H<*Gv+ GA0J>trnDmnq%bc yj}Km^%" SII #pq87Rc 'S uC '7˗Ccʾa Nc 1HD0d@k8DBQ@&6 # 7fAA!EZhr",PaG &T4AM)ZфO.TxC 4U*UY 0a"ԪW)pakڍ,V5g0f譋-! , @pH(18t:0 Ge{xEĂJD ǣthC&:^~E!!#cd$I{k ~q!%%TM  Cd"##%vCwC "Uſ66BR %'7SRBR  E`@AiDH0SDDd$0")9BHG |$ҁ 򭬂 .f1U:X AX *j$E1E ,bua1` /`ȘAL-Φ]V'agM ܽ|ҭ^! , @pH(d(&Ĩt(I@ ؇½\*t:Wlpx5 A0C`/p"bc IY}mo""!SI #C c!!#%PCuC!%%v#̅ Q %  R$ Q''Db>)Jظa < q0 8#u::$2qr:,`RJL $ЬIVvBP)X BB.T,biT/Paj0P+ 3P54h,eaV\S_W|x0! , @pHdP(Pt*I|Xp8t:$ö[iW(PBA >zhx+bc vvxi|}^S   C EQC rC"!C̰D""## E!(  E#%# %%% 8(P0)_aD$,ѠE L@$a%HpqW%DN`EI! NXD /ŊERzP"*ZeQ#!,xS,^!cU1v1׭di5{5-ۯ%vݻx ! , @pHt@A$t*5?`2өel" kh<pb)B(C(\,@aLhtBD"J(,!*X|VbĈ%PXJ! `LɢƋI7)E0`%ă/˜6N|@:u AL`!4҆-UZ_N+W غx˷ ! , @pHt< @ D2t*PvY8x)ԢHPM xh$ s wIY~S(  $  E aSQC s C. $D & D*(D-&-dȷa-\(tP " "PA⊆Elk`$2 D!.XEC1B8a IT3dȀY %4]:(PKpa 8PbBVxH$r… A 7]_(A! , @pHL"H(rLeFx@ 4TW`Q(DBaakպfI[ q bR332xzhXZor R44x,**}~ OQ3/RvB2C$ED  ۈc$ ޻ v c RQ2 I h"T@+ThЭ` (E28 )1)L  "MC%I@B=kV AAGCB}%N@:5 hZbA͝X6 P\c! , @pHX*W eL,ŨTWIE(itFŎmWtbm>YY+ 5Yt qC4e15+-)&~  rUHz 3S&pRs  ˜ b  qbS RQE D"0! (4@ c rhб FpK e8f 4B@ M< P*{Pi!DPTà n8놢R*[`ckhj`s'>Xm>,q! , @pHf3XR\ŨxT.ŒzUUHWJeI'AmrP  wCH2VMg _. _  _ S ^ Q R Q ED$CB   00߫i *̧M ,E"p` TpqS "00…#%QpC#FAC H tsSA(Z恉k:8} U Eo2He\NzVT 1"I_! , @pH$f3U+:OQbЬ([Z]K&cU2IsmJ&uc_&( &|Z,k {Y. $Z&$Y  Y  O N N E$ D C  $=H HxDo<xB2b6p( L_6ll\i pȉZu xBcju&Kr̙LZ[L(P{M,m& K*x&K. K  (E&E D  CB $   F E C7'%pB!'d8P` `(!D 8@}B&\h8"t@"E t0 P!0`&U# D8Q .8X@N hAǎ0&tN  " G/TZAS q& j:0 , 0[K! , @pH,dl6i3Raڙ5V{} bH5R9KJEm|.&&F|)&.D+C B&$ & (C$  '6%  ''% p $p   _ B !#R: !`- p@pPb":ҁA 0PąClp@28pX$O"6A $$ ]ɲQ ,p`g4pQX )e d+uT)hf{w;k뺔Y``b63t5iljk1GSEz]FUuMm]m2F,Ȁ0213bJu TVIENDB`components/com_sef/assets/images/tooltip.png000066600000001354150771655450015341 0ustar00PNG  IHDR(-S+tEXtCreation TimeThu 5 Aug 2004 20:24:37 -0000 =tIME pHYs  ~gAMA aDPLTEs)9s{{c)){ss!1)!c9B!Z{ƭ)R)9k)BRkνR{9{Js9ZZs9B9{9kJB{!1JJ9R1kJskBk1{kZ)1{ZƜc!s{9k)sޭc9c!1!Z){9k!ZZޥ)BB99RwtRNS@fIDATxc`/gk̬lNNIMKKcbU|@"!aa**aaaQ@&>>>~@J90E \݀'XX)gƠRQ 44Հ( u@YEEHs00HJIKKK ]*,"*B prq  AbX+yXOIENDB`components/com_sef/assets/images/icon-48-301-redirects.png000066600000005220150771655450017307 0ustar00PNG  IHDR00WsRGBbKGDC pHYs B4tIME - IDAThZkpUʽ yDECդL2*XKHǟZfQiGNVjttl8@*D̃%'t tx,4.e̞Bwܹse@ )/aQţ% {ntt:B1]1ܻuNy|v_5_x=ሉ1/ƱVy[mH X\UPi6;owĘ=^_ܽ9t^;%֎M.C;os&9eDt$Mŵ W&n{{7:U3_XZ֢b B\%խ7iM.nفȔG ջknAQفo}qnRo3Q** aH@UOk(!lcb~BjZ?Pv֛ jKɾ}륔btJtiYd٢Jv7/)6( @WΧ6he7X °Ĭnytw6ͯ@yMU^xQ%jgOICs&5$㴟=?xPioߣoe9.I|2b4G羭_{/>e+WV:ߖ-f+읽tkNO>[u\RN%!A5ͯh\jr "7' u麕?ou\W"gnP]QԶmQcrbZ5 U, G|򆵯f$!y慲2<HD0Cq˄e$!-L*Q4(LQݑPP_=ÕD{um{,pݍHNC22Qw&.^ ]*$c P0@%ӴFOqgEˡ9ͳ~A>},~g𝳶v쿋tCH;68Foφc87{Fvݹu5D"0MsB(TE`10EiH$0  '?]=xc7i܌XUCRJ]o>T> Q!DݽGN )+#tkiBH)(2PJXÄiP5i@Q޿p-.p]/qF*Yxݲa_ɾ4~ H"bRBqӍ ns^hFUz4tߵxkn^Cwd%@wȼ1f/խOs:M @ yy.$q#Q݀kf-i.\NPCBP@J۴9KppsP(MSHA 'Ϭ$@\PJLg5! uBKHlJC~Hmf !E!>AL7OXPLL$ S.$@(e (! @H J p!q!B@ H$LUInġOAwV@˯&c  Pĥq&L@l(TUWO-++ќ,"8OQ|/ʼnHltSW!RR"R!fȀn B NWJ Hp=p`d&I]B),# A 𓿂T7B(*UpJ!'9Nͅp2#|R<-!E<!YfFO7D"AUUpn[ T p)@fRAK2(~ޏjh ǃҒbŁJaSk B!8l6-k(|v BHm i@P֡(-^U@ A!)0Cd@q8#8َ.oIENDB`components/com_sef/assets/images/icon-16-config.png000066600000001373150771655450016267 0ustar00PNG  IHDRaIDATx^]H{Ϟ={u"v!1,|&2(vPs,y2#H8Ŭu87G{1#*JHZ2SsiԶ9_F7_}ߛ/C& ?>RTĹ''Xi&!*6a=H7\kƟs=7~NRSS_}Z\yԊTqh=?6t9BD}k!:238g9O[;t6;joŝF(?x^j0 CV*6';6@2&bR26[Iq1lA H.NFqhRrEHҟx4j47)U/P*0fAh?nK)'<gVg8@(.؎j- /;|I2G+`e@V?Ü^B=ٜu \. R"@~m|S0;Aor} E!ͅQ^D;[C{qv#W)% clތ@_g-_WE)8bԥSni-iK*#[Xk8i|)CC%a3O[ctD'e()͆5!Fz{xUɉNKVT?h F~br`1ˇ=bPAFy C6IENDB`components/com_sef/assets/images/icon-32-services.png000066600000004717150771655450016650 0ustar00PNG  IHDR szzbKGD pHYsnu>tIME #@ \IDATxڽk]Wu{s95s}v<1c!mLMK*@"UPQ)H}I$H«N! 88A`q8qlό_{>=G?1Jihy/h~gkm~R}ɓw!?v}/[BߞKK[fμh^ngL]N=|ƗWw'kܙͪ^G&T[$uq33zzov_3|~q";>[~_;HSz >X|O"%(%6-wݽQ[43 8(!7~;cM*o d2cR(2YE&#J vC-;n{&nt'v#6ެۯdTR `bgᑐj5ݽT*:mIpH!h6 n%@L썥 ^F5ž[o<_xaVdŢO|CDpB̛n)N H%" /ОZrǟ]ozT_yٜGK$'i6 w|uMu)ǩhmپ#BSO, '٬>w[#@-_/fsp&#2L dq1fEĖy&ϵf%~&Bn32%j[iNWهvJGZ-]}I(<_!%T*>ʪ!)3j)ܴ-O6\MISKiEU`t']В}}΁R=<__4)} LF25iJ `q!&Xjk XQ h{`C9COs!讒lΧocHH@pd{J )eMt>'DjKԠd\]@:CCBq!!. E9 O/38 mwϺgZ(W|CqH)떄{&Z -c^:&ξ`xD;˴]BlssȲЉ4: 4 FYZ[v,m{FCc6^S{KH)1RкRHeN-a(f=B }@n `Ͼ2ai1PQ]i ˳ϮQx 8pNXK9J)@H<-p868&sZ&;62-O҉Qdm351;k8ztfˢUμ:u`RqmIbpau _F[뮍l^%} 1V23ORpΑZqnK*?Gkؕszes)`YFG=FFK9dibd/xd - NF_Ai4{\ | cc= 8dsx,RH<%<L˕34C0q劤1LO7014R0:% = 4u\8z׾߿xN-OS+]l.QR`1KI`ͻzYa){_}m-JRÜ_3oe2 VkY+s{$`%MibcAz`I{f6πK@❘>y}l癳?gMe_Au2ڹj}n_HkSzޗ3c{{խ7{o33#0B@D4ηO"WVV>m&im[,*{½@4u3j۶RWWWeY1UHX#WކPIf&e)шdBY3&з;ix]x qΑ))p7|Cˇ̽CX{`*?3 f&S͢Nc_<{09'X01CfQ@D1h!r>I1&x"ߑ9:V.#1]Qys")E~3JӧńNCxn?Gp4㏋SOb8<̊bbUȆÑ̮%e T58,څ} vww#VT~@IENDB`components/com_sef/assets/images/icon-48-manage-tags.png000066600000012163150771655450017212 0ustar00PNG  IHDR00W OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD pHYs  tIME# nU IDATh{\U{ggg  `A,BhZb  4 j|"1 DB$yP@kv۴9t.%ٓ|9ws;9{Q.xw 6 "H&H'' Xr4˚ (J5iUX FV0V# V+`4떫_8?3WTI.;87::%"OK5󽝝۫lu;U@\ ,_|q[lYF=fdqfgLTjQ(`fp |]gDXoۭ@燶RL&s5Zͮ[`e/SkC: ]YWn'| 8+ρH$ljH2 cemr+-naM袹fH+LYDcF&z_ RaLTU8z6@hZy.Zd'i1*mv3G?,@ xZ;H$N7@ 1,ކz'{"Bljl9m[se6 LlpBqQ?ڗC r 68EFY\GUp`Ҳ[qjG2 ###N) 8CE bt:ctTdaZ򧥥~timܤWA{+QM vዽ# x B+TU0$ϓfQJQi4ds9<̎nVSJ֟X`sўۨ5Sfvn[@F _uqA3\""E$"cLp+1OhRS}F<x锎ʧh*d8i+p %$ a8؊2"+-}pq7ODڥ^o022B6%J! \)Tv :z(p&]/`$c`"y"W"\ PZ˽pbq=BQXkqW ?xci `<ڥҴq!_¦!70`b-a?+Z`-@Â2\ګXsxbc>LU'Ow8cNϠ e!T~Gus$ڞ8%a^s]L56wIDO#q'7{+w\ܻiAq'"؏fRhnjBjAOP40j6{pg]r1}^{ޒZN6:o4=ٖ h3o̼f?p|e==UŒIENDB`components/com_sef/assets/images/icon-16-sefplugin.png000066600000001060150771655450017007 0ustar00PNG  IHDR(-SsBITOPLTE)AX۫qst VUxUUUwv@j=qMMMޤaaa3fƈU|||ݚ%Bl`|1\{H|̼]r\\\kkk-JdJl-Nnֽĵǎ΋w 9tRNS*e pHYs  ~tEXtSoftwareMacromedia Fireworks 8hxtEXtCreation Time02/15/06jIDAT@ unDY q`/đ'I/lg汔[OF݊rAƗg{*5' NNhN'ycط@Z˺LpiauCD~]L@썯I"2V}:) bIMa+IENDB`components/com_sef/assets/images/icon-32-google.png000066600000003350150771655450016271 0ustar00PNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxW[lU޻--V,- [B <)/>ģ&>KI KB -/۽Μ?wݙ9aiQI|0,kii vtt|FɖD_N8Y#@ccc`yy~a<K~ԩŇ,8{'⮮&655 V<OisssNH-P3N4 3`@$6ˊͣ tV"9͊ { :!SPUA25B~H2Z _mp:s]/@. Ӯ0$7A'V榠) k-AGkp`b‘ p: S/LH$yIŵ GE~`2cӺEuOԔAD9lmڱYbcS0tJJȐ](Ý[*vluCMru O fqs.NINU/z"[Z]K47<HT+dq,/xD^4hag7LE u%דaȈ0T#_JbUZES$ Ob~z۟R$kK=iMU-=6v3TRWC UO'-Fa/@ˤ4E$a/Bء%,ܝ} Kb32z:e u@TMC&';B pJCAF%9E]FOڥ`V7ܸ=BWu|aW:Hy,vHUC X/`b/ LLe N d;p#m Q+Ke=M9Ň! \fB L[/]kZ.1֓?C9i!=~=W7FIENDB`components/com_sef/assets/images/icon-16-key_bw.png000066600000006120150771655450016275 0ustar00PNG  IHDR7 OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD̿ pHYs  ~tIME, m IDAT(e+qߟ*DKQ~,䆰r찒RFr@vYr89h꡵؞u͚ p{ <}8pd!L`^w;! h֠Xk߃m ]m/Y+[B9iŪ2}"35_*8/" i+ ,"Bѓ /jJ{U' q]Z Әr '|\S#|[zto}A)־<0m>V[k1T%kb{ؼs/^Bcnoo֭[]ι1eع]^(//紐<}W3F[ws9::wyOkrM;[ ihokՆ!J92G $aRaKsN.Ձ70|؄dfB%D)$ k*_%X6a<OHe2Hs|MXgRג`y;x7xDbX4jĹ;Q}|?XV @ bgZr pw'PB,ޥck-j Swh)G ދ̜Yp|e[+ι58M6!$PH).Pcxi2^6uژ #48!s(%.gvy%EIr4Nl|^d+4dZ̽MB"B5RMbOL/Ƈ_g1( }=fg06Nr8k^b|v_g1{9پ0W 2 jR`3S//UZN\g35pΠer8Oa|>3v!V>wbae=[,VJ`rUZPX3_ܹڤ!mcCTJ?a}hk좹T6,׭&Q e`DOe85/Y|]|@t3{?]'9}2 w[Z"^@ :QOSX_2JzUo:apA#N$5%rej:KX&1MMr9J% c`6\ihY~(Uc&d[ڌ:(ݓFVj̓RYLHJ *d0 :99[E-).q72Jk*&^LL>SJ@Ge22Owb%_ n"eBSY!&ȤI PdS]mǎhm п6FGX\Z<}[# Ï&Bt;DY3kUe rvom%6kCaV2J'،X/} ̥A`d0bR )<DBpMfԩΥeZѴPzq.NuqiX <}aM΍Lsfp) X.s K%'X J|X;'zM6sK\;MԎߩ/'غPƒD/,!RԱmӳ=Oc"(ņJ%)Lh iZZ:9{S*ђQ@0\$0+dt}kPܵ[[>Ǟߤ0L{70 8 ?||c ÈNfQ;^5bM4kŭBp!'*s8J%LIdž #(p3IhVUutz}K*$,6*qJJգUEQ')M:Hp:jY5Hrw>{fpjdBa'IۍIk1w\/^2_~0_*(8[ck #敯~O-(rٝ:yřlކf=X֝Lic4?yM A{;wux^WU+צ~o8= ^Y$Q$T 錅6~6R5;78(+H/v[CFwƀdtʖ:8k*}]QnM?/պ5WD36OJ"xk]Au2eߧ\pl\ٶ~{].m.lq(="V67fٿ(^A2J P0nHZbqq|6NK y_6ӽGmik6PⷄwXa?#vnERkP47uUOf/Nlٽٛ6 kOgϢ 1&T/6St{񟻑'f&XPA[\a e㬮\.e}䓕 k犆ϗ{1ÖMk8§(9UD;U`WKGg,E,,;nAM@ ddl l}4m>@/0擥 p}E_mj~&jMj`,I.OǬLўCSwjĺ:o㖬K TtUU6-גSD%*Q a#r}5l,]A8|>u=W/WlsO7i)'ذ-/$Zݑ6)JC$T.(U3%F&k'K&__Xo}U.;pv͞D\lLҰ #W!WD)O'7HDLZ6/y-=!wT}u[:c\+hcs33"U CҒ! X5#]܅ OJ4}G u<{y5)C? @Mw3oЕVg4g8۰Nc Xh4H `/V'\>{XdGo#B{{\,U~> {7r ?O^ <rM!x|g ]&~g.-Sm`% zx4ŊȬE,禫|~-=sUWܷtwxG ?45F|+ tu)׶La#d0䬽F:BHX3o=No#z%}Wl1g uav~9 |_,aLd.~4%z 󥯓.C(<Ո_;+IDN*Ir[ib1z='g89=͑T|,z `}#wlAS?4G>Ra'EE](:.<у 1Q@'˔&.' Dh`Vfl.`:13w틹'JN-~xc~LIڞB*oZɦWcKA|;H4ͩߵOz[F f>r1C?ٸ;7x䋷8<~K'E@\BBhHe-whR R~cxE:_5S>̻h_^.n`Mh+B<0cxx!BUm* ԋԛ g86K:C/L&y=O7Uh(B)#)ul'DՎP7 ]Oz'iMЫ˝,RQʨ{Q:}@%)8H?w}"}OR0[")Px8 < Q[D1 "ރe2sE ٴ_>kzMmOrz.otY mbx%zfPJM|Bn+Gn5t]"r 44e/O=~t]~o 4mW"9:g7퀟 ??)Js v3 M\SК"Fd21'¿ǹC{˩j`7αF>(rH5p[ T_4GQPfq=Yfpu ]SxuhԦ曱,م c#!ܽ642oR0>/^fGOgϞ=,--F:?[\+< z[HT۹gQ%i0 \ <@GkH^ כmDl6$ sNn^BK<hol梾o݂=,h]vѤF.G)iTIxq<4]o 44TkA) ^a}P[$h Å^HXP6n؝$0.R6%:(zՑ}Hprl()Λx϶l.b_ O)*5JͥTuȗ|l1b.lc6mEu xN|LW=AAP!8+ I;Η6yLQh4FJ>,k>z˚w4VOJ+M\Oq%G2k&ݭ6x( !߈L23KK91 ו @[@lj  p iWqb2|iB8T,XijH֭f<)h#G3%Wz M>լbhb6CGsdd/r%)FpbH0dkU]`l~L|&_1.sl,Z(JI1]d>snR,,,P:SJ|X5BDw@}wpt]/: "bxxh4ǮgxlZH#xjU]+OJr&F*7aYX{YۚŒMß,P/mh!m}xR_EOs)*W^ ,Q+SmT}k/oS7DH8=>9_oFV>װH.۱ݘ^*~-5.r-$\ȥs6~C(R\Y]zMۙf_DYV\_ZJe}nL82ɶD8+\ B2F D]/i&3(ꯢ^eUrfy'L@ @KK KsU' 냅3r1;9h2)˗ljΙEmݯ!YL P.-rv.k$/11g!SZ4߽> #9qtttL>}wjgk,ʵan̗ݾz*Wh8Mk*DNƩ0 ﻤn.txgff@ @:M=I^~JSW^i޹&s2wEv=۱]-Wh (XQ !2dӋJ%"BL&<3A&L1660'G8|rOe8e@Ñ),x҅&*U)=Jz(U?KMgAgK-!7760֨iRJ$7pCCC444̏\8+$6=t-0~GSel$ZE(b;g`.RjߧCc$¯Č3<2~9۷>Fz{{ q:kbneum9RG27+$ P2~_jͥZqOzPg%[(pbb*U)-<z~0ZUJoM6:dPJٜ3ƙlVqgF߼+-}7 =05 D(i@JU)rskʎ?VA/ԕ6`www'{-lݳg{j[8dbE赙J?* hrvوaĔ*ʩ+?c&/-iZd2in۶ w8pI fpNbz+︳ltZre>94sJE?!֜w-+IENDB`components/com_sef/assets/charts/line2d/preview.jpg000066600000033345150771655450016525 0ustar00JFIFHHC     C  ,"[  !1W"7AQUVuv236aqrt#$8BFRbs%5CDE'4GTdefBQ!1Aaq"2R3#b4BrCDSc ?E4ADADADADADADA*{Th˜DG9uD*XARw>n=3^o$Nq6 P&i̠#-WHcqomcg %D s&7 Q;"=9IpW"D( S18z*Mӭ/ФpcsN$ȊH P 1$$zv~gxS<ȱOBG d/5{٭3NdzJ7RJuK7s2NR#P %NCIFK$372@]&cTK&ګgyp{yzg/~#٫|;R(8&+T) uљ9bU)`NYGC4mT]Ⱀh$`&ph@U.|*ګgyevde-in-ufzpQ*nʠY70S FQ51ɪe * m͒k(@wXڦȓeC(R3E@ʨy1DT1KK$Pzј{yzg?zdW<ch+s4zv~ggy/0K)Zi6?T2o_#N"ibh4zv~ggy4yU4RJVx U;=3̃U<ȚXê)|+A <^GjAevdM,^aMRYsӼԶM1RnytR(LrD@8qkpnZdE=v^6 4ٮGC!,I$L`]9DA /Cf&D10$0ͪF-,5yk \īl]5!6D.L:;Q䪮%PB\W(O4ч\4QUrߜaa6 =Ӱ!;};;G$..wBrC8-5ku.zNA B)G ZYy_wO=[)&s0 SRi$e0pu9K<>f} }L LZf7*h}uKk֔Tm+t~'k;=syF~JuхG{37F%oS1+#z(pu9K<>4ǔ? hM)Em?R{ěN`frPy~|:3] kP渏~f .gŮ%p؎_9WB*8Cjwv/ w;wf Ju•s XG7橔eWv&5SD[DgT7OH [7s&筱р kPj8/Dz%'Jf*oI$L`:΀`5xvos/IQJ-.21ȩ+$b9.sj9bGHYc6]dnVQRջH tja~@cT|*Ѵm@2l"’3@u8E%L@j}` *EGlP94l]YNܾ9!O Uzi͐mx)~T[E9`[kk}USE; bUW6H_qpPȏ:~S[u;fdۈ}(3',~p*kc}nm}BpHTT.46/lPi|6"ZïxϊA |$?a vEF4d:3//˃x*ؕh)$P\Pxmx<a2^w 0W߼T6 n!mπ4 qNʃuQŻ.Mlso-5_<ݿ.Fzti&fxvyFѿ ^O_Nwӻ" Xu#af/۞7s&筱=V9{)=$ԑIK7ERT=z꿕.^0[y71~˖\J=u_ʗ/-9?O }pcrCaFo-F<`FRsӞ0#q$7x!|r wK?G#<Ǻ"\_ wWq|N(BHIPD5WU ByAMY`*h5TI=@$;`z74ۖXTA11~d,* S${qAJvR &R6?2Ӭ:1>:e4 Shc3 fK)D7581P#-7zOFaQ6&Gấ_|Lt":f.)Gxc爩TRC^98Jo@OMj`A"J8 QUB4S"fp1K >!ILbi.Ns6 ~᧩sc;j}iHƩJvQgZJi>4.2#pC 1P3JG*gmsH- bBEs ,( 5[-?Zb^ٻOXJfr&$Tw:D)ljB&p*Y2#QM1\s^1 jDC9{yE3g/byO(}Y6XAEbg(=+Dbg(=+ďkONv5嚅f;ͻD>H^`ӥ B&"i]$7DZE_Խg9{CRi'GxFrds#-3.b  j fބA3K:H,ǖ:^lMcc@N;(3,b0ĉ*'0zH@RkqO`["2:c_Txo1͒;39S9^nC%WMA{rAՊP| +$><\?Dou᳠MVI 5WsD#"C?L`ukkڔ=3ne)Nx^#F6̤Q.3խ jP(xOk/F?r *E2ϸ9X ) #V3 Uhl}Iyd{H۳ptPm:ڿ* CܣYsǜE/)O&~,}Qɿ#rOsZZ~VjhJRHs8PxTx)>5?ri@?^6[~'e-S\Ff+Jڒ a?J@*!$0!׌qF#i\k~J*FKGH\%/Pn݁Oonh&g:™X A1@` ! R~l%w_/\9I32a!~> ~?/mGKe34-`fW :gI^ƀR ӸNK\:f^e3M<'6)NT˃KS7On")eSFfnDVzichY &P MH 8@1EO&oAV;%:0ڴ, iF[7&ۛ9MV[,ۢMӫ˨fiW{0Á`b@xT=Hu YY)uRPL ckd7.k{4\Q;FPUb9F}(|A12rmN1M)d&90U&??D=+O}p}86ngvP򎳳dӈJ @ .uRꋑb3qrMNIuS̢x˞10^<>KBl<Þk4ݏ$2u{v(rI$gRi@x8f5qoeAҿͶ4xjeeT/$:![ke5jj! BG9X{ČTI* S"L))nMZ9F tlܱRr!TEX bh1uZZhL*i5|.?P`EIv6?j&t=ڿj CܣMTn=E@:J E3-#R∏^A9t)A)81L=&NΨé͹i6sPl=]jguID :l)5*9' =0?JU[ hW7¨g/pntPm:Om_5ӡPBS4*4FNXJrsX)f: K@RK 9Ƽ,V3dnM[b; Q7 z\XN^A%?h)NU:y!'KEGfLLIr Puj҆dFېO$^w1~˖\J?*.^0[PE;aw F+ĥm$y,89t@4LbG^4D5YQ*Jq Pbw##QW e2> /:[W4&PTW{I ^ B:VCtcZƹ Pt0Βs$º9]p;qKj ,"D ΅=/?75@K1>lHimmg!B<d\ݫyoN{ugd['xyL(cB@J Xds\nPRo<(9N]]Zji'e!iIb.'I2p)JRj)sD2#DZP* CߡؿA l;5s O )y$:8]6rU햮ŶtCIcP*D9G(VC1Bkꦸ!%jיnNU9w4z`L}34@1H]b8'h =DZP*CߡZ)i>{}Cy0{Z|k\YXȜj|C63 ƴ7C~.(fޡt=Z CcSEEE0 JK!s%ɪ7}AWأe-]?L֖@C4;X>~8["P*4k7$委gxIq@)ɹ/G>-_(5!YS gIZZeoa稉mq$h7?Gj|86a}Êfz]u z|E3}nfri+a7'Mr@xELC DZP*CߠT"ߡe$[Ip74׭)^-g(ʡN[ jEJJ: e *g!њ܎GHI1HPC7HWˡtxoP3C#hr{{- _)[_9oi,2%]ЩET=OSb}qϒ^x$tx%û/bI(=]ED=d)a)j`@L X.-y59 FmLޞvO*F0T<ҵNiͬ!*P]#!\T0;SA{y>SޘT;|3F]ؑNSIQp؎Zndpm;BG֩%"(E t."]u >W*oW:7,bg Iw&){K6^ZY3jEK|g;OhDduWn۾!AL紿9>⮌ k65ѸxrvA'iZDAգpMvAO{{*.^0[x_ψUvt%$Clg][7]*G}⚙pQqiG**'90><\?}pcG 4hk@XN{qѺݔj_zson5/=99 Q K8k_//,a9e1 Eu~W.C\_o < Uƴy=%a֏'Fdi`ҋf)'ajnx=nfEaT2i>Cc!Zj}iHIyqw/pIޟ- 0Rv7bKBH>OC9{yE3g/byO(}$jbA[|l |ls !ր*:jݾ7&b;:s4:phi{S{{Y;GBv~IСZ/$+\FrtlӕcNԄE@7è oR.r9U] ]\s$e&6@ =0إXx]],F~Qu@]mpJI^#ĉ "LC8QD?q8:>ocB%I[iigԣWrߜc,s .+ \7~|}ݭn慷~[”sCs$׷ԝn Ψ+8g=ZQ|î0zu5  >E; CQӿn*ꑈU7^[`uLD4/hW`;kі4/ln;"3^=׻wӻ\7{xT1O7o2ۥBtinՍ+}8\ ׿6xż.MPB<07 IPwPneoo^;Avdj,>~(`;:ucxL5 ]AoW[)&s0Ay_$ j*im@=/DEIڟ Y걼iPu%?MRf#38C;\Hû-n NswwS\R <$\LPjz ;xŠ4LUCx\Pim^뷔?&`;;wqAp<;Pu5 ^VOKPLUւ)<2jrcЉ<h8sùm;Nkwַ{*'䋍*(mSj&[DjB_·PnǞ㿔~G aU 7^[`យn#<\?ir3Vl29a,A5U^ٞԁXVtIWwOr%W׳iENKOO 7pJ0؎_9WB<ߣJ٩g*!*k9UPLSzgH ( 8s W8j*hIr/2IK&lSE_mC@Z媬oB)6T<Š*u*F@S6SK0éo& uja[<#1=yntke^Q# s]$@<LQPxt3lm׺3OOtif2rROF8B* s8&% E=N"xzEыkgXo7JޕDRhbU BW H83;?ҔLU&sQ9 L()s5dŭ [\#>xEѭBյ5AV5Tmѭꉧu_ "R!!J RDDP,W{՞B_NԸH3C"\̸Hׯ:-Ό\A0D@Rq$[n;$ri6Np(`G&ESs-[S"RR U:I> ýW$-6['-vRxG~=yntzYyVII-0BLMcP6M5!v.;l@vM)ЮmRU9FuIaUCMIR8zZ;1j&A;bA)MU5Zq"8 8qk O٫ԭ.'^t[P+RL0Ru9iJdTD`Q rSadŢ_Le^?N2tI)2tBnUS$iqq@D5 x?|:1@1Eey;OUYiv䍺$Q'U!Q1HAK!cNAC^tBqX1SU$sn˜ ILnLQL.2: 9(f C ՊW$Mcomponents/com_sef/assets/charts/line2d/params.xml000066600000030606150771655450016344 0ustar00
    BACKGROUND PROPERTIES
    components/com_sef/assets/charts/line2d/index.html000066600000000054150771655450016326 0ustar00components/com_sef/assets/charts/line2d/icon.png000066600000007527150771655450016003 0ustar00PNG  IHDR00`nsRGB pHYs  tIME 9Al]gIDATXÍYYu9V6pHӔddödCH b?5 ?! 1$@ ؎ǖD˴EYz{9yE)t7Ͻ'w_[H)m=9K(N0"bHxգplf 1s "z[ߤ,Nӽܝ]ܼwf̦p8ŧnul%>#\d%{3pw;=e'PH^<ȧy_SqN38ה]fGL= wFc?{$"=tK/1˙6I]}Fr~"/z+7M%'nLn%z-e4,@gALDT Ě-= )L0fr"bf!rDDLҲA r5TIlF4sm2j 0b}25bjҬJDm6S`S:AFLA[@DP"AE_PR 97I5w+kk$l""6W_8::<9913fi9ݾ},KG/ wUD_pa-${+!n 7:MgEztxhh"4ۋ9I._@lfFf>W׵;ňܜf |G"E@N!pwwef"D !l8-#blW<"%`Y(T-mqwy+wΚM 19QMZ9@h"A0MK{Kf:pTD!RBP(0 wie h3nffFDA4cbԠFsfn v7wW5i!"œջw/ ݦ~88*֐fB,!Cճ)&."OWT:Qjkԭɪ]gq`yf[X]]7y?{ tyHnN e]'K˲=7xU%!pPq$PnOpˇ'uH pQAEU͠{`1d  ukKG/??x;Ƀ'hյh"H4D; ~.s zPsdД':pȣ .('5u2/<;j}+eã~1v:7-R=?6KQt!h\44Ոeh]˯=x43f Å)gs 9] pD._Aɟ}ӕť[wN+eq]ڶDp((3ťnS׮#cmL,'VL0ku2aJ 27~\72诅03b03=r歋K+AU?3?d-OFǹ F-hD)?/;o}k~;zHѝɅ84\F@:Zյj:>nog?yeW郧8HǑQq'k n\Z7Ó}e5o(#u``3r]_\vz4w:nge-V\a tյeVsa/%JwAo~[ܸxtߏeaiuQu-ŔX3$}㍍~v!IlFd`{{';'H4'X2o~^Vׯ~/'ѣOJ0J5F5._mbM$~J.D!KI8:llҊŹ'h@^Vp<,`{>ƅ/ve~{w>.]C{SU\y]YuG, ̌-e\q1||2[w<zxJ`9T19rdS[Hn*2\OnQZj1 Dfɬ bġ U2sid(+X Os'L'Nf( FN-:y@a6`;B-/$_f65J g;CHLNHy~V[^a̴=?-3l:!;Ŋ%؊dD'jA 'k/ *gM N 3 QNnDL 3vԟg/ 3VLֲ "X.mf3ehIn)VqS-1B RZ%8SLDksI{ߺ-@s4-N;ᔭO "F0@ 3Kp =}]ȁL)><{̘Lm 3 dLfAƱ` c'YZ֨&Ln5ͲYWKT'eGrh*k%MQ_8]ßsss\zx7%lafr@8[V[fhZ;iϩ ӱk Z؞”[s`qiAlVPhMǼY]Q' XK@o-,X凶oJ(6D"?;Z Ozj]ѼmAg̠7.خ%fX@Lf+; 7ćU߰.z4zX07*f披s%QZZX\b}KeG `/_s XR0uoսmmbЬ$*c=p2Yb ʻAhE3fv: jЇه7oo. PM/WMz yX4V `j~`aڶ,oٛ!dVI?z,yb @TMH-*˝iϯB{RE eW^_4 \yZ̪H4w6j'D??G~clű@^63z7Yո 렡NY3 !EX6;`ّM6=1 qs(y߬[qCb`Cy|vg틽>atu q]Dgwqq/:D](PWK4SQӳ4dJ+wѲbF~i"A fcC,a~2#i&`A  s"w g`' $42Ҁ6RH5liaZ$ UGp5Ʃ'i'OQzG| ~p lgʝcpxU*gJ~Fsrqoc>? 4)IM,}"!:izpc~XNc{ 9\D0MH\qXqM'#IZ\\; ZAeQI)-ҕOuް&   LqG0I Uo&ߨPRUFrYrm>zs 8Mt4oqB'"sS=yV*!mcV|Z ۖ^}٩"d| ތYٲ0zJOljt>^OsŜ{JO1[ݩ;Wf Ē kSY!J[,pݱ(]4řCenY#|Mpkl8VջMK],t`%CO ը;prBtAaK ^+xǢ~`Ҍ~YNŋ#p/I\j4C=F:Xo!N,@S(ZRR]!ph󦂓a>Xj'\$v)db%G*6#|u@ő]G N,4/3JkvFGObGc\!Ζp szlC>N.H$,a/$KDs.v0D~ZpG"$y$H_^#I6M\YP\/"=v@T6ibH>&.\.D ȫ w# O*uYJ53~]o}{jzIzԍEݡsX4ݪcr !,L,GbHHnKXBhLPLǃv?S!:fbxDAƺDaQ1c򡴪!}y~7 *ڮU=0G]V>;$9'&w{K]RN:%#=EilV2L*uLwwc4s?j%3FŒ},r#L$㫨{kE.,Rj#M0~7X1,*$JGik"$4z l0_7hIKڥ\6rFl9\/V-Ej ~1]<ԑx<8KZgG+m\^:Y'r|~oP$ސb8r.oAMbR7 mq{A'tgЪoץhAJxf՛l7,p,%C*?DjamP^¾6آ#Џc"~Ŋ%WUlֱɬU[%h޶$!#4^C@fY*0 $ flқ!tTexjy`Bt"Uo{77FVƸ2m+[`v̸1WYt^>d(Eql Î tT5;g~Oی@7r-z{27˙L*CIHAV+𛽜}0[;4ޮ&}1'5]S 8 j h[%>Y9 gycyNP!IGQkK4-B֤#.\R.l>c% We~%Ҟ_<Դj: ꪌnIA%\nYiz"17ƜI q3%\q\zYJg4l]Ѷ i wӋIx4rlݧdE>=zާ8iώ<9y}vz?Gg볽DO:2I#~fqܿ'퉦""eE 1S qOd53'g:(4R~>l<{ny͙,Nc)*m×qZaȔ-rm42**+#gJ z<'Kzd kBa$ȏ.UP9O֚YL yw2 ΩtKZ"UFƗP⤒TʷM۷HQ["I:]òk=4[-۩rю $Cbf0 QF':Q+=0Re\\V\ƥ )gj4֥&C[ Qŷr9¶fi6+k$f4C~+L>ܛ&>;^V[ # ĮTQsHAee Bri9uo_$J(VN2 9>{jTRgY_-وXqw'tU{)@@ |@B  (ME|0/ ((J1"X+W[v>?ta)&]!wٴ`hDM6Jǔs~ 9ל/u#el|uR< 3+{Zu̶pcI>4kۈ }#}Љ*W)zb'TܑXCJbaFr2*E'F62w* N#zSr?7kL>,3􆣬s7cHښ(Z?vOM.Sa*5|oubaC).777@IB @δe|9e<a}v؝ Q:>Y򚻿aKS `y lDcdpVX#V`U&aVfQI ~;/iU5 D 1XJx%NvUHs\"2u!:`%Wj 6XSVa:lZ ӽF}XH-|[7븈 E d Hl,61"X|Ql1ELer[ʀiR[c.]g[]Ԭh VeFmV:vlY&vd2cO%+Lɮ#bױj\A&9 mvs5wkZ[  ^CIN5H 3z÷ldCոi9j_|s_ox)GVB?%m@}:X9.  ' P34%tSCmz:oG~l4S.'H4Bn#ZHEtLQM5_-w12^ &^ ձ2B缏Ss/LU$*r L5$TI2bgd3UéΩN4g;S͐ks5?+r+=a~39~St4;.8kVFnuN6wͭRgg9>G.godN>W.\g<ΗS] k Bg;ջdTw)N9{d1^bu~cW.- yAf8+7S^T >gznW2 ׿,Z,?@S%!,q&-?\.Wrg2T?eT-J`J<9a**YG2G[5c25I=>!zm-\eQ 3Y1Ycd~rŨ~T8SZzIe=ETE%X.^lm""ɁjX5Lhb at9\v`蛿`)(4db؞myq*[vt;MpxǬ;"qRw++3JyԮS箫DFPVXI)2.x&^L&I&ߢ%'$޳pVԻ=1e[õ =Umkzt}y}~OM R?xK=}hգe$ڂNoe I~,Df[9 c]4 Qv($z;ؾ;6֎ ̋`mjX+wN^x-Gq83Y\1~aS`ɐlO% V#uܢJ~T> p [w|L|%c[TdOXvNuDSȣ~~8' W ՠ|kG[Ў1A݃S ?OP\#¸QV!왻buS;Az7o!65zBg)r^ aK4M=n&tZgO2z"2cr4r#< g ]9P*`O+{ԍ q"' D BY3xbD%?g4&si ^u/V|ihZT/k{_Z1;8.[8 zTgg*|zB6- JIPE| nj^ ̣҄zǸl6JQ:I#gq$`wk\2Hi(6cc Fsc@<| ״ԦN-u'[IFe{(\i~<-D˶nnV;u ߪ |cg]]d:,VX@d*>  6 ҹuZF"X[ SLe|Np+ɲT摯^d1јC`/=^$AHxP(f ~E(>/|6 i"1N8'|=Y6\ѐI\xDǫmPςDKT:dU"WxOY7YF28=/ 9+q UK ;N"HTځI9U{LvOwsG~D"X]u ~j8з}U/ Nװ|WA~2O 0 "?!ZGIfɕ> !iq M8 r$+z])7'WaDqh@9&Nsä__ohⷎwlDsQ&&c`--z4ъjV?j# R)Oud)R #]h<"z.5TROQ8eFsK 5(I? 0ٌ 6MG$ِeQ3kaTI4ms]TaiQ/( \ m>ҧ0 >ק,5XklH%%JZr_цMNX ZU$nzPK}{dʺ)br$qw]]Dͷ/|fԣ߯ty9E>ZT/51w=s6̌[ q-E˳Ek-ߴG@TRII$*׆h FC08+F i͐#"ZEe )&6-Ѳh͞vn1q aidFۮZ/GőB9 JD&v"p)I\v8 ť 6zI( '֗9nռ6XK)ۥMB~{au#YdT_'$G'Sd#.2 xe`f础qbX:!prZJRc,R:-;E&`p-{pȀP+"X@6V.1T8ja0!}_f/1D|o!ң`Df6X wjcL1J[g~cH߻hndh4{h^cׂjeU&qE8ܳ9%6j[(z~otbh~ n[x}?2U4J*KTR^1$,*bv)?]*(>] e9 JQ{> w`9}dx0px3PDхjE5H^c24]wLG5f/e5ޗ&OFcˁ={w/P;LmjI1ġNS{H3oZN$kamva"3C @f'J>Z#p[:(5FS 85*W s` s#qӞHdNEǔ'J{t- z7yO{u6,lB7ajDU}#=JuqT解߉>/fjLI[1?D6 [ag*X=.-./nQܺ7Ŀߠ=~Ըʧ+Wɩ2ʂ*gNXsBF''M <^ĵlrG~ÔZޛWŅK~v]쐕EuZV‘dӍN+M0k#}O.gv/m;v+75`34M~R{h`x^E)ow־f?x\ol߬yw}3iMˢv]y_U7}e C8uس7ui'γ%b?O^̚%6n_vu>-{ i[w5t OB "*ń@ H WQQPVBW J3A#t](Xe{ =<3s攙s˜Q8+ :d`)a5Qt=ыWA!X#"1f9|uO,MɔK< f3upA6]ΐaLo-yKÛ`m FJg5ʧpdʤKqy'\ uTَ&!Ve=&F6O~DcKC^_AJV zbמlMG@BܝSԞ7N_8|[{tX4]2`Mb>z'**It(~ujI8_m7=\____`j$R&#C>n{Jrѹ;XeJOMϪidNJً1= P֐4vʶ^um"#z2T rRsf = ܄'#o|7QО&_M僑_L|TݷEiҀʠPFm UA֏_vXkSQ'~M$j fjJUۊ-5uӈ?Ha{&祗. 9v+.]Rc+VG (8:t(-Ҋ|/='"tY-π1Vq߹i#vE$N7a3׮>gZOe&ȏBKFG4ǝnWV^\0mlv;?|J-k_\p\/?.3ߋƋL~}mS_Q<4n6^pxY0~+dO}Pٜ ׳#}X1[ i}nd}^ V`IY]M'(BH~~72ea ,jB+hYo]Zට/m_ 8_dHO^*\+#=RbΩK~/xdŦ9m8jkKPXX$cgjꮕv38aUӺQ}lg_^y,|/ދtOt#jB MuN?RX(/pG]u AHqE"f-^MErsSӜnM[l@S}X򛗴{ѤsD31׈*(csuŪ݇ZJy>}9KA̶5OqEZ7##pf祝)n-r%pk@ 7UH فy+|6SNfw+tkՑ M'TPg%@aO#lo/NхT;9{5 Cu3apƞf@AyPo;pԹK~mu^9E+Y,{TmYS8(\XG<\ܺ2(#,Eg:p8y7\/0B z{(JczLŶP_rH k\hy8/U Y<\Z>Y[A6.xDi Ny #%.)K4x3z`E/!K1V]wq;MSVQ{R!e"&hkTNffs4A:x~2! ŝX,헴/Nw< _=`PQ :p"33~J<ӯhnh3]MeohT ueϠƭ"sEܐo}ĺqi϶-\, Dж-2nyLVJs}H[3UxۧG@ +(׈bŸiL K /_u.ո0Ti@LN>UG(Ƣnth@DXV 5Ձ|>OoE 'Β-|4֚vlXq/U-x/F!0)7Ǭ q\@XűUtgw- Jl糧QXj7RUSx18&Rܳ%ziU qДK25fhuA M4"{IDUC 4!/ιFw\ӹ4NϪT)}?OUO6ɮkU#K}X v kڱYyN??֛@.JIA=\mep ƒY=#ӛ^5hOouЕu)MO maϧbtjO Nu"D0D?4-?A@genjzOmDgØZ]F ^j9(`"qr52zR7'?p{n;*!=#͒/WHB8![8nAJLͫcߚ>طgpA50Vre8 Pmʽq_yQH͚;sޡ(/+{-+$rezJiSNh v)zOÄ5pL}ݱ]؁pۧ<~xxA2y+z SuiKwK*Q68ƶnDcA|щi@?O^EڮT]e;/?S7~LEU:;{1}NU0`~2Wbc5uv W}E3֠>(b;Fx}. kNuRIx{Lzfo)='W>8OZh_U[?;̔rY;x$O%ma_S †70wM;(@Y׉aK@dۀ~^r^toJT8|FtEՋ^^m$,yɁa臬s<0^_O-j`/}>)HkR\3^cZXc[1ʜΗm1HkW,V(#/[sr7%WB)GsڏUYE2oYyOS0ì+idY\@,47cbYQӗBޫxSÃ$F=zMQGgܷgćoyYiUSβ PS`/o:z0O(u6ji"S(uFgZK1 sn_zNO:ׄ񅟍 f-(.hqE\aU1u=2B:iHPS!BK*PaKh[/^V:gR|e|y*g4Uֽ}OW`rػ=EùYGxIL$lK(fu[;?SJl1,Ʃ%/W=M/9w<7~Wr<0o`í: W e3h0T'%lT=T%W$tݯtuGDtXқJ;:{XI-g5gck,i]`%F4+ qui{et{ܞTX!.:mO' ˧x-9χ ?+_?6ƺ%;#EtY]ŧYWd x/g9YK)T~7|oc@+*@h5@= !03`ւulx Xk`l8g\ @D<> @d ( h :@4 b@, @"HۀP7xQ.MZu;H05/}hW9D]GCcq׊nD'_B?1lށV~dt8jzz ߁R@sQAvTBê!xr@ rsȬㄨåDu$UF7 >Noިqfl[?O^ uShXnq4V߇vFD9ą@)[':UD9>k!rOZ4sox|ީs|$=}8X! A3րQ"HA& FR{A,\...EPu\U2ɳv77D/Lt` !莤C=9>ƛe{d0ԆEJ[4´Rq.3 pk(@P`bo&HP p@33Xfs/{6\i&2A Btz彟,'$|\$bF%3$S)j&G{+]lL0/9H ᬒφr蕘o lY4tKaX#b`T%Cfȡa;B*2"d.pv32YBLB!G-̠- =Ϳ_&3o Շd!)FANj+>ߩ| c;Z ^#\?A 1#P}3X7*bA֬Xp#LbD&DBm. &Td(ٿ6oo )vfؤ$>UC,?6t E X,MX%@01 v vUon?:GZ0f!s#waKDEU components/com_sef/assets/charts/line2d/params-set.xml000066600000005612150771655450017134 0ustar00
    components/com_sef/assets/charts/line2d/trendlines.xml000066600000003774150771655450017236 0ustar00
    components/com_sef/assets/charts/index.html000066600000000054150771655450015151 0ustar00components/com_sef/assets/charts/FusionCharts116.js000066600000032240150771655450016354 0ustar00/** * FusionCharts: Flash Player detection and Chart embedding. * Version 1.2.3F ( 22 November 2008) - Specialized for FusionChartsFREE * Checking Flash Version >=6 and added updateChartXML() for FREE Charts. * Version: 1.2.3 (1st September, 2008) - Added Fix for % and & characters, scaled dimensions, fixes in to properly handling of double quotes and single quotes in setDataXML() function. * Version: 1.2.2 (10th July, 2008) - Added Fix for % scaled dimensions, fixes in setDataXML() and setDataURL() functions * Version: 1.2.1 (21st December, 2007) - Added setting up Transparent/opaque mode: setTransparent() function * Version: 1.2 (1st November, 2007) - Added FORM fixes for IE * Version: 1.1 (29th June, 2007) - Added Player detection, New conditional fixes for IE * * Morphed from SWFObject (http://blog.deconcept.com/swfobject/) under MIT License: * http://www.opensource.org/licenses/mit-license.php * */ if(typeof infosoftglobal == "undefined") var infosoftglobal = new Object(); if(typeof infosoftglobal.FusionChartsUtil == "undefined") infosoftglobal.FusionChartsUtil = new Object(); infosoftglobal.FusionCharts = function(swf, id, w, h, debugMode, registerWithJS, c, scaleMode, lang, detectFlashVersion, autoInstallRedirect){ if (!document.getElementById) { return; } //Flag to see whether data has been set initially this.initialDataSet = false; //Create container objects this.params = new Object(); this.variables = new Object(); this.attributes = new Array(); //Set attributes for the SWF if(swf) { this.setAttribute('swf', swf); } if(id) { this.setAttribute('id', id); } w=w.toString().replace(/\%$/,"%25"); if(w) { this.setAttribute('width', w); } h=h.toString().replace(/\%$/,"%25"); if(h) { this.setAttribute('height', h); } //Set background color if(c) { this.addParam('bgcolor', c); } //Set Quality this.addParam('quality', 'high'); //Add scripting access parameter this.addParam('allowScriptAccess', 'always'); //Pass width and height to be appended as chartWidth and chartHeight this.addVariable('chartWidth', w); this.addVariable('chartHeight', h); //Whether in debug mode debugMode = debugMode ? debugMode : 0; this.addVariable('debugMode', debugMode); //Pass DOM ID to Chart this.addVariable('DOMId', id); //Whether to registed with JavaScript registerWithJS = registerWithJS ? registerWithJS : 0; this.addVariable('registerWithJS', registerWithJS); //Scale Mode of chart scaleMode = scaleMode ? scaleMode : 'noScale'; this.addVariable('scaleMode', scaleMode); //Application Message Language lang = lang ? lang : 'EN'; this.addVariable('lang', lang); //Whether to auto detect and re-direct to Flash Player installation this.detectFlashVersion = detectFlashVersion?detectFlashVersion:1; this.autoInstallRedirect = autoInstallRedirect?autoInstallRedirect:1; //Ger Flash Player version this.installedVer = infosoftglobal.FusionChartsUtil.getPlayerVersion(); if (!window.opera && document.all && this.installedVer.major > 7) { // Only add the onunload cleanup if the Flash Player version supports External Interface and we are in IE infosoftglobal.FusionCharts.doPrepUnload = true; } } infosoftglobal.FusionCharts.prototype = { setAttribute: function(name, value){ this.attributes[name] = value; }, getAttribute: function(name){ return this.attributes[name]; }, addParam: function(name, value){ this.params[name] = value; }, getParams: function(){ return this.params; }, addVariable: function(name, value){ this.variables[name] = value; }, getVariable: function(name){ return this.variables[name]; }, getVariables: function(){ return this.variables; }, getVariablePairs: function(){ var variablePairs = new Array(); var key; var variables = this.getVariables(); for(key in variables){ variablePairs.push(key +"="+ variables[key]); } return variablePairs; }, getSWFHTML: function() { var swfNode = ""; if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { // netscape plugin architecture swfNode = ' 0){ swfNode += 'flashvars="'+ pairs +'"'; } swfNode += '/>'; } else { // PC IE swfNode = ''; swfNode += ''; var params = this.getParams(); for(var key in params) { swfNode += ''; } var pairs = this.getVariablePairs().join("&"); if(pairs.length > 0) {swfNode += '';} swfNode += ""; } return swfNode; }, setDataURL: function(strDataURL){ //This method sets the data URL for the chart. //If being set initially if (this.initialDataSet==false){ this.addVariable('dataURL',strDataURL); //Update flag this.initialDataSet = true; }else{ //Else, we update the chart data using External Interface //Get reference to chart object var chartObj = infosoftglobal.FusionChartsUtil.getChartObject(this.getAttribute('id')); if (!chartObj.setDataURL) { __flash__addCallback(chartObj, "setDataURL"); } chartObj.setDataURL(strDataURL); } }, //This function : //fixes the double quoted attributes to single quotes //Encodes all quotes inside attribute values //Encodes % to %25 and & to %26; encodeDataXML: function(strDataXML){ var regExpReservedCharacters=["\\$","\\+"]; var arrDQAtt=strDataXML.match(/=\s*\".*?\"/g); if (arrDQAtt){ for(var i=0;i compatibility //Check if it's added in Mozilla embed array or if already exits if(!document.embeds[this.getAttribute('id')] && !window[this.getAttribute('id')]) window[this.getAttribute('id')]=document.getElementById(this.getAttribute('id')); //or else document.forms[formName/formIndex][chartId] return true; } } } /* ---- detection functions ---- */ infosoftglobal.FusionChartsUtil.getPlayerVersion = function(){ var PlayerVersion = new infosoftglobal.PlayerVersion([0,0,0]); if(navigator.plugins && navigator.mimeTypes.length){ var x = navigator.plugins["Shockwave Flash"]; if(x && x.description) { PlayerVersion = new infosoftglobal.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split(".")); } }else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0){ //If Windows CE var axo = 1; var counter = 3; while(axo) { try { counter++; axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+ counter); PlayerVersion = new infosoftglobal.PlayerVersion([counter,0,0]); } catch (e) { axo = null; } } } else { // Win IE (non mobile) // Do minor version lookup in IE, but avoid Flash Player 6 crashing issues try{ var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); }catch(e){ try { var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); PlayerVersion = new infosoftglobal.PlayerVersion([6,0,21]); axo.AllowScriptAccess = "always"; // error if player version < 6.0.47 (thanks to Michael Williams @ Adobe for this code) } catch(e) { if (PlayerVersion.major == 6) { return PlayerVersion; } } try { axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); } catch(e) {} } if (axo != null) { PlayerVersion = new infosoftglobal.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(",")); } } return PlayerVersion; } infosoftglobal.PlayerVersion = function(arrVersion){ this.major = arrVersion[0] != null ? parseInt(arrVersion[0]) : 0; this.minor = arrVersion[1] != null ? parseInt(arrVersion[1]) : 0; this.rev = arrVersion[2] != null ? parseInt(arrVersion[2]) : 0; } // ------------ Fix for Out of Memory Bug in IE in FP9 ---------------// /* Fix for video streaming bug */ infosoftglobal.FusionChartsUtil.cleanupSWFs = function() { var objects = document.getElementsByTagName("OBJECT"); for (var i = objects.length - 1; i >= 0; i--) { objects[i].style.display = 'none'; for (var x in objects[i]) { if (typeof objects[i][x] == 'function') { objects[i][x] = function(){}; } } } } // Fixes bug in fp9 if (infosoftglobal.FusionCharts.doPrepUnload) { if (!infosoftglobal.unloadSet) { infosoftglobal.FusionChartsUtil.prepUnload = function() { __flash_unloadHandler = function(){}; __flash_savedUnloadHandler = function(){}; window.attachEvent("onunload", infosoftglobal.FusionChartsUtil.cleanupSWFs); } window.attachEvent("onbeforeunload", infosoftglobal.FusionChartsUtil.prepUnload); infosoftglobal.unloadSet = true; } } /* Add document.getElementById if needed (mobile IE < 5) */ if (!document.getElementById && document.all) { document.getElementById = function(id) { return document.all[id]; }} /* Add Array.push if needed (ie5) */ if (Array.prototype.push == null) { Array.prototype.push = function(item) { this[this.length] = item; return this.length; }} /* Function to return Flash Object from ID */ infosoftglobal.FusionChartsUtil.getChartObject = function(id) { var chartRef=null; if (navigator.appName.indexOf("Microsoft Internet")==-1) { if (document.embeds && document.embeds[id]) chartRef = document.embeds[id]; else chartRef = window.document[id]; } else { chartRef = window[id]; } if (!chartRef) chartRef = document.getElementById(id); return chartRef; } /* Function to update chart's data at client side (FOR FusionCharts vFREE and 2.x */ infosoftglobal.FusionChartsUtil.updateChartXML = function(chartId, strXML){ //Get reference to chart object var chartObj = infosoftglobal.FusionChartsUtil.getChartObject(chartId); //Set dataURL to null chartObj.SetVariable("_root.dataURL",""); //Set the flag chartObj.SetVariable("_root.isNewData","1"); //Set the actual data chartObj.SetVariable("_root.newData",strXML); //Go to the required frame chartObj.TGotoLabel("/", "JavaScriptHandler"); } /* Aliases for easy usage */ var getChartFromId = infosoftglobal.FusionChartsUtil.getChartObject; var updateChartXML = infosoftglobal.FusionChartsUtil.updateChartXML; var FusionCharts = infosoftglobal.FusionCharts;components/com_sef/assets/charts/pie2d/preview.jpg000066600000017347150771655450016357 0ustar00JFIFHHC     C  " K !1AQa "2BRq3Wr#Sb$%45Dcs > !1AQaq"2R#BbrT ?JиիCµH 4mOb)RJTG(x }/&xqWMG{ nm&CjjdP ڧֲdR w^8ꏤAj/ozdnzkf뭻kyrs ls?x̙F;zk-75}aQK( RPw%$V_!Ӎ>r9w4ܢ*qgm֣SVBB,&$$3{!G#@/+K\8c棾*8/dCi͢>XlBڏP-%[A+ HP* IX '`׼1̯x&)Y]Ol-SFg.K0CMH})s<@LBsR0+gZkgyHZeBIeqN8~KRV>-;iG-]n !qҮd\PՖK]RMbћX;,UKf蹬Y^[,A;'v-SrκBmͺ㴖a6JR %)J"R%)J",\Y,RT#RBJT; WFKROAmKTڜ#~b;dD^xvU;l2RHܝ̓ג[.Mm<Ƌl@m PPN-6Wi'~QNEKGq镌1z:KHdR y6Н~ ԼVƻ$2"Hf6@蔓G[c-?6˧k.#J;$3_< *w법E Zߧ,ewU~)d8@>j tMu!$cG[1_9ֺ\u?l:@Xx/brI+jv}LHԟ srm"qth)$tRs^Ui/]n cc/NCu5ۜ1@e7//wFXgoA6$;qЭb?J3[Kiw^Q[Jy}Bv\=NȔZeDKWlUԮ5 ߻p?‘]1b•A73Iˋ$9dAU+rT'FѢdˋwvdr r$'bwƲ'q%[yO)N{;z@+lZ7zEs6@e%[3%M0mV>\!=U$#{}(a5dI٭<"<-bU)JQo%*<ʍ&':_@_7Qvٟ ʱ\T|p qcK9Dz띌'A+ Ti-Caլn ugz^<HܱfA%fv1.͔GFHk2@rO’a|X kF6Ythh$ ۴cs>NJAB:ބ2^_.Lܦ 0b# QI%?>$^:aXĶW=oq0q=r$۽M94iu=e+ߍdw,Z AhWq'* ׂa ,{9)w6ob[XH>kٖiv1L1i6.ʧ%mqKBC>S4IiTEe=k HQ臾蟼yW=vg&ꙙAvq81E*"q} p:0V̕oURDMT;?ұis~T<#Ԁrll3 m#v",{)y(_ q. )g]+լZ4gqu6i2-"s;nR JOQNЭ tיR2LXLa $6c̮ekRjRDl4y-~%}ѩq9 _گn굔/Vo蚦tcQ밋&H>*d<^kSqCy[2`~:@"'qy%Q;iyTҠ$~K/4.hR Z{E*sQdMiLP%)*KkW2)Cq̸M +Ihd9ΓtX~jd#-FwˎeoƭQ{K[07T"Q㞠lD׆isۖȎ}o!`AЃ]_^~ORôY CZ- xIsQV|y`D7'g^JֿH&?ǘ^~O[_zO|{hܶZVE7!<"wcz}H?;?rkkGԋ0?@BаH&?ǘ- 3߲cmY,HuiG}ҖRzw4 MJIq^ٲoJw&%awl_E8Ipktێ ?Q(JR(P H79gVv)q7R?M'^.[;,r*ܗ!lƶ%Z Y2q)5 VSϤq\:`e_ JREd%)J"TN“C]HWuʡ\녧3[ryn3wQE “G+ plV?v•u)JQ)JQ2a云*o:J"/Enj[I߬Tg$:'4 oأky6L#JvﯞUxN'gǼgNiBjT##u)J)DJRDFu^nF?~kݯďOT-'e!_UIVJL@tkܑ\9K>Z`Y6?ꦵIAa9Sm0!CX{co`'nj>*'ukc-4 %PrZ.|$h$CwrNJR(JR9NU^B!zi=4#Ӎ␬k%8쫓k,mִ[݆wz;\,#d4 Sgj(KKxc]<uVEwJ\%K3G-Ipu,)m/Ѐ$!0TD8^fh_Xuɝor3]~jR[H#cޥ8{PeS(7PjުZlO,V[mvz2C#+ηٴMdܠ q~ rV`ymO; 64iMHS0au[(LD{q٩\,-(n-sgMu<ݢ~UMT$lxRhRufqKjEnD BM`^URXx =1{YS~ Ү%ىGpޯ^f'0İO⷗ROÈ?^Gs<Տ3 9c?uxZ`ȓ>6TCMBÃbqC:SҬ{:5)ݙT~RsQVðSfƒi osw5koNј'E_huƘrmxpZ#XOXlV,[]"vjmz;|TwQ56l4RHrW{8J\nRy_JR(JRcomponents/com_sef/assets/charts/pie2d/params.xml000066600000013456150771655450016176 0ustar00
    ATTRIBUTES
    components/com_sef/assets/charts/pie2d/index.html000066600000000054150771655450016154 0ustar00components/com_sef/assets/charts/pie2d/icon.png000066600000010416150771655450015620 0ustar00PNG  IHDR00`nsRGB pHYs  tIME  ՑoIDATXUyYgr9Wu pR=_&vXQ`C29C+vt}<~ UQQQ/'9Y4Z*f4jEy^IǨ9C̨& A$z}n(았*< *D+FBI( F~iıp[fd z T"CR(8Jnr3@sHZh0ba5 SaVӣŭ;~݃PQMY*|і[+KKΦbV$ IP6vWwC[հ޻,֖HA0dh2]>h|͹Lnk %ʓ D*XS_m_?5eUḡ'pvS?lh&B0<)x}}ZU(TAB4QܽG}뻿z2]_GQK)cœY]N6R%"Ɍ{ͶWtd@d A%gOsOtnRZc4+,]ok{4qd,@p:TtYz'")R w\RD)jɵ˾s Z YBR[ ofmw&[gBD5X4CNgX{ftR X IC89=l[K4QdEHP%q|v^O|=vtZҝ'Gn5EA*\PҲѷ/(/J $9͝fF9JOS89 `23U0}^kopŅ%5ttqpҥvTC(PIn5`ɇE6^ CCe¼@͎{7>Tiz] nl=v5\aJ-=>¬!,0DY_ܾy2Okd)#; LA`Ũ &/z֮UV됍6-cnwN/wR)AhQh:-6W0tk~jDj_flZ$B짋C} 0$0"mto3#0UW򝧳%kalD'z{׻WO>ásg $( NӲ?;gC%S%ڊ/u$C$"*hCpkmj'nk/~ݿwtsY?MJ9!ǧ'Ww^fWA H<绘X겧!8դJT''uhY-Jܧ櫷yڏ㵷GѿL,͇BZhn Xtz75Ʃ]D;][{vtcF RTrNC0C]>i}\c'O 'EK$AlѭrbdOO${@Aw[t/an;G|_{pӅ_dcK3,T @[#B+ (h 5K,g7K)2ƀV6p^W=w}mv?[C55/7y`U<%ęY+}ђt<u qTWӶk5̫jpn ~7?xr㽽Sl̓''KP;&T"΢7V 3R`9Խ٧[Pb$FVj ^h +@ Yw<GdzNpFIɣ 0,4 EX"͝d)eC,d` &Ti-h뛏ŵ(F c%R᱂SJ􉦨JpW_R!tҋDP?R\#SjBnzet:Xj@ԒDgD+Q9%:ZnZG3 +8V+̚3LҒa(Xn|߹>,9YDmٿ,EJFJyr[h-&Y TI "LF#@U s07yޕ7Y$0YU&0KYLlUZT3Cͪ<% 3J(pePprT*YQ4zP_?l^}y< )\A GH"&em4ɕ\جbeaxV T;g!F*(Z/}a\{TwgZƳHJUC79` {i> K93BPʳP҂)fX cwˍ3bg AFi1$XUȱw JD\}]MV7s*ɮT3<:][U_hJ`+ˆZ+=-m 3@m:E@H+1 00!d5t3 5lS[U%Q2KjHuz/\12D ?cɋPU+:RJJV>J=k,"J*`hNN.(yҳI%ȘR2/}_ s%fZ==\{Ҵ) `47 j!PLl9JbQ, kUvXރoJa3 ('\,[/ 놦1%`x'{Wy9BT #00xD3K)j>t^KU2W( x]*$Mn9,a..Ìn k1KғT (xGJ5en&CH0C[yŶ//+kM&d*Y""RJQ)W_m_鵚] s`J273x22t͗7=_|%&d-'io ;jd91%TJmD~~t)N82 4E?#ي$`&}[-Ǘ^:x;iʥn6.CȜ#"2IE-5Ϳ?֥I^R(1l \mw {YgZIHգw^<ucQ RgC0F%/M*pכmj.E13IaffTJ9ל3f䠌Зs{k+]bP+jDr>?D3b܄|}porIceP`f!HV% @R]tO/?_݈vڏlYF1~g\NO&$XiB`5e|p{ZbZՄe% F;X,}'xh-t1 I0 Y<` 1!g5?>aƽ5L? <fBaCЬۍ7^s6{y l Ogx@=%@i(Ck gs<&"St Eˊmlmx•hc`KeJPj@3WZsP55)F&Oqza7}uZ"P׶FfmsN9DZjA,WLʩY@+AR X M-ٳ1GbU* !R!;{skZ>R~J/GS €x%eKy*ޘRb$8I*I\5m)}Ԋ`8JC"UjIENDB`components/com_sef/assets/charts/pie2d/chart.swf000066600000041214150771655450016004 0ustar00CWS3x;MoVm]v#88igL^>$g8vm;$W]nLuWOUc Iœ`= !` @c; X@B [UIxQn{ι{ιbO"z 7ۙg%0]sc$o!]0ܲc6<ӮQ!ˮ_xO͊-ˆYfղK%3{[MCBw͚Q\a*e=cVEYٮ(ም9؞CW-h]x[e %e95e۲d)X :fJ8<04\Z({$j.vdzIh@yn6LZ̼Y7l5,hV/dE ѺC&FdTr6.ڦPSُ0֬"bQW7ܖ+6_ANnfQercj<Ǩ;= (Ȯnc7Pl5t,אztWm„%fis`^΍bfr (+7+Ɩk{z΄`.,oѬW T.]/oo[w`;YfI.?1rG9l@T.k HrXy۩@}bEmqXU(pb+fJ[3P ZDIѮG)nqk 7T7Ku@ {"̨ _ |L螧AL /oLwȁ>K6>8k1w®/6fA)Tf2! I~b?%n!"(v!j"ue ѱ2G̈HQu,aD Fۻ[C|(צּ_"_{z"E@х0wߡp{34< A 4sM"w OKi}XXUsB@KO-= (=NtPʃ-[9Lm(x} jÙUY=Gd$Ր(.T>F>Nާ1d(4Rq]Žvf&+wY;LJBR(̲!v9 <7>Bэ vƔ:W"+3AC1Zpa ejTZ[_<)`_+,H7 )\$O2O ɶ/rPiey;&-9[4m1ox`ws)%A8tUB+ }? 3!9YZ9?RqEJ#UXdg,wdwRSiJRв==V(jy;GDާ "x@Âr1>zpKxXcz<4o_sqCX7j#G#j#Gm>F|PV!}*{xslw 9vmժ c^6-Ͽ''@{<{Ţ؎zDi fom,]tJ}֦2Gpטv)7~i<f3]m+s!ְLn!вƁޝ̢7#.v{⪻c 3xϦIgFl4ÑOltZہn;n 3rU$9/2M5FY"zJkq`?ۼDtNRZrhJ YDsNYĜ#t$.${E˒Hl'( .#ZSxt @¢pҚwq.Аq s?ZgٞJ)NiK.hI^ iW.v) xIį#YwE#DZ${$%8b(8^~ob ts!s;v@X6}I$֮о\:l9WnF?Be*+g0Z5l%Q'Q7fN7}G氬+ֻXWpaar@?GBTt@ ЄJPѪǃ?S?Xg{`  T{]br\ jwnoU:WL&4z)豻WWN| umCƴRj}USpC1ʺ+U4LgxF$rǭFu!.eI*c3 u%Ob^#+Bq))QγOQ;q:.#~aܡm_P,X$Ob13C۸TZ1J T8$ kf@f$jQCH5 MXR 5QxK,XҮP䒁uk= r\/S] lP] n}䥀 y%.girh?wK' >Qw'?8\0J\W}5A$ ο=߹BY[ 2>ٰ .ٗ.!50Ӝ'Ma[[ lؕLJqMls:kj}5`͚nxB;*?BEn3* Pz\`:NIyv^7uB5HsrOjZwf"0Qcz<&3Q1aF!{?R((<OJUs!")j\/kmD:~d[u+,Ҟ(e]i"s23|2R ĥQt6+r T~s9NMnzzj SSd?["  '2CLNߞ8^?@"ڈ¿ k?I9!" d0@zo崾 G+7EHky 7z/p$A{s鍷_ޜg`1-W P=fN`KQ|dQu2%\.{OP:JIJOT*/p'&1*DM v{G7zHL)Pr@I'NR1eHLWoOMrL> w z7d%ϠȮ&3הl˱{dT%r|G3t^~:H7b1 lLK9}dإ=NiO? ĎJ9'-䓨R h9'I^qc2/0qQኌT\gû w^iag̡Hoj5ﺌH\ 4Ȟ}R8ӑ.nĶo(q% 3> @>SIZ?lv?ꧦoj۔Nb]~>-nZIm*,3K0sp ãLygzRm'V7Mӡ0#,ۯÇ9fyRzYJ')]tK.SBJRvBSw*|a +3@Z?6O+lNǙ'-ldHz8!T6;jGzvlk$8s~f%}\ͤޫOq*~H IQ^7F2K~}{5c!rԋ A9t,Eb "Yڋj@6PvҐ{5AP (}Hj+\b:o![7"f1A7~g J /z^)|Ԩ}z~Ry%0D@EW` ,u9i,2*AK~.TZeT֮b_/gEKzЕv\v֣9}dDuTEYe, WČn592GmpԨlP #l)yzYkPaqa8 WY.|cQ%~e(^^i:mSK~ӴZ7 vW~۴*5BGdKŹUO0혥gCʫ1 {Y?ǂQ1}D<xG&*Mw {%21IP s欚:#hI[fpqwߌ[SnD53䜝RÏ;X$ “=3*ek4QyܗVOL [(zrMc ZdT)RЌleJPoQW!? )UYTM H֌֯MX>*KW8cIyb:S=rZӠ1@ s}"zU<]3YƩt_Qt&S _{0tW?\Ga$a9цK4Jt `LQ26AW(ẫIqRBcDo/7}1fx Ii 74\΄̈́+(p6,ij:e*m%aȴ%mhM{;m6lD't[ 3O>- #Ǻ#Ov=ӦށxDLsF҉3ٙL:̤ L̤ξ@Ą;HS%|OE-^|_ n&C}Fҟ;J2?1=r?W?%]c@%?F e@g@(ZGOx ^Q*vADo6Ĝ*+>D_!`9IRKG~J"T3ɝG&L&Nda `TҙrSE f_?DQ Y Q 4L!La*Re) SE SE& QbeDӎ'"F~!eK 58qBD # K4)D^(܏KMJ2sh:ǕHt5\'a=^IBnK%L50UJ3L5ZX S! Qi\҉qBJcD 0L%ng&%Di*[xʦx;A˄%(%ǠژD M2H'< esM0+h /< daɆS SMʡ"uY/@ - BR.(]P~p9K̕Q⟑gBw`U<˫rdL8M#=qtr 1 f%"tԘ.FYp泝ATpG9|Τ:X%; t"EdLb<\mscQQ /S21qOd|~3N)C+$k?%{ z99ZV%:ml\b 5p\Jd+F)?wɼI_4gstPȊ.i9}\ζd]@I=#é( T(=ʊ|̘sU̧ 2sAh- h%.첖crüZqVr hsHJt7WLԆ5c >qคdW~2a2v\ ԛ{ʁc#Rm O0JmZbn٦)1 D[{B)OŤ;-^ e$~20}k׸m_4\e(d %e(NbVRȿJkbiRQ)Z+3I&bk\{w0`p8SD_d2V$!փA6mƋ k̀mp~EVb-#BBIba QCk;FОb5 ]>Z` U6]Y5P9q}*'>noLMAǖ&Z*^7 dS,x jSZgVgw}A%nl]OnĔ*I; 5FVH2qx bl(t7 19&?K?Fm8{P7E.}>JڇJ`/DV7qK5'Wh^)Q)p.6(Fl<2j% nB_lBXMO!Æ=Ҙm݌u00ByM)0QcY /ŸDl~4wcL* rU>Y=8Q M[覭(D+7>Pl'eط8Cp_zCc:87f `0(0Q ;Dc"c8L]op1^.CiìH/ O<(%'N<#Z*dʐ+`i uLdp //햺?r+ qg/Ic E I O,Z&IHS(Jqxj +S:[U;'ub{Ew^E4;zE@!xMsu=npʆv}Vujv}Ӎ_X ~N:NW <+@bobwBXYxp;'0r g}0n!?NE|#O_lU!^(ھyMZKt`k)οFmT'#Kz yKRd5:q&&pJ19$i431gy1dZVAZh&4Z`M/lH$|^ C/> R8@/dye@0[4Mq7nZA|5ӉNWVHi#-d#i-q.mDj&(@-Bjͮ N@J2dp=fH +C1Z4Zvއuߩ(.mf6 2FT6\}tri[zDcv)Hu`TL,wiAG Qܫ_3ܟ'<(D.G#؛&9&WR?"+I ̝y" srtg]gp1 rY| 7 ýmbӫ0~Fڟ.pT'{]NkҢN} YT࠿`vX2[S `I5)S|Py)Teh t*wu9o_OGF%L?G%Cgۊr2X2%t ) C!?QQO7w6L_bmU2IGvnBJcGɝx^*70aϸqqxRB[YIXI|O\$ 0˦CͶ1{`6<ϼSsnJ: 5,7ZX:ZXoUUzSMG!m}iӮ],{3B 88;VՇݮRKRnWtUsN}'9JV0M76\Δ6-\y ~(Ys^/Rg˰iv ځGz ,ZV=y4\ Уϭ^y}cb{5}M";UgyБ2gUT=%jYSfmu}x>f Ǖ.>EO2ʯfT6GE߿kmkv~ :gm W4{_u\󍽶g=8utPT~S軅 Fk(F55gw;2x_lnAզ5?B7W},9ܽƻDž|c9T2|M-@,?ڐi3n|CpN`_Km3KOͲ:|*_A=dCr;b>CM/y/?&Qo4OwHቍ? mX!m9Z Ų} J 8bIwI U ~h:[iaX7[`J.k |ᝑcҰjk0}-߆w*Q'(YRysOѶzyTuj -TK5ғ Ϩ- x?y$ybTؿZ;Ơ e6 H-S<.rkav-k^SɐCv.wsXj9^i}Q$];^~c.cI.Օ^Y.?4aN#V[z{ԗڰgѺy#/$򄢡ȫz:Nu&W>V<њKZWՓN+u]ut-->DҼo+aSo&YEt=۸3 }M`f,ua?r>Cv yיE`X_h>ƾ~Iswۥ޵ K;u)e=J}Tծ+~M mϚGB-^| ߝqjf9f|LhW1*ĢbY~Q~UXϷf`@jϲVZʹҬ3ÞLi"_ D^ mgԊK_? %#Nv.^V&^[HqK6d8nc+\_"xܳѬ=ؠ^;wn[V#g (5]L*RZ4 |͠>Yl{d|t+TUN/}۱qrzϲKƄOYP6[.?Ws_X0׮!_ EXRM-Wj^ʳV(57z=ؑs!sTdң}*lo&<5~_$\|quo{7;fcaTݨTDG/CSCJ^'3s%)Mob!1siEbY~瓬.7I*}',vW=jE`:( >20HRCE4{ŰݲuS5GFwOMF$ϓ̜+E8wD\ (`jS$> w:DQbF͑SOSZ;tYǒUڅk)|PVBA'gӍop^> o R}<}mE°y!k>d, f 6tQoںRÝ瞤5>9V6:yHJrw4r56<Â/1r5Y'q-3bum#YC.+53;|X6Vu]jO J@E?gd?9`z'+i-Os4E7Β?׍+atOoD>BSg>{-WxIJS{޻[=OXHC(0e&=bsRoȰKg_z⎗"UprzZa5I ?dl'h2rh OU@MnXv۽25W 1gg o3z!  zYPihwfPx}e5zg;0ۤ|m<Q ZِYՐW3i=sʱۑ䚖q@!X_zxMJҸDي\zΝ7:v\q="E= C`Dyo܄r@dk]E^v1o7;]IvZ::r$yf94YP  l̠k{sYu Om7ldQ!7'^Uy<™eiY(4e` .FPo2xr%k ,浉# ʤ |p!7Xt{NajvO]]';NII,C?h./m>79ӕ ~PFAK1t1#9jZTehY #F1W*aHu>_q*6>Hי&bրޤXGs2KT̍&,*"?>NruLBiS庞Y_D.TYfaPU~b.CB"0c͟FٹL8~QDOh8Sm5(AF1yϫ^N${)3sGDԈ[7ќd=8F* FؽNc[֦5%_>N/yY>uLN@ Yԥ QQFr d6.1iij|OIzSِ|sJ6!"R>7&\N {# eaB#SMIU\e&eNU=EϫQ$9**Ogu۲"px:^,C#JZ*åo8} kʃ!UB.sWQ\S@[+ KY=o m9t3%];a7Wq|='\:F]縮gH،Ml$^ıdD_hxBqfH#>{M#E~&躋8Tt)RRr" y#zvUٕt>2:Gu9O߸AtrJ+|%D zSI囶OطcR)ǘ*!W1td{JPVݬ]Խ+bJl{θ'9W6/nΒ~5ʢ/Syry7zuRkSE ƍ]2/Z1, =r:ZP>ܽO@ 2P56Mz@C` L`+`' k`lpd\p* @ @0tL  @4/A>(,q`{ԅ~N1C|M `9uC-)&o+GówM8 4x, Bq DuHfA'`o=-M7g'2FrVJ!ĸ:+UD pz%λTā{H2޷=m'IR{jcgT#@klcL^V>hn5KMHq3jAmZ]q+SBjV^{e4^qO~%hӀG$-YI< TQaN<Νj|[+/k1ٻ8x(5Xw{fHEʶ;`{^Cl(K]Ҋ%yշ8r`1$я&[\%7N [ߌV0*rZJcc_Aq?SE6components/com_sef/assets/charts/pie2d/params-set.xml000066600000006400150771655450016756 0ustar00
    components/com_sef/assets/index.html000066600000000054150771655450013665 0ustar00components/com_sef/assets/css/index.html000066600000000054150771655450014455 0ustar00components/com_sef/assets/css/words.css000066600000000726150771655450014336 0ustar00/* AUTOCOMPLETE */ ul#autocomplete { position: absolute; border: 1px solid #9a9a9a; background-color: #ffffff; overflow: hidden; margin: 0px; padding: 0px; color: #000; } ul#autocomplete li { list-style-type: none; /*font-size: 8pt;*/ padding: 0px; margin: 0px; cursor: pointer; display: block; width: 100%; } ul#autocomplete li.selected { background-color: #39f; color: #fff; } components/com_sef/assets/css/default.css000066600000007376150771655450014634 0ustar00div#cpanel { margin-right: 15px; } div.icons h2 { font-family: Tahoma, Arial, Verdana; font-size: 110%; } /* To override the default Joomla behaviour, * which causes loading of /administrator/separator URL */ .icon-16-separator { background: none !important; } .icon-32-install { background-image: url('../images/install.png'); } .icon-32-uninstall { background-image: url('../images/uninstall.png'); } .icon-32-upgrade { background-image: url('../images/upgrade.png'); } .icon-32-delete_f2 { background-image: url('../images/delete_f2.png'); } .icon-32-import { background-image: url('../images/reload_f2.png'); } .icon-32-export { background-image: url('../images/download_f2.png'); } .icon-32-clear { background-image: url('../images/icon-32-clear.png'); } .icon-32-xml { background-image: url('../images/icon-32-xml.png'); } .icon-32-services { background-image: url('../images/icon-32-services.png'); } .icon-32-google { background-image: url('../images/icon-32-google.png'); } .icon-32-yahoo { background-image: url('../images/icon-32-yahoo.png'); } .icon-32-bing { background-image: url('../images/icon-32-bing.png'); } .icon-48-artio { background-image: url('../images/icon-48-artio.png'); } .icon-48-edit { background-image: url('../images/icon-48-edit.png'); } .icon-48-update { background-image: url('../images/icon-48-update.png'); } .icon-48-docs { background-image: url('../images/icon-48-docs.png'); } .icon-48-help { background-image: url('../images/icon-48-help.png'); } .icon-48-info { background-image: url('../images/icon-48-info.png'); } .icon-48-manage-sitemap { background-image: url('../images/icon-48-manage-sitemap.png'); } .icon-48-manage-tags { background-image: url('../images/icon-48-manage-tags.png'); } .icon-48-manage-words { background-image: url('../images/icon-48-manage-words.png'); } .icon-48-301-redirects { background-image: url('../images/icon-48-301-redirects.png'); } .icon-48-url-edit { background-image: url('../images/icon-48-url-edit.png'); } .icon-48-url-delete { background-image: url('../images/icon-48-url-delete.png'); } .icon-48-url-user { background-image: url('../images/icon-48-url-user.png'); } .icon-48-404-logs { background-image: url('../images/icon-48-404-logs.png'); } .icon-48-url-update { background-image: url('../images/icon-48-url-update.png'); } .icon-48-web-crawl { background-image: url('../images/icon-48-web-crawl.png'); } .icon-48-cron { background-image: url('../images/icon-48-cron.png'); } .icon-48-statistics { background-image: url('../images/icon-48-statistics.png'); } .joomsef_feed { padding: 10px 15px; } .feed-item { margin-bottom: 15px; } .feed-title { font-weight: bold; } table.admintable td { padding: 3px; } table.admintable td.key, table.admintable td.paramlist_key { background-color: #f6f6f6; text-align: right; width: 140px; color: #666; font-weight: bold; border-bottom: 1px solid #e9e9e9; border-right: 1px solid #e9e9e9; } input.classic, select.classic, button.classic { float: none; margin: 0px; } div#jsInfoText { background: #c3d2e5 url('../images/notice-info.png') 5px 5px no-repeat; padding: 10px 10px 10px 45px; color: #05b; font-weight: bold; min-height: 20px; } /* Align extension parameters */ fieldset.panelform div.control-label label { min-width: 250px; } /* To fix problems with Joomla 3 */ .sef-width-60 { width: 60%; } .sef-width-40 { width: 40%; } .sef-width-100 { width: 100%; } .sef-width-50 { width: 50%; }components/com_sef/assets/css/joomla3.css000066600000003730150771655450014542 0ustar00/* Divs */ .fltlft { float: left; } .fltrt { float: right; } fieldset.adminform { margin: 0px 10px; } /* Tabs */ dl.tabs { margin-bottom: 18px; border-bottom: 1px solid #dddddd; display: table; line-height: 0; clear: both; } dl.tabs dt h3 { font-size: 1em; font-weight: normal; margin: 0; padding: 0; } dt.tabs { float: left; line-height: 18px; margin-bottom: -1px; } dt.tabs a { display: block; padding: 8px 12px; margin-right: 2px; line-height: 18px; border: 1px solid transparent; border-radius: 4px 4px 0 0; } dt.tabs a:hover { background-color: #eeeeee; text-decoration: none; border-color: #eeeeee #eeeeee #dddddd; } dl.tabs dt.open a, dl.tabs dt.open a:hover { background-color: #ffffff; border-color: #dddddd #dddddd transparent; border-style: solid; border-width: 1px; color: #555555; cursor: default; } /* Sliders */ div.panel { border: 1px solid #dddddd; border-radius: 4px; margin-bottom: 3px; } div.panel h3 { font-size: 1em; margin: 0px; } div.panel h3 a { display: block; padding: 5px 0px 5px 10px; } /* Icons */ .cpanel div.icon, #cpanel div.icon { float: left; margin: 0px 15px 15px 0px; text-align: center; } .cpanel div.icon a, #cpanel div.icon a { border: 1px solid #cccccc; border-radius: 5px; display: block; float: left; width: 126px; height: 110px; text-decoration: none; vertical-align: middle; color: #565656; } .cpanel div.icon a:hover, #cpanel div.icon a:hover, .cpanel div.icon a:focus, #cpanel div.icon a:focus, .cpanel div.icon a:active, #cpanel div.icon a:active { border-bottom-left-radius: 50% 20px; box-shadow: -5px 10px 15px rgba(0, 0, 0, 0.25); } .cpanel img, #cpanel img { margin: 0 auto; padding: 10px 0; } .cpanel span, #cpanel span { display: block; text-align: center; } /* Date selector */ .input-append { display: inline; }components/com_sef/classes/index.html000066600000000054150771655450014020 0ustar00components/com_sef/classes/config.php000066600000066404150771655450014014 0ustar00|:|;|{|}|[|]|---|--|..|."; /* string, suffix for "files" */ public $suffix = ""; /* string, file to display when there is none */ public $addFile = ''; /* trims friendly characters from where they shouldn't be */ public $friendlytrim = "-|."; /** * generate canonical links * @var bool */ public $canonicalLink = true; /** * page text * @var string */ public $pagetext = "JText::_('COM_SEF_PAGE')-%s"; /** * Should lang be part of path or suffix? * @var bool */ public $langPlacement = _COM_SEF_LANG_PATH; /* boolean, convert url to lowercase */ public $lowerCase = true; /* boolean, use the title_alias instead of the title */ public $useAlias = true; /** * should we extract Itemid from URL? * @var bool */ public $excludeSource = false; /** * should we extract Itemid from URL? * @var bool */ public $reappendSource = false; /** * should we ignore multiple Itemids for the same page in database? * @var bool */ public $ignoreSource = true; /** * excludes often changing variables from SEF URL and * appends them as non-SEF query * @var bool */ public $appendNonSef = true; /** * consider both URLs with/without / in theend valid * @var bool */ public $transitSlash = true; /** * redirect URLs with / on the end to URLs without / on the end * @var bool */ public $redirectSlash = COM_SEF_REDIRECT_SLASH_NEVER; /** * whether to use cache * @var bool */ public $useCache = true; /** * maximum count of URLs in cache * @var int */ public $cacheSize = 1000; /** * minimum hits count that URLs must have to get into cache * @var int */ public $cacheMinHits = 10; /** * record hits for URLs in cache? * @var bool */ public $cacheRecordHits = false; /** * Whether to show error message about cache corruption * * @var bool */ public $cacheShowErr = false; /** * translate titles in URLs using JoomFish * @var bool */ public $translateNames = true; /** int, id of #__content item to use for static page */ public $page404 = 0; /** * record 404 pages? * @var bool */ public $record404 = false; /** * if set to yes, the standard Joomla message will be also shown when 404 * @var boolean */ public $showMessageOn404 = false; /** * whether to set the ItemID variable when Default 404 Page is displayed * @var boolean */ public $use404itemid = false; /** * ItemID used for the Default 404 page * @var int */ public $itemid404 = 0; /** * Redirect nonSEF URLs to their SEF equivalents with 301 header? * @var bool */ public $nonSefRedirect = true; /** * Use Moved Permanently redirection table? * @var bool */ public $useMoved = true; /** * Use Moved Permanently redirection table? * @var bool */ public $useMovedAsk = true; /** * Definitions of replacement characters. * @var string */ public $replacements = "Á|A, Â|A, Å|A, Ă|A, Ä|A, À|A, Æ|A, Ć|C, Ç|C, Č|C, Ď|D, É|E, È|E, Ë|E, Ě|E, Ê|E, Ì|I, Í|I, Î|I, Ï|I, Ĺ|L, ľ|l, Ľ|L, Ń|N, Ň|N, Ñ|N, Ò|O, Ó|O, Ô|O, Õ|O, Ö|O, Ø|O, Ŕ|R, Ř|R, Š|S, Ś|S, Ť|T, Ů|U, Ú|U, Ű|U, Ü|U, Û|U, Ý|Y, Ž|Z, Ź|Z, á|a, â|a, å|a, ä|a, à|a, æ|a, ć|c, ç|c, č|c, ď|d, đ|d, é|e, ę|e, ë|e, ě|e, è|e, ê|e, ì|i, í|i, î|i, ï|i, ĺ|l, ń|n, ň|n, ñ|n, ò|o, ó|o, ô|o, ő|o, ö|o, ø|o, š|s, ś|s, ř|r, ŕ|r, ť|t, ů|u, ú|u, ű|u, ü|u, û|u, ý|y, ž|z, ź|z, ˙|-, ß|ss, Ą|A, µ|u, ą|a, Ę|E, ż|z, Ż|Z, ł|l, Ł|L, А|A, а|a, Б|B, б|b, В|V, в|v, Г|G, г|g, Д|D, д|d, Е|E, е|e, Ж|Zh, ж|zh, З|Z, з|z, И|I, и|i, Й|I, й|i, К|K, к|k, Л|L, л|l, М|M, м|m, Н|N, н|n, О|O, о|o, П|P, п|p, Р|R, р|r, С|S, с|s, Т|T, т|t, У|U, у|u, Ф|F, ф|f, Х|Kh, х|kh, Ц|Tc, ц|tc, Ч|Ch, ч|ch, Ш|Sh, ш|sh, Щ|Shch, щ|shch, Ы|Y, ы|y, Э|E, э|e, Ю|Iu, ю|iu, Я|Ia, я|ia, Ъ| , ъ| , Ь| , ь| , Ё|E, ё|e, ου|ou, ού|ou, α|a, β|b, γ|g, δ|d, ε|e, ζ|z, η|i, θ|th, ι|i, κ|k, λ|l, μ|m, ν|n, ξ|ks, ο|o, π|p, ρ|r, σ|s, τ|t, υ|i, φ|f, χ|x, ψ|ps, ω|o, ά|a, έ|e, ί|i, ή|i, ό|o, ύ|i, ώ|o, Ου|ou, Ού|ou, Α|a, Β|b, Γ|g, Δ|d, Ε|e, Ζ|z, Η|i, Θ|th, Ι|i, Κ|k, Λ|l, Μ|m, Ν|n, Ξ|ks, Ο|o, Π|p, Ρ|r, Σ|s, Τ|t, Υ|i, Φ|f, Χ|x, Ψ|ps, Ω|o, ς|s, Ά|a, Έ|e, Ή|i, Ί|i, Ό|o, Ύ|i, Ώ|o, ϊ|i, ΐ|i"; /* Array, contains predefined components. */ public $predefined = array('0' => "com_login",'1' => "com_newsfeeds",'2' => "com_sef",'3' => "com_weblinks",'4' => "com_joomfish"); /* String, contains URL to new version file located on server */ public $serverNewVersionURL = "http://www.artio.cz/updates/joomla/joomsef4/version.xml"; /* String, contains URL to automatic upgrade script */ public $serverAutoUpgrade = 'http://www.artio.net/joomla-auto-upgrade'; /* String, contains URL to registration check script */ public $serverLicenser = 'http://www.artio.net/license-check'; /* Array, contains domains for different languages */ public $langDomain = array(); /** * If set to yes, new SEF URLs won't be generated and only those already * in database will be used * @var boolean */ public $disableNewSEF = false; /** * If set to yes, the sid variable won't be removed from SEF url * @var boolean */ public $dontRemoveSid = true; /** * If set to yes, the $_SERVER['QUERY_STRING'] will be set according to parsed variables * @var boolean */ public $setQueryString = true; /** * If set to yes, URLs that can't be parsed by JoomSEF will be parsed by Joomla's router * @var boolean */ public $parseJoomlaSEO = true; /** * Semicolon separated list of global custom non-sef variables * @var string */ public $customNonSef = ''; /** * If enabled, JoomSEF will try to set language according to user's browser setting * @var boolean */ public $jfBrowserLang = true; /** * If enabled, JoomSEF will store the user's language selection in a cookie for next visit * * @var boolean */ public $jfLangCookie = true; /** * Array of [lang] => subdomain to use the subdomains for languages * @var array */ public $jfSubDomains = array(); /** * Whether to use default index file for content sections and categories * @var boolean */ public $contentUseIndex = false; /** * If set to yes, the URL variables will be checked * to not contain the http://something.com or similar junk * @var boolean */ public $checkJunkUrls = true; /** * Pipe (|) separated list of junk words to search for * @var string */ public $junkWords = 'http:// http// https:// https// www. @'; /** * Semicolon separated list of variables to exclude from junk check * @var boolean */ public $junkExclude = ''; /** * Sets if the non-SEF variables should be prevented from * overwriting the parsed ones * @var boolean */ public $preventNonSefOverwrite = true; /** * Main language - this language won't have language code added to URL * @var mixed */ public $mainLanguage = 0; /** * Whether to allow UTF-8 characters in URL * @var boolean */ public $allowUTF = false; /** * Whether to number duplicate URLs or use the duplicates management system * @var boolean */ public $numberDuplicates = false; /** * Artio site login name * @var string */ public $artioUserName = ''; /** * Artio site password * @var string */ public $artioPassword = ''; /** * Artio download id * @var string */ public $artioDownloadId = ''; /** * Enable URL source tracing * @var bool */ public $trace = false; /** * Tracing depth if enabled * @var int */ public $traceLevel = 3; /** * Create canonical link automatically for URLs with nonSEF variables * * @return SEFConfig */ public $autoCanonical = true; /** * Whether to SEF URLs containing the tmpl=component variable * * @var bool */ public $sefComponentUrls = false; /** * Whether to check for newer versions in control panel * * @var bool */ public $versionChecker = true; /** * Generator meta tag * * @var string */ public $tag_generator = ''; /** * Google key meta tag * * @var string */ public $tag_googlekey = ''; /** * Live.com key meta tag * * @var string */ public $tag_livekey = ''; /** * Yahoo key meta tag * * @var string */ public $tag_yahookey = ''; /** * Custom meta tags * * @var array */ public $customMetaTags = array(); /** * www and non-www domain handling * * @var int */ public $wwwHandling = _COM_SEF_WWW_NONE; /** * Enable metadata generation? * * @var bool */ public $enable_metadata = true; /** * Enable metadata auto-generation? * @var int */ public $metadata_auto = _COM_SEF_META_GEN_EMPTY; /** * Prefer joomsef tile? * * @var bool */ public $prefer_joomsef_title = true; /** * How to use sitename? * * @var int */ public $use_sitename = _COM_SEF_SITENAME_AFTER; /** * Sitename separator string * * @var string */ public $sitename_sep = '-'; /** * Rewrite keywords? * * @var bool */ public $rewrite_keywords = true; /** * Rewrite description? * * @var bool */ public $rewrite_description = true; /** * Prevent sitename duplicity? * * @var bool */ public $prevent_dupl = true; /** * Sets the tag behaviour * @var int */ public $check_base_href = _COM_SEF_BASE_CURRENT; /** * Internal variable for sitemap change flag * * @var bool */ public $sitemap_changed = true; /** * Sitemap XML file name * * @var string */ public $sitemap_filename = 'sitemap'; /** * Whether to use HTTPS in sitemap URLs * * @var bool */ public $sitemap_ssl = false; /** * Default Sitemap indexed state * * @var bool */ public $sitemap_indexed = false; /** * Default Sitemap change frequency * * @var string */ public $sitemap_frequency = 'weekly'; /** * Default Sitemap priority * * @var string */ public $sitemap_priority = '0.5'; /** * Which items show in the sitemap * * @var bool */ public $sitemap_show_date = true; public $sitemap_show_frequency = true; public $sitemap_show_priority = true; /** * Whether to automatically ping generated Sitemap to google, yahoo and bing * * @var bool */ public $sitemap_pingauto = true; /** * Yahoo application ID * * @var string */ public $sitemap_yahooId = ''; /** * Array of sitemap ping services * * @var array */ public $sitemap_services = array('http://blogsearch.google.com/ping/RPC2', 'http://rpc.pingomatic.com/'); /** * Whether to add the rel="nofollow" to external links * * @var bool */ public $external_nofollow = false; /** * Whether internal links for words will be enabled * * @var bool */ public $internal_enable = true; /** * Whether to add rel="nofollow" to internal links * * @var bool */ public $internal_nofollow = false; /** * Whether to open internal links in new window * * @var bool */ public $internal_newwindow = false; /** * How many word occurences will be linked * * @var int */ public $internal_maxlinks = 1; /** * Whether to display ARTIO Newsfeed on control panel * * @var bool */ public $artioFeedDisplay = true; /** * ARTIO Newsfeed URL * * @var string */ public $artioFeedUrl = 'http://www.artio.net/joomsef-news/rss'; /** * Whether to rewrite index.php links in content and redirect them to / * * @var bool */ public $fixIndexPhp = true; /** * Whether to fix document format after route * * @var bool */ public $fixDocumentFormat = false; /** * Whether to filter global variables * * @var bool */ public $useGlobalFilters = true; /** * Whether the error log is enabled * @var bool */ public $logErrors = false; /** * Whether cron tasks are enabled * @var bool */ public $cronEnabled = false; /** * Whether cron tasks can only be run from local server * @var bool */ public $cronOnlyLocal = true; /** * Secret key to run cron * @var bool */ public $cronKey = ''; // Automatically lock created URLs public $autolock_urls=false; // Automatically update URLs public $update_urls=false; // Enable languages management from JoomSEF public $langEnable=false; // Where to place language public $langPlacementJoomla=_COM_SEF_LANG_PATH; // Add language to multilanguage content public $addLangMulti=true; // Allways use language public $alwaysUseLangJoomla=true; // Always add language code to URL on homepage public $alwaysUseLangHomeJoomla = true; // Get language from browser public $browserLangJoomla=true; // Get and save language to cookie public $langCookieJoomla=true; // Main Joomla language public $mainLanguageJoomla=""; // Subdomains for languages public $subDomainsJoomla=array(); // Translate Items public $translateItems=true; // Username for Google Analytics API public $google_email=""; // Password for Google Analytics API public $google_password=""; // Google API key for pageSpeed service public $google_apikey=""; // Google ID public $google_id=""; // Enable google tracking code public $google_enable=false; // Enable Demographics and Interest Reports in GA tracking code public $google_demographic_reports=false; // Use enhanced link attribution public $google_link_attribution=false; // Exclude IPs from tracking public $google_exclude_ip=""; // Exclude this level from Google tracking public $google_exclude_level=array(); /** * How should we handle the case when domain and SEF URL * have different languages? * @var int */ public $wrongDomainHandling = _COM_SEF_WRONG_DOMAIN_REDIRECT; /** * How should we handle the case when language doesn't match Itemid? * @var int */ public $mismatchedLangHandling = _COM_SEF_MISMATCHED_LANG_DONT_HANDLE; /** * Whether root URL should be redirected to correct language with 303 or 301 code * @var bool */ public $rootLangRedirect303 = true; /** * Whether variables in SEF URL's query string should be * handled as non-SEF for other URLs on the page * @var bool */ public $nonSefQueryVariables = true; /** * Whether VM currency is automatically selected according to language */ public $vmCurrencyEnable = false; /** * Language to VM currency association */ public $vmCurrency = array(); /** * Whether to replace index.php with current menu query (default Joomla behaviour) */ public $indexPhpCurrentMenu = true; /** * Whether to generate multiple sitemap XML files for different language domains */ public $multipleSitemaps = false; /** * File names for multiple sitemaps [lang] => filename */ public $multipleSitemapsFilenames = array(); /** * Whether menu associations should be used on multilanguage website */ public $langMenuAssociations = false; /** * Whether to update hits count for homepage URLs */ public $homePageHits = true; /** * Whether Joomla generated canonical links should be removed */ public $canonicalsRemove = false; /** * Whether canonical links URLs should be fixed */ public $canonicalsFix = true; /** * Whether the SEF URLs export file should be sent using chunked transfer * * @var bool */ public $chunkedExport = true; /** * Whether JoomSEF should redirect http GET requests to https * * @var bool */ public $forceSsl = false; /** * Whether Itemid should always be added to URLs (eg. the K2 link to user profile doesn't contain the Itemid) * * @var bool */ public $alwaysAddItemid = true; private function __construct() { // If the configuration file exists, load data from file $sef_config_file = JPATH_ROOT.'/administrator/components/com_sef/configuration.php'; if (JFile::exists($sef_config_file)) { include($sef_config_file); } // Get parameters // We cannot use the JComponentHelper::getParams() function as it // (for some strange reason) caches the component parameters! // 30.11.2012 dajo: we need to store parameters in custom_data column, as parameters get cleared // by Joomla when permissions are saved (as from Joomla's point of view JoomSEF doesn't have parameters) $db = JFactory::getDbo(); $db->setQuery("SELECT `custom_data` FROM `#__extensions` WHERE `type` = 'component' AND `element` = 'com_sef'"); $tmp = $db->loadResult(); $params = new JRegistry(); if (is_string($tmp)) { $params->loadString($tmp); } // Assign values $boolFalse = serialize(false); $dontLoad = array('serverNewVersionURL', 'serverAutoUpgrade', 'serverLicenser'); foreach ($this as $key => $value) { if (in_array($key, $dontLoad)) { // Don't load, use default values continue; } // Check if we have value from file if (isset($$key)) { $val = $$key; } else { // Otherwise get value from params $val = $params->get($key); if (!is_null($val)) { $newVal = @unserialize($val); if (($newVal !== false) || ($val === $boolFalse)) { $val = $newVal; } } } if (!is_null($val)) { // Change objects to associative arrays if (is_object($val)) { $this->$key = (array)$val; } else { $this->$key = $val; } } } if ($this->devel == 1) { $this->serverNewVersionURL = 'http://demo.tramin.artio.cz/new-update/joomsef4/version.xml'; $this->serverAutoUpgrade = 'http://demo.tramin.artio.cz/new-update/joomla-auto-upgrade'; $this->serverLicenser = 'http://demo.tramin.artio.cz/new-update/licenser2.php'; } } public function saveConfig($return_data = 0) { // Create params $params = new JRegistry(); // Set data to params foreach ($this as $key => $value) { $params->set($key, serialize($value)); } if ($return_data == 1) { return $params->toString(); } else { // Save params to database // 30.11.2012 dajo: to the custom_data column! $db = JFactory::getDBO(); $query = "UPDATE `#__extensions` SET `custom_data` = ".$db->quote($params->toString())." WHERE `type` = 'component' AND `element` = 'com_sef' LIMIT 1"; $db->setQuery($query); if (!$db->query()) { return false; } else { // Check if there's an old configuration file present and delete it $sef_config_file = JPATH_ROOT.'/administrator/components/com_sef/configuration.php'; if (JFile::exists($sef_config_file)) { JFile::delete($sef_config_file); } return true; } } } public function getPageText() { $pagetext = $this->pagetext; // if JText is used, parse out the string if (strpos($pagetext, 'JText::_(') === 0) { // make sure we use single quotes $pagetext = str_replace('"', '\'', $pagetext); // find first and second quote $quot1 = strpos($pagetext, '\''); $quot2 = strpos($pagetext, '\'', $quot1 + 1); // replace JText text with real text $pagetext = JText::_(substr($pagetext, $quot1 + 1, $quot2 - strlen($pagetext))) . substr($pagetext, strpos($pagetext, ')', $quot2) + 1); } return $pagetext; } /** * Return array of URL characters to be replaced. * * @return array */ public function getReplacements() { static $replacements; if( isset($replacements) ) { return $replacements; } $replacements = array(); $str = trim($this->replacements); if( $str != '' ) { $items = explode(',', $str); foreach ($items as $item) { @list ($src, $dst) = explode('|', trim($item)); // $dst can be empty, so the character can be removed if( trim($src) == '' ) { continue; } $replacements[trim($src)] = trim($dst); } } return $replacements; } public function getJunkWords() { static $words; if (!isset($words)) { $words = explode(' ', $this->junkWords); if( count($words) ) { foreach($words as $key => $val) { $words[$key] = trim($val); if( empty($words[$key]) ) { unset($words[$key]); } } } } return $words; } public function getJunkExclude() { static $excludes; if (!isset($excludes)) { $excludes = explode(';', $this->junkExclude); if( count($excludes) ) { foreach($excludes as $key => $val) { $excludes[$key] = trim($val); if( empty($excludes[$key]) ) { unset($excludes[$key]); } } } } return $excludes; } /** * Set config variables. * * @param string $var * @param mixed $val * @return bool */ public function set($var, $val) { if (isset($this->$var)) { $this->$var = $val; return true; } return false; } /** * Returns the singleton instance of current configuration * * @return SEFConfig */ public static function getConfig() { static $instance = null; if (!$instance) { $instance = new SEFConfig(); } return $instance; } } components/com_sef/classes/seftools.php000066600000137605150771655450014407 0ustar00version; } } } return $version; } static function getSEFInfo() { static $info; if( !isset($info) ) { $info = array(); $xmlFile = JPATH_ADMINISTRATOR . '/' . 'components' . '/' . 'com_sef' . '/' . 'sef.xml'; if (JFile::exists($xmlFile)) { $xml = simplexml_load_file($xmlFile); if ($xml !== false) { $info['version'] = (string)$xml->version; $info['creationDate'] = (string)$xml->creationDate; $info['author'] = (string)$xml->author; $info['authorEmail'] = (string)$xml->authorEmail; $info['authorUrl'] = (string)$xml->authorUrl; $info['copyright'] = (string)$xml->copyright; $info['license'] = (string)$xml->license; $info['description'] = JText::_((string)$xml->description); } } } return $info; } static function getExtVersion($extension) { $xml = SEFTools::getExtXML($extension); $version = null; if ($xml) { $root = $xml; $ver = (string)$root['version']; if (($root->getName() == 'extension') && version_compare($ver, '1.5', '>=') && ((string)$root['type'] == 'sef_ext')) { $element = & $root->version; $version = $element ? (string)$element : ''; } } return $version; } /** * Returns extension name from its XML file. * * @return string */ static function getExtName($extension) { $xml = SEFTools::getExtXML($extension); $name = null; if ($xml) { $root = $xml; $ver = (string)$root['version']; if (($root->getName() == 'extension') && version_compare($ver, '1.5', '>=') && ((string)$root['type'] == 'sef_ext')) { $element = & $root->name; $name = $element ? (string)$element : ''; } } return $name; } /** * Returns the extension XML object * * @param string $extension Extension option * @return JSimpleXML Extension XML */ static function getExtXML($extension) { static $xmls; if (! isset($xmls)) { $xmls = array(); } if (! isset($xmls[$extension])) { $xmls[$extension] = null; $xmlFile = JPATH_ROOT . '/' . 'components' . '/' . 'com_sef' . '/' . 'sef_ext' . '/' . $extension . '.xml'; if (JFile::exists($xmlFile)) { $xmls[$extension] = simplexml_load_file($xmlFile); } } return $xmls[$extension]; } static function &getExtAcceptVars($option, $includeGlobal = true) { static $acceptVars = array(); if( !isset($acceptVars[$option]) ) { $sefConfig = SEFConfig::getConfig(); $params =& SEFTools::getExtParams($option); $aVars = trim($params->get('acceptVars', '')); if( $aVars == '' ) { $acceptVars[$option] = array(); } else { $aVars = explode(';', $aVars); $aVars = array_map('trim', $aVars); $acceptVars[$option] = $aVars; } } return $acceptVars[$option]; } static function &getExtFilters($option, $includeGlobal = true) { static $filters = array(); if( !isset($filters[$option]) ) { $filters[$option] = array(); $filters[$option]['pos'] = array(); $filters[$option]['neg'] = array(); $db = JFactory::getDBO(); $element = str_replace('com_', 'ext_joomsef4_', $option); $query = $db->getQuery(true); $query->select('custom_data')->from('#__extensions')->where('type='.$db->quote('sef_ext'))->where('enabled=1')->where('element='.$db->quote($element)); $db->setQuery($query); $row = $db->loadResult(); if ($row) { // Parse the filters $rules = explode("\n", $row); $rules = array_map('trim', $rules); if( count($rules) > 0 ) { foreach($rules as $rule) { // Is the rule positive or negative? if( $rule[0] == '+' ) { $type = 'pos'; } else if( $rule[0] == '-' ) { $type = 'neg'; } else { continue; } $rule = substr($rule, 1); // Split the rule to regexp and variables parts $pos = strrpos($rule, '='); if( $pos === false ) { continue; } $re = substr($rule, 0, $pos); $vars = substr($rule, $pos + 1); if ($re == '') { continue; } // Create the filter object $filter = new stdClass(); $filter->rule = $re; if ($vars != '') { $filter->vars = array_map('trim', explode(',', $vars)); } else { $filter->vars = array(); } // Add the filter to filters $filters[$option][$type][] = $filter; } } } } return $filters[$option]; } static function &getExtFiltersByVars($option, $includeGlobal = true) { static $byVars = array(); if (empty($option)) { $option = '_default'; } if( !isset($byVars[$option]) ) { $byVars[$option] = array(); // Get filters $filters =& SEFTools::getExtFilters($option, $includeGlobal); if( count($filters) > 0 ) { // Loop through filter types (pos, neg) foreach($filters as $type => $typeFilters) { if( count($typeFilters) > 0 ) { // Loop through filters foreach($typeFilters as $filter) { if( count($filter->vars) > 0 ) { // Loop through variables foreach($filter->vars as $var) { // Add filter to var and type if( !isset($byVars[$option][$var]) ) { $byVars[$option][$var] = array(); } if( !isset($byVars[$option][$var][$type]) ) { $byVars[$option][$var][$type] = array(); } $byVars[$option][$var][$type][] = $filter->rule; } } } } } } } return $byVars[$option]; } /** * Returns JForm object representing extension's parameters * * @param string Extension name * @return JForm Extension's parameters */ static function &getExtParamsForm($option) { static $forms; if (!isset($forms)) { $forms = array(); } if (!isset($forms[$option])) { $forms[$option] = new JForm($option, array('control' => 'params')); // Set the extension's parameters renderer $pxml = SEFTools::getExtParamsXML($option); if (is_a($pxml, 'SimpleXMLElement')) { $forms[$option]->load($pxml); } else if( is_array($pxml) && count($pxml) > 0 ) { for( $i = 0, $n = count($pxml); $i < $n; $i++ ) { if( is_a($pxml[$i], 'SimpleXMLElement') ) { $forms[$option]->load($pxml[$i]); } } } // Set the default parameters renderer $xml = SEFTools::getExtsDefaultParamsXML(); if (is_a($xml, 'SimpleXMLElement')) { $forms[$option]->load($xml); } else if( is_array($xml) && count($xml) > 0 ) { for( $i = 0, $n = count($xml); $i < $n; $i++ ) { if( is_a($xml[$i], 'SimpleXMLElement') ) { $forms[$option]->load($xml[$i]); } } } // Bind data $forms[$option]->bind(self::getExtParams($option)); } return $forms[$option]; } static function &getExtParams($option) { $db = JFactory::getDBO(); $element = str_replace('com_', 'ext_joomsef4_', $option); // Cache all data and parameters!!! static $exts, $params; // Load all params data only once if (!isset($exts)) { $query = $db->getQuery(true); $query->select(array('element', 'params'))->from('#__extensions')->where('type='.$db->quote('sef_ext')); $db->setQuery($query); $exts = $db->loadObjectList('element'); } // Cache params objects if (!isset($params)) { $params = array(); } if (!isset($params[$element])) { // Create new params object if used for the first time $data = ''; if (isset($exts[$element])) { $data = $exts[$element]->params; } $params[$element] = new JRegistry($data); } return $params[$element]; } /** * Returns the JSimpleXMLElement object representing * the default parameters for every extension * * @return JSimpleXMLElement Extensions' default parameters */ static function getExtsDefaultParamsXML() { static $xml; if (isset($xml)) { return $xml; } $xml = null; $xmlpath = JPATH_ROOT . '/' . 'administrator' . '/' . 'components' . '/' . 'com_sef' . '/' . 'extensions_params.xml'; if (JFile::exists($xmlpath)) { $xml = simplexml_load_file($xmlpath); } return $xml; } /** * Returns the JSimpleXMLElement object representing * the extension's parameters * * @param string $option Extension name * @return JSimpleXMLElement Extension's parameters */ static function getExtParamsXML($option) { static $xmls; if (! isset($xmls)) { $xmls = array(); } if (! isset($xmls[$option])) { $xmls[$option] = null; $xml = SEFTools::getExtXML($option); if ($xml) { $form = $xml->form; if (!empty($form)) { $xmls[$option] = $form; } } } return $xmls[$option]; } /** Returns the array of texts used by the extension for creating URLs * in currently selected language (for JoomFish support) * * @param string Extension name * @return array Extension's texts */ static function getExtTexts($option, $lang = '') { $database = JFactory::getDBO(); static $extTexts; if ($option == '') { return false; } // Set the language if ($lang == '') { $lang = JFactory::getLanguage()->getTag(); } if (!isset($extTexts)) { $extTexts = array(); } if (!isset($extTexts[$option])) { $extTexts[$option] = array(); } if (!isset($extTexts[$option][$lang])) { $extTexts[$option][$lang] = array(); // If lang is different than current language, change it if ($lang !=JFactory::getLanguage()->getTag()) { $language = JFactory::getLanguage(); $oldLang = $language->setLanguage($lang); $language->load(); } $query = "SELECT `lang_id` AS `id`"; $query.= " FROM `#__languages`"; $query.= " WHERE `lang_code` = ".$database->quote($lang); $database->setQuery($query); $lang_id = $database->loadResult(); //$query = "SELECT `id`, `name`, `value` FROM `#__sefexttexts` WHERE `extension` = '$option'"; $query = "SELECT `lang_id`, `name`, `value`"; $query.= " FROM `#__sefexttexts`"; $query.= " WHERE `extension` = ".$database->quote($option); $query.= " AND (`lang_id` = 0".($lang_id ? " OR `lang_id` = ".$lang_id : "").")"; $query.= " ORDER BY `lang_id` DESC"; $database->setQuery($query); $texts = $database->loadObjectList(); /*$ntexts=array(); for($i=0;$ilang_id][$texts[$i]->name]=$texts[$i]; }*/ if (is_array($texts) && (count($texts) > 0)) { foreach (array_keys($texts) as $i) { $name = $texts[$i]->name; //$value = $texts[$i]->value; if(!isset($extTexts[$option][$lang][$name])) { $extTexts[$option][$lang][$name] = $texts[$i]->value; } //$extTexts[$option][$lang][$name] = $value; } } // Set the language back to previously selected one if (isset($oldLang) && ($oldLang != SEFTools::getLangLongCode())) { $language = JFactory::getLanguage(); $language->setLanguage($oldLang); $language->load(); } } return $extTexts[$option][$lang]; } static function removeVariable($url, $var, $value = '') { if ($value == '') { //$newurl = eregi_replace("(&|\?)$var=[^&]*", '\\1', $url); $regex = "(&|\?)$var=[^&]*"; $regex = addcslashes($regex, '/'); $newurl = preg_replace('/' . $regex . '/i', '$1', $url); } else { $trans = array('?' => '\\?' , '.' => '\\.' , '+' => '\\+' , '*' => '\\*' , '^' => '\\^' , '$' => '\\$'); $value = strtr($value, $trans); //$newurl = eregi_replace("(&|\?)$var=$value(&|\$)", '\\1\\2', $url); $regex = "(&|\?)$var=$value(&|\$)"; $regex = addcslashes($regex, '/'); $newurl = preg_replace('/' . $regex . '/i', '$1$2', $url); } $newurl = trim($newurl, '&?'); $trans = array('&&' => '&' , '?&' => '?'); $newurl = strtr($newurl, $trans); return $newurl; } static function getVariable($url, $var) { $value = null; $matches = array(); if( preg_match("/[&\?]$var=([^&]*)/", $url, $matches) > 0 ) { $value = $matches[1]; } return $value; } static function extractVariable(&$url, $var) { $value = SEFTools::getVariable($url, $var); $url = SEFTools::removeVariable($url, $var); return $value; } /** * Fixes numerical variable by converting it to integer in the URI */ static function fixVariable(&$uri, $varName) { $value = $uri->getVar($varName); if (!is_null($value)) { $value = (int) $value; $uri->setVar($varName, $value); } } /** * Removes given variables from URI and returns a query string * built of them * * @param JURI $uri * @param array $vars Variables to remove */ static function RemoveVariables(&$uri, $vars) { $query = array(); if (is_array($vars) && count($vars) > 0) { foreach($vars as $var) { // Get the variable value $value = $uri->getVar($var); // Skip variables not present in URL if( is_null($value) ) { continue; } // Add variable to query if( is_array($value) ) { // Variable is an array, let's remove all its occurences foreach($value as $key => $val) { $query[] = $var.'['.$key.']='.urlencode($val); } } else { // Variable is not an array $query[] = $var.'='.urlencode($value); } // Remove variable from URI $uri->delVar($var); } } $query = implode('&', $query); return $query; } static function ReplaceAll($search, $replace, $subject) { while (strpos($subject, $search) !== false) { $subject = str_replace($search, $replace, $subject); } return $subject; } /** * Checks whether to use alias from extension parameter value * * @param string $params * @param string $paramName * @return boolean */ static function UseAlias(&$params, $paramName) { $sefConfig = SEFConfig::getConfig(); $param = $params->get($paramName, 'global'); if( ($param == 'alias') || ($param == 'global' && $sefConfig->useAlias) ) { return true; } return false; } /** * Convert description of extensions from html to plain for metatags * * @param string $text * @return string */ static function cleanDesc($text) { // Remove javascript $regex = "']*?>.*?'si"; $text = preg_replace($regex, " ", $text); $regex = "']*?>.*?'si"; $text = preg_replace($regex, " ", $text); // Strip any remaining html tags $text = strip_tags($text); // Remove any mambot codes $regex = '(\{.*?\})'; $text = preg_replace($regex, " ", $text); // Some replacements $text = str_replace(array('\n', '\r', '"'), array(' ', '', '"'), $text); $text = trim($text); return $text; } /** * Clip text to use as meta description * * @param string $text * @param int $limit * @return string */ static function clipDesc($text, $limit) { if (JString::strlen($text) > $limit) { $text = JString::substr($text, 0, $limit); $pos = JString::strrpos($text, ' '); if ($pos !== false) { $text = JString::substr($text, 0, $pos); } $text = JString::trim($text); } return $text; } /** * Generate for metatags * * @param string $desc * @param string $blacklist * @param int $count * @param int $minLength * @return string */ static function generateKeywords($desc, $blacklist, $count, $minLength) { // Remove any email addresses $regex = '/(([_A-Za-z0-9-]+)(\\.[_A-Za-z0-9-]+)*@([A-Za-z0-9-]+)(\\.[A-Za-z0-9-]+)*)/ix'; $desc = preg_replace($regex, '', $desc); // Some unwanted replaces $desc = preg_replace('/<[^>]*>/', ' ', $desc); $desc = preg_replace('/[\\\\.;:|\'"`,()\[\]]/', ' ', $desc); $desc = str_replace(' - ', ' ', $desc); $keysArray = explode(" ", $desc); // Sort words from up to down $keysArray = array_count_values(array_map(array('JoomSEF', '_utf8LowerCase'), $keysArray)); if( is_null($blacklist) ) { $blacklist = "a, able, about, above, abroad, according, accordingly, across, actually, adj, after, afterwards, again, against, ago, ahead, ain't, all, allow, allows, almost, alone, along, alongside, already, also, although, always, am, amid, amidst, among, amongst, an, and, another, any, anybody, anyhow, anyone, anything, anyway, anyways, anywhere, apart, appear, appreciate, appropriate, are, aren't, around, as, a's, aside, ask, asking, associated, at, available, away, awfully, b, back, backward, backwards, be, became, because, become, becomes, becoming, been, before, beforehand, begin, behind, being, believe, below, beside, besides, best, better, between, beyond, both, brief, but, by, c, came, can, cannot, cant, can't, caption, cause, causes, certain, certainly, changes, clearly, c'mon, co, co., com, come, comes, concerning, consequently, consider, considering, contain, containing, contains, corresponding, could, couldn't, course, c's, currently, d, dare, daren't, definitely, described, despite, did, didn't, different, directly, do, does, doesn't, doing, done, don't, down, downwards, during, e, each, edu, eg, eight, eighty, either, else, elsewhere, end, ending, enough, entirely, especially, et, etc, even, ever, evermore, every, everybody, everyone, everything, everywhere, ex, exactly, example, except, f, fairly, far, farther, few, fewer, fifth, first, five, followed, following, follows, for, forever, former, formerly, forth, forward, found, four, from, further, furthermore, g, get, gets, getting, given, gives, go, goes, going, gone, got, gotten, greetings, h, had, hadn't, half, happens, hardly, has, hasn't, have, haven't, having, he, he'd, he'll, hello, help, , hence, her, here, hereafter, hereby, herein, here's, hereupon, hers, herself, he's, hi, him, himself, his, hither, hopefully, how, howbeit, however, hundred, i, i'd, ie, if, ignored, i'll, i'm, immediate, in, inasmuch, inc, inc., indeed, indicate, indicated, indicates, inner, inside, insofar, instead, into, inward, is, isn't, it, it'd, it'll, its, it's, itself, i've, j, just, k, keep, keeps, kept, know, known, knows, l, last, lately, later, latter, latterly, least, less, lest, let, let's, like, liked, likely, likewise, little, look, looking, looks, low, lower, ltd, m, made, mainly, make, makes, many, may, maybe, mayn't, me, mean, meantime, meanwhile, merely, might, mightn't, mine, minus, miss, more, moreover, most, mostly, mr, mrs, much, must, mustn't, my, myself, n, name, namely, nd, near, nearly, necessary, need, needn't, needs, neither, never, neverf, neverless, nevertheless, new, next, nine, ninety, no, nobody, non, none, nonetheless, noone, no-one, nor, normally, not, nothing, notwithstanding, novel, now, nowhere, o, obviously, of, off, often, oh, ok, okay, old, on, once, one, ones, one's, only, onto, opposite, or, other, others, otherwise, ought, oughtn't, our, ours, ourselves, out, outside, over, overall, own, p, particular, particularly, past, per, perhaps, placed, please, plus, possible, presumably, probably, provided, provides, q, que, quite, qv, r, rather, rd, re, really, reasonably, recent, recently, regarding, regardless, regards, relatively, respectively, right, round, s, said, same, saw, say, saying, says, second, secondly, , see, seeing, seem, seemed, seeming, seems, seen, self, selves, sensible, sent, serious, seriously, seven, several, shall, shan't, she, she'd, she'll, she's, should, shouldn't, since, six, so, some, somebody, someday, somehow, someone, something, sometime, sometimes, somewhat, somewhere, soon, sorry, specified, specify, specifying, still, sub, such, sup, sure, t, take, taken, taking, tell, tends, th, than, thank, thanks, thanx, that, that'll, thats, that's, that've, the, their, theirs, them, themselves, then, thence, there, thereafter, thereby, there'd, therefore, therein, there'll, there're, theres, there's, thereupon, there've, these, they, they'd, they'll, they're, they've, thing, things, think, third, thirty, this, thorough, thoroughly, those, though, three, through, throughout, thru, thus, till, to, together, too, took, toward, towards, tried, tries, truly, try, trying, t's, twice, two, u, un, under, underneath, undoing, unfortunately, unless, unlike, unlikely, until, unto, up, upon, upwards, us, use, used, useful, uses, using, usually, v, value, various, versus, very, via, viz, vs, w, want, wants, was, wasn't, way, we, we'd, welcome, well, we'll, went, were, we're, weren't, we've, what, whatever, what'll, what's, what've, when, whence, whenever, where, whereafter, whereas, whereby, wherein, where's, whereupon, wherever, whether, which, whichever, while, whilst, whither, who, who'd, whoever, whole, who'll, whom, whomever, who's, whose, why, will, willing, wish, with, within, without, wonder, won't, would, wouldn't, x, y, yes, yet, you, you'd, you'll, your, you're, yours, yourself, yourselves, you've, z, zero"; } $blackArray = explode(",", $blacklist); foreach($blackArray as $blackWord){ if(isset($keysArray[trim($blackWord)])) unset($keysArray[trim($blackWord)]); } arsort($keysArray); $i = 1; $keywords = ''; foreach($keysArray as $word=>$instances){ if($i > $count) break; if(JString::strlen(trim($word)) >= $minLength ) { $keywords .= $word . ", "; $i++; } } $keywords = rtrim($keywords, ", "); return $keywords; } static function GetSEFGlobalMeta() { return '6275a94572c5c3aa3f19065ac1a208dc'; // sef.global.meta } /** * Sends the request and follows redirects * * @param string $url * @param string $referer * @param string|array $_data * @param string $method * @param string $userAgent * @param array $headers * @param int $maxRedirs * @return object */ static function PostRequestFollowRedirects($url, $referer = null, $_data = null, $method = 'post', $userAgent = null, $headers = null, $maxRedirs = 5) { $response = false; for ($redirs = 0; $redirs <= $maxRedirs; $redirs++) { $response = self::PostRequest($url, $referer, $_data, $method, $userAgent, $headers); // Check if we should redirect if (is_object($response) && $response->code >= 300 && $response->code <= 399) { // We got a redirect response code, try to parse new location from headers $matches = array(); if (preg_match('/^Location:\s*(.*)$/im', $response->header, $matches)) { // Found, update URL and send request again $url = $matches[1]; continue; } } // No redirect, return response return $response; } return $response; } /** * Sends the POST request * * @param string $url * @param string $referer * @param array $_data * @return object */ static function PostRequest($url, $referer = null, $_data = null, $method = 'post', $userAgent = null, $headers = null) { // convert variables array to string: $data = ''; if( is_array($_data) && count($_data) > 0 ) { // format --> test1=a&test2=b etc. $data = array(); while( list($n, $v) = each($_data) ) { $data[] = "$n=$v"; } $data = implode('&', $data); $contentType = "Content-type: application/x-www-form-urlencoded\r\n"; } else { $data = $_data; $contentType = "Content-type: text/xml\r\n"; } if( is_null($referer) ) { $referer = JURI::root(); } // parse the given URL $url = parse_url($url); if( !isset($url['scheme']) ) { return false; } // extract host and path: $host = $url['host']; $path = isset($url['path']) ? $url['path'] : '/'; // Prepare host and port to connect to $connhost = $host; $port = 80; // Workaround for some PHP versions, where fsockopen can't connect to // 'localhost' string on Windows servers if ($connhost == 'localhost') { $connhost = gethostbyname('localhost'); } // Handle scheme if ($url['scheme'] == 'https') { $connhost = 'ssl://'.$connhost; $port = 443; } else if ($url['scheme'] != 'http') { return false; } // open a socket connection $errno = null; $errstr = null; $fp = @fsockopen($connhost, $port, $errno, $errstr, 5); if (!is_resource($fp) || ($fp === false)) { return false; } if (!is_null($userAgent)) { $userAgent = "User-Agent: ".$userAgent."\r\n"; } // send the request if ($method == 'post') { // Check the first fputs, sometimes fsockopen doesn't fail, but fputs doesn't work if (!@fputs($fp, "POST $path HTTP/1.1\r\n")) { @fclose($fp); return false; } if (!is_null($userAgent)) { fputs($fp, $userAgent); } fputs($fp, "Host: $host\r\n"); fputs($fp, "Referer: $referer\r\n"); fputs($fp, $contentType); fputs($fp, "Content-length: ". strlen($data) ."\r\n"); // Send additional headers if set if (is_array($headers)) { foreach ($headers as $h) { $h = rtrim($h); $h .= "\r\n"; fputs($fp, $h); } } fputs($fp, "Connection: close\r\n\r\n"); fputs($fp, $data); } elseif ($method == 'get') { $query = ''; if (isset($url['query'])) { $query = '?'.$url['query']; } // Check the first fputs, sometimes fsockopen doesn't fail, but fputs doesn't work if (!@fputs($fp, "GET {$path}{$query} HTTP/1.1\r\n")) { @fclose($fp); return false; } if (!is_null($userAgent)) { fputs($fp, $userAgent); } fputs($fp, "Host: $host\r\n"); // Send additional headers if set if (is_array($headers)) { foreach ($headers as $h) { $h = rtrim($h); $h .= "\r\n"; fputs($fp, $h); } } fputs($fp, "Connection: close\r\n\r\n"); } $result = ''; while(!feof($fp)) { // receive the results of the request $result .= fgets($fp, 128); } // close the socket connection: fclose($fp); // split the result header from the content $result = explode("\r\n\r\n", $result, 2); $header = isset($result[0]) ? $result[0] : ''; $content = isset($result[1]) ? $result[1] : ''; $response = new stdClass(); $response->header = $header; $response->content = $content; // Handle chunked transfer if needed if( strpos(strtolower($response->header), 'transfer-encoding: chunked') !== false ) { $parsed = ''; $left = $response->content; while( true ) { $pos = strpos($left, "\r\n"); if( $pos === false ) { return $response; } $chunksize = substr($left, 0, $pos); $pos += strlen("\r\n"); $left = substr($left, $pos); $pos = strpos($chunksize, ';'); if( $pos !== false ) { $chunksize = substr($chunksize, 0, $pos); } $chunksize = hexdec($chunksize); if( $chunksize == 0 ) { break; } $parsed .= substr($left, 0, $chunksize); $left = substr($left, $chunksize + strlen("\r\n")); } $response->content = $parsed; } // Get the response code from header $headerLines = explode("\n", $response->header); $header1 = explode(' ', trim($headerLines[0])); $code = intval($header1[1]); $response->code = $code; return $response; } static function getSEOStatus() { static $status; if( !isset($status) ) { $sefConfig = SEFConfig::getConfig(); $status = array(); $config = JFactory::getConfig(); $status['sef'] = (bool)$config->get('sef'); $status['mod_rewrite'] = (bool)$config->get('sef_rewrite'); $status['sef_suffix'] = (bool)$config->get('sef_suffix'); $status['joomsef'] = (bool)$sefConfig->enabled; $status['plugin'] = JPluginHelper::isEnabled('system', 'joomsef'); $status['newurls'] = !$sefConfig->disableNewSEF; } return $status; } static function getNonSefVars(&$uri, $nonSefVars, $ignoreVars) { $mainframe = JFactory::getApplication(); $sefConfig = SEFConfig::getConfig(); // Get the parameters for this component if( !is_null($uri->getVar('option')) ) { $params =& SEFTools::getExtParams($uri->getVar('option')); } // Build array of nonSef vars if set to $nonSef = array(); if( $sefConfig->appendNonSef ) { // Save the given nonsef vars $nonSef = $nonSefVars; // load the nonSEF vars from option parameters $paramNonSef = array(); if( isset($params) ) { $nsef = $params->get('customNonSef', ''); if( !empty($nsef) ) { // Some variables are set, let's explode them $paramNonSef = explode(';', $nsef); } } // get globally configured nonSEF vars $configNonSef = array(); if( !empty($sefConfig->customNonSef) ) { $configNonSef = explode(';', $sefConfig->customNonSef); } // Get nonSEF vars from variable filter test if set to $failedVars = array(); // combine all the nonSEF vars arrays $nsefvars = array_merge($paramNonSef, $configNonSef, $failedVars); if (!empty($nsefvars)) { foreach($nsefvars as $nsefvar) { // add each variable, that isn't already set, and that is present in our URL if( !isset($nonSef[$nsefvar]) && !is_null($uri->getVar($nsefvar)) ) { $nonSef[$nsefvar] = $uri->getVar($nsefvar); } } } // if $nonSefVars mixes with $GLOBALS['JOOMSEF_NONSEFVARS'], exclude the mixed vars // this is important to prevent duplicating params by adding JOOMSEF_NONSEFVARS to // $ignoreSefVars $gNonSef = JoomSEF::get('sef.global.nonsefvars'); if (!empty($gNonSef)) { foreach (array_keys($gNonSef) as $key) { if (isset($nonSef[$key])) unset($gNonSef[$key]); } JoomSEF::set('sef.global.nonsefvars', $gNonSef); } } // Combine nonSef and ignore vars if (!empty($ignoreVars)) { $nonSef = array_merge($nonSef, $ignoreVars); } // Globally add the Smart Search's highlight variable if (!is_null($uri->getVar('highlight'))) { $nonSef['highlight'] = $uri->getVar('highlight'); } // If the component requests strict accept variables filtering, add the ones that don't match if( isset($params) && ($params->get('acceptStrict', '0') == '1') ) { $acceptVars =& SEFTools::getExtAcceptVars($uri->getVar('option')); $uriVars = $uri->getQuery(true); if( (count($acceptVars) > 0) && (count($uriVars) > 0) ) { foreach($uriVars as $name => $value) { // Standard Joomla variables if( in_array($name, array('option', 'Itemid', 'limit', 'limitstart', 'format', 'tmpl', 'lang')) ) { continue; } // Accepted variables if( in_array($name, $acceptVars) ) { continue; } // Variable not accepted, add it to non-SEF $nonSef[$name] = $value; } } } return $nonSef; } static function getHomeQueries($includeLang = true) { // Cache result to save DB queries!!! static $items; if (!isset($items)) { $db = JFactory::getDBO(); $query = $db->getQuery(true); $query->select('id, link, language')->from('#__menu')->where('home=1'); $db->setQuery($query); $items = $db->loadObjectList('id'); } return $items; } static function getMenuItemSubDomains($id) { // Cache results to save DB queries!!! static $items; if (!isset($items)) { $items = array(); } if (!isset($items[$id])) { $db = JFactory::getDBO(); $query = $db->getQuery(true); $query->select('link')->from('#__menu')->where('id='.$id); $db->setQuery($query); $items[$id] = $db->loadResult(); } return $items[$id]; } static function getAllSubdomains() { // Cache subdomains data to save DB queries! static $subdomains; if (!isset($subdomains)) { $subdomains = array(); // Load all subdomains $db = JFactory::getDBO(); $query = $db->getQuery(true); $query->select('*')->from('#__sef_subdomains'); $db->setQuery($query); $rows = $db->loadObjectList(); // Create structure of subdomains according to languages foreach ($rows as $row) { // Add subdomain to correct language if (!empty($row->lang)) { $subdomains[$row->lang][] = $row; } if ($row->lang != '*') { $subdomains['*'][] = $row; } } } return $subdomains; } static function getSubDomain($Itemid,$uri,&$titlepage) { $sefConfig=SEFConfig::getConfig(); $titlepage=false; $option=$uri->getVar('option'); $db=JFactory::getDBO(); $lang = '*'; if ($sefConfig->langEnable) { $lang = $uri->getVar('lang', '*'); } // Get subdomains $subdomains = self::getAllSubdomains(); if (!array_key_exists($lang, $subdomains)) { // No subdomain for given language return null; } for($i=0;$iItemid); if($Itemid==$subdomains[$lang][$i]->Itemid_titlepage) { $link=new JURI(self::getMenuItemSubDomains($Itemid)); $uri_query=$uri->getQuery(true); $titlepage=true; foreach($link->getQuery(true) as $opt=>$val) { if($val!=@$uri_query[$opt]) { $titlepage=false; } } return $subdomains[$lang][$i]->subdomain; } if($option==$subdomains[$lang][$i]->option) { return $subdomains[$lang][$i]->subdomain; } if(strlen($subdomains[$lang][$i]->Itemid) && in_array($Itemid,$Itemids)) { return $subdomains[$lang][$i]->subdomain; } } return null; } static function normalizeURI(&$uri) { $option = $uri->getVar('option'); if (!is_null($option)) { $extfile = JPATH_ROOT.'/components/com_sef/sef_ext/'.$option.'.php'; if (file_exists($extfile)) { require_once($extfile); $class = 'SefExt_'.$option; $ext = new $class(); $ext->beforeCreate($uri); list($nonsef, $ignore) = $ext->getNonSefVars($uri); if (!empty($ignore)) { $nonsef = array_merge($nonsef, $ignore); } $keys = array_keys($nonsef); SEFTools::RemoveVariables($uri, $keys); } } } /** * Checks, whether the given Itemid is ignored for the given component * * @param string $option * @param string $Itemid * @return bool */ static function isItemidIgnored($option, $Itemid) { $params =& SEFTools::getExtParams($option); $ignoredIds = trim($params->get('ignoreItemids', '')); if (empty($ignoredIds)) { return false; } $ids = array_map('trim', explode(',', $ignoredIds)); if (in_array($Itemid, $ids)) { return true; } return false; } public static function getInstalledComponents() { static $components; if (!isset($components)) { $db = JFactory::getDbo(); // Get components $db->setQuery("SELECT `name`, `element` AS `option` FROM `#__extensions` WHERE `type` = 'component'"); $components = $db->loadObjectList('option'); if (is_null($components)) { $components = array(); return $components; } // Remove system components $remove = array('com_sef', 'com_admin', 'com_cache', 'com_categories', 'com_checkin', 'com_config', 'com_cpanel', 'com_installer', 'com_joomfish', 'com_joomlaupdate', 'com_languages', 'com_login', 'com_media', 'com_menus', 'com_messages', 'com_modules', 'com_plugins', 'com_redirect', 'com_templates', 'com_falang'); foreach($remove as $r) { if (isset($components[$r])) { unset($components[$r]); } } // Translate names $lang = JFactory::getLanguage(); foreach($components as &$item) { $extension = $item->option; $source = JPATH_ADMINISTRATOR . '/components/' . $extension; $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, false) || $lang->load("$extension.sys", $source, null, false, false) || $lang->load("$extension.sys", JPATH_ADMINISTRATOR, $lang->getDefault(), false, false) || $lang->load("$extension.sys", $source, $lang->getDefault(), false, false); $item->name = JText::_($item->name); } // Sort by name uasort($components, array('SEFTools', 'cmpComponents')); } return $components; } protected static function cmpComponents(&$a, &$b) { return strnatcasecmp($a->name, $b->name); } static function getDefaultParams($element) { //$element = $this->manifest->getElementByPath('install/defaultparams'); //$element=$this->manifest->install->defaultparams; if( !is_a($element, 'SimpleXMLElement') || !count($element->children()) ) { return ''; } $defaultParams = $element->children(); if( count($defaultParams) == 0 ) { return ''; } $params = array(); foreach($defaultParams as $param) { if( $param->getName() != 'defaultParam' ) { continue; } $name = $param->attributes()->name; $value = $param->attributes()->value; $params[] = $name . '=' . $value; } if( count($params) > 0 ) { return implode("\n", $params); } else { return ''; } } static function getDefaultFilters($element) { //$element = $this->manifest->getElementByPath('install/defaultfilters'); //$element=$this->manigest->install->defaultfilters; if( !is_a($element, 'SimpleXMLElement') || !count($element->children()) ) { return ''; } $defaultFilters = $element->children(); if( count($defaultFilters) == 0 ) { return ''; } $filters = array(); foreach($defaultFilters as $filter) { if( $filter->getName() != 'defaultFilter' ) { continue; } $filters[] = (string)$filter; } if( count($filters) > 0 ) { return implode("\n", $filters); } else { return ''; } } /** * Redirects current page to given URL, handles different Joomla versions. * By default uses 303 code, if $moved is true, uses 301 code. * Optionally you can also specify message. * * @param string $url * @param bool $moved * @param string $message * @param string $type */ public static function redirect($url, $moved = false, $message = '', $type = 'message') { // Make sure the URL is absolute // #23740: Handle also empty URL if ($url == '' || substr($url, 0, 1) == '/') { $uri = JUri::getInstance(); $domain = $uri->toString(array('scheme', 'user', 'pass', 'host', 'port')); $url = rtrim($domain, '/').$url; } // Change http protocol to https if set to $sefConfig = SEFConfig::getConfig(); if ($sefConfig->forceSsl) { if (substr($url, 0, 5) == 'http:') { $url = 'https:'.substr($url, 5); } } $app = JFactory::getApplication(); // Handle redirect according to Joomla version if (version_compare(JVERSION, '3.2', 'ge')) { // New handling if ($message) { $app->enqueueMessage($message, $type); } $app->redirect($url, $moved); } else { // Old handling $app->redirect($url, $message, $type, $moved); } $app->close(); } /** * Creates a new instance of JoomSefDomainUri object copied from given JUri with given host set. The JoomSefDomainUri * is used with multi-language websites using different domains, its toString method always outputs scheme and host. * * @param JUri $srcUri * @param string $host * @return JoomSefDomainUri */ public static function createDomainUri($srcUri, $host) { $srcUri->setHost($host); $newUri = new JoomSefDomainUri(); JoomSefUri::copyUri($srcUri, $newUri); $newUri->storeHost(); return $newUri; } } components/com_sef/tables/index.html000066600000000054150771655450013635 0ustar00components/com_sef/tables/word.php000066600000002772150771655450013335 0ustar00_error = null; $this->word = trim($this->word); // check for valid word if ($this->word == '') { $this->_error .= JText::_('COM_SEF_ERROR_EMPTY_WORD'); return false; } if (is_null($this->_error)) { // check for existing words $this->_db->setQuery("SELECT id FROM #__sefwords WHERE `word` LIKE " . $this->_db->Quote($this->word)); $xid = intval($this->_db->loadResult()); if ($xid && $xid != intval($this->id)) { $this->_error = JText::_('COM_SEF_ERROR_WORD_EXISTS'); return false; } return true; } else { return false; } } } components/com_sef/tables/movedurl.php000066600000001221150771655450014203 0ustar00_error = null; $this->sefurl = trim($this->sefurl); $this->origurl = trim($this->origurl); $this->metadesc = trim($this->metadesc); $this->metakey = trim($this->metakey); // check for valid URLs if ($this->origurl == '') { $this->_error .= JText::_('COM_SEF_ERROR_EMPTY_URL'); return false; } //if (eregi("^\\/", $this->sefurl)) { if (preg_match("|^\\/|i", $this->sefurl)) { $this->_error .= JText::_('COM_SEF_ERROR_URL_LEADING_SLASH'); } //if ((eregi("^index.php", $this->origurl)) === false) { if (!preg_match("/^index.php/i", $this->origurl)) { $this->_error .= JText::_('COM_SEF_ERROR_URL_MISSING_INDEX'); } if (is_null($this->_error)) { // 15.5.2012 dajo: REMOVED, as duplicate SEF URLs can also be stored in database // check for existing URLS /*$this->_db->setQuery("SELECT id FROM #__sefurls WHERE `sefurl` LIKE " . $this->_db->Quote($this->sefurl) . " AND `origurl` LIKE " . $this->_db->Quote($this->origurl)); $xid = intval($this->_db->loadResult()); if ($xid && $xid != intval($this->id)) { $this->_error = JText::_('COM_SEF_ERROR_URL_EXISTS'); return false; }*/ return true; } else { return false; } } } components/com_sef/views/urls/view.html.php000066600000002151150771655450015136 0ustar00get( 'Count' ); if( $count == 0 ) { $msg = JText::_('COM_SEF_NO_RECORDS_FOUND'); } elseif( $count == 1 ) { $msg = JText::_('COM_SEF_WARNING_DELETE') . ' ' . $count . ' ' . JText::_('COM_SEF_RECORD'); } else { $msg = JText::_('COM_SEF_WARNING_DELETE') . ' ' . $count . ' ' . JText::_('COM_SEF_RECORDS'); } $this->assign( 'count', $count ); $this->assign( 'msg', $msg ); parent::display($tpl); } } components/com_sef/views/urls/tmpl/index.html000066600000000054150771655450015461 0ustar00components/com_sef/views/urls/tmpl/confirm.php000066600000002157150771655450015640 0ustar00

    msg; ?>
    count == 0 ) { ?>

    components/com_sef/views/urls/index.html000066600000000054150771655450014505 0ustar00components/com_sef/views/sef/view.html.php000066600000004707150771655450014737 0ustar00authorise('core.admin', 'com_sef')) { JToolBarHelper::preferences('com_sef'); } // Get number of URLs for purge warning $model = SEFModel::getInstance('URLs', 'SEFModel'); $this->assign('purgeCount', $model->getCount(0)); // Get newest version available $sefConfig = SEFConfig::getConfig(); if ($sefConfig->versionChecker) { $model2 = SEFModel::getInstance('Upgrade', 'SEFModel'); $newVer = $model2->getNewSEFVersion(); $sefinfo = SEFTools::getSEFInfo(); if( ((strnatcasecmp($newVer, $sefinfo['version']) > 0) || (strnatcasecmp($newVer, substr($sefinfo['version'], 0, strpos($sefinfo['version'], '-'))) == 0)) ) { $newVer = ''.$newVer.'  '; } $newVer .= ' '; $this->assign('newestVersion', $newVer); } else { $newestVersion = JText::_('COM_SEF_VERSION_CHECKER_DISABLED') . '  '; $this->assign('newestVersion', $newestVersion); } // Get statistics $stats = $model->getStatistics(); $this->assign('stats', $stats); // Get feed $feed = $this->get('Feed'); $this->assign('feed', $feed); // Check language filter plugin $this->getModel('sef')->checkLanguagePlugins(); parent::display($tpl); } } components/com_sef/views/sef/tmpl/default.php000066600000046356150771655450015430 0ustar00
    1)); echo JHtml::_('tabs.panel', JText::_('COM_SEF_JOOMSEF_CONFIGURATION'), 'config'); ?>
    1, 'allowAllClose' => true)); echo JHtml::_('sliders.panel', JText::_('COM_SEF_ARTIO_JOOMSEF'), 'info-panel'); ?>
    JoomSEF logo
    ARTIO JoomSEF
    :
    : newestVersion; ?>
    :
    : Copyright © 2006 -
    : ,
    :
    : GNU/GPL
    :
    showStatus('sef'); ?>
    showStatus('mod_rewrite'); ?>
    showStatus('joomsef'); ?>
    showStatus('plugin'); ?>
    showStatus('newurls'); ?>
    artioFeedDisplay) { echo JHtml::_('sliders.panel', JText::_('COM_SEF_ARTIO_NEWSFEED'), 'feed-panel'); ?>
    feed; ?>
    stats)) { foreach($this->stats as $stat) { if ($stat->text == '') { ?> text), 'total') !== false); $strong1 = $isTotal ? '' : ''; $strong2 = $isTotal ? '' : ''; $text = $stat->text.':'; if (isset($stat->link) && !empty($stat->link)) { $span1 = ''; $text = ''.$text.''; $span2 = ''; $text = $span1 . $text . $span2; } ?>
       
    value . $strong2; ?>
    components/com_sef/views/sef/tmpl/index.html000066600000000054150771655450015251 0ustar00components/com_sef/views/sef/tmpl/default.php.backup000066600000053110150771655450016656 0ustar00
    1)); echo JHtml::_('tabs.panel', JText::_('COM_SEF_JOOMSEF_CONFIGURATION'), 'config'); ?>
    1, 'allowAllClose' => true)); echo JHtml::_('sliders.panel', JText::_('COM_SEF_ARTIO_JOOMSEF'), 'info-panel'); ?>
    JoomSEF logo
    ARTIO JoomSEF
    :
    : newestVersion; ?>
    :
    : Copyright © 2006 -
    : ,
    :
    : GNU/GPL
    :
    ' . JText::_('COM_SEF_ENABLED') . ''; echo ' '; } else { echo '' . JText::_('COM_SEF_DISABLED') . ''; echo ' '; } } } ?>
    artioFeedDisplay) { echo JHtml::_('sliders.panel', JText::_('COM_SEF_ARTIO_NEWSFEED'), 'feed-panel'); ?>
    feed; ?>
    stats)) { foreach($this->stats as $stat) { if ($stat->text == '') { ?> text), 'total') !== false); $strong1 = $isTotal ? '' : ''; $strong2 = $isTotal ? '' : ''; $text = $stat->text.':'; if (isset($stat->link) && !empty($stat->link)) { $span1 = ''; $text = ''.$text.''; $span2 = ''; $text = $span1 . $text . $span2; } ?>
       
    value . $strong2; ?>
    components/com_sef/views/sef/index.html000066600000000054150771655450014275 0ustar00components/com_sef/views/movedurl/view.html.php000066600000002254150771655450016012 0ustar00get('Data'); $isNew = ($url->id < 1); $text = $isNew ? JText::_( 'COM_SEF_NEW' ) : JText::_( 'COM_SEF_EDIT' ); JToolBarHelper::title( JText::_( 'COM_SEF_301_REDIRECT' ).': [ ' . $text.' ]', '301-redirects.png' ); JToolBarHelper::save(); if ($isNew) { JToolBarHelper::cancel(); } else { // for existing items the button is renamed `close` JToolBarHelper::cancel( 'cancel', 'Close' ); } $this->assign('url', $url); JHTML::_('behavior.tooltip'); parent::display($tpl); } } components/com_sef/views/movedurl/tmpl/default.php000066600000003710150771655450016473 0ustar00
    tooltip(JText::_('COM_SEF_THIS_IS_URL_TO_REDIRECT_FROM')); ?>
    tooltip(JText::_('COM_SEF_THIS_IS_URL_TO_REDIRECT_TO'));?>
    components/com_sef/views/movedurl/tmpl/index.html000066600000000054150771655450016331 0ustar00components/com_sef/views/movedurl/index.html000066600000000054150771655450015355 0ustar00components/com_sef/views/htaccess/view.html.php000066600000001307150771655450015750 0ustar00components/com_sef/views/htaccess/tmpl/redirect.php000066600000000576150771655450016617 0ustar00components/com_sef/views/htaccess/tmpl/advanced.php000066600000000577150771655450016564 0ustar00components/com_sef/views/htaccess/tmpl/simple.php000066600000000634150771655450016302 0ustar00components/com_sef/views/htaccess/tmpl/index.html000066600000000054150771655450016271 0ustar00components/com_sef/views/htaccess/index.html000066600000000054150771655450015315 0ustar00components/com_sef/views/extensions/view.html.php000066600000002734150771655450016357 0ustar00_addPath('template', $this->_basePath.'/views/templates'); }*/ function display($tpl = null) { JToolBarHelper::title('JoomSEF - '. JText::_('COM_SEF_EXTENSIONS_MANAGEMENT'), 'plugin.png' ); $bar = JToolBar::getInstance(); JToolBarHelper::custom('installext', 'install', '', 'COM_SEF_INSTALL', false); //$bar->appendButton('Confirm', 'COM_SEF_CONFIRM_UNINSTALL_EXTENSION', 'uninstall', 'COM_SEF_UNINSTALL', 'uninstallext', true, false); JToolBarHelper::editList('editext'); JToolBarHelper::spacer(); JToolBarHelper::back('COM_SEF_BACK', 'index.php?option=com_sef'); $exts = $this->get('extensions', 'extensions'); $this->assign('extensions', $exts); $noExts = $this->get('ComponentsWithoutExtension', 'extensions'); $this->assign('components', $noExts); JHTML::_('behavior.tooltip'); JHTML::_('behavior.modal'); JHTML::_('behavior.framework'); parent::display($tpl); } } components/com_sef/views/extensions/tmpl/default.php000066600000016024150771655450017037 0ustar00
    loadTemplate('extslist'); ?>
    extensions); foreach (array_keys($this->components) as $key) { $row =& $this->components[$key]; ?>
    name; ?> extType) ) { echo '-'; } else { if ($row->extType == 'Paid') { $img = 'icon-16-key'; $ttl = JText::_('COM_SEF_DOWNLOAD_ID_SET'); $txt = JText::_('COM_SEF_CLICK_TO_CHANGE'); if ($row->params->get('downloadId', '') == '') { $img .= '_bw'; $ttl = JText::_('COM_SEF_DOWNLOAD_ID_NOT_SET'); $txt = JText::_('COM_SEF_CLICK_TO_SET'); } $href = 'index.php?option=com_sef&controller=extension&cid[]='.$row->id.'&task=editId&tmpl=component'; echo ''; echo ''; echo ' '; } if ($row->extType == 'Free') { echo JText::_('COM_SEF_FREE'); } else { echo JText::_('COM_SEF_PAID'); } } ?> extType) ) { echo '-'; } else { if( ($row->extType == 'Free') || ($row->params->get('downloadId', '') != '') ) { $fn = 'getExt(\'' . $row->option . '\');'; } else { $fn = 'window.open(\'' . $row->extLink . '\');'; } ?> handler->text; ?> Open parameters
    components/com_sef/views/extensions/tmpl/index.html000066600000000054150771655450016673 0ustar00components/com_sef/views/extensions/tmpl/default_extslist.php000066600000016467150771655450021011 0ustar00
    extensions) as $key) { $row = &$this->extensions[$key]; ?>
    name; ?> component) ) { echo $row->component->name; } else { echo '- ' . JText::_('COM_SEF_NOT_INSTALLED') . ' -'; } ?> authorUrl != '' ) { echo ''; echo ''; echo @$row->author != '' ? $row->author : " "; echo ''; echo ''; } else { echo @$row->author != '' ? $row->author : " "; } ?> version) && !empty($row->version)) { if (is_null($row->newestVersion) || version_compare($row->version, $row->newestVersion, '>=')) { echo ''.$row->version.''; } else { echo ''.$row->version.''; } } else { echo " "; } ?> creationdate != '' ? $row->creationdate : " "; ?> newestVersion) ) { echo '-'; } else { echo $row->newestVersion; } ?> type) ) { echo '-'; } else { if ($row->type == 'Paid') { $img = 'icon-16-key'; $ttl = JText::_('COM_SEF_DOWNLOAD_ID_SET'); $txt = JText::_('COM_SEF_CLICK_TO_CHANGE'); if ($row->params->get('downloadId', '') == '') { $img .= '_bw'; $ttl = JText::_('COM_SEF_DOWNLOAD_ID_NOT_SET'); $txt = JText::_('COM_SEF_CLICK_TO_SET'); } $href = 'index.php?option=com_sef&controller=extension&cid[]='.$row->id.'&task=editId&tmpl=component'; echo ''; echo ''; echo ' '; } if ($row->type == 'Free') { echo JText::_('COM_SEF_FREE'); } else { echo JText::_('COM_SEF_PAID'); } } ?> newestVersion) ) { echo '-'; } else if( ((strnatcasecmp($row->newestVersion, $row->version) > 0) || (strnatcasecmp($row->newestVersion, substr($row->version, 0, strpos($row->version, '-'))) == 0)) ) { ?> handler->text; ?>
    components/com_sef/views/extensions/index.html000066600000000054150771655450015717 0ustar00components/com_sef/views/extension/view.html.php000066600000004030150771655450016163 0ustar00get('extension'); $this->assign('extension', $extension); $this->langs=$this->get('languages'); $this->strings=$this->get('strings'); $this->translation=$this->get('translation'); $this->subdomains=$this->get('subdomains'); $this->menus=$this->get('menus'); $filters =& SEFTools::getExtFilters($extension->option, false); $this->assign('filters', $filters); $acceptVars =& SEFTools::getExtAcceptVars($extension->option, false); sort($acceptVars, SORT_STRING); $this->assign('acceptVars', $acceptVars); // Root domain for subdomains configuration $rootDomain = JFactory::getURI()->getHost(); if (substr($rootDomain, 0, 4) == 'www.') { $rootDomain = substr($rootDomain, 4); } $this->assign('rootDomain', $rootDomain); JToolBarHelper::title( JText::_( 'SEF Extension' ).' '.JText::_( 'Edit' ).' [ ' . (strlen($extension->name)?$extension->name:$extension->component->name) . ' ]', 'plugin.png' ); JToolBarHelper::save(); JToolBarHelper::apply(); JToolBarHelper::spacer(); JToolBarHelper::cancel(); JHTML::_('behavior.tooltip'); $redir = JRequest::getVar('redirto', ''); $this->assign('redirto', $redir); parent::display($tpl); } function showEditId() { $ext = $this->get('extension'); /*print_r($ext); exit;*/ $this->assign('ext', $ext); $this->setLayout('editid'); parent::display(null); } }components/com_sef/views/extension/tmpl/default.php000066600000017515150771655450016662 0ustar00
    1)); // Render each parameters group $fieldsets = $this->extension->form->getFieldsets(); if (is_array($fieldsets) && count($fieldsets) > 0) { $i = 0; foreach ($fieldsets as $name => $fieldset) { if ($name == 'varfilter') { continue; } $fields = $this->extension->form->getFieldset($name); if (count($fields) > 0) { $label = JText::_($name); $i++; echo JHtml::_('tabs.panel', $label, 'page-'.$i); $this->renderParams($this->extension->form, $name); } } } echo JHTML::_('tabs.panel',Jtext::_('COM_SEF_SUBDOMAINS'),'subdomains'); ?>
    langs as $lang) { $sef=$lang->sef; ?>
    .rootDomain; ?> menus[$sef],"subdomain[".$sef."][titlepage]",array('list.select'=>@$this->subdomains[$sef]->Itemid_titlepage)); ?> title; ?>
    strings)>0) { echo JHtml::_('tabs.panel', JText::_('COM_SEF_TEXTS'), 'texts'); echo JHTML::_('tabs.start','sef-extension-texts'); echo JHTML::_('tabs.panel',JText::_('COM_SEF_Default'),'default'); ?>
    strings);$j++) { $name=$this->strings[$j]->name; ?>
    langs);$i++) { //echo JHTML::_('tabs.panel',JHTML::_('image','../media/mod_languages/images/'.$this->langs[$i]->image.'.gif',$this->langs[$i]->code)." ".$this->langs[$i]->code,$this->langs[$i]->code); echo JHTML::_('tabs.panel','langs[$i]->image.'.gif alt="'.$this->langs[$i]->lang_code.'"/> '.$this->langs[$i]->lang_code,$this->langs[$i]->lang_code); ?>
    strings);$j++) { $name=$this->strings[$j]->name; ?>
    strings[$j]->name; ?>
    extension->name) ) { ?>
    : extension->name; ?>
    : extension->version; ?>
    : extension->description; ?>
    extension->component) ) { ?>
    : extension->component->name; ?>
    : extension->component->option; ?>
    components/com_sef/views/extension/tmpl/editid.php000066600000004021150771655450016464 0ustar00
    ext->name) ? $this->ext->name : $this->ext->component->name; ?>
    components/com_sef/views/extension/tmpl/index.html000066600000000054150771655450016510 0ustar00components/com_sef/views/extension/index.html000066600000000054150771655450015534 0ustar00components/com_sef/views/templates/default_infotext.php000066600000001650150771655450017601 0ustar00infoShown ? 'block' : 'none'; $linkText = $this->infoShown ? JText::_('COM_SEF_INFOTEXT_HIDE') : JText::_('COM_SEF_INFOTEXT_SHOW'); ?>
    infoTextClass; ?>> ()
    infoString; ?>
    components/com_sef/views/templates/index.html000066600000000054150771655450015516 0ustar00components/com_sef/views/importexport/view.html.php000066600000001520150771655450016724 0ustar00assign('aceSefPresent', $this->get('AceSefTablePresent')); $this->assign('shSefPresent', $this->get('ShTablePresent')); parent::display($tpl); } } components/com_sef/views/importexport/tmpl/default.php000066600000005362150771655450017417 0ustar00

    aceSefPresent || $this->shSefPresent ) { ?>
    aceSefPresent ) { ?> shSefPresent ) { ?>
    components/com_sef/views/importexport/tmpl/index.html000066600000000054150771655450017250 0ustar00components/com_sef/views/importexport/tmpl/importstats.php000066600000003332150771655450020357 0ustar00
    success ) { echo '' . JText::_('COM_SEF_IMPORT_SUCCESSFUL') . ''; } else { echo '' . JText::_('COM_SEF_ERROR_IMPORT') . ''; } ?>
    : filetype; ?>
    : total; ?>
    : imported; ?>
    : notImported; ?>
    components/com_sef/views/importexport/index.html000066600000000054150771655450016274 0ustar00components/com_sef/views/sefurl/view.html.php000066600000003314150771655450015453 0ustar00get('Data'); $lists = $this->get('Lists'); if(JRequest::getInt('viewmode')!=6) { $isNew = ($sef->id < 1); } else { $isNew = strlen($sef->sefurl)?false:true; } $text = $isNew ? JText::_( 'COM_SEF_NEW' ) : JText::_( 'COM_SEF_EDIT' ); JToolBarHelper::title('JoomSEF - ' . JText::_( 'COM_SEF_SEF_URL' ).' [ ' . $text.' ]', 'url-edit.png' ); if(JRequest::getInt('viewmode')==6) { JToolBarHelper::save('save_cache'); } else { JToolBarHelper::save(); } if ($isNew) { JToolBarHelper::cancel(); } else { // for existing items the button is renamed `close` JToolBarHelper::cancel('cancel', 'Close'); } $this->assign('sef', $sef); $this->assign('lists', $lists); JHTML::_('behavior.tooltip'); // Load JS $document = JFactory::getDocument(); $document->addScript('components/com_sef/assets/js/words.js'); $document->addStyleSheet('components/com_sef/assets/css/words.css'); parent::display($tpl); } } ?>components/com_sef/views/sefurl/tmpl/default.php000066600000030771150771655450016145 0ustar00
    1)); echo JHtml::_('tabs.panel', JText::_('COM_SEF_URL'), 'url-panel'); ?>
    trace && $this->sef->id) : ?>
    tooltip(JText::_('COM_SEF_TT_SEF_URL'), JText::_('COM_SEF_NEW_SEF_URL')); ?>
    tooltip(JText::_('COM_SEF_TT_ORIG_URL'), JText::_('COM_SEF_OLD_NON_SEF_URL'));?>
    tooltip(JText::_('COM_SEF_TT_ITEMID'), JText::_('COM_SEF_ITEMID'));?>
    lists['customurl']; ?>
    lists['enabled']; ?> tooltip(JText::_('COM_SEF_TT_URL_ENABLED'), JText::_('COM_SEF_ENABLED'));?>
    lists['sef']; ?> tooltip(JText::_('COM_SEF_TT_URL_SEF'), JText::_('COM_SEF_SEF'));?>
    lists['locked']; ?> tooltip(JText::_('COM_SEF_TT_URL_LOCKED'), JText::_('COM_SEF_LOCKED'));?>
    : sef->trace)); ?>
    tooltip(JText::_('COM_SEF_TT_ALIAS_LIST'), JText::_('COM_SEF_ALIAS_LIST')); ?>
    tooltip(JText::_('COM_SEF_INFO_JOOMSEF_PLUGIN'), JText::_('COM_SEF_JOOMSEF_PLUGIN_NOTICE')); ?>
    :
    :
    :
    :
    :
    :
    :
    : lists['showsitename']; ?>
    sef->metacustom)) { foreach ($this->sef->metacustom as $name => $content) { ?>
     
    components/com_sef/views/sefurl/tmpl/index.html000066600000000054150771655450015774 0ustar00components/com_sef/views/sefurl/index.html000066600000000054150771655450015020 0ustar00components/com_sef/views/config/view.html.php000066600000004402150771655450015417 0ustar00get('Lists'); $this->assign('lists', $lists); $this->langs=$this->get('langs'); $this->subdomains=$this->get('subdomains'); // Which tabs to show? $sefConfig = SEFConfig::getConfig(); $tabs = array('basic'); if ($sefConfig->professionalMode) { $tabs[] = 'advanced'; } $tabs[] = 'cache'; $tabs[] = 'metatags'; $tabs[] = 'seo'; $tabs[] = 'sitemap'; $tabs[] = 'language'; $tabs[] = 'analytics'; $tabs[] = 'subdomains'; $tabs[] = '404'; $tabs[] = 'registration'; $tab = JRequest::getVar('tab', 'basic'); $tabIdx = array_search($tab, $tabs); if ($tabIdx === false) { $tabIdx = 0; } $this->assign('tabs', $tabs); $this->assign('tab', $tabIdx); // Root domain for subdomains configuration $rootDomain = JFactory::getURI()->getHost(); if (substr($rootDomain, 0, 4) == 'www.') { $rootDomain = substr($rootDomain, 4); } $this->assign('rootDomain', $rootDomain); JHTML::_('behavior.tooltip'); JHTML::_('behavior.framework'); $doc = JFactory::getDocument(); $doc->addStyleDeclaration('form#adminForm div.current { width: auto; }'); $sefConfig = SEFConfig::getConfig(); if (!$sefConfig->professionalMode) { $mainframe = JFactory::getApplication(); $mainframe->enqueueMessage(JText::_('COM_SEF_BEGINNER_MODE_INFO')); } parent::display($tpl); } } ?>components/com_sef/views/config/tmpl/default_sitemap.php000066600000000657150771655450017634 0ustar00components/com_sef/views/config/tmpl/default_basic.php000066600000014072150771655450017247 0ustar00
    > > >
    tooltip(JText::_('COM_SEF_TT_JOOMSEF_ENABLED'),JText::_('COM_SEF_ENABLED'));?> ? lists['enabled'];?>
    tooltip(JText::_('COM_SEF_TT_DISABLE_NEW_SEF'),JText::_('COM_SEF_DISABLE_CREATION_OF_NEW_SEF_URLS'));?> lists['disableNewSEF']; ?>
    tooltip(JText::_('COM_SEF_TT_ENABLE_PROFESSIONAL_MODE'),JText::_('COM_SEF_ENABLE_PROFESSIONAL_MODE'));?> lists['professionalMode']; ?>
    > > > > > professionalMode) { ?> > > > > > > professionalMode ?>
    tooltip(JText::_('COM_SEF_TT_SUFFIX'),JText::_('COM_SEF_SUFFIX'));?>
    tooltip(JText::_('COM_SEF_TT_USE_ALIAS'),JText::_('COM_SEF_USE_TITLE_ALIAS'));?> lists['useAlias'];?>
    tooltip(JText::_('COM_SEF_TT_LOWERCASE'),JText::_('COM_SEF_ALL_LOWERCASE'));?> ? lists['lowerCase'];?>
    tooltip(JText::_('COM_SEF_TT_FORCE_SSL'),JText::_('COM_SEF_FORCE_SSL'));?> ? lists['forceSsl'];?>
    tooltip(JText::_('COM_SEF_TT_WWW_HANDLING'),JText::_('COM_SEF_WWW_HANDLING'));?> lists['wwwHandling']; ?>
    tooltip(JText::_('COM_SEF_TT_NUMBER_DUPLICATES'),JText::_('COM_SEF_NUMBER_DUPLICATE_URLS'));?> lists['numberDuplicates']; ?>
    tooltip(JText::_('COM_SEF_TT_REPLACE_CHAR'),JText::_('COM_SEF_REPLACE_CHAR'));?>
    tooltip(JText::_('COM_SEF_TT_PAGE_SEP_CHAR'),JText::_('COM_SEF_PAGE_SEP_CHAR'));?>
    tooltip(JText::_('COM_SEF_TT_STRIP_CHAR'),JText::_('COM_SEF_STRIP_CHAR'));?>
    tooltip(JText::_('COM_SEF_TT_FRIEND_TRIM_CHAR'),JText::_('COM_SEF_TRIM_FRIEND_TRIM_CHAR'));?>
    tooltip(JText::_('COM_SEF_TT_PAGE_TEXT'),JText::_('COM_SEF_PAGE_TEXT'));?>
    components/com_sef/views/config/tmpl/default.php000066600000025331150771655450016106 0ustar00
    lists; if (!$config->get('sef')) { JError::raiseNotice('100', JText::sprintf('COM_SEF_INFO_SEF_DISABLED', '', '')); } $x = 0; ?> tab)) { JRequest::setVar('jpanetabs_sef-config-tabs', $this->tab, 'cookie'); } //$tabs = array('default','advanced','cache','metatags','seo','sitemap','language','analytics','subdomains','404','registration'); echo JHtml::_('tabs.start', 'sef-config-tabs', array('startOffset' => $this->tab, 'useCookie' => true)); foreach($this->tabs as $tab) { echo $this->loadTemplate($tab); } echo JHtml::_('tabs.end'); ?>
    components/com_sef/views/config/tmpl/default_cache.php000066600000005014150771655450017225 0ustar00
    lists['cache_info']; ?>
    > professionalMode) { ?> > > > > professionalMode ?>
    tooltip(JText::_('COM_SEF_TT_USE_CACHE'), JText::_('COM_SEF_USE_CACHE'));?> lists['useCache'];?>
    tooltip(JText::_('COM_SEF_TT_CACHE_SIZE'), JText::_('COM_SEF_MAXIMUM_CACHE_SIZE'));?> : lists['cacheSize'];?>
    tooltip(JText::_('COM_SEF_TT_CACHE_HITS'), JText::_('COM_SEF_MINIMUM_CACHE_HITS_COUNT'));?> : lists['cacheMinHits'];?>
    tooltip(JText::_('COM_SEF_TT_CACHE_RECORDHITS'), JText::_('COM_SEF_RECORD_HITS_FOR_CACHED_URLS'));?> : lists['cacheRecordHits'];?>
    tooltip(JText::_('COM_SEF_TT_CACHE_SHOWERR'), JText::_('COM_SEF_DISPLAY_CACHE_CORRUPTED_ERROR'));?> : lists['cacheShowErr'];?>
    components/com_sef/views/config/tmpl/default_subdomains.php000066600000005336150771655450020335 0ustar00
    langs as $lang) { $sef = $lang->sef; echo JHTML::_('tabs.panel', JHTML::_('image', 'media/mod_languages/images/' . $lang->image . '.gif', $lang->sef, 'title="'.$lang->sef.'"'), 'subdomains_lang_' . $lang->sef); ?> subdomains[$sef])) { foreach ($this->subdomains[$sef] as $i => $subdomain) { ?>
    .rootDomain; ?> Itemid; ?> Itemid_titlepage; ?>
    components/com_sef/views/config/tmpl/default_metatags.php000066600000016761150771655450020002 0ustar00
    > > > > > > > >
    tooltip(JText::_('COM_SEF_TT_ENABLE_METADATA'), JText::_('COM_SEF_ENABLE_METADATA_GENERATION'));?> : lists['enable_metadata'];?>
    tooltip(JText::_('COM_SEF_TT_METADATA_AUTO'), JText::_('COM_SEF_METADATA_AUTO_GENERATION'));?> : lists['metadata_auto'];?>
    tooltip(JText::_('COM_SEF_TT_PREFER_JOOMSEF_TITLE'), JText::_('COM_SEF_PREFER_JOOMSEF_TITLES'));?> : lists['prefer_joomsef_title'];?>
    tooltip(JText::_('COM_SEF_TT_USE_SITENAME'), JText::_('COM_SEF_USE_SITENAME_IN_PAGE_TITLES'));?> : lists['use_sitename'];?>
    tooltip(JText::_('COM_SEF_TT_SITENAME_SEPARATOR'), JText::_('COM_SEF_SITENAME_SEPARATOR'));?> : lists['sitename_sep'];?>
    tooltip(JText::_('COM_SEF_TT_REWRITE_KEYWORDS'), JText::_('COM_SEF_META_KEYWORDS_PREFERENCE'));?> : lists['rewrite_keywords'];?>
    tooltip(JText::_('COM_SEF_TT_REWRITE_DESC'), JText::_('COM_SEF_META_DESCRIPTION_PREFERENCE'));?> : lists['rewrite_description'];?>
    tooltip(JText::_('COM_SEF_TT_NO_SITENAME_DUPLICITY'), JText::_('COM_SEF_PREVENT_SITENAME_DUPLICITY'));?> : lists['prevent_dupl'];?>
    > > > >
    tooltip(JText::_('COM_SEF_TT_TAG_GENERATOR'), JText::_('COM_SEF_GENERATOR_TAG'));?> : lists['tag_generator'];?>
    tooltip(JText::_('COM_SEF_TT_TAG_GOOGLE_KEY'), JText::_('COM_SEF_GOOGLE_KEY'));?> : lists['tag_googlekey'];?>
    tooltip(JText::_('COM_SEF_TT_TAG_LIVE_KEY'), JText::_('COM_SEF_LIVECOM_KEY'));?> : lists['tag_livekey'];?>
    tooltip(JText::_('COM_SEF_TT_TAG_YAHOO_KEY'), JText::_('COM_SEF_YAHOO_KEY'));?> : lists['tag_yahookey'];?>
    customMetaTags)) { foreach($sefConfig->customMetaTags as $name => $content) { ?>
    components/com_sef/views/config/tmpl/index.html000066600000000054150771655450015741 0ustar00components/com_sef/views/config/tmpl/default_language.php000066600000016725150771655450017760 0ustar00
    >
    > > > > > > > > > > > > >
    tooltip(JText::_('COM_SEF_TT_LANG_ENABLE'),JText::_('COM_SEF_LANG_ENABLE')); ?> lists['langEnable']; ?>
    tooltip(JText::_('COM_SEF_TT_JF_LANG_PLACEMENT'), JText::_('COM_SEF_LANGUAGE_INTEGRATION'));?> lists['langPlacementJoomla'];?>
    tooltip(JText::_('COM_SEF_TT_JF_ALWAYS_USE_LANG'), JText::_('COM_SEF_ALWAYS_USE_LANGUAGE'));?> lists['alwaysUseLangJoomla'];?>
    tooltip(JText::_('COM_SEF_TT_JF_ALWAYS_USE_LANG_HOME'), JText::_('COM_SEF_ALWAYS_USE_LANGUAGE_HOME'));?> lists['alwaysUseLangHomeJoomla'];?>
    tooltip(JText::_('COM_SEF_TT_ADDLANG_TO_MULTILANGUAGE'),JText::_('COM_SEF_ADDLANG_TO_MULTILANGUAGE')); ?> lists['addLangMulti']; ?>
    tooltip(JText::_('COM_SEF_TT_TRANSLATE_ITEMS'),JText::_('COM_SEF_TRANSLATE_ITEMS')); ?> lists['translateItems']; ?>
    tooltip(JText::_('COM_SEF_TT_JF_BROWSER_LANG'), JText::_('COM_SEF_GET_LANGUAGE_FROM_BROWSER_SETTING'));?> lists['browserLangJoomla'];?>
    tooltip(JText::_('COM_SEF_TT_JF_LANG_COOKIE'), JText::_('COM_SEF_SAVE_LANGUAGE_TO_COOKIE'));?> lists['langCookieJoomla'];?>
    tooltip(JText::_('COM_SEF_TT_ROOT_303'), JText::_('COM_SEF_ROOT_303'));?> : lists['rootLangRedirect303'];?>
    tooltip(JText::_('COM_SEF_TT_MENU_ASSOCIATIONS'), JText::_('COM_SEF_MENU_ASSOCIATIONS'));?> : lists['langMenuAssociations'];?>
    tooltip(JText::_('COM_SEF_TT_MISMATCHED_LANG'), JText::_('COM_SEF_MISMATCHED_LANG'));?> : lists['mismatchedLangHandling'];?>
    tooltip(JText::_('COM_SEF_TT_JF_MAIN_LANG'), JText::_('COM_SEF_MAIN_LANGUAGE'));?> : lists['mainLanguageJoomla'];?>
    lists["subdomainsJoomla"]);$i++) { $l=$this->lists["subdomainsJoomla"][$i]; ?> >
    tooltip(JText::_('COM_SEF_TT_JF_DOMAIN'), JText::_('COM_SEF_DOMAIN_CONFIGURATION'));?>  
    title; ?>
    lists['wrongDomainHandling']; ?>
    lists['vm_installed']) { echo JText::_('COM_SEF_VM_NOT_INSTALLED'); } else { $x = 0; ?> > lists['vmCurrency'] as $currency) { ?> >
    tooltip(JText::_('COM_SEF_TT_VM_CURRENCY_ENABLE'), JText::_('COM_SEF_VM_CURRENCY_ENABLE'));?> : lists['vmCurrencyEnable'];?>
    lang; ?> list; ?>
    components/com_sef/views/config/tmpl/default_seo.php000066600000002730150771655450016752 0ustar00
    > >
    tooltip(JText::_('COM_SEF_TT_CANONICALS_REMOVE'), JText::_('COM_SEF_CANONICALS_REMOVE'));?> : lists['canonicalsRemove'];?>
    tooltip(JText::_('COM_SEF_TT_CANONICALS_FIX'), JText::_('COM_SEF_CANONICALS_FIX'));?> : lists['canonicalsFix'];?>
    components/com_sef/views/config/tmpl/default_registration.php000066600000006274150771655450020705 0ustar00

    >
    tooltip(JText::_('COM_SEF_TT_ARTIO_DOWNLOAD_ID'), JText::_('COM_SEF_JOOMSEF_DOWNLOAD_ID'));?> : lists['artioDownloadId'];?>

    > >
    tooltip(JText::_('COM_SEF_TT_ARTIO_USERNAME'), JText::_('COM_SEF_ARTIO_SITE_USERNAME'));?> : lists['artioUserName'];?>
    tooltip(JText::_('COM_SEF_TT_ARTIO_PASSWORD'), JText::_('COM_SEF_ARTIO_SITE_PASSWORD'));?> : lists['artioPassword'];?>
    > >
    tooltip(JText::_('COM_SEF_TT_ARTIO_FEED'), JText::_('COM_SEF_DISPLAY_ARTIO_NEWSFEED'));?> : lists['artioFeedDisplay'];?>
    tooltip(JText::_('COM_SEF_TT_VERSION_CHECKER'),JText::_('COM_SEF_CHECK_FOR_NEWER_VERSIONS'));?> : lists['versionChecker'];?>
    components/com_sef/views/config/tmpl/default_analytics.php000066600000012770150771655450020160 0ustar00
    > > */ ?> > > > > > > > > >
    //tooltip(JText::_('COM_SEF_TT_GOOGLE_EMAIL'),JText::_('COM_SEF_GOOGLE_EMAIL')); ?> // " />
    //tooltip(JText::_('COM_SEF_TT_GOOGLE_PASSWORD'),JText::_('COM_SEF_GOOGLE_PASSWORD')); ?> // " />
    tooltip(JText::_('COM_SEF_TT_GOOGLE_WEB_ID'),JText::_('COM_SEF_WEB_ID')); ?> " />
    tooltip(JText::_('COM_SEF_TT_GOOGLE_APIKEY'),JText::_('COM_SEF_GOOGLE_APIKEY')); ?> " />
    tooltip(JText::_('COM_SEF_TT_GOOGLE_ENABLE'),JText::_('COM_SEF_GOOGLE_ENABLE')); ?> lists["google_enable"]; ?>
    tooltip(JText::_('COM_SEF_TT_GOOGLE_DEMOGRAPHIC'),JText::_('COM_SEF_GOOGLE_DEMOGRAPHIC')); ?> lists["google_demographic_reports"]; ?>
    tooltip(JText::_('COM_SEF_TT_GOOGLE_ATTRIBUTION'),JText::_('COM_SEF_GOOGLE_ATTRIBUTION')); ?> lists["google_link_attribution"]; ?>
    tooltip(JText::_('COM_SEF_TT_GOOGLE_EXCLUDE_IP'),JText::_('COM_SEF_GOOGLE_EXCLUDE_IP')); ?>
    tooltip(JText::_('COM_SEF_TT_GOOGLE_EXCLUDE_LEVEL'),JText::_('COM_SEF_GOOGLE_EXCLUDE_LEVEL')); ?> lists["google_exclude_level"]; ?>
    tooltip(JText::_('COM_SEF_TT_GOOGLE_EXCLUDE_COOKIE'),JText::_('COM_SEF_GOOGLE_EXCLUDE_COOKIE')); ?> /> />
    components/com_sef/views/config/tmpl/default_advanced.php000066600000036537150771655450017745 0ustar00professionalMode) { echo JHtml::_('tabs.panel', JText::_('COM_SEF_ADVANCED'), 'advanced'); $x = 0; ?>
    > > > > > > > > > > >
    tooltip(JText::_('COM_SEF_TT_ALLOW_UTF'), JText::_('COM_SEF_ALLOW_UTF'));?> lists['allowUTF'];?>
    tooltip(JText::_('COM_SEF_TT_REPLACEMENTS'), JText::_('COM_SEF_REPLACEMENTS'));?>
    tooltip(JText::_('COM_SEF_TT_TRANSIT_SLASH'), JText::_('COM_SEF_BE_TOLERANT_TO_TRAILING_SLASH'));?> lists['transitSlash'];?>
    tooltip(JText::_('COM_SEF_TT_REDIRECT_SLASH'),JText::_('COM_SEF_REDIRECT_SLASH')); ?> lists['redirectSlash']; ?>
    tooltip(JText::_('COM_SEF_TT_PARSE_JOOMLA_SEO'), JText::_('COM_SEF_PARSE_JOOMLA_SEO_LINKS'));?> lists['parseJoomlaSEO'];?>
    tooltip(JText::_('COM_SEF_TT_CHECK_BASE_HREF'), JText::_('COM_SEF_SET_PAGE_BASE_HREF_VALUE'));?> : lists['check_base_href']; ?>
    tooltip(JText::_('COM_SEF_TT_FIX_INDEX_PHP'), JText::_('COM_SEF_FIX_INDEXPHP_LINKS'));?> : lists['fixIndexPhp']; ?>
    tooltip(JText::_('COM_SEF_TT_FIX_DOCUMENT_FORMAT'), JText::_('COM_SEF_FIX_DOCUMENT_FORMAT'));?> : lists['fixDocumentFormat']; ?>
    tooltip(JText::_('COM_SEF_TT_INDEX_PHP_CURRENT_MENU'), JText::_('COM_SEF_INDEX_PHP_CURRENT_MENU'));?> : lists['indexPhpCurrentMenu']; ?>
    tooltip(JText::_('COM_SEF_TT_HOME_PAGE_HITS'), JText::_('COM_SEF_HOME_PAGE_HITS'));?> : lists['homePageHits']; ?>
    tooltip(JText::_('COM_SEF_TT_CHUNKED_EXPORT'), JText::_('COM_SEF_CHUNKED_EXPORT'));?> : lists['chunkedExport']; ?>
    > > > */ ?>
    tooltip(JText::_('COM_SEF_TT_USE_MOVED_ASK'), JText::_('COM_SEF_ASK_BEFORE_SAVING_URL_TO_MOVED_PERMANENTLY_TABLE'));?> lists['useMovedAsk'];?>
    tooltip(JText::_('COM_SEF_TT_AUTOLOCK_URLS'),JText::_('COM_SEF_AUTOLOCK_URLS')); ?> : lists['autolock_urls']; ?>
    tooltip(JText::_('COM_SEF_TT_AUTO_UPDATE_URLS'),JText::_('COM_SEF_AUTO_UPDATE_URLS')); ?> : lists['update_urls']; ?>
    > > >
    tooltip(JText::_('COM_SEF_TT_LOG_ERRORS'), JText::_('COM_SEF_ENABLE_LOG_ERRORS'));?> lists['logErrors'];?>
    tooltip(JText::_('COM_SEF_TT_TRACE'), JText::_('COM_SEF_TRACE_URL_SOURCE'));?> lists['trace'];?>
    tooltip(JText::_('COM_SEF_TT_TRACE_DEPTH'), JText::_('COM_SEF_TRACING_DEPTH'));?> : lists['traceLevel'];?>
    > > > > > > >
    tooltip(JText::_('COM_SEF_TT_NONSEF_REDIRECT'), JText::_('COM_SEF_REDIRECT_NONSEF_URLS_TO_SEF'));?> lists['nonSefRedirect'];?>
    tooltip(JText::_('COM_SEF_TT_APPEND_NONSEF'), JText::_('COM_SEF_APPEND_NONSEF'));?> lists['appendNonSef'];?>
    tooltip(JText::_('COM_SEF_TT_PREVENT_NONSEF_OVERWRITE'), JText::_('COM_SEF_PREVENT_NONSEF_OVERWRITE'));?> : lists['preventNonSefOverwrite'];?>
    tooltip(JText::_('COM_SEF_TT_CUSTOM_NONSEF'), JText::_('COM_SEF_CUSTOM_NONSEF'));?> :
    tooltip(JText::_('COM_SEF_TT_AUTO_CANONICAL'), JText::_('COM_SEF_AUTO_CANONICAL'));?> : lists['autoCanonical']; ?>
    tooltip(JText::_('COM_SEF_TT_SEF_COMPONENT_URLS'), JText::_('COM_SEF_SEF_COMPONENT_TEMPLATE'));?> : lists['sefComponentUrls']; ?>
    tooltip(JText::_('COM_SEF_TT_NONSEF_QUERY_VARIABLES'), JText::_('COM_SEF_NONSEF_QUERY_VARIABLES'));?> : lists['nonSefQueryVariables']; ?>
    > > >
    tooltip(JText::sprintf('COM_SEF_TT_CHECK_JUNK_URLS', JText::_('COM_SEF_FILTER_THESE_WORDS')), JText::_('COM_SEF_FILTER_VARIABLE_VALUES'));?> lists['checkJunkUrls'];?>
    tooltip(JText::_('COM_SEF_TT_JUNK_WORDS'), JText::_('COM_SEF_FILTER_THESE_WORDS'));?> : lists['junkWords'];?>
    tooltip(JText::_('COM_SEF_TT_JUNK_EXCLUDE'), JText::_('COM_SEF_JUNK_EXCLUDE'));?> : lists['junkExclude'];?>
    > > > >
    tooltip(JText::_('COM_SEF_TT_EXCLUDE_SOURCE'), JText::_('COM_SEF_EXCLUDE_SOURCE'));?> lists['excludeSource'];?>
    tooltip(JText::_('COM_SEF_TT_REAPPEND_SOURCE'), JText::_('COM_SEF_REAPPEND_SOURCE'));?> lists['reappendSource'];?>
    tooltip(JText::_('COM_SEF_TT_IGNORE_SOURCE'), JText::_('COM_SEF_IGNORE_MULTIPLE_SOURCES'));?> lists['ignoreSource'];?>
    tooltip(JText::_('COM_SEF_TT_ALWAYS_ADD_ITEMID'), JText::_('COM_SEF_ALWAYS_ADD_ITEMID'));?> lists['alwaysAddItemid'];?>
    professionalMode components/com_sef/views/config/tmpl/default_404.php000066600000006533150771655450016500 0ustar00
    > > >
    tooltip(JText::_('COM_SEF_TT_404_PAGE'), JText::_('COM_SEF_404_PAGE'));?> lists['page404'];?>
    tooltip(JText::_('COM_SEF_TT_404_MESSAGE'), JText::_('COM_SEF_SHOW_404_MESSAGE'));?> lists['msg404'];?>
    tooltip(JText::_('COM_SEF_TT_404_RECORD_HITS'), JText::_('COM_SEF_RECORD_404_PAGE_HITS'));?> lists['record404'];?>
    > >
    tooltip(JText::_('COM_SEF_TT_USE_404_ITEMID'), JText::_('COM_SEF_USE_ITEMID_FOR_DEFAULT_404_PAGE'));?> lists['use404itemid'];?>
    tooltip(JText::_('COM_SEF_TT_SELECT_ITEMID'), JText::_('COM_SEF_SELECT_ITEMID'));?> lists['itemid404'];?>
    display('introtext', $this->lists['txt404'], '450', '250', '50', '11'); ?>
    components/com_sef/views/config/index.html000066600000000054150771655450014765 0ustar00components/com_sef/views/info/view.html.php000066600000002142150771655450015104 0ustar00
    components/com_sef/views/info/tmpl/changelog.php000066600000001274150771655450016077 0ustar00
    
    
    components/com_sef/views/info/tmpl/index.html000066600000000054150771655450015427 0ustar00components/com_sef/views/info/tmpl/help.php000066600000004567150771655450015110 0ustar00 components/com_sef/views/info/tmpl/readme.inc.html000066600000114415150771655450016334 0ustar00

    JoomSEF User Manual

    version 3.4.0
    by ARTIO s.r.o.
    last updated on 16. October 2009

    Table of contents

    1. Introduction
    2. Licence
    3. Installing and Configuring
      1. Installation
      2. Configuring IIS
      3. Uninstall
      4. Upgrading from free to paid version
      5. Configuration Checklist
      6. Non-latin languages
      7. Automatic Updates
    4. Useful Usage Tips
      1. Configuration
      2. Optimization
      3. Preventing duplicates
      4. Cache
      5. Patch System
      6. JoomFish Support
      7. Component Configuration
      8. Modifying URLs
      9. Metadata and Page Titles Organization - JoomSEF Metabot
      10. Backing up your Custom URLs
    5. Supported Joomla! Components
      1. Joomla! Built-in Components
      2. 3rd Party Components
      3. List of Official Extensions Available
      4. Extension Downloads
      5. Extension Installation
      6. Extension Upgrade
      7. Extension Parameters
    6. Support and Help
    7. Donate to JoomSEF
    8. Advertisement Notice
    9. Credits
    1. Introduction

      ARTIO JoomSEF is a Joomla! component that generates and allows creation of Search Engine Friendly (SEF) URLs for Apache and IIS, returns proper 404 status code for missing content, provides logging of 404 errors, and creation of special "shortcut" URLs that allow the user to redirection to the new URL.

      Starting with version 1.3.0 JoomSEF also allows control of specific meta tags, such as description or keywords for each generated URL. JoomSEF comes with SEF support for most popular Joomla! components. Some of those are delivered free as part of the JoomSEF installation package and some are also available under commercial licence. If you are missing a support for your favourite component, ARTIO may develop it on request.

      This documents describes how to install and setup ARTIO JoomSEF Joomla! component. You can view this documentation again by selecting the "ARTIO JoomSEF Documentation" button from the ARTIO JoomSEF Control Panel.

    2. Licence

      This software is distributed under following licensing conditions. By installing and using this software, you agree to bind to the licence conditions. Author reserves right to change these conditions at any time without prior notice.

    3. Installing and Configuring

      You can view installation instructions below by clicking the appropriate arrow.

      If your .htaccess file was set as writable the install may have updated it already and you should not have to worry about it.

      If your site is in a subdirectory be sure to change the RewriteBase line accordingly. ex/ RewriteBase /joomla

      1. Installation

        1. Upload the zip file to Joomla! using the component installer in the usual way.
        2. If not processed automatically by installer (e.g. due to write restriction to file), adjust your .htaccess file. Please note, that some directives may not be supported with specific web server or dependant on its configuration. See the comments in file for details.

          Unsupported directives in .htaccess file are most common cause for seeing "500 Internal Server Error" message after JoomSEF installation.

        3. For Apache, set your ".htaccess" file like this (this is file for Joomla 1.5.x):
          ##
          # @version $Id: htaccess.txt 9975 2008-01-30 17:02:11Z ircmaxell $
          # @package Joomla
          # @copyright Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
          # @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
          # Joomla! is Free Software
          ##


          #####################################################
          # READ THIS COMPLETELY IF YOU CHOOSE TO USE THIS FILE
          #
          # The line just below this section: 'Options +FollowSymLinks' may cause problems
          # with some server configurations. It is required for use of mod_rewrite, but may already
          # be set by your server administrator in a way that disallows changing it in
          # your .htaccess file. If using it causes your server to error out, comment it out (add # to
          # beginning of line), reload your site in your browser and test your sef url's. If they work,
          # it has been set by your server administrator and you do not need it set here.
          #
          #####################################################

          ## Can be commented out if causes errors, see notes above.
          # Options +FollowSymLinks

          #
          # mod_rewrite in use

          RewriteEngine On


          # Uncomment following line if your webserver's URL
          # is not directly related to physical file paths.
          # Update Your Joomla! Directory (just / for root)

          # RewriteBase /


          ########## Begin - Joomla! core SEF Section
          #
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteCond %{REQUEST_URI} !^/index.php
          RewriteCond %{REQUEST_URI} (/|\.php|\.html|\.htm|\.feed|\.pdf|\.raw|/[^.]*)$ [NC]
          RewriteRule (.*) index.php
          RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
          #
          ########## End - Joomla! core SEF Section


          ########## Begin - Rewrite rules to block out some common exploits
          ## If you experience problems on your site block out the operations listed below
          ## This attempts to block the most common type of exploit `attempts` to Joomla!
          #
          # Block out any script trying to set a mosConfig value through the URL
          RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
          # Block out any script trying to base64_encode crap to send via URL
          RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
          # Block out any script that includes a <script> tag in URL
          RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
          # Block out any script trying to set a PHP GLOBALS variable via URL
          RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
          # Block out any script trying to modify a _REQUEST variable via URL
          RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
          # Send all blocked request to homepage with 403 Forbidden error!
          RewriteRule ^(.*)$ index.php [F,L]
          #
          ########## End - Rewrite rules to block out some common exploits

          For older Joomla versions (1.0.x) see the original file in the website root (htaccess.txt), rename it to .htaccess and follow the comments within. Htaccess file for Joomla 1.0.x contains 2 rewrite rules sections. With JoomSEF installation, the latter must be uncommented (by default, it is commented out).

        4. For IIS, see Configuring IIS.
        5. Ensure that SEF is enabled under Global Configuration in the Joomla! backend.
        6. Edit the JoomSEF configuration, Change Enable to yes and save.
          This is necessary to ensure the default 404 document gets saved to the Joomla! database.
      2. Configuring IIS

        Since JoomSEF 1.3.2, support for IIS servers has been retested and updated.

        JoomSEF has been successfully tested on IIS5 and IIS6. As the installation process is rather complex, we provide just the basic steps and hints here. If you have problems setting this up, please contact our support team (please note that the support is a paid service).

        1. Configure PHP as ISAPI filter

          In your IIS website configuration, configure PHP to run as ISAPI filter. (recommended)
        2. Install ISAPI Rewrite Filter

          To make JoomSEF work on your IIS, you will further need a rewrite component similar to mod_rewrite to Apache. There is several of them available, both free or commercial. Staying with free solutions, it works e.g. with ISAPI_Rewrite Lite. From the others IISRewrite or ISAPI_Rewrite Full should be ok. We have also tested it with IIRF (Ionic's ISAPI Rewrite Filter) but this one was a bit buggy, although closes to the original Apache's mod_rewrite (hopefully author can fix it soon).
          Download the chosen component and follow its documentation to install it.
        3. Create rewrite rules definition file

          Create an .ini with rewrite rules for the rewrite components. The name of file and location may differ based on selected rewrite module. For ISAPI_Rewrite the file name is httpd.ini and should be store in the modules install directory. For details for your module check its documentation.

          The file analogy of the Apache's .htaccess. The rules needed may differ on component chosen, your server configuration and your usage needs. If you are unsure about configuring this (or also any of the previous steps), you may contact our support.

          In general you may copy the rules from the htaccess.txt file distributed with Joomla! and adjust them to match the rewrite component possibilities. Please note that every module has a slightly different set of rules that it supports. (e.g. ISAPI_Rewrite does NOT support %{REQUEST_FILENAME} !-f) and existing files need to be checked by other rule. E.g. for every RewriteRule, add [L,U] modifier.

          If your Joomla! installation is not located in the website root, you will need to add the relative path to all the RewriteRules. (to simulate Apache's RewriteBase setting). If your Joomla! is located directly in the web site root, just add "/" before the index.php in the 2nd part of the RewriteRules.

          Specific configuration may differ with different IIS Rewrite modules used and its versions (Helicon Isapi Rewrite 2 or 3) and also with Joomla versions 1.0 or 1.5.

          An example configuration for IIRF for the site located in subdirectory /joomla/demo would be following:

          ########## Begin - Joomla! core SEF Section
          #
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteCond %{REQUEST_URI} !^/index.php
          RewriteCond %{REQUEST_URI} (/|\.php|\.html|\.htm|\.feed|\.pdf|\.raw|/[^.]*)$ [NC]
          RewriteRule /joomla/demo/(.*) /joomla/demo/index.php
          RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
          #
          ########## End - Joomla! core SEF Section


          ########## Begin - Rewrite rules to block out some common exploits
          ## If you experience problems on your site block out the operations listed below
          ## This attempts to block the most common type of exploit `attempts` to Joomla!
          #
          # Block out any script trying to set a mosConfig value through the URL
          RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
          # Block out any script trying to base64_encode crap to send via URL
          RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
          # Block out any script that includes a <script> tag in URL
          RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
          # Block out any script trying to set a PHP GLOBALS variable via URL
          RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
          # Block out any script trying to modify a _REQUEST variable via URL
          RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
          # Send all blocked request to homepage with 403 Forbidden error!
          RewriteRule ^(.*)$ index.php [F,L]
          #
          ########## End - Rewrite rules to block out some common exploits

        4. Configure the Custom Errors (optional)

          NOTE: in the example below, Joomla! is installed in the virtual directory Joomla! Using the Internet Services Manager, right-click the directory in which Joomla! is installed.
          Select properties >> Custom Error
          set the 404 to URL:/joomla/index.php
          set the 405 to URL:/joomla/index.php
      3. Uninstall

        1. Uninstall the component using the component unistaller in the usual way.
        2. Restore your .htaccess file to the default version (see htaccess.txt) or remove it completely - depending on whether you will continue to use Joomla! default SEO or not.
      4. Upgrading from free to paid version

        If you have purchased a paid version of JoomSEF and you want to replace the free one without loosing the current configuration and already stored SEF URLs, please follow this procedure:

        1. from JoomSEF control panel, choose "Upgrade"
        2. from upgrade page, choose "Install from page"
        3. choose the installation file you have download from ARTIO website
        4. click the upgrade button
      5. Configuration Checklist

        Make sure that:

        1. the .htaccess exists in the root of your Joomla! site
        2. the 3rd party section rules in .htaccess are uncommented
        3. the "RewriteBase" rule matches YOUR Joomla! installation
        4. Joomla! SEF is "ON" in site "Global configuration"
        5. JoomSEF is "ON" in site "JoomSEF configuration"
      6. Non-latin languages

        If your web site uses non-latin languages (such as Greek, Hebrew, etc.), make sure to configure the character conversion map correctly in JoomSEF Configuration / Non-ASCII character replacements for all characters your language is using.

        The format you need to use is oldChar1|newChar1,oldChar2|newChar2,... .
        Example: α|a,β|b,γ|c,...

      7. Automatic Updates

        Starting with version 1.3.0, JoomSEF provides automatic updates capabilities. From version 2.0.x automatic upgrades also apply to JoomSEF extensions.

        Thanks to this feature, it is no longer needed to uninstall and install the component each time you want to upgrade to newer version. After activating the automatic upgrade tool in the JoomSEF control panel, the component will check, whether newer version is available on-line and if yes, it will automatically download it and install rewriting your current version.

    4. Useful Usage Tips

      1. Configuration

        Using the ARTIO JoomSEF configuration is fairly straight forward. For more information on each item hover your mouse over the blue (i) images when you are in the configuration screen.

        When you save the configuration it will remove all your URL's from the database. If you have a high traffic site it may be wise to put it offline before saving the ARTIO JoomSEF config or purging the database and go and browse your site starting at the main page. This will create the URL's properly for you and prevent numbers from being added to the ends of URL's people were browsing that changed.

        You may want to purge the 404 log before creating fresh urls.

      2. Optimization

        To achieve maximum performance, you should consider several things.

        Always have the latest JoomSEF version installed as we continue optimizations with every release.

        Enable Joomla! caching.

        Use JoomSEF Configuration to turn SEF off for those components you do not need it or which generate too many unoptimized links. Typically when you note links like 45.html, 46.html, ..., something is probably wrong.

        If certain component is using pagination, sorting and similar parameters an advanced configuration option "Append non-SEF variables to URL" may significantly reduce a number of SEF links generated and thus also your DB load. However, please note that the excluded variables will be reappended to your URL in standard form as &varname=value.

        JoomSEF will always be a DB-driven SEO component. It will produce very nice and highly editable URLs for you, but for the cost of higher load for your DB. When configured properly and cached, the load increase should not be significant, but especially with big and frequently visited sites, pay a special attention to configuration and installed modules and plan your SEO carefully.

      3. Preventing duplicates

        If you are facing duplicate content items links e.g. http://yoursite.you/article.html, http://yoursite.you/article-2.html, etc. that lead to the same content, this is most probably caused by so called "Itemid" variable (although there may be other reasons also).

        The Itemid is internal Joomla! variable used to identify the source of a URL link. E.g. main menu or sub menu item that your visitor used to get to a certain content. According to this variable, different Joomla! configurations are applied - e.g. what template will be used or what modules will be visible, etc.

        Since JoomSEF 1.4.0, several new configuration options are provided in "Advanced configuration" section. The option "Exclude source info" may be used to exclude the Itemid variable from the URL and thus eliminate the duplicates caused by it. However, ignoring it completely may lead to unwanted Joomla! functionality, like not switching the templates as desired or so. Whether this will be a problem for you or not depends mainly on the way how your site is designed and how complicated it is. If you need to fix this, the Itemid should be "reappended" to the SEF URL as an extra part using the option "Reappend source". Then the resulting URL will look http://yoursite.you/article.html&Itemid=xy.

        Since JoomSEF 2.0.0 there is a possibility to set your own Itemid for each extension that will always be used with it - thus even when "Reappend source" is set to Yes, that extension won't have the ?Itemid=xy appended. You can find this option in extension parameters. If you leave the "Override Itemid" field blank, the default Itemid will be used, but won't be appended as ?Itemid=xy in URL. Thus you can achieve that the ?Itemid=xy will be added only to those extensions that need it (mostly content). But be careful, setting Itemid to some random number can ruin your menu functionality!

        Another new option is "Ignore multiple sources". If selected, only one URL will be created for each page using the first Itemid. Every other link varying in Itemid only will be ignored and the already created one will be used instead. But again - this can ruin your menu functionality! This option has no effect on extensions with custom Itemid set.

      4. Cache

        JoomSEF 2.0.0 introduces own cache functionality to decrease the amount of queries to your database. You can find this option in Advanced Configuration section.

        When caching is enabled, the most often used links will be kept in memory and will not require querying database every time. You can set the cache size (how many links can be stored in memory) and minimum hit count - only links with hit count greater than specified value will be stored in cache. Be careful about the cache size option - the more links in cache means less queries to database, but on the other hand bigger memory consumption.

      5. Patch System

        JoomSEF 2.0.0 also comes with the new Patch System. This will also decrease amount of queries made to database because everyone can use only those patches he needs, so no more "SELECT DATABASE()" queries if you use only one database.

        A patch is basically a mambot specifically designed to work with JoomSEF only. This means that you can use default Joomla! Mambot installer to manage these patches. Also every patch you install must be published in Site Mambots section in order to work.

      6. JoomFish Support

        There are several ways you can let JoomSEF build URLs on your multi-lingual site. They are displayed in JoomFish Related Configuration section of JoomSEF configuration when JoomFish is installed.

        Language integration

        • Include in path - with this option selected your URLs will look like www.mysite.com/en/somepage.html
        • Add as suffix - this option will make your URLs look like www.mysite.com/somepage_en.html
        • Use different domains - useful option if you have several domains registered for your site. Resulting URLs will look like http://en.mysite.com/somepage.html
        • Do not add - does not add any language code to URLs. Should be used only when "Translate URLs" option is active or it will create duplicate links.

        Always use language
        With this option active the language code will always be added to resulting URL. This may decrease duplicate links count as there won't be two links (with and without language code) pointing to the same page.

        Translate URLs
        Activate to have your URLs translated using JoomFish - this will improve the readability of your URLs for people preferring other languages.

        Domain Configuration
        Here is the place to set custom domain for each language if you have Use different domains selected.

      7. Component Configuration

        In the Component Configuration section of JoomSEF configuration you can set some options for each component individually.

        Handling
        Controls the way how links are processed.

        • Use default handler - JoomSEF will try to create the best looking URL it can using all available resources.
        • Nocache - JoomSEF will create URLs the same way as default Joomla! SEF does - they won't be stored in database and will look like www.mysite.com/component/option,com_virtuemart/Itemid,50/
        • Skip - JoomSEF will not process URLs at all and they will look as with the SEF disabled entirely.

        Custom title
        Lets you set your own extension title to use in URL instead of default menu title. Leave blank for default one. If you use JoomFish you can also translate these custom titles.
        When checking the check box next to the custom title box, the menu title part of the URL will be left empty.

      8. Modifying URLs

        You can modify URL's to your liking. Go into the ARTIO JoomSEF Control Panel and click ' View/Edit SEF Urls'. Select the URL you wish to modify. If you click the check box labeled 'Save as Custom Redirect' it will place this URL into the 'Custom Redirect' area which you can navigate to from the ARTIO JoomSEF Control Panel. When you click 'View/Edit Custom Redirects' you will see your URL in here now instead. These urls will not be removed when you save the config. You can modify these and save them as you wish.

        This is particularly useful if you are updating from an old site because any URL's that are no longer available will be logged. You can view these URL's by clicking 'View/Edit 404 Logs' in the ARTIO JoomSEF Control Panel. You can redirect visitors to the new page by selecting the URL you wish to modify and entering the new url. Note: The ability to enter non-Joomla! URL's into this area is coming soon! This will allow you to easily transfer a non-Joomla! site to Joomla using ARTIO JoomSEF and any of your old URL's will be redirected to the new page within Joomla!.

      9. Metadata and Page Titles Organization - JoomSEF Metabot

        To organize and adjust your site metadata (such as title, meta desc, meta keywords, etc.] from one place, you may use features offered by JoomSEF Metabot. Metabot is installed as a standard Joomla! system mambot (plugin in Joomla 1.5.x) and takes care about composition of your page title and meta data in the page head section.

        Metabot will load the metadata you have defined for a certain SEF URL using the JoomSEF URL editor and will place them into the head section of your current Joomla! page.

        Hint: To define title and/or meta tags for your homepage (that has not really an URL generated by SEF, but composes just from your site base URL), create a new entry in the URL list where the SEF URL will stay blank and the original URL will say just index.php.

        For metabot, to work correctly, it must be used always with JoomSEF component and it has to be in published state. Metabot has also several user configurable option, such as the way how page / site name in page titles is organized and other metadata related settings. To access this configuration, find the ARTIO Metabot in installed Joomla mambots (plugins) list and click it. The configurable parameters then can be found on the right side of the mambot (plugin) detail page.

      10. Backing up your Custom URLs

        It is recommended to backup your database before doing this.

        You can also import and export URL's from the Custom Redirect area. To do this click the 'Import/Export Custom URLS' link above the table of URL's. To backup your URL's click the 'Backup Custom URLS' button and you will be presented with a file named 'ARTIO JoomSEF_custom_urls.sql' to download.

        If you want to import your urls browse to the file and click the 'Import Custom URLS' button.

    5. Supported Joomla! Components

      1. Joomla! Built-in Components

        The support for Joomla! core components, such as banners, content, contacts, news, newsfeeds, weblinks, etc. is already integrated in the JoomSEF component. Optimization of URLs for these components requires no further efforts.

      2. 3rd Party Components

        The situation is slightly different for 3rd party components. There exists many 3rd party components and modules for Joomla!, which usually differ significantly in complexity and structure. This means that for some of those (usually the simple ones), the SEO may work fine, while for other, you can experience, problems such as disfunctionality, insufficient SEO, or generation of duplicate URLs. These can be either skipped in JoomSEF Control Panel, so no SEF URLs will be generated for them, or will require a special "extensions".k using the the default JoomSEF component handler. The others (usually more complex ones) may cause problems when used with the default handler. Such problems may include errors, loss of fun

        Extensions are special pieces of code for JoomSEF, written with particular 3rd party component in mind (e.g. VirtueMart, JoomlaBoard, ...}. Such extension can be either part of the component/module self (provided by component/module author), may come as part of JoomSEF installation package or be provided by 3rd parties. ARTIO offeres most of such extensions available for free as part of the JoomSEF distribution package. However, some of the extensions are provided also under commercial licence. Bellow, you may find list of official extensions available for JoomSEF.

      3. List of Official Extensions Available

        To get the list of the latest JoomSEF extensions available, please, visit the JoomSEF official website.
        We hope this list will spread fast. Our priority is to add and maintain support for the most popular extensions. If you haven't found your favourite component here and it does not work with JoomSEF correctly, please, let us know.

      4. Extension Downloads

        JoomSEF extensions can be free or paid. Many free extensions can be downloaded directly from ARTIO downloads section or from authors' websites. ARTIO also publishes paid extensions that are available from ARTIO webshop.

      5. Extension Installation

        To install extra SEF extension for a component, use installer accessible from the JoomSEF Control Panel.

        1. Click "Install" tool in the toolbar
        2. Use "Upload file" box to select an extension installation file and press "Upload and Install" button
        3. If everything went ok, you should get an confirmation screen with installation status; after clicking "Continue..." link, your new SEF extension is ready to use
      6. Extension Upgrade

        If a new version of extension becomes available, you can update it using JoomSEF Online Upgrade function (if released by ARTIO) or by downloading the recent version and reinstalling it (by uninstalling the old and reinstalling the new version; existing URLs will be maintained).

      7. Extension Parameters

        Since JoomSEF 2.0.0 each extension can have its own parameters affecting resulting URLs - you can access them through main JoomSEF's administration page using the Edit button in the toolbar or simply clicking on extension's name.

    6. Donate to JoomSEF

      ARTIO JoomSEF is a free software. However the development costs are same as for any other software. If you are satisfied with this software and you would like us to implement new features, fix the bugs promptly and publish new releases regularly, you can send us a donation and thus support the JoomSEF further development.

      You may do so via PayPal service using your credit card or transfer, or you can send us the payment directly.

      Bank account information:
      Receiving Bank: Ceskoslovenska obchodni banka (CSOB)
      Address: Hollarova 5, Ostrava, Czech Republic
      Account No.: 199371035, Bank code: 0300
      SWIFT: CEKOCZPP
      IBAN: CZ1303000000000199371035

    7. Support & Help

      If you need more help with the ARTIO JoomSEF component, visit our webpages at http://www.artio.net and check our FAQs & support forums.

    8. Advertisement Notice

      Free edition of JoomSEF may add links pointing to websites of JoomSEF authors (ARTIO s.r.o.) and/or to its sponsors. Such links appear in page footers or meta tag fields of pages, where it is used. This has no direct influence to functionality of your site and you will NOT be penalized by search engines for it.

      You may also purchase a commercial version of JoomSEF that DOES NOT contain these advertisement links. This component is available from ARTIO on-line store.

    9. Credits

      ARTIO s.r.o.
      Mrstikova 840/6
      Ostrava - Marianske Hory
      709 00 Czech Republic

      http://www.artio.net
      info@artio.cz

      Michal Unzeitig, team leader
      David Jozefov, developer
      Petr Vlasak, developer

    components/com_sef/views/info/tmpl/readme.inc.html.backup000066600000113212150771655450017572 0ustar00

    JoomSEF User Manual

    version 3.4.0
    by ARTIO s.r.o.
    last updated on 16. October 2009

    Table of contents

    1. Introduction
    2. Licence
    3. Installing and Configuring
      1. Installation
      2. Configuring IIS
      3. Uninstall
      4. Upgrading from free to paid version
      5. Configuration Checklist
      6. Non-latin languages
      7. Automatic Updates
    4. Useful Usage Tips
      1. Configuration
      2. Optimization
      3. Preventing duplicates
      4. Cache
      5. Patch System
      6. JoomFish Support
      7. Component Configuration
      8. Modifying URLs
      9. Metadata and Page Titles Organization - JoomSEF Metabot
      10. Backing up your Custom URLs
    5. Supported Joomla! Components
      1. Joomla! Built-in Components
      2. 3rd Party Components
      3. List of Official Extensions Available
      4. Extension Downloads
      5. Extension Installation
      6. Extension Upgrade
      7. Extension Parameters
    6. Support and Help
    7. Donate to JoomSEF
    8. Advertisement Notice
    9. Credits
    1. Introduction

      ARTIO JoomSEF is a Joomla! component that generates and allows creation of Search Engine Friendly (SEF) URLs for Apache and IIS, returns proper 404 status code for missing content, provides logging of 404 errors, and creation of special "shortcut" URLs that allow the user to redirection to the new URL.

      Starting with version 1.3.0 JoomSEF also allows control of specific meta tags, such as description or keywords for each generated URL. JoomSEF comes with SEF support for most popular Joomla! components. Some of those are delivered free as part of the JoomSEF installation package and some are also available under commercial licence. If you are missing a support for your favourite component, ARTIO may develop it on request.

      This documents describes how to install and setup ARTIO JoomSEF Joomla! component. You can view this documentation again by selecting the "ARTIO JoomSEF Documentation" button from the ARTIO JoomSEF Control Panel.

    2. Licence

      This software is distributed under following licensing conditions. By installing and using this software, you agree to bind to the licence conditions. Author reserves right to change these conditions at any time without prior notice.

    3. Installing and Configuring

      You can view installation instructions below by clicking the appropriate arrow.

      If your .htaccess file was set as writable the install may have updated it already and you should not have to worry about it.

      If your site is in a subdirectory be sure to change the RewriteBase line accordingly. ex/ RewriteBase /joomla

      1. Installation

        1. Upload the zip file to Joomla! using the component installer in the usual way.
        2. If not processed automatically by installer (e.g. due to write restriction to file), adjust your .htaccess file. Please note, that some directives may not be supported with specific web server or dependant on its configuration. See the comments in file for details.

          Unsupported directives in .htaccess file are most common cause for seeing "500 Internal Server Error" message after JoomSEF installation.

        3. For Apache, set your ".htaccess" file like this (this is file for Joomla 1.5.x):
          ##
          # @version $Id: htaccess.txt 9975 2008-01-30 17:02:11Z ircmaxell $
          # @package Joomla
          # @copyright Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
          # @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
          # Joomla! is Free Software
          ##


          #####################################################
          # READ THIS COMPLETELY IF YOU CHOOSE TO USE THIS FILE
          #
          # The line just below this section: 'Options +FollowSymLinks' may cause problems
          # with some server configurations. It is required for use of mod_rewrite, but may already
          # be set by your server administrator in a way that disallows changing it in
          # your .htaccess file. If using it causes your server to error out, comment it out (add # to
          # beginning of line), reload your site in your browser and test your sef url's. If they work,
          # it has been set by your server administrator and you do not need it set here.
          #
          #####################################################

          ## Can be commented out if causes errors, see notes above.
          # Options +FollowSymLinks

          #
          # mod_rewrite in use

          RewriteEngine On


          # Uncomment following line if your webserver's URL
          # is not directly related to physical file paths.
          # Update Your Joomla! Directory (just / for root)

          # RewriteBase /


          ########## Begin - Joomla! core SEF Section
          #
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteCond %{REQUEST_URI} !^/index.php
          RewriteCond %{REQUEST_URI} (/|\.php|\.html|\.htm|\.feed|\.pdf|\.raw|/[^.]*)$ [NC]
          RewriteRule (.*) index.php
          RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
          #
          ########## End - Joomla! core SEF Section


          ########## Begin - Rewrite rules to block out some common exploits
          ## If you experience problems on your site block out the operations listed below
          ## This attempts to block the most common type of exploit `attempts` to Joomla!
          #
          # Block out any script trying to set a mosConfig value through the URL
          RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
          # Block out any script trying to base64_encode crap to send via URL
          RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
          # Block out any script that includes a <script> tag in URL
          RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
          # Block out any script trying to set a PHP GLOBALS variable via URL
          RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
          # Block out any script trying to modify a _REQUEST variable via URL
          RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
          # Send all blocked request to homepage with 403 Forbidden error!
          RewriteRule ^(.*)$ index.php [F,L]
          #
          ########## End - Rewrite rules to block out some common exploits

          For older Joomla versions (1.0.x) see the original file in the website root (htaccess.txt), rename it to .htaccess and follow the comments within. Htaccess file for Joomla 1.0.x contains 2 rewrite rules sections. With JoomSEF installation, the latter must be uncommented (by default, it is commented out).

        4. For IIS, see Configuring IIS.
        5. Ensure that SEF is enabled under Global Configuration in the Joomla! backend.
        6. Edit the JoomSEF configuration, Change Enable to yes and save.
          This is necessary to ensure the default 404 document gets saved to the Joomla! database.
      2. Configuring IIS

        Since JoomSEF 1.3.2, support for IIS servers has been retested and updated.

        JoomSEF has been successfully tested on IIS5 and IIS6. As the installation process is rather complex, we provide just the basic steps and hints here. If you have problems setting this up, please contact our support team (please note that the support is a paid service).

        1. Configure PHP as ISAPI filter

          In your IIS website configuration, configure PHP to run as ISAPI filter. (recommended)
        2. Install ISAPI Rewrite Filter

          To make JoomSEF work on your IIS, you will further need a rewrite component similar to mod_rewrite to Apache. There is several of them available, both free or commercial. Staying with free solutions, it works e.g. with ISAPI_Rewrite Lite. From the others IISRewrite or ISAPI_Rewrite Full should be ok. We have also tested it with IIRF (Ionic's ISAPI Rewrite Filter) but this one was a bit buggy, although closes to the original Apache's mod_rewrite (hopefully author can fix it soon).
          Download the chosen component and follow its documentation to install it.
        3. Create rewrite rules definition file

          Create an .ini with rewrite rules for the rewrite components. The name of file and location may differ based on selected rewrite module. For ISAPI_Rewrite the file name is httpd.ini and should be store in the modules install directory. For details for your module check its documentation.

          The file analogy of the Apache's .htaccess. The rules needed may differ on component chosen, your server configuration and your usage needs. If you are unsure about configuring this (or also any of the previous steps), you may contact our support.

          In general you may copy the rules from the htaccess.txt file distributed with Joomla! and adjust them to match the rewrite component possibilities. Please note that every module has a slightly different set of rules that it supports. (e.g. ISAPI_Rewrite does NOT support %{REQUEST_FILENAME} !-f) and existing files need to be checked by other rule. E.g. for every RewriteRule, add [L,U] modifier.

          If your Joomla! installation is not located in the website root, you will need to add the relative path to all the RewriteRules. (to simulate Apache's RewriteBase setting). If your Joomla! is located directly in the web site root, just add "/" before the index.php in the 2nd part of the RewriteRules.

          Specific configuration may differ with different IIS Rewrite modules used and its versions (Helicon Isapi Rewrite 2 or 3) and also with Joomla versions 1.0 or 1.5.

          An example configuration for IIRF for the site located in subdirectory /joomla/demo would be following:

          ########## Begin - Joomla! core SEF Section
          #
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteCond %{REQUEST_URI} !^/index.php
          RewriteCond %{REQUEST_URI} (/|\.php|\.html|\.htm|\.feed|\.pdf|\.raw|/[^.]*)$ [NC]
          RewriteRule /joomla/demo/(.*) /joomla/demo/index.php
          RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
          #
          ########## End - Joomla! core SEF Section


          ########## Begin - Rewrite rules to block out some common exploits
          ## If you experience problems on your site block out the operations listed below
          ## This attempts to block the most common type of exploit `attempts` to Joomla!
          #
          # Block out any script trying to set a mosConfig value through the URL
          RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
          # Block out any script trying to base64_encode crap to send via URL
          RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
          # Block out any script that includes a <script> tag in URL
          RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
          # Block out any script trying to set a PHP GLOBALS variable via URL
          RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
          # Block out any script trying to modify a _REQUEST variable via URL
          RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
          # Send all blocked request to homepage with 403 Forbidden error!
          RewriteRule ^(.*)$ index.php [F,L]
          #
          ########## End - Rewrite rules to block out some common exploits

        4. Configure the Custom Errors (optional)

          NOTE: in the example below, Joomla! is installed in the virtual directory Joomla! Using the Internet Services Manager, right-click the directory in which Joomla! is installed.
          Select properties >> Custom Error
          set the 404 to URL:/joomla/index.php
          set the 405 to URL:/joomla/index.php
      3. Uninstall

        1. Uninstall the component using the component unistaller in the usual way.
        2. Restore your .htaccess file to the default version (see htaccess.txt) or remove it completely - depending on whether you will continue to use Joomla! default SEO or not.
      4. Upgrading from free to paid version

        If you have purchased a paid version of JoomSEF and you want to replace the free one without loosing the current configuration and already stored SEF URLs, please follow this procedure:

        1. from JoomSEF control panel, choose "Upgrade"
        2. from upgrade page, choose "Install from page"
        3. choose the installation file you have download from ARTIO website
        4. click the upgrade button
      5. Configuration Checklist

        Make sure that:

        1. the .htaccess exists in the root of your Joomla! site
        2. the 3rd party section rules in .htaccess are uncommented
        3. the "RewriteBase" rule matches YOUR Joomla! installation
        4. Joomla! SEF is "ON" in site "Global configuration"
        5. JoomSEF is "ON" in site "JoomSEF configuration"
      6. Non-latin languages

        If your web site uses non-latin languages (such as Greek, Hebrew, etc.), make sure to configure the character conversion map correctly in JoomSEF Configuration / Non-ASCII character replacements for all characters your language is using.

        The format you need to use is oldChar1|newChar1,oldChar2|newChar2,... .
        Example: α|a,β|b,γ|c,...

      7. Automatic Updates

        Starting with version 1.3.0, JoomSEF provides automatic updates capabilities. From version 2.0.x automatic upgrades also apply to JoomSEF extensions.

        Thanks to this feature, it is no longer needed to uninstall and install the component each time you want to upgrade to newer version. After activating the automatic upgrade tool in the JoomSEF control panel, the component will check, whether newer version is available on-line and if yes, it will automatically download it and install rewriting your current version.

    4. Useful Usage Tips

      1. Configuration

        Using the ARTIO JoomSEF configuration is fairly straight forward. For more information on each item hover your mouse over the blue (i) images when you are in the configuration screen.

        When you save the configuration it will remove all your URL's from the database. If you have a high traffic site it may be wise to put it offline before saving the ARTIO JoomSEF config or purging the database and go and browse your site starting at the main page. This will create the URL's properly for you and prevent numbers from being added to the ends of URL's people were browsing that changed.

        You may want to purge the 404 log before creating fresh urls.

      2. Optimization

        To achieve maximum performance, you should consider several things.

        Always have the latest JoomSEF version installed as we continue optimizations with every release.

        Enable Joomla! caching.

        Use JoomSEF Configuration to turn SEF off for those components you do not need it or which generate too many unoptimized links. Typically when you note links like 45.html, 46.html, ..., something is probably wrong.

        If certain component is using pagination, sorting and similar parameters an advanced configuration option "Append non-SEF variables to URL" may significantly reduce a number of SEF links generated and thus also your DB load. However, please note that the excluded variables will be reappended to your URL in standard form as &varname=value.

        JoomSEF will always be a DB-driven SEO component. It will produce very nice and highly editable URLs for you, but for the cost of higher load for your DB. When configured properly and cached, the load increase should not be significant, but especially with big and frequently visited sites, pay a special attention to configuration and installed modules and plan your SEO carefully.

      3. Preventing duplicates

        If you are facing duplicate content items links e.g. http://yoursite.you/article.html, http://yoursite.you/article-2.html, etc. that lead to the same content, this is most probably caused by so called "Itemid" variable (although there may be other reasons also).

        The Itemid is internal Joomla! variable used to identify the source of a URL link. E.g. main menu or sub menu item that your visitor used to get to a certain content. According to this variable, different Joomla! configurations are applied - e.g. what template will be used or what modules will be visible, etc.

        Since JoomSEF 1.4.0, several new configuration options are provided in "Advanced configuration" section. The option "Exclude source info" may be used to exclude the Itemid variable from the URL and thus eliminate the duplicates caused by it. However, ignoring it completely may lead to unwanted Joomla! functionality, like not switching the templates as desired or so. Whether this will be a problem for you or not depends mainly on the way how your site is designed and how complicated it is. If you need to fix this, the Itemid should be "reappended" to the SEF URL as an extra part using the option "Reappend source". Then the resulting URL will look http://yoursite.you/article.html&Itemid=xy.

        Since JoomSEF 2.0.0 there is a possibility to set your own Itemid for each extension that will always be used with it - thus even when "Reappend source" is set to Yes, that extension won't have the ?Itemid=xy appended. You can find this option in extension parameters. If you leave the "Override Itemid" field blank, the default Itemid will be used, but won't be appended as ?Itemid=xy in URL. Thus you can achieve that the ?Itemid=xy will be added only to those extensions that need it (mostly content). But be careful, setting Itemid to some random number can ruin your menu functionality!

        Another new option is "Ignore multiple sources". If selected, only one URL will be created for each page using the first Itemid. Every other link varying in Itemid only will be ignored and the already created one will be used instead. But again - this can ruin your menu functionality! This option has no effect on extensions with custom Itemid set.

      4. Cache

        JoomSEF 2.0.0 introduces own cache functionality to decrease the amount of queries to your database. You can find this option in Advanced Configuration section.

        When caching is enabled, the most often used links will be kept in memory and will not require querying database every time. You can set the cache size (how many links can be stored in memory) and minimum hit count - only links with hit count greater than specified value will be stored in cache. Be careful about the cache size option - the more links in cache means less queries to database, but on the other hand bigger memory consumption.

      5. Patch System

        JoomSEF 2.0.0 also comes with the new Patch System. This will also decrease amount of queries made to database because everyone can use only those patches he needs, so no more "SELECT DATABASE()" queries if you use only one database.

        A patch is basically a mambot specifically designed to work with JoomSEF only. This means that you can use default Joomla! Mambot installer to manage these patches. Also every patch you install must be published in Site Mambots section in order to work.

      6. JoomFish Support

        There are several ways you can let JoomSEF build URLs on your multi-lingual site. They are displayed in JoomFish Related Configuration section of JoomSEF configuration when JoomFish is installed.

        Language integration

        • Include in path - with this option selected your URLs will look like www.mysite.com/en/somepage.html
        • Add as suffix - this option will make your URLs look like www.mysite.com/somepage_en.html
        • Use different domains - useful option if you have several domains registered for your site. Resulting URLs will look like http://en.mysite.com/somepage.html
        • Do not add - does not add any language code to URLs. Should be used only when "Translate URLs" option is active or it will create duplicate links.

        Always use language
        With this option active the language code will always be added to resulting URL. This may decrease duplicate links count as there won't be two links (with and without language code) pointing to the same page.

        Translate URLs
        Activate to have your URLs translated using JoomFish - this will improve the readability of your URLs for people preferring other languages.

        Domain Configuration
        Here is the place to set custom domain for each language if you have Use different domains selected.

      7. Component Configuration

        In the Component Configuration section of JoomSEF configuration you can set some options for each component individually.

        Handling
        Controls the way how links are processed.

        • Use default handler - JoomSEF will try to create the best looking URL it can using all available resources.
        • Nocache - JoomSEF will create URLs the same way as default Joomla! SEF does - they won't be stored in database and will look like www.mysite.com/component/option,com_virtuemart/Itemid,50/
        • Skip - JoomSEF will not process URLs at all and they will look as with the SEF disabled entirely.

        Custom title
        Lets you set your own extension title to use in URL instead of default menu title. Leave blank for default one. If you use JoomFish you can also translate these custom titles.
        When checking the check box next to the custom title box, the menu title part of the URL will be left empty.

      8. Modifying URLs

        You can modify URL's to your liking. Go into the ARTIO JoomSEF Control Panel and click ' View/Edit SEF Urls'. Select the URL you wish to modify. If you click the check box labeled 'Save as Custom Redirect' it will place this URL into the 'Custom Redirect' area which you can navigate to from the ARTIO JoomSEF Control Panel. When you click 'View/Edit Custom Redirects' you will see your URL in here now instead. These urls will not be removed when you save the config. You can modify these and save them as you wish.

        This is particularly useful if you are updating from an old site because any URL's that are no longer available will be logged. You can view these URL's by clicking 'View/Edit 404 Logs' in the ARTIO JoomSEF Control Panel. You can redirect visitors to the new page by selecting the URL you wish to modify and entering the new url. Note: The ability to enter non-Joomla! URL's into this area is coming soon! This will allow you to easily transfer a non-Joomla! site to Joomla using ARTIO JoomSEF and any of your old URL's will be redirected to the new page within Joomla!.

      9. Metadata and Page Titles Organization - JoomSEF Metabot

        To organize and adjust your site metadata (such as title, meta desc, meta keywords, etc.] from one place, you may use features offered by JoomSEF Metabot. Metabot is installed as a standard Joomla! system mambot (plugin in Joomla 1.5.x) and takes care about composition of your page title and meta data in the page head section.

        Metabot will load the metadata you have defined for a certain SEF URL using the JoomSEF URL editor and will place them into the head section of your current Joomla! page.

        Hint: To define title and/or meta tags for your homepage (that has not really an URL generated by SEF, but composes just from your site base URL), create a new entry in the URL list where the SEF URL will stay blank and the original URL will say just index.php.

        For metabot, to work correctly, it must be used always with JoomSEF component and it has to be in published state. Metabot has also several user configurable option, such as the way how page / site name in page titles is organized and other metadata related settings. To access this configuration, find the ARTIO Metabot in installed Joomla mambots (plugins) list and click it. The configurable parameters then can be found on the right side of the mambot (plugin) detail page.

      10. Backing up your Custom URLs

        It is recommended to backup your database before doing this.

        You can also import and export URL's from the Custom Redirect area. To do this click the 'Import/Export Custom URLS' link above the table of URL's. To backup your URL's click the 'Backup Custom URLS' button and you will be presented with a file named 'ARTIO JoomSEF_custom_urls.sql' to download.

        If you want to import your urls browse to the file and click the 'Import Custom URLS' button.

    5. Supported Joomla! Components

      1. Joomla! Built-in Components

        The support for Joomla! core components, such as banners, content, contacts, news, newsfeeds, weblinks, etc. is already integrated in the JoomSEF component. Optimization of URLs for these components requires no further efforts.

      2. 3rd Party Components

        The situation is slightly different for 3rd party components. There exists many 3rd party components and modules for Joomla!, which usually differ significantly in complexity and structure. This means that for some of those (usually the simple ones), the SEO may work fine, while for other, you can experience, problems such as disfunctionality, insufficient SEO, or generation of duplicate URLs. These can be either skipped in JoomSEF Control Panel, so no SEF URLs will be generated for them, or will require a special "extensions".k using the the default JoomSEF component handler. The others (usually more complex ones) may cause problems when used with the default handler. Such problems may include errors, loss of fun

        Extensions are special pieces of code for JoomSEF, written with particular 3rd party component in mind (e.g. VirtueMart, JoomlaBoard, ...}. Such extension can be either part of the component/module self (provided by component/module author), may come as part of JoomSEF installation package or be provided by 3rd parties. ARTIO offeres most of such extensions available for free as part of the JoomSEF distribution package. However, some of the extensions are provided also under commercial licence. Bellow, you may find list of official extensions available for JoomSEF.

      3. List of Official Extensions Available

        To get the list of the latest JoomSEF extensions available, please, visit the JoomSEF official website.
        We hope this list will spread fast. Our priority is to add and maintain support for the most popular extensions. If you haven't found your favourite component here and it does not work with JoomSEF correctly, please, let us know.

      4. Extension Downloads

        JoomSEF extensions can be free or paid. Many free extensions can be downloaded directly from ARTIO downloads section or from authors' websites. ARTIO also publishes paid extensions that are available from ARTIO webshop.

      5. Extension Installation

        To install extra SEF extension for a component, use installer accessible from the JoomSEF Control Panel.

        1. Click "Install" tool in the toolbar
        2. Use "Upload file" box to select an extension installation file and press "Upload and Install" button
        3. If everything went ok, you should get an confirmation screen with installation status; after clicking "Continue..." link, your new SEF extension is ready to use
      6. Extension Upgrade

        If a new version of extension becomes available, you can update it using JoomSEF Online Upgrade function (if released by ARTIO) or by downloading the recent version and reinstalling it (by uninstalling the old and reinstalling the new version; existing URLs will be maintained).

      7. Extension Parameters

        Since JoomSEF 2.0.0 each extension can have its own parameters affecting resulting URLs - you can access them through main JoomSEF's administration page using the Edit button in the toolbar or simply clicking on extension's name.

    6. Donate to JoomSEF

      ARTIO JoomSEF is a free software. However the development costs are same as for any other software. If you are satisfied with this software and you would like us to implement new features, fix the bugs promptly and publish new releases regularly, you can send us a donation and thus support the JoomSEF further development.

      You may do so via PayPal service using your credit card or transfer, or you can send us the payment directly.

      Bank account information:
      Receiving Bank: Ceskoslovenska obchodni banka (CSOB)
      Address: Hollarova 5, Ostrava, Czech Republic
      Account No.: 199371035, Bank code: 0300
      SWIFT: CEKOCZPP
      IBAN: CZ1303000000000199371035

    7. Support & Help

      If you need more help with the ARTIO JoomSEF component, visit our webpages at http://www.artio.net and check our FAQs & support forums.

    8. Advertisement Notice

      Free edition of JoomSEF may add links pointing to websites of JoomSEF authors (ARTIO s.r.o.) and/or to its sponsors. Such links appear in page footers or meta tag fields of pages, where it is used. This has no direct influence to functionality of your site and you will NOT be penalized by search engines for it.

      You may also purchase a commercial version of JoomSEF that DOES NOT contain these advertisement links. This component is available from ARTIO on-line store.

    9. Credits

      ARTIO s.r.o.
      Mrstikova 840/6
      Ostrava - Marianske Hory
      709 00 Czech Republic

      http://www.artio.net
      info@artio.cz

      Michal Unzeitig, team leader
      David Jozefov, developer
      Petr Vlasak, developer

    components/com_sef/views/info/index.html000066600000000054150771655450014453 0ustar00components/com_sef/views/index.html000066600000000054150771655450013520 0ustar00components/com_sef/views/statistics/view.html.php000066600000001362150771655450016346 0ustar00setLayout(JRequest::getCmd('layout','default')); $icon = 'statistics.png'; JToolbarHelper::title(JText::_('COM_SEF_STATISTICS'), $icon); JToolBarHelper::back('COM_SEF_BACK', 'index.php?option=com_sef'); parent::display($tpl); } } ?>components/com_sef/views/statistics/tmpl/default.php000066600000000547150771655450017035 0ustar00components/com_sef/views/statistics/tmpl/index.html000066600000000054150771655450016666 0ustar00components/com_sef/views/statistics/tmpl/default_analytics.php000066600000000512150771655450021074 0ustar00components/com_sef/views/statistics/tmpl/default_statistics_sources.php000066600000000512150771655450023042 0ustar00components/com_sef/views/statistics/tmpl/updatestatistics.php000066600000000547150771655450021006 0ustar00components/com_sef/views/statistics/tmpl/default_statistics_visits.php000066600000000512150771655450022700 0ustar00components/com_sef/views/statistics/tmpl/default_statistics_top.php000066600000000512150771655450022161 0ustar00components/com_sef/views/statistics/tmpl/default_statistics.php000066600000000512150771655450021277 0ustar00components/com_sef/views/statistics/tmpl/default_statistics_referers.php000066600000000512150771655450023174 0ustar00components/com_sef/views/statistics/tmpl/speed.php000066600000000547150771655450016511 0ustar00components/com_sef/views/statistics/tmpl/default_statistics_global.php000066600000000512150771655450022617 0ustar00components/com_sef/views/statistics/tmpl/updatevalidity.php000066600000000547150771655450020441 0ustar00components/com_sef/views/statistics/index.html000066600000000054150771655450015712 0ustar00components/com_sef/views/statistics/view.html.php.backup000066600000014356150771655450017621 0ustar00setLayout(JRequest::getCmd('layout','default')); $icon = 'statistics.png'; if(JRequest::getCmd('layout','default')=='speed') { $this->speed=$this->get('pageSpeed'); JFactory::getDocument()->addScript(JFactory::getURI()->base(false)."/components/com_sef/assets/charts/FusionCharts116.js"); } else { $this->items=$this->get('Items'); $this->pagination=$this->get('Pagination'); $this->state=$this->get('State'); $this->config=$this->get('config'); $this->ordering = $this->get('Ordering'); $this->accounts=$this->get('accounts'); if($this->accounts!==false) { $this->globals_html=$this->renderGlobals(); $this->top_urls_html=$this->renderTopUrls(); $this->top_referers_html=$this->renderTopReferers(); $this->sources_html=$this->renderSources(); $this->visits_html=$this->renderVisits(); } JHTML::_('behavior.tooltip'); JHTML::_('behavior.modal'); JFactory::getDocument()->addScript(JFactory::getURI()->base(false)."/components/com_sef/assets/charts/FusionCharts116.js"); JToolbarHelper::title(JText::_('COM_SEF_STATISTICS'), $icon); JToolbarHelper::custom("update_statistics","refresh.png","refresh_f2.png",JText::_('COM_SEF_UPDATE_STATS')); JToolbarHelper::custom("updatevalidity","refresh.png","refresh_f2.png",JText::_('COM_SEF_UPDATE_VALIDITY')); JToolBarHelper::spacer(); JToolBarHelper::back('COM_SEF_BACK', 'index.php?option=com_sef'); // Check CURL and OpenSSL presence if (!function_exists('curl_init') && !function_exists('openssl_open')) { $app = JFactory::getApplication(); $app->enqueueMessage(JText::_('COM_SEF_ANALYTICS_NO_SSL')); } } parent::display($tpl); } function __construct() { parent::__construct(); $this->cache=JFactory::getCache('com_sef','output'); $this->cache->setLifeTime(3600*24); $this->cache->setCaching(1); } function showUpdateValidity() { JToolbarHelper::title(JText::_('COM_SEF_UPDATE_VALIDITY')); $this->total=$this->get('totalUrls'); $this->setLayout('updatevalidity'); JHTML::_('behavior.framework'); parent::display(); } function showUpdateStatistics() { JToolbarHelper::title(JText::_('COM_SEF_UPDATE_STATS')); $this->total=$this->get('totalUrls'); // Check API key presence $config = SEFConfig::getConfig(); if (strlen($config->google_apikey) == 0) { $app = JFactory::getApplication(); $app->enqueueMessage(JText::_('COM_SEF_PAGESPEED_UPDATE_NO_KEY')); } // Check SSL support else if (!function_exists('curl_init') && !function_exists('openssl_open')) { $app = JFactory::getApplication(); $app->enqueueMessage(JText::_('COM_SEF_PAGESPEED_UPDATE_NO_SUPPORT')); } $this->setLayout('updatestatistics'); JHTML::_('behavior.framework'); parent::display(); } function renderGlobals($force=false) { $id=md5(JRequest::getInt('account_id',$this->get('defaultAccountId')).JRequest::getString('start_date',JFactory::getDate((JFactory::getDate()->toUnix()-(60*60*24*7)))->format("Y-m-d")).JRequest::getString('end_date',JFactory::getDate()->format("Y-m-d"))."globals"); if($force) { $this->cache->remove($id); } $data=$this->cache->get($id); if($data==false) { $this->globals=$this->get('globals'); $data=$this->loadTemplate('statistics_global'); $this->cache->store($data,$id); } return $data; } function renderTopUrls($force=false) { $id=md5(JRequest::getInt('account_id',$this->get('defaultAccountId')).JRequest::getString('start_date',JFactory::getDate((JFactory::getDate()->toUnix()-(60*60*24*7)))->format("Y-m-d")).JRequest::getString('end_date',JFactory::getDate()->format("Y-m-d"))."topUrls"); if($force) { $this->cache->remove($id); } $data=$this->cache->get($id); if($data==false) { if(!isset($this->globals)) { $this->globals=$this->get('globals'); } $this->top=$this->get('topUrls'); $data=$this->loadTemplate('statistics_top'); $this->cache->store($data,$id); } return $data; } function renderTopReferers($force=false) { $id=md5(JRequest::getInt('account_id',$this->get('defaultAccountId')).JRequest::getString('start_date',JFactory::getDate((JFactory::getDate()->toUnix()-(60*60*24*7)))->format("Y-m-d")).JRequest::getString('end_date',JFactory::getDate()->format("Y-m-d"))."topReferers"); if($force) { $this->cache->remove($id); } $data=$this->cache->get($id); if($data==false) { if(!isset($this->globals)) { $this->globals=$this->get('globals'); } $this->referers=$this->get('topReferers'); $data=$this->loadTemplate('statistics_referers'); $this->cache->store($data,$id); } return $data; } function renderSources($force=false) { $id=md5(JRequest::getInt('account_id',$this->get('defaultAccountId')).JRequest::getString('start_date',JFactory::getDate((JFactory::getDate()->toUnix()-(60*60*24*7)))->format("Y-m-d")).JRequest::getString('end_date',JFactory::getDate()->format("Y-m-d"))."sources"); if($force) { $this->cache->remove($id); } $data=$this->cache->get($id); if($data==false) { $this->sources=$this->get('sources'); $data=$this->loadTemplate('statistics_sources'); } return $data; } function renderVisits($force=false) { $id=md5(JRequest::getInt('account_id',$this->get('defaultAccountId')).JRequest::getString('start_date',JFactory::getDate((JFactory::getDate()->toUnix()-(60*60*24*7)))->format("Y-m-d")).JRequest::getString('end_date',JFactory::getDate()->format("Y-m-d"))."sources"); if($force) { $this->cache->remove($id); } $data=$this->cache->get($id); if($data==false) { $this->visits=$this->get('visits'); $data=$this->loadTemplate('statistics_visits'); } return $data; } } ?>components/com_sef/views/movedurls/view.html.php000066600000002557150771655450016203 0ustar00appendButton( 'Confirm', 'COM_SEF_CONFIRM_DEL_FILTER', 'delete_f2', 'COM_SEF_DELETE_ALL_FILTERED', 'deletefiltered', false, false ); JToolBarHelper::spacer(); JToolBarHelper::back('COM_SEF_BACK', 'index.php?option=com_sef'); // Get data from the model $this->assign('items', $this->get('Data')); $this->assign($this->getModel()); $this->assign('total', $this->get('Total')); $this->assign('lists', $this->get('Lists')); $this->assign('pagination', $this->get('Pagination')); parent::display($tpl); } } components/com_sef/views/movedurls/tmpl/default.php000066600000010630150771655450016655 0ustar00
    showInfoText('COM_SEF_INFOTEXT_301REDIRECTS'); ?>
    ' . $this->lists['filterOld']; ?> ' . $this->lists['filterNew']; ?> ' . $this->lists['filterDays']; ?> ' . $this->lists['filterReset']; ?>
    getPaginationFooter(5); ?> items) as $i) { $row = &$this->items[$i]; ?>
    lists['filter_order'] == 'old' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); ?> lists['filter_order'] == 'new' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); ?> lists['filter_order'] == 'lastHit' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); ?>
    pagination->getRowOffset($i); ?> id ); ?> old); ?> new); ?> lastHit, 0, 10) == '0000-00-00' ? JText::_('COM_SEF_NEVER') : $row->lastHit); ?>
    components/com_sef/views/movedurls/tmpl/index.html000066600000000054150771655450016514 0ustar00components/com_sef/views/movedurls/index.html000066600000000054150771655450015540 0ustar00components/com_sef/views/word/view.html.php000066600000001036150771655450015125 0ustar00components/com_sef/views/word/tmpl/default.php000066600000000633150771655450015612 0ustar00components/com_sef/views/word/tmpl/index.html000066600000000054150771655450015447 0ustar00components/com_sef/views/word/index.html000066600000000054150771655450014473 0ustar00components/com_sef/views/metatags/view.html.php000066600000002254150771655450015762 0ustar00assign($this->getModel()); JToolBarHelper::save(); JToolBarHelper::apply(); JToolBarHelper::spacer(); JToolBarHelper::back('COM_SEF_BACK', 'index.php?option=com_sef'); // Get data from the model $this->assign('items', $this->get('Data')); $this->assign('total', $this->get('Total')); $this->assign('lists', $this->get('Lists')); $this->assign('pagination', $this->get('Pagination')); JHTML::_('behavior.tooltip'); parent::display($tpl); } } components/com_sef/views/metatags/tmpl/default.php000066600000015376150771655450016456 0ustar00
    langEnable) { ?> langEnable) { ?>
    lists['filterSEFRE']; ?> lists['filterRealRE']; ?>
    lists['filterSEF']; ?> lists['filterReal']; ?> lists['filterTitle']; ?> lists['filterDesc']; ?> lists['filterKeys']; ?> lists['comList']; ?> lists['filterLang']; ?> lists['filterReset']; ?>
    getPaginationFooter(5); ?> items) as $i) { $row = &$this->items[$i]; ?>
    lists['filter_order'] == 'sefurl' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); ?> / lists['filter_order'] == 'origurl' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); ?> lists['filter_order'] == 'metatitle' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); ?> lists['filter_order'] == 'metadesc' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); ?> lists['filter_order'] == 'metakey' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); ?>
    pagination->getRowOffset($i); ?> sefurl); ?>

    origurl . ($row->Itemid == '' ? '' : (strpos($row->origurl, '?') ? '&' : '?') . 'Itemid='.$row->Itemid ) ); ?>
    components/com_sef/views/metatags/tmpl/index.html000066600000000054150771655450016301 0ustar00components/com_sef/views/metatags/index.html000066600000000054150771655450015325 0ustar00components/com_sef/views/cron/view.html.php000066600000001252150771655450015113 0ustar00components/com_sef/views/cron/tmpl/index.html000066600000000054150771655450015435 0ustar00components/com_sef/views/cron/index.html000066600000000054150771655450014461 0ustar00components/com_sef/views/install/view.html.php000066600000003644150771655450015627 0ustar00_addPath('template', $this->_basePath.'/views/templates'); } function display($tpl = null) { JToolBarHelper::title( JText::_( 'COM_SEF_INSTALL' ).' '.JText::_('COM_SEF_SEF_EXTENSION'), 'plugin.png' ); $bar = JToolBar::getInstance(); $bar->appendButton('Confirm', 'COM_SEF_CONFIRM_UNINSTALL_EXTENSION', 'uninstall', 'COM_SEF_UNINSTALL', 'uninstallext', true, false); JToolBarHelper::spacer(); JToolBarHelper::back('COM_SEF_BACK', 'index.php?option=com_sef&controller=extension'); $exts = $this->get('extensions', 'extensions'); $this->assign('extensions', $exts); // Check that the sef_ext directory is writable if( !is_writable(JPATH_ROOT.'/components/com_sef/sef_ext') ) { JError::raiseWarning(100, JText::_('COM_SEF_ERROR_EXTENSIONS_DIRECTORY')); } JHTML::_('behavior.tooltip'); parent::display($tpl); } function showMessage() { JToolBarHelper::title( JText::_( 'Install' ).' '.JText::_('COM_SEF_SEF_EXTENSION'), 'plugin.png' ); $url = 'index.php?option=com_sef&task=installext'; $redir = JRequest::getVar('redirto', null, 'post'); if( !is_null($redir) ) { $url = 'index.php?option=com_sef&'.$redir; } JToolBarHelper::back('Continue', $url); $this->assign('url', $url); $this->setLayout('message'); parent::display(); } } components/com_sef/views/install/tmpl/default.php000066600000010053150771655450016302 0ustar00
    Warning: Installing 3rd party extensions may compromise your server's security. Upgrading your Joomla! installation will not update your 3rd party extensions.
    For more information on keeping your site secure, please see the Joomla! Security Forum.
    loadTemplate('extslist'); ?>
    components/com_sef/views/install/tmpl/message.php000066600000001667150771655450016315 0ustar00get('State'); $result = $state->get('result'); $name = $state->get('name'); $message = $state->get('message'); ?>
    Continue ... ]
    components/com_sef/views/install/tmpl/index.html000066600000000054150771655450016142 0ustar00components/com_sef/views/install/index.html000066600000000054150771655450015166 0ustar00components/com_sef/views/upgrade/view.html.php000066600000003572150771655450015610 0ustar00_addPath('template', $this->_basePath.'/views/templates'); } function display($tpl = null) { JToolBarHelper::title( JText::_( 'COM_SEF_JOOMSEF' ).' - '.JText::_('COM_SEF_UPGRADE_MANAGER'), 'update.png' ); JToolBarHelper::back('COM_SEF_BACK', 'index.php?option=com_sef'); $exts = $this->get('UpgradeExts'); $this->assign('extensions', $exts); $oldVer = SEFTools::getSEFVersion(); $this->assign('oldVer', $oldVer); $newVer = $this->get('newSEFVersion'); $this->assign('newVer', $newVer); $regInfo = $this->get('RegisteredInfo'); $this->assign('regInfo', $regInfo); $isPaidVersion = $this->get('IsPaidVersion'); $this->assign('isPaidVersion', $isPaidVersion); JHTML::_('behavior.tooltip'); JHTML::_('behavior.modal'); parent::display($tpl); } function showMessage() { JToolBarHelper::title( JText::_( 'JoomSEF' ).' '.JText::_('COM_SEF_UPGRADE_MANAGER'), 'update.png' ); $url = 'index.php?option=com_sef&task=showupgrade'; $redir = JRequest::getVar('redirto', null, 'post'); if( !is_null($redir) ) { $url = 'index.php?option=com_sef&'.$redir; } JToolBarHelper::back('Continue', $url); $this->assign('url', $url); $this->setLayout('message'); parent::display(); } } components/com_sef/views/upgrade/tmpl/default.php000066600000021334150771655450016267 0ustar00artioDownloadId) != '') && (is_null($this->regInfo) || ($this->regInfo->code != 10)) ) { $needConfirm = true; } else { $needConfirm = false; } if( (trim($sefConfig->artioDownloadId) == '') || is_null($this->regInfo) || ($this->regInfo->code != 10) ) { $downloadPaid = false; } else { $downloadPaid = true; } ?>
    oldVer; ?>
    newVer; ?>
    artioDownloadId) != '' ) { ?> regInfo) ) { ?> regInfo->code == 90 ) { ?> regInfo->name; if( !empty($this->regInfo->company) ) { $regTo .= ', ' . $this->regInfo->company; } ?> regInfo->code == 10 || $this->regInfo->code == 30) { $dateText = JText::_('COM_SEF_FREE_UPGRADES_AVAILABLE_UNTIL'); } elseif ($this->regInfo->code == 20) { $dateText = JText::_('COM_SEF_FREE_UPGRADES_EXPIRED'); } ?>
    artioDownloadId)); ?>
    :
    : regInfo->date; ?>
    newVer, $this->oldVer) > 0) || (strnatcasecmp($this->newVer, substr($this->oldVer, 0, strpos($this->oldVer, '-'))) == 0) || ($this->newVer == "?.?.?") ) { $available = true; if (!$this->isPaidVersion && $downloadPaid) { $btnText = JText::_('COM_SEF_ONLINE_UPGRADE_TO_PAID_VERSION'); } else { $btnText = JText::_('COM_SEF_UPGRADE_FROM_ARTIO_SERVER'); } } elseif (($this->newVer == $this->oldVer)) { //else { $available = true; if (!$this->isPaidVersion && $downloadPaid) { $btnText = JText::_('COM_SEF_ONLINE_MIGRATE_TO_PAID_VERSION'); } else { $btnText = JText::_('COM_SEF_REINSTALL_FROM_ARTIO_SERVER'); } } if( $available ) { ?>
    newVer == '?.?.?' ) { echo JText::_('COM_SEF_SERVER_NOT_AVAILABLE'); } else { ?>
    extensions) > 0) ) { foreach(array_keys($this->extensions) as $i) { $row = &$this->extensions[$i]; ?>
    name; ?> old, $row->new, '>=') ? 'green' : 'red'; echo ''.$row->old.''; ?> new; ?> type == 'Paid') { $img = 'icon-16-key'; $ttl = JText::_('COM_SEF_DOWNLOAD_ID_SET'); $txt = JText::_('COM_SEF_CLICK_TO_CHANGE'); if ($row->params->get('downloadId', '') == '') { $img .= '_bw'; $ttl = JText::_('COM_SEF_DOWNLOAD_ID_NOT_SET'); $txt = JText::_('COM_SEF_CLICK_TO_SET'); } $href = 'index.php?option=com_sef&controller=extension&cid[]='.$row->option.'&task=editId&tmpl=component'; echo ''; echo ''; echo ' '; } echo JText::_($row->type); ?> new, $row->old) > 0) || (strnatcasecmp($row->new, substr($row->old, 0, strpos($row->old, '-'))) == 0) ) { ?>
    components/com_sef/views/upgrade/tmpl/message.php000066600000001431150771655450016263 0ustar00get('State'); $result = $state->get('result'); $message = $state->get('message'); ?>
    Continue ... ]
    components/com_sef/views/upgrade/tmpl/index.html000066600000000054150771655450016123 0ustar00components/com_sef/views/upgrade/index.html000066600000000054150771655450015147 0ustar00components/com_sef/views/words/view.html.php000066600000001404150771655450015307 0ustar00components/com_sef/views/words/tmpl/index.html000066600000000054150771655450015632 0ustar00components/com_sef/views/words/index.html000066600000000054150771655450014656 0ustar00components/com_sef/views/sitemap/view.html.php000066600000001422150771655450015613 0ustar00components/com_sef/views/sitemap/tmpl/index.html000066600000000054150771655450016136 0ustar00components/com_sef/views/sitemap/index.html000066600000000054150771655450015162 0ustar00components/com_sef/views/crawler/view.html.php000066600000003643150771655450015617 0ustar00addScriptDeclaration($js); // Load JS JHTML::script('administrator/components/com_sef/assets/js/crawler.js', true); JHTML::_('behavior.tooltip'); parent::display($tpl); } } components/com_sef/views/crawler/tmpl/default.php000066600000006570150771655450016304 0ustar00
    showInfoText('COM_SEF_INFOTEXT_CRAWL', true); ?>
    :
    :
    :
       
    : 0
    : 0 / 0
     
    components/com_sef/views/crawler/tmpl/index.html000066600000000054150771655450016133 0ustar00components/com_sef/views/crawler/index.html000066600000000054150771655450015157 0ustar00components/com_sef/views/sefurls/view.html.php000066600000006442150771655450015643 0ustar00getUserStateFromRequest('sef.sefurls.viewmode', 'viewmode', 0); if ($viewmode == 2) { $icon = 'url-user.png'; } else if( $viewmode == 1 ) { $icon = '404-logs.png'; } else { $icon = 'url-edit.png'; } JToolBarHelper::title(JText::_('COM_SEF_JOOMSEF_URL_MANAGER'), $icon); $this->assign($this->getModel()); $lists = $this->get('Lists'); $bar = JToolBar::getInstance(); // Actions $bar->appendButton('Custom', $lists['selection']); $bar->appendButton('Custom', $lists['actions']); $bar->appendButton('Custom', ''); JToolBarHelper::divider(); if($viewmode!=6) { JToolBarHelper::addNew(); } if ($this->viewmode == 1) { // 404 log JToolBarHelper::addNew('create301', 'COM_SEF_CREATE_301'); } if($viewmode!=6) { JToolBarHelper::editList(); JToolBarHelper::spacer(); JToolBarHelper::custom('showimport', 'import', '', 'COM_SEF_IMPORT', false); JToolBarHelper::spacer(); } JToolBarHelper::back('COM_SEF_BACK', 'index.php?option=com_sef'); // Get data from the model $this->assign('items', $this->get('Data')); $this->assign('total', $this->get('Total')); $this->assign('lists', $lists); if($viewmode!=6) { $this->assign('pagination', $this->get('Pagination')); } JHtml::_('behavior.tooltip'); parent::display($tpl); } function showUpdate($controller = '') { JToolBarHelper::title( JText::_('COM_SEF_JOOMSEF_URLS_UPDATE'), 'url-update.png' ); $this->setLayout('update'); $this->assign('totalUrls', $this->get('UrlsToUpdate')); $this->assign('controllerVar', $controller); JHTML::_('behavior.framework'); parent::display(); } function showUpdateMeta($controller = '') { JToolBarHelper::title( JText::_('COM_SEF_JOOMSEF_META_TAGS_UPDATE'), 'url-update.png' ); $this->setLayout('updatemeta'); $this->assign('totalUrls', $this->get('UrlsToUpdate')); $this->assign('controllerVar', $controller); JHTML::_('behavior.framework'); parent::display(); } function showChangeMeta() { JToolbarHelper::title(JText::_('COM_SEF_JOOMSEF_META_TAGS_CHANGE')); JToolbarHelper::save('save_changed_metas'); JToolbarHelper::cancel('cancel_changed_metas'); $this->setLayout('changemeta'); $this->cid=$this->get('ids'); JHTML::_('behavior.framework'); parent::display(); } } components/com_sef/views/sefurls/tmpl/default.php000066600000054151150771655450016326 0ustar00useCache) { //require(JPATH_ROOT.'/components/com_sef/sef.cache.php'); $cache = sefCache::getInstance(); } ?>
    viewmode != 1 ) { ?> viewmode != 1 ) { ?> langEnable) { ?> viewmode != 1) { ?> viewmode != 1) { ?> langEnable) { ?>
    lists['filterSEFRE']; ?> viewmode == 1) ? JText::_('COM_SEF_FILTER_URLS') : JText::_('COM_SEF_FILTER_SEF_URLS')) . ':'; ?> lists['filterRealRE']; ?>
    lists['viewmode']; ?> lists['hitsCmp']; ?> lists['hitsVal']; ?> lists['itemid']; ?> lists['filterSEF']; ?> lists['filterReal']; ?> lists['comList']; ?> lists['filterLang']; ?> lists['filterReset']; ?>
    viewmode == 4) { ?>
    viewmode!=6) { ?> trace) { ?> viewmode != 1) { ?> viewmode!=6) { ?> useCache) { ?> viewmode != 1) { $colspan += 5; if ($sefConfig->useCache) $colspan++; } if ($this->trace )$colspan++; ?> viewmode!=6) { echo $this->getPaginationFooter($colspan); } ?> items) as $i) { $row = &$this->items[$i]; ?> viewmode!=6) { ?> trace) : ?> viewmode != 1 ) { ?> viewmode!=6) { ?> useCache) { ?>
    viewmode!=6) { echo JHTML::_('grid.sort', 'COM_SEF_HITS', 'cpt', $this->lists['filter_order'] == 'cpt' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); } else { echo JText::_('COM_SEF_HITS'); } ?> viewmode == 1) { echo JHTML::_('grid.sort', 'COM_SEF_DATE_ADDED', 'dateadd', $this->lists['filter_order'] == 'dateadd' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); } else { if($this->viewmode!=6) { echo JHTML::_('grid.sort', 'COM_SEF_SEF_URL', 'sefurl', $this->lists['filter_order'] == 'sefurl' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); } else { echo JText::_('COM_SEF_URL'); } } ?> viewmode == 1) { echo JHTML::_('grid.sort', 'COM_SEF_URL', 'sefurl', $this->lists['filter_order'] == 'sefurl' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); } else { if($this->viewmode!=6) { echo JHTML::_('grid.sort', 'COM_SEF_REAL_URL', 'origurl', $this->lists['filter_order'] == 'origurl' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); } else { echo JText::_('COM_SEF_REAL_URL'); } } ?> viewmode!=6) { echo JHTML::_('grid.sort', 'COM_SEF_ENABLED', 'enabled', $this->lists['filter_order'] == 'enabled' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); } else { echo JText::_('COM_SEF_ENABLED'); } ?> viewmode!=6) { echo JHTML::_('grid.sort', 'COM_SEF_SEF', 'sef', $this->lists['filter_order'] == 'sef' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); } else { echo JText::_('COM_SEF_SEF'); } ?> lists['filter_order'] == 'locked' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); ?> lists['filter_order'] == 'priority' ? $this->lists['filter_order_Dir'] : 'desc', $this->lists['filter_order']); ?>
    pagination->getRowOffset($i); ?> viewmode != 6 ? $row->id : htmlspecialchars($row->sefurl)); ?> cpt; ?> viewmode == 1 ) { echo $row->dateadd; } else { ?> viewmode != 6) { ?> ".(strlen($row->sefurl) ? htmlspecialchars($row->sefurl) : '('.JText::_('COM_SEF_HOMEPAGE').')').""; } } ?> viewmode == 1 ) { ?> sefurl); ?> viewmode != 6) { ?>
    <?php echo JText::_('COM_SEF_AJAX_EDIT_ORIGURL'); ?> origurl . ($row->Itemid == '' ? '' : (strpos($row->origurl, '?') ? '&' : '?') . 'Itemid='.$row->Itemid ) ); ?>
    getAjaxWorking('origurl_'.$row->id); ?>
    origurl); } } ?>
    trace) ? '' : $row->trace; echo $this->tooltip(nl2br($urlTrace), JText::_('COM_SEF_TRACE_INFORMATION')); ?>
    getAjaxField('enabled', $row->id, '1', 'disable', JText::_('COM_SEF_DISABLE').'::'.JText::_('COM_SEF_TT_DISABLED_URL'), 'admin/tick.png', JText::_('COM_SEF_ENABLED'), $row->enabled); echo $this->getAjaxField('enabled', $row->id, '0', 'enable', JText::_('COM_SEF_ENABLE').'::'.JText::_('COM_SEF_TT_ENABLED_URL'), 'admin/publish_x.png', JText::_('COM_SEF_DISABLED'), !$row->enabled); echo $this->getAjaxWorking('enabled_'.$row->id); ?>
    getAjaxField('sef', $row->id, '1', 'sefdisable', JText::_('COM_SEF_DONT_SEF').'::'.JText::_('COM_SEF_TT_SEF_REAL_URL'), 'admin/tick.png', JText::_('COM_SEF_SEF'), $row->sef); echo $this->getAjaxField('sef', $row->id, '0', 'sefenable', JText::_('COM_SEF_SEF').'::'.JText::_('COM_SEF_TT_SEF_SEF_URL'), 'admin/publish_x.png', JText::_('COM_SEF_DONT_SEF'), !$row->sef); echo $this->getAjaxWorking('sef_'.$row->id); ?>
    getAjaxField('locked', $row->id, '1', 'unlock', JText::_('COM_SEF_UNLOCK').'::'.JText::_('COM_SEF_TT_UNLOCKED_URLS'), 'admin/checked_out.png', JText::_('COM_SEF_LOCKED'), $row->locked); echo $this->getAjaxField('locked', $row->id, '0', 'lock', JText::_('COM_SEF_LOCK').'::'.JText::_('COM_SEF_TT_LOCKED_URLS'), 'admin/publish_x.png', JText::_('COM_SEF_UNLOCKED'), !$row->locked); echo $this->getAjaxWorking('locked_'.$row->id); ?>
    getAjaxField('active', $row->id, '0', '', JText::_('COM_SEF_TT_ACTIVE_LINK'), 'admin/tick.png', JText::_('COM_SEF_ACTIVE'), $row->priority == 0, false); echo $this->getAjaxField('active', $row->id, '50', 'setActive', JText::_('COM_SEF_TT_MAKE_ACTIVE'), 'admin/publish_g.png', JText::_('COM_SEF_TT_NOT_ACTIVE'), ($row->priority > 0) && ($row->priority < 100)); echo $this->getAjaxField('active', $row->id, '100', 'setActive', JText::_('COM_SEF_TT_MAKE_ACTIVE'), 'admin/publish_r.png', JText::_('COM_SEF_TT_NOT_ACTIVE'), $row->priority == 100); echo $this->getAjaxWorking('active_'.$row->id); ?>
    getNonSefUrl($row->sefurl) !== false ) { if( $cache->getSefUrl($row->origurl,$row->Itemid) !== false ) { ?> 0), true); ?> 0), true); ?> host; ?>
    components/com_sef/views/sefurls/tmpl/updatemeta.php000066600000006672150771655450017040 0ustar00
    : 0
    : totalUrls; ?>
    : totalUrls; ?>
    components/com_sef/views/sefurls/tmpl/updatesitemap.php000066600000000576150771655450017551 0ustar00components/com_sef/views/sefurls/tmpl/index.html000066600000000054150771655450016157 0ustar00components/com_sef/views/sefurls/tmpl/changemeta.php000066600000004215150771655450016772 0ustar00
    tooltip(JText::_('COM_SEF_INFO_JOOMSEF_PLUGIN'), JText::_('COM_SEF_JOOMSEF_PLUGIN_NOTICE')); ?>
    :
    :
    :
    :
    :
    :
    cid); ?>" />
    components/com_sef/views/sefurls/tmpl/update.php000066600000006427150771655450016167 0ustar00
    : 0
    : totalUrls; ?>
    : totalUrls; ?>
    components/com_sef/views/sefurls/index.html000066600000000054150771655450015203 0ustar00components/com_sef/views/logger/view.html.php000066600000002432150771655450015432 0ustar00assign('items', $this->get('Data')); $this->assign('total', $this->get('Total')); $this->assign('lists', $this->get('Lists')); $this->assign('pagination', $this->get('Pagination')); $enabled = $this->get('Enabled'); if (!$enabled) { $app = JFactory::getApplication(); $app->enqueueMessage(JText::_('COM_SEF_LOGS_DISABLED_NOTICE')); } JHTML::_('behavior.tooltip'); parent::display($tpl); } } components/com_sef/views/logger/tmpl/default.php000066600000011545150771655450016122 0ustar00
    lists['filterMessage']; ?> lists['filterUrl']; ?> lists['filterPage']; ?> lists['comList']; ?> lists['filterReset']; ?>
    items) as $i) { $row = &$this->items[$i]; ?>
    lists['filter_order_Dir'], $this->lists['filter_order'], null, 'desc'); ?> lists['filter_order_Dir'], $this->lists['filter_order']); ?> lists['filter_order_Dir'], $this->lists['filter_order']); ?> lists['filter_order_Dir'], $this->lists['filter_order']); ?> lists['filter_order_Dir'], $this->lists['filter_order']); ?>
    pagination->getListFooter(); ?>
    pagination->getRowOffset($i); ?> time; ?> message; ?> url); ?> page); ?> component; ?>
    components/com_sef/views/logger/tmpl/index.html000066600000000054150771655450015753 0ustar00components/com_sef/views/logger/index.html000066600000000054150771655450014777 0ustar00components/com_sef/sql/4.2.1.sql000066600000000451150771655450012351 0ustar00ALTER TABLE `#__sef_subdomains` ADD `lang` varchar(10) NOT NULL; ALTER TABLE `#__sef_subdomains` DROP `menuitems`; ALTER TABLE `#__sef_subdomains` DROP `menuitem_titlepage`; ALTER TABLE `#__sef_subdomains` DROP PRIMARY KEY; ALTER TABLE `#__sef_subdomains` ADD PRIMARY KEY(`subdomain`, `lang`);components/com_sef/sql/index.html000066600000000054150771655450013162 0ustar00components/com_sef/sql/4.7.5.sql000066600000000106150771655450012357 0ustar00ALTER TABLE `#__sefurls` MODIFY `metadesc` VARCHAR(1024) DEFAULT ''; components/com_sef/sql/4.2.5.sql000066600000000123150771655450012351 0ustar00ALTER TABLE `#__sefurls` ADD COLUMN `showsitename` INTEGER(1) NOT NULL DEFAULT '3';components/com_sef/sql/4.1.0.sql000066600000000000150771655450012335 0ustar00components/com_sef/sql/4.5.2.sql000066600000000153150771655450012354 0ustar00ALTER TABLE `#__sefurls` ADD KEY `idx_updates` (`locked`, `flag`); ALTER TABLE `#__sefurls` ENGINE=InnoDB;components/com_sef/sql/4.4.2.sql000066600000000111150771655450012345 0ustar00ALTER TABLE `#__sefurls` ADD COLUMN `metacustom` TEXT AFTER `metagoogle`;components/com_sef/sql/4.1.1.sql000066600000002101150771655450012342 0ustar00CREATE TABLE IF NOT EXISTS `#__sef_statistics` ( `url_id` int(5) NOT NULL, `page_rank` int(3) NOT NULL, `total_indexed` int(10) NOT NULL, `popularity` int(10) NOT NULL, `facebook_indexed` int(10) NOT NULL, `twitter_indexed` int(10) NOT NULL, `validation_score` varchar(255) NOT NULL, `page_speed_score` mediumtext NOT NULL, PRIMARY KEY (`url_id`) ); CREATE TABLE IF NOT EXISTS `#__seflog` ( `id` INTEGER(11) NOT NULL AUTO_INCREMENT, `time` DATETIME NOT NULL, `message` VARCHAR(255) DEFAULT NULL, `url` VARCHAR(255) NOT NULL DEFAULT '', `component` VARCHAR(255) DEFAULT NULL, `page` VARCHAR(255) DEFAULT NULL, PRIMARY KEY (`id`) ); CREATE TABLE IF NOT EXISTS `#__sef_subdomains` ( `subdomain` varchar(255) NOT NULL DEFAULT '', `Itemid` mediumtext NOT NULL, `Itemid_titlepage` int(10) NOT NULL, `option` varchar(255) NOT NULL, `menuitems` mediumtext NOT NULL, `menuitem_titlepage` varchar(255) NOT NULL, PRIMARY KEY (`subdomain`) ); ALTER TABLE `#__sefurls` ADD COLUMN `host` varchar(255) NOT NULL DEFAULT '';components/com_sef/view.php000066600000016123150771655450012055 0ustar00addTemplatePath($this->_basePath.'/views/templates'); $this->loadSelectSkin(); } public function display($tpl = null) { // Load JS JHtml::_('behavior.framework'); JHtml::script('administrator/components/com_sef/assets/js/joomsef.js', true); // Set JS texts $js = 'JoomSEF.txtHomePage = '.json_encode('('.JText::_('COM_SEF_HOMEPAGE').')').";\n"; $doc = JFactory::getDocument(); $doc->addScriptDeclaration($js); parent::display($tpl); } protected function tooltip($tooltip, $title = '', $image = 'tooltip.png') { $tooltip = str_replace('"', '\\"', htmlspecialchars($tooltip, ENT_COMPAT, 'UTF-8')); $title = str_replace('"', '\\"', htmlspecialchars($title, ENT_COMPAT, 'UTF-8')); $image = JURI::root(true).'/administrator/components/com_sef/assets/images/'. $image; $text = ''. JText::_('COM_SEF_TOOLTIP') .''; if ($title) { $title .= '::'; } $style = 'style="text-decoration: none; color: #333;"'; $tip = ''; $tip .= $text . ''; return $tip; } protected function renderParams($params, $group) { $fields = $params->getFieldset($group); if (count($fields) > 0) { echo '
    '; //echo '
      '; foreach ($fields as $field) { echo '
      '; //echo '
    • '; echo '
      '.$field->label.'
      '; echo '
      '.$field->input.'
      '; //echo '
    • '; echo '
      '; } //echo '
    '; echo '
    '; } } public function showInfoText($str, $adminForm = false) { $sefConfig = SEFConfig::getConfig(); $this->assign('infoString', JText::_($str)); $this->assign('infoShown', $sefConfig->showInfoTexts); $this->assign('infoTextClass', $adminForm ? 'class="adminform"' : ''); // Prepare JS variables $document = JFactory::getDocument(); $js = "var jsInfoTextShown = ".($sefConfig->showInfoTexts ? 'true' : 'false').";\n"; $js .= "var jsInfoTextHide = '".JText::_('COM_SEF_INFOTEXT_HIDE', true)."';\n"; $js .= "var jsInfoTextShow = '".JText::_('COM_SEF_INFOTEXT_SHOW', true)."';\n"; $js .= "var jsInfoTextUrl = '".JURI::root()."administrator/index.php?option=com_sef&controller=config&task=setinfotext';\n"; $document->addScriptDeclaration($js); // Load JS JHTML::script('administrator/components/com_sef/assets/js/infotexts.js', true); $prevLayout = $this->setLayout('default'); echo $this->loadTemplate('infotext'); $this->setLayout($prevLayout); } public function loadSelectSkin() { if (version_compare(JVERSION, '3.0', '>=')) { // Convert only select boxes that have size="1" or size is not set JHtml::_('formbehavior.chosen', 'select[size="1"], select:not([size])'); } } function getAjaxField($container, $id, $value, $task, $title, $img, $alt, $visible, $link = true, $controller = null) { $html = '
    '; $html .= ''; if ($link) { $html .= ''; } $html .= JHtml::_('image', $img, $alt, array('border' => 0), true); if ($link) { $html .= ''; } $html .= ''; $html .= '
    '; return $html; } function getAjaxWorking($container) { $html = ''; return $html; } function showStatus($type) { static $status; if( !isset($status) ) { $status = SEFTools::getSEOStatus(); } $html = '
    '; $html .= ''; $html .= ''; $html .= $this->getAjaxWorking('status_'.$type); $html .= '
    '; echo $html; } /** * Generates HTML code for pagination footer table row for specified columns. * Handles both Joomla 2.5 and 3.x * * @param int $cols * @return string */ function getPaginationFooter($cols) { $html = ' '; if (version_compare(JVERSION, '3.0', '>=')) { $html .= '
    '.$this->pagination->getLimitBox().'
    '; } $html .= $this->pagination->getListFooter().' '; return $html; } } components/com_sef/index.html000066600000000054150771655450012363 0ustar00components/com_sef/config.xml000066600000001111150771655450012350 0ustar00
    components/com_sef/changelog.txt000066600000037607150771655450013074 0ustar00JoomSEF 4 Changelog (C) 2020 ARTIO International Co. -------------------------------- --- 4.7.8 --- [14.7.2020] New - Handle format=pdf in URLs for Joomla! Content Improved - Disable internal links on defined words in meta tags when using some plugins (eg. JSN PageBuilder) Fix - "Add layout to URL" options switched in Content extension Fix - Fatal PHP error in MailTo extension on PHP 7.3 Fix - Some PHP Notices --- 4.7.7 --- [27.9.2019] Fix - Added missing file to installation package --- 4.7.6 --- [5.4.2019] Improved - Compatibility with PHP 7.3 ("Only variables can be passed by reference" error) Improved - User friendly selection of excluded categories in Content extension Fix - Multilanguage menu associations on Joomla! 3.9.4 --- 4.7.5 --- [24.5.2018] Improved - Increased allowed meta description length Fix - Allow * in lang variable when "Filter system variables" is enabled Fix - Fixed PHP Notice when redirecting to homepage on multi-language website --- 4.7.4 --- [12.4.2018] Fix - Hide DB error message --- 4.7.3 --- [23.3.2018] Fix - Multi-language domains on SSL enabled websites --- 4.7.2 --- [20.3.2018] Fix - Fixed fatal error on multi-language websites using different domains --- 4.7.1 --- [22.11.2017] Fix - Prevent SEF URLs with duplicate non-SEF URLs being created Fix - Don't number duplicate homepage SEF URLs when different domains for languages are used Fix - Changing active handler for components without JoomSEF extension installed Fix - Pagination string not being translated --- 4.7.0 --- [31.7.2017] Fix - Guess Itemid option in Content extension on Joomla! 3.7 Fix - Deprecated PHP warnings Fix - Missing subdirectory in internal links Fix - Author user ID in 404 page content article --- 4.6.10 --- [1.2.2017] Improved - Updated Google Analytics tracking code Improved - Compatibility with JInput Fix - Some Strict Standards warnings --- 4.6.9 --- [10.8.2016] Fix - Menu item parameters being overwritten by JoomSEF Fix - SEF URLs for articles editing in Joomla! 3.6 Fix - Handling variables arrays when editing SEF URLs --- 4.6.8 --- [20.6.2016] Improved - Trailing slash handling in Joomla! 3 Fix - Support for menu associations in Joomla! 3.5 Fix - Deprecated errors on Control Panel with PHP 7 --- 4.6.7 --- [17.5.2016] Improved - Option not to add Itemid to URL if the original URL doesn't contain any Fix - Incorrect Itemid in articles pagination Fix - "File not uploaded for security reasons" error on Upgrade page Fix - Deprecated warnings in PHP 7 --- 4.6.6 --- [28.1.2016] New - Filter SEF URLs by Active column on Sitemap page Improved - Strict types for SQL queries Fix - Strict Standards warnings in uninstall script --- 4.6.5 --- [14.1.2016] Improved - Redirect to https and www domain doesn't cause chain 301 redirect anymore Improved - Tags extension: Support for multiple tags in SEF URL Fix - Some more Strict Standards warnings Fix - Possible SQL injection Fix - Removing Joomla! base sub-directory from SEF URLs --- 4.6.4 --- [10.11.2015] New - Option to force SSL directly in JoomSEF to avoid chain 301 redirecting Fix - Language overrides not working on Joomla! 3.x Fix - Some texts not being translated on Joomla! 3.x --- 4.6.3 --- [29.9.2015] New - Option to disable chunked transfer when exporting SEF URLs Improved - Strict Standards warnings on PHP 5.4 and higher Improved - Displayed number of items select box in Joomla 3 Fix - HTML characters display in URLs lists Fix - Using domain in SEF URL if not required Fix - SQL query for duplicate URLs Fix - Duplicate domain in URLs for components using own router Fix - Installing extension automatically from ARTIO server Fix - HTML entities in internal links --- 4.6.2 --- [10.3.2015] Fix - Error with new Joomla 3 component router interface support --- 4.6.1 --- [5.3.2015] Fix - ACL permissions check in backend Fix - Extensions installation on Joomla 3.4 ("sef_ext adapter doesn't exist" error) --- 4.6.0 --- [3.3.2015] New - Options to remove and fix canonical links in Joomla 3 Improved - Statistics parsing from Google Fix - Pagination problem in Joomla 3.4 Fix - SQL error when no accepted currencies selected in VirtueMart Fix - Support for new Joomla 3 component router interface Fix - Component router loading isolated from local variables Fix - Error when Auto Update URLs option was enabled Fix - Updating validity getting stuck --- 4.5.6 --- [27.11.2014] Improved - Added new options for GA tracking --- 4.5.5 --- [26.11.2014] Improved - Updated GA tracking code --- 4.5.4 --- [7.11.2014] Improved - Caching duplicate SEF URLs (solves problems with cache when using domains for different languages) Fix - 301 redirects in Joomla 3.2 and newer Fix - Caching "Use sitename in title" option Fix - Generating crontab file --- 4.5.3 --- [18.9.2014] New - Added option to update Sitemap XML file during cron task Fix - URLs to non-existent articles are no longer stored in DB Fix - Calendar field was not displayed correctly in Joomla 3 Fix - Variables filtering rules were not loaded correctly for components without JoomSEF extension --- 4.5.2 --- [30.5.2014] Improved - Caching menu items Improved - Compatibility with Joomla! 3.3 Improved - DB table optimization Fix - Website crawler recover function Fix - Fatal error on Joomla! 3.3 when saving configuration Fix - 404 article creation and language Fix - Deprecated warning Fix - DB error when frontend language not set as Content language --- 4.5.1 --- [8.11.2013] Fix - Compatibility with Joomla 3.2.0 --- 4.5.0 --- [23.10.2013] New - AJAX user interface for comfortable URLs editation New - Tags extension for Joomla 3 Improved - Avoid endless loop with Kunena 3 Fix - Pagination in articles category view --- 4.4.4 --- [29.8.2013] Improved - Extensions installer and updater don't require installation anymore Fix - Query variables of 404 page are not used as non-SEF anymore Fix - PHP warning in Contacts extension Fix - PHP warning in Configuration when there's no content language published --- 4.4.3 --- [26.7.2013] Fix - Renamed view classes according to new Joomla 3.1.4 requirements --- 4.4.2 --- [25.7.2013] New - Custom meta tags for individual SEF URLs New - Filters in Statistics view New - Option to count homepage hits Improved - No language code in URL for main language Improved - Usage of language code stored in cookie (eg. for VM cart) Fix - Custom SEF URLs have variables automatically sorted when saved Fix - "Fix document format" option Fix - Homepage link display in URLs Manager Fix - String standard warning in extension view Fix - Standardized line endings in all files Fix - Added info to Cache configuration page Fix - Removed meta title generation Fix - Limitstart replaced by start for component's router handling Fix - "Guess Itemid" option in Content extension Fix - "Check all" checkbox in Joomla 3 --- 4.4.1 --- [15.3.2013] New - Option to create multiple sitemaps for different language domains New - Options to always use English texts in standard extensions New - Option to enable Menu Associations for multilanguage websites Improved - Database tables are created with utf-8 encoding Improved - Optimized database query for duplicate SEF URLs Fix - Problems with AJAX requests being cached Fix - Aliases redirect for index.php links Fix - Alias field usage in page titles Fix - Print article links handling Fix - New article links handling Fix - option variable added to pure index.php --- 4.4.0 --- [11.2.2013] New - Option to choose HTTPS usage in Sitemap Improved - Multilanguage domains in Sitemap URLs Improved - Memory requirements when generating Sitemap XML file Fix - Links in Help and Support Fix - Non-existent language handling Fix - Possible XSS vulnerability --- 4.3.2 --- [5.2.2013] Fix - Joomla! update system Fix - Language detection with File Suffix set to "/" --- 4.3.1 --- [4.2.2013] New - Check if Joomla version is supported before installation Improved - Joomla 3.0 support Improved - Hide FaLang from Manage Extensions page Fix - Empty sitename for selected language Fix - "&" in non-SEF URLs (problem with VirtueMart) Fix - "www" being displayed in Subdomains configuration Fix - Duplicate subdomains in configuration Fix - Warning when saving configuration Fix - Numeric IDs in common components' URLs Fix - Non-existent language handling Fix - Endless loop in menu item alias handling Fix - Error when component's router doesn't return array --- 4.3.0 --- [2.1.2013] New - Compatible with Joomla 3.0, no longer compatible with Joomla < 2.5.6 New - Options to handle mismatched lang and Itemid New - Option to use 303 code for root URL redirection to correct language New - Option to change pure index.php to current menu link New - Option to use Joomla's error page for 404 errors Improved - Redirect wrong cased URL to correct one Improved - Support for nested arrays in Alias query Improved - PHP 5.4 compatibility Improved - UTF-8 support for Internal Links Improved - Language detection for non-SEF URLs Improved - Missing Czech translation strings Improved - Meta keywords generation for words with hyphen Fix - Correct sitename for selected language is used Fix - Fixed article category URLs Fix - Backlink displayed only in HTML documents Fix - Czech translation of reset button Fix - Create links to homepage function Fix - Nested menu aliases Fix - Menu title in URLs when Itemid is excluded Fix - Itemid always parsed as numeric Fix - Configuration being reset when Permissions are changed Fix - Possible XSS vulnerability Fix - Wrong language used in modules Fix - Displayed URLs and sorting on Statistics page Fix - Some problems with URLs Auto update Removed - Pinging Yahoo when sitemap is generated --- 4.2.9 --- [18.9.2012] New - Option not to add language code to homepage URLs New - Automatic VirtueMart currency selection according to language Improved - Website Crawler Improved - Content extension uses alias in URLs as default Fix - Statistics and Analytics not working Fix - Language domains not being displayed Fix - Long language codes can be used in URLs Fix - Saving subdomains in JoomSEF's Configuration Fix - Handling of www with subdomains and IP Fix - sid variable being removed sometimes Fix - Missing slash in base tag --- 4.2.8 --- [29.6.2012] Improved - Website Crawler can recover from errors Improved - Excluded categories in Content extension are case insensitive now Improved - Recognition of home page URLs Fix - Handling of missing option variable (fixes payment and shipping selection in VM) Fix - Errors when ARTIO update server is not available Fix - Website Crawler - workaround for bug in some versions of PHP --- 4.2.7 --- [4.6.2012] Improved - Translate items option for FaLang Improved - Greek characters in non-ASCII characters replacements Improved - Added language filter to URLs list Improved - FaLang support Improved - Language Filter plugin can be disabled directly from Configuration Improved - UTF-8 support for meta tags generation Fix - Manual editation of duplicate SEF URLs Fix - Add menu title option with FaLang Fix - Ampersand character in non-SEF to SEF redirection --- 4.2.6 --- [27.4.2012] New - FaLang support New - Option to disable handling of query variables as non-SEF New - Option to add page number to page title in Content extension Improved - Support for slashes in Google News numbering for Content articles Improved - Compatibility with JoomImages module Fix - Some problems with language on homepage Fix - Support for magic_quotes_gpc in Configuration Fix - Unwanted domain redirects on language mismatch Fix - Prevented double loading of JoomSefLogger class Fix - Custom menu title not working Fix - Headers already sent error is no longer displayed Fix - Problem with certificate for Google Analytics --- 4.2.5 --- [15.3.2012] New - Support for page titles in multipage articles New - Handle mismatch between URL and domain language New - Sitename in page title option for individual URLs Improved - Web Crawler Improved - System variables filter Improved - Joomla update system for extensions Improved - Weblinks extension Fix - Problems with configuration saving Fix - Caching of SEF Status changes Fix - Fatal error in Auto Update URLs function Fix - Wrong menu title when Exclude Itemid was enabled Fix - Handling of www and non-www domains Fix - Duplicate suffix with Default Joomla router --- 4.2.4 --- [21.2.2012] New - Configuration is now stored in database Improved - Multilanguage compatibility with Joomla 1.6 Improved - Custom JRoute class loaded only if needed Improved - Menu item aliases handling Fix - Menu title for Search Fix - Recognition of links to home page Fix - Changed 303 redirects to 301 Fix - Editing articles in frontend Fix - Automatic canonical link generation option Fix - Default frontend language Fix - Opensearch links are not SEFed anymore Fix - Disabling SEF for individual URLs Fix - Meta tags on multilanguage home pages --- 4.2.3 --- [12.1.2012] Improved - Performance (unnecessary SQL queries removed) Fix - Problem with Itemid when Default Joomla! router used Fix - Non-SEF URLs handled by Default Joomla! router Fix - Warning in JoomSEF's router Fix - Division by zero error Fix - Language detection Fix - Duplicate sitename in page titles Fix - Meta tags on home page Fix - Users activation and links Fix - Default parameters for Wrapper extension --- 4.2.2 --- [6.12.2011] Fix - RSS feeds Fix - Infinite redirect on multilanguage site homepage --- 4.2.1 --- [1.12.2011] Improved - Subdomains with multiple languages Fix - Duplicate domains in URLs Fix - SSL URLs Fix - Problems with connecting to Google Analytics --- 4.2.0 --- [21.11.2011] New - Configuration separated to Beginner and Professional modes New - Crawl Web function New - Statistics and Analytics functions (only paid) New - Info texts for some less intuitive features New - Option to log errors in non-SEF URLs New - Supported extensions may now index URLs in Sitemap automatically New - Usage of different subdomains for specific menu items New - Updates may now be run periodically using cron (only paid) Improved - Administration layout Improved - URLs import from JoomSEF 3.x Fix - Problems with Search extension Fix - Fatal error caused by JoomShopping extension Fix - Problem with duplicate .html suffix Fix - Extensions discovery function in Joomla! Fix - Error in "Show Links to Homepage" option Fix - Custom menu title not working --- 4.1.1 --- [6.10.2011] New - Added possibility to autolock created URLs New - Added possibility to update SEF URLs when changing content items New - Added possibility to manage Joomla language URL settings from JoomSEF New - Added possibility to manage JoomSEF cache Improved - Possibility to update only filtered metas and URLs Improved - sh404sef URLs import Improved - Frontpage pagination Fix - Fixed problems with Joomla on subfolders Fix - Internal links don't link to current page anymore Fix - Fixed AJAX search in yootheme template --- 4.1.0 --- [6.10.2011] New - Installing and upgrading through Joomla built-in updater Improved - Joomla 1.7 compatibility --- 4.0.9 --- [20.7.2011] Fix - default configuration parameters Fix - bugs with Joomla installed in domain subfolders and extensions without own SEF routers --- 4.0.8 --- [19.7.2011] Fix - nonSEF urls generation with JoomSEF Improved - translate URL extension texts in JoomSEF --- 4.0.7 --- [14.7.2011] Fix - compatibility bug when using with JCE 2.0 --- 4.0.6 --- [9.7.2011] Fix - compatibility with Joomla language plugin Fix - multilanguage content titles Fix - content pagination Fix - Joomla bug when checking for default menu entry Fix - Joomla in front-end does not load language by default, so load this manually --- 4.0.5 --- [4.7.2011] Fix - extension installer problems --- 4.0.4 --- [20.5.2011] Fix - changes requested by JED --- 4.0.3 --- [11.5.2011] Fix - wrong 404 page handling --- 4.0.2 --- [18.3.2011] Fix - Upgrading free to paid error --- 4.0.1 --- [16.3.2011] New - Added options related to metadata generation and overriding New - Added Update Meta tags function Improved - URLs Update using AJAX Improved - Support for native Joomla! 1.6 language filtering --- 4.0.0 --- [2.2.2011] New - First stable release for Joomla! 1.6 components/com_sef/model.php000066600000002015150771655450012176 0ustar00'; $html .= str_replace(array('
    ', '
    '), '', JHtml::_('select.radiolist', $arr, $name, $attrs, 'value', 'text', (int) $selected, false)); $html .= ''; return $html; } } ?>components/com_sef/extensions_params.xml000066600000013226150771655450014657 0ustar00
    components/com_sef/controller.php000066600000027772150771655450013302 0ustar00getModel('extensions'); $view = $this->getView('sef', 'html', 'sefview'); $view->setModel($model); } parent::display(); $this->addSubmenu(); } function editExt() { JRequest::setVar('view', 'extension'); parent::display(); } function doInstall() { $model = $this->getModel('extension'); $msg = null; $err = null; if (!$model->install()) { $msg = $model->getError(); $err = 'error'; } $this->setRedirect('index.php?option=com_sef&controller=extension', $msg, $err); } function installExt() { $this->setRedirect('index.php?option=com_installer'); } function uninstallExt() { JRequest::checkToken() or jexit( 'Invalid Token' ); //JFactory::getApplication()->setState('filter.type','sef-ext'); $this->setRedirect('index.php?option=com_installer&view=manage',JText::_('COM_SEF_USE_STANDARD_UNINSTALL')); /*$cid=JRequest::getVar('cid',array(),'','array'); //I know that it is controller but temporarilly add this query $db=JFactory::getDBO(); $query=$db->getQuery(true); $query->select('extension_id')->from('#__extensions')->where('state>=0')->where('enabled=1')->where('type='.$db->quote('sef_ext'))->where('element='.$db->quote($cid[0])); $db->setQuery($query); $eid=$db->loadResult(); JTable::addIncludePath(JPATH_LIBRARIES.'/joomla/database/table'); echo JPATH_LIBRARIES.'/joomla/database/table'; JModel::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_installer/models','InstallerModel'); $model=JModel::getInstance('manage','InstallerModel'); $model->remove(array($eid)); $this->setRedirect('index.php?option=com_sef');*/ } function showUpgrade() { JRequest::setVar('view', 'upgrade'); parent::display(); $this->addSubmenu(); } function doUpgrade() { JRequest::checkToken() or jexit( 'Invalid Token' ); $model = $this->getModel('upgrade'); $err=''; if(!$model->upgrade()) { $err='error'; } $msg=$model->getState('message'); $this->setRedirect(JRoute::_('index.php?option=com_sef&task=showUpgrade',false),$msg,$err); } function cleanCache() { require_once(JPATH_COMPONENT.'/controllers/urls.php'); $controller = new SEFControllerURLs(); $controller->execute( 'cleancache' ); $this->setRedirect('index.php?option=com_sef', JText::_('COM_SEF_CACHE_CLEANED')); } function UpdateURLs() { $model = $this->getModel('sefurls'); $result = $model->UpdateURLs(); $this->setRedirect('index.php?option=com_sef&task=urlsupdated&result='.$result); } function URLsUpdated() { $view = $this->getView('sefurls', 'html'); $view->showUpdated(); } function enableStatus() { $this->setStatus(1); } function disableStatus() { $this->setStatus(0); } function setStatus($state) { $ajax = (intval(JRequest::getVar('ajax')) == 1); if (!$ajax) { JRequest::checkToken() or jexit( 'Invalid Token' ); } $type = JRequest::getVar('cid', array(''), 'post', 'array'); $type = JRequest::getVar('statusType', $type[0], 'post', 'string'); $types = array('sef', 'mod_rewrite', 'sef_suffix', 'joomsef', 'plugin', 'newurls', 'versioncheck', 'jfrouter'); $msg = ''; if( in_array($type, $types) ) { // SEF and mod_rewrite settings if( $type == 'sef' || $type == 'mod_rewrite' || $type == 'sef_suffix' ) { jimport('joomla.client.helper'); jimport('joomla.filesystem.path'); jimport('joomla.filesystem.file'); // We need to load the config file manually, // because on Joomla 3 the global JFactory::getConfig() // already contains some changed themeParams data, // which causes fatal error after saving $file = JPATH_CONFIGURATION.'/configuration.php'; if (!is_file($file)) { $msg = JText::_('COM_SEF_ERROR_LOADING_CONFIG'); } else { include_once($file); if (!class_exists('JConfig')) { $msg = JText::_('COM_SEF_ERROR_LOADING_CONFIG'); } else { $config = new JRegistry(); $data = new JConfig(); $config->loadObject($data); if( $type == 'sef' ) { $config->set('sef', $state); } else if( $type == 'mod_rewrite' ) { $config->set('sef_rewrite', $state); } else { $config->set('sef_suffix', $state); } // Store the configuration // Get the new FTP credentials. $ftp = JClientHelper::getCredentials('ftp', true); // Attempt to make the file writeable if using FTP. if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0644')) { $msg = JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTWRITABLE'); } $str = $config->toString('PHP', array('class' => 'JConfig', 'closingtag' => false)); if( !JFile::write($file, $str) ) { $msg = JText::_('COM_SEF_ERROR_WRITING_CONFIG'); } } } } else if( $type == 'joomsef' || $type == 'newurls' || $type == 'versioncheck' ) { // JoomSEF and new URLs settings $sefConfig = SEFConfig::getConfig(); if( $type == 'joomsef' ) { $sefConfig->enabled = $state; } else if( $type == 'newurls' ) { $sefConfig->disableNewSEF = 1 - $state; } else { $sefConfig->versionChecker = $state; } // Store the configuration if( !$sefConfig->saveConfig() ) { $msg = JText::_('COM_SEF_ERROR_WRITING_CONFIG'); } } else if( $type == 'plugin' || $type == 'jfrouter' ) { // Plugins settings $db = JFactory::getDBO(); if( $type == 'plugin' ) { $plg = 'joomsef'; } else if( $type == 'jfrouter' ) { $plg = 'jfrouter'; } $query = "UPDATE `#__extensions` SET `enabled` = '{$state}' WHERE (`type` = 'plugin') AND (`element` = '{$plg}') AND (`folder` = 'system') LIMIT 1"; $db->setQuery($query); if( !$db->query() ) { $msg = JText::_('COM_SEF_ERROR_WRITING_CONFIG'); } // Clear cache for com_plugins! $model = $this->getModel(); $model->clearCache('com_plugins'); } } if ($ajax) { $obj = new stdClass(); $obj->id = $type; $obj->newValue = $state; $ret = array($obj); echo json_encode($ret); $app = JFactory::getApplication(); $app->close(); } else { $return = JRequest::getVar('return', 'index.php?option=com_sef'); $this->setRedirect($return, $msg); } } function finish_upgrade() { $db=JFactory::getDBO(); $sefConfig = SEFConfig::getConfig(); $download_id=$sefConfig->artioDownloadId; $query=$db->getQuery(true); $query->select('location')->from('#__update_sites')->where('name='.$db->quote('com_joomsef')); $db->setQuery($query); $location=$db->loadResult(); $location_match=array(); if(preg_match("/(-([A-Za-z0-9]*)).xml/",$location,$location_match)) { if(strlen($download_id)) { $location=str_replace($location_match[0],'-'.$download_id.'.xml',$location); } else { $location=str_replace($location_match[0],'.xml',$location); } $query="UPDATE #__update_sites \n"; $query.="SET location=".$db->quote($location)." \n"; $query.="WHERE name=".$db->quote('com_joomsef'); $db->setQUery($query); if(!$db->query()) { $this->setError($db->stderr(true)); return false; } } else if(strlen($download_id)) { $location=str_replace('.xml','-'.$download_id.'.xml',$location); $query="UPDATE #__update_sites \n"; $query.="SET location=".$db->quote($location)." \n"; $query.="WHERE name=".$db->quote('com_joomsef'); $db->setQUery($query); if(!$db->query()) { $this->setError($db->stderr(true)); return false; } } $this->setRedirect('index.php?option=com_sef',JText::_('COM_SEF_UPGRADE_SUCCESSFULL')); } } ?>components/com_sef/controllers/metatags.php000066600000002671150771655450015261 0ustar00registerTask('apply', 'save'); } function display($cachable = false, $urlparams = false) { JRequest::setVar( 'view', 'metatags' ); parent::display(); } function save() { $model = $this->getModel('metatags'); if ($model->store()) { $msg = JText::_( 'Meta Tags Saved' ); } else { $msg = JText::_( 'Error Saving Meta Tags' ) . ': ' . $model->getError(); } $task = JRequest::getCmd('task'); $link = 'index.php?option=com_sef'; if ($task == 'apply') { $link = 'index.php?option=com_sef&controller=metatags'; } $this->setRedirect($link, $msg); } function cancel() { $this->setRedirect( 'index.php?option=com_sef' ); } } ?>components/com_sef/controllers/htaccess.php000066600000001177150771655450015251 0ustar00components/com_sef/controllers/sefurls.php000066600000032737150771655450015145 0ustar00registerTask('add', 'edit'); } function display($cachable = false, $urlparams = false) { JRequest::setVar( 'view', 'sefurls' ); parent::display(); } function edit() { JRequest::setVar( 'view', 'sefurl' ); parent::display(); } function save() { $model = $this->getModel('sefurl'); if ($model->store()) { $msg = JText::_( 'URL Saved' ); } else { $msg = JText::_( 'Error Saving URL' ) . ': ' . $model->getError(); } $this->setRedirect('index.php?option=com_sef&controller=sefurls', $msg); } function save_cache() { $model = $this->getModel('sefurl'); if ($model->storeCache()) { $msg = JText::_( 'URL Saved' ); } else { $msg = JText::_( 'Error Saving URL' ) . ': ' . $model->getError(); } $this->setRedirect('index.php?option=com_sef&controller=sefurls', $msg); } function setActive() { $model = $this->getModel('sefurl'); $ret = $model->setActive(); if ($ret === false) { $msg = JText::_( 'Error: URL could not be set active' ); } else { $msg = JText::_( 'URL Activated' ); } if (intval(JRequest::getVar('ajax', 0)) == 1) { $this->showAjaxResponse($ret); } else { $this->setRedirect('index.php?option=com_sef&controller=sefurls', $msg); } } function _getWhere() { $selection = JRequest::getVar('selection', 'selected', 'post'); $model = $this->getModel('sefurls'); $where = ''; if ($selection == 'selected') { $where = $model->_getWhereIds(); } else { $where = $model->_getWhere(); } return $where; } function enable() { $this->_setEnabled(1); } function disable() { $this->_setEnabled(0); } function lock() { $this->_setLocked(1); } function unlock() { $this->_setLocked(0); } function sefEnable() { $this->_setSEF(1); } function sefDisable() { $this->_setSEF(0); } function delete() { $selection = JRequest::getVar('selection', 'selected', 'post'); if ($selection == 'selected') { $this->delete_selected(); } else { $this->delete_filtered(); } } function delete_selected() { $model = $this->getModel('sefurl'); if(!$model->delete()) { $msg = JText::_( 'Error: One or More URLs Could not be Deleted' ); } else { $msg = JText::_( 'URL(s) Deleted' ); } $this->setRedirect( 'index.php?option=com_sef&controller=sefurls', $msg ); } function delete_filtered() { $model = $this->getModel('sefurls'); if(!$model->deleteFiltered()) { $msg = JText::_( 'Error: One or More URLs Could not be Deleted' ); } else { $msg = JText::_( 'URL(s) Deleted' ); } $this->setRedirect( 'index.php?option=com_sef&controller=sefurls', $msg ); } function cancel() { $this->setRedirect( 'index.php?option=com_sef&controller=sefurls' ); } function showimport() { $model = $this->getModel('import'); $view = $this->getView('importexport', 'html'); $view->setModel($model, true); $view->display(); } function import() { $model = $this->getModel('import'); $view = $this->getView('importexport', 'html'); $view->setModel($model); $view->setLayout('importstats'); if(!$model->import()) { $view->assign('success', false); } else { $view->assign('success', true); } $view->assign('filetype', $model->type); $view->assign('total', $model->total); $view->assign('imported', $model->imported); $view->assign('notImported', $model->notImported); $view->display(); } function importdbace() { $model = $this->getModel('import'); $view = $this->getView('importexport', 'html'); $view->setModel($model); $view->setLayout('importstats'); if(!$model->importDBAce()) { $view->assign('success', false); } else { $view->assign('success', true); } $view->assign('filetype', $model->type); $view->assign('total', $model->total); $view->assign('imported', $model->imported); $view->assign('notImported', $model->notImported); $view->display(); } function importdbsh() { $model = $this->getModel('import'); $view = $this->getView('importexport', 'html'); $view->setModel($model); $view->setLayout('importstats'); if(!$model->importDBSh()) { $view->assign('success', false); } else { $view->assign('success', true); } $view->assign('filetype', $model->type); $view->assign('total', $model->total); $view->assign('imported', $model->imported); $view->assign('notImported', $model->notImported); $view->display(); } function export() { $model = $this->getModel('sefurls'); $where = $this->_getWhere(); if(!$model->export($where)) { $msg = JText::_( 'Error: URLs could not be exported.' ); } else { $msg = JText::_( 'URL(s) Exported' ); } $this->setRedirect( 'index.php?option=com_sef&controller=sefurls', $msg ); } function create301() { $model = $this->getModel('sefurl'); $url301 =& $model->getData(); $sefurl = ''; if( !empty($url301->sefurl) ) { $sefurl = '&sefurl='.urlencode($url301->sefurl); } $this->setRedirect('index.php?option=com_sef&controller=movedurls&task=add'.$sefurl); } function showAjaxResponse($states) { $ret = array(); foreach ($states as $id => $state) { $obj = new stdClass(); $obj->id = $id; $obj->newValue = $state; $ret[] = $obj; } echo json_encode($ret); $app = JFactory::getApplication(); $app->close(); } function _setEnabled($state) { $model = $this->getModel('sefurls'); $where = $this->_getWhere(); $msg = ''; $newState = $state; if (!$model->setEnabled($state, $where)) { $msg = JText::_('Error Saving URL'); $newState = ($state == '1' ? '0' : '1'); } if (intval(JRequest::getVar('ajax', 0)) == 1) { $ids = JRequest::getVar('cid', array(), 'post', 'array'); $this->showAjaxResponse(array($ids[0] => $newState)); } else { $this->setRedirect( 'index.php?option=com_sef&controller=sefurls', $msg ); } } function _setLocked($state) { $model = $this->getModel('sefurls'); $where = $this->_getWhere(); $msg = ''; $newState = $state; if( !$model->setLocked($state, $where) ) { $msg = JText::_( 'Error Saving URL' ); $newState = ($state == '1' ? '0' : '1'); } if (intval(JRequest::getVar('ajax', 0)) == 1) { $ids = JRequest::getVar('cid', array(), 'post', 'array'); $this->showAjaxResponse(array($ids[0] => $newState)); } else { $this->setRedirect( 'index.php?option=com_sef&controller=sefurls', $msg ); } } function _setSEF($state) { $model = $this->getModel('sefurls'); $where = $this->_getWhere(); $msg = ''; $newState = $state; if( !$model->setSEF($state, $where) ) { $msg = JText::_( 'Error Saving URL' ); $newState = ($state == '1' ? '0' : '1'); } if (intval(JRequest::getVar('ajax', 0)) == 1) { $ids = JRequest::getVar('cid', array(), 'post', 'array'); $this->showAjaxResponse(array($ids[0] => $newState)); } else { $this->setRedirect( 'index.php?option=com_sef&controller=sefurls', $msg ); } } function setOrigurl() { $ret = new stdClass(); $ret->success = true; $model = $this->getModel('sefurl'); $origurl = $model->setOrigurl(); if ($origurl === false) { $ret->success = false; $ret->msg = JText::_('COM_SEF_ERR_SET_ORIGURL'); } else { $ret->origurl = $origurl; } echo json_encode($ret); $app = JFactory::getApplication(); $app->close(); } function setSefurl() { $ret = new stdClass(); $ret->success = true; $model = $this->getModel('sefurl'); $sefurl = $model->setSefurl(); if ($sefurl === false) { $ret->success = false; $ret->msg = JText::_('COM_SEF_ERR_SET_SEFURL'); } else { $ret->sefurl = $sefurl; } echo json_encode($ret); $app = JFactory::getApplication(); $app->close(); } function createLinks() { $model = $this->getModel('sefurls'); $model->CreateHomeLinks(); $this->setRedirect( 'index.php?option=com_sef&controller=sefurls' ); } function update_urls() { $model = $this->getModel('sefurls'); $view = $this->getView('sefurls', 'html'); $view->setModel($model, true); if (!$model->prepareUpdateSelected()) { $msg = JText::_('COM_SEF_ERROR_UPDATE_PREPARE'); $this->setRedirect('index.php?option=com_sef&controller=sefurls', $msg); return; } $view->showUpdate('sefurls'); } function update_metas() { $model = $this->getModel('sefurls'); $view = $this->getView('sefurls', 'html'); $view->setModel($model, true); if (!$model->prepareUpdateSelected()) { $msg = JText::_('COM_SEF_ERROR_META_UPDATE_PREPARE'); $this->setRedirect('index.php?option=com_sef&controller=sefurls', $msg); return; } $view->showUpdateMeta('sefurls'); } function update_sitemap() { $model = $this->getModel('sefurls'); $view = $this->getView('sefurls', 'html'); $view->setModel($model, true); if (!$model->prepareUpdateSelected()) { $msg = JText::_('COM_SEF_UPDATE_SITEMAP_PREPARE_FAILED'); $this->setRedirect('index.php?option=com_sef&controller=sefurls', $msg); return; } $view->showUpdateSitemap('sefurls'); } function updateUrls() { $model = $this->getModel('sefurls'); $view = $this->getView('sefurls', 'html'); $view->setModel($model, true); if (!$model->prepareUpdate()) { $msg = JText::_('COM_SEF_ERROR_UPDATE_PREPARE'); $this->setRedirect('index.php?option=com_sef', $msg); return; } $view->showUpdate(); } function updateMeta() { $model = $this->getModel('sefurls'); $view = $this->getView('sefurls', 'html'); $view->setModel($model, true); if (!$model->prepareUpdate()) { $msg = JText::_('COM_SEF_ERROR_META_UPDATE_PREPARE'); $this->setRedirect('index.php?option=com_sef', $msg); return; } $view->showUpdateMeta(); } function copy_to_cache() { $model=$this->getModel('sefurl'); $model->copyToCache(); $this->setRedirect( 'index.php?option=com_sef&controller=sefurls'); } function change_metas() { $model = $this->getModel('sefurls'); $view = $this->getView('sefurls', 'html'); $view->setModel($model, true); $view->showChangeMeta(); } function save_changed_metas() { $model=$this->getModel('sefurls'); $msg=""; $err=''; if(!$model->saveChangedMetas()) { $msg=$model->getError(); $err='error'; } $this->setRedirect( 'index.php?option=com_sef&controller=sefurls',$msg,$err); } function cancel_changed_metas() { $this->setRedirect( 'index.php?option=com_sef&controller=sefurls' ); } } ?> components/com_sef/controllers/words.php000066600000001106150771655450014602 0ustar00components/com_sef/controllers/extension.php000066600000005503150771655450015465 0ustar00registerTask('apply', 'save'); } function display($cachable = false, $urlparams = false) { JRequest::setVar('view', 'extensions'); parent::display(); } function save() { JRequest::checkToken() or jexit( 'Invalid Token' ); $task = JRequest::getCmd('task'); $file = JRequest::getVar('element'); $model = $this->getModel('extension'); if ($model->store()) { $msg = JText::_( 'Extension Saved' ); } else { $msg = JText::_( 'Error Saving Extension' ); } $redir = JRequest::getVar('redirto', ''); if( $task == 'save' ) { $link = 'index.php?option=com_sef'; if( !empty($redir) ) { $link .= '&'.$redir; } } elseif( $task == 'apply' ) { $link = 'index.php?option=com_sef&task=editext&cid[]='.$file; if( !empty($redir) ) { $link .= '&redirto='.urlencode($redir); } } $this->setRedirect($link, $msg); } function cancel() { $redir = JRequest::getVar('redirto', ''); $link = 'index.php?option=com_sef'; if( !empty($redir) ) { $link .= '&'.$redir; } $this->setRedirect($link); } function editId() { $model = $this->getModel('extension'); $view = $this->getView('extension', 'html', 'sefview'); $view->setModel($model, true); $view->showEditId(); } function saveId() { JRequest::checkToken() or jexit( 'Invalid Token' ); $model = $this->getModel('extension'); $model->storeId(); jexit(); } function changeHandler() { JRequest::checkToken() or jexit( 'Invalid Token' ); $model = $this->getModel('extension'); $msg = ''; if (!$model->changeHandler()) { $msg = 'Could not change handler'; } $redir = JRequest::getVar('redirto', ''); $link = 'index.php?option=com_sef'; if( !empty($redir) ) { $link .= '&'.$redir; } $this->setRedirect($link, $msg); } } ?>components/com_sef/controllers/logger.php000066600000001745150771655450014734 0ustar00getModel('logger'); if (!$model->clearLogs()) { $msg = JText::_('COM_SEF_LOGS_CLEARED_ERROR'); $type = 'error'; } else { $msg = JText::_('COM_SEF_LOGS_CLEARED'); $type = null; } $this->setRedirect('index.php?option=com_sef&controller=logger', $msg, $type); } } components/com_sef/controllers/index.html000066600000000054150771655450014731 0ustar00components/com_sef/controllers/crawler.php000066600000007374150771655450015120 0ustar00 10) { $timeLimit = 10; } $maxTime = $_SERVER['REQUEST_TIME'] + $timeLimit; $urls = JRequest::getVar('url', array()); $crawled = 0; $found = array(); // Crawl URLs foreach ($urls as $url) { // Find URLs on URL $this->_parseLinks($url, $found); // Increase counter $crawled++; // Check time if (time() > $maxTime) { // We need to interrupt the script break; } } // Create response object $ret = new stdClass(); $ret->crawled = $crawled; $ret->found = $found; ob_end_clean(); // Write response echo json_encode($ret); jexit(); } function _parseLinks($url, &$found) { // Get response, follow 5 redirections $redirs = 0; do { $redirect = false; $response = SEFTools::PostRequest($url, null, null, 'get', null); if ($response === false) { // Error return; } if ($redirs < 5 && $response->code >= 300 && $response->code < 400) { // Parse redirect URL $pos = stripos($response->header, 'location:'); if ($pos !== false) { $pos += 9; // Skip header name $pos2 = strpos($response->header, "\r", $pos); $url = substr($response->header, $pos, $pos2 - $pos); $url = trim($url); $redirect = true; $redirs++; } } } while ($redirect); // Check code if ($response->code == 200) { // Parse URLs $matches = array(); if (preg_match_all('#]*href=["\']([^"\']+)#i', $response->content, $matches) > 0) { // Loop through found URLs foreach ($matches[1] as $link) { $link = str_replace(JURI::root(), '', $link); if (strpos($link, '://') !== false) { // Absolute external link, skip continue; } // Internal link $link = JURI::root().ltrim(html_entity_decode(urldecode($link)), '/'); if (!in_array($link, $found)) { $found[] = $link; } } } } } }components/com_sef/controllers/config.php000066600000004440150771655450014715 0ustar00registerTask('apply', 'save'); } function edit() { JRequest::setVar( 'view', 'config' ); parent::display(); } function save() { $model = $this->getModel('config'); if ($model->store()) { $msg = JText::_('COM_SEF_CONFIGURATION_UPDATED').' - '.JText::_('COM_SEF_INFO_CONFIG_UPDATE'); } else { $err = $model->getError(); $msg = JText::_('COM_SEF_ERROR_WRITING_CONFIG').": ".$model->getError(); } $task = JRequest::getCmd('task'); if( $task == 'save' ) { $link = 'index.php?option=com_sef'; } elseif( $task == 'apply' ) { $link = 'index.php?option=com_sef&controller=config&task=edit'; } $this->setRedirect($link, $msg); } function cancel() { $this->setRedirect( 'index.php?option=com_sef' ); } function setinfotext() { // Get new state $state = JRequest::getVar('state'); if (is_null($state)) { jexit(); } $sefConfig = SEFConfig::getConfig(); $sefConfig->showInfoTexts = ($state ? true : false); $sefConfig->saveConfig(0); jexit(); } function disable_plugin() { $obj = new stdClass(); $obj->success = true; // Disable the Language Filter plugin $db = JFactory::getDbo(); $db->setQuery("UPDATE `#__extensions` SET `enabled` = '0' WHERE `type` = 'plugin' AND `element` = 'languagefilter' AND `folder` = 'system'"); if (!$db->query()) { $obj->success = false; } echo json_encode($obj); jexit(); } } ?>components/com_sef/controllers/cron.php000066600000001076150771655450014413 0ustar00getModel('urls'); if( $model->purge() ) { $this->cleanCache(); $this->setRedirect('index.php?option=com_sef', JText::_('COM_SEF_SUCCESSFULLY_PURGED_RECORDS')); } else { $this->setRedirect('index.php?option=com_sef', JText::_('COM_SEF_COULD_NOT_PURGE_RECORDS')); } } parent::display(); } function cleanCache() { require_once(JPATH_ROOT.'/components/com_sef/sef.cache.php'); $cache = sefCache::getInstance(); $cache->cleanCache(); } } ?>components/com_sef/controllers/sitemap.php000066600000001112150771655450015103 0ustar00components/com_sef/controllers/info.php000066600000001736150771655450014410 0ustar00components/com_sef/controllers/ajax.php000066600000000642150771655450014373 0ustar00components/com_sef/controllers/statistics.php000066600000001150150771655450015635 0ustar00components/com_sef/controllers/movedurls.php000066600000004040150771655450015464 0ustar00registerTask('add', 'edit'); } function display($cachable = false, $urlparams = false) { JRequest::setVar( 'view', 'movedurls' ); parent::display(); } function edit() { JRequest::setVar( 'view', 'movedurl' ); parent::display(); } function save() { $model = $this->getModel('movedurl'); if ($model->store()) { $msg = JText::_( 'URL Saved' ); } else { $msg = JText::_( 'Error Saving URL' ); } $this->setRedirect('index.php?option=com_sef&controller=movedurls', $msg); } function remove() { $model = $this->getModel('movedurl'); if(!$model->delete()) { $msg = JText::_( 'Error: One or More URLs Could not be Deleted' ); } else { $msg = JText::_( 'URL(s) Deleted' ); } $this->setRedirect( 'index.php?option=com_sef&controller=movedurls', $msg ); } function deleteFiltered() { $model = $this->getModel('movedurls'); if(!$model->deleteFiltered()) { $msg = JText::_( 'Error: One or More URLs Could not be Deleted' ); } else { $msg = JText::_( 'URL(s) Deleted' ); } $this->setRedirect( 'index.php?option=com_sef&controller=movedurls', $msg ); } function cancel() { $this->setRedirect( 'index.php?option=com_sef&controller=movedurls' ); } } ?>components/com_sef/sef.xml000066600000015657150771655450011704 0ustar00 com_sef 14. July 2020 ARTIO s.r.o. info@artio.net http://www.artio.net ARTIO s.r.o. GNU/GPLv3 http://www.artio.net/license/gnu-general-public-license 4.7.8 COM_SEF_JOOMSEF_DESCRIPTION install.php sql install.sql uninstall.sql index.html joomsef.php sef.php sef.cache.php sef.ext.php sef.router.php sef_ext/_com_example.txt sef_ext/com_banners.php sef_ext/com_banners.xml sef_ext/com_contact.php sef_ext/com_contact.xml sef_ext/com_content.php sef_ext/com_content.xml sef_ext/com_mailto.php sef_ext/com_mailto.xml sef_ext/com_newsfeeds.php sef_ext/com_newsfeeds.xml sef_ext/com_search.php sef_ext/com_search.xml sef_ext/com_tags.php sef_ext/com_tags.xml sef_ext/com_users.php sef_ext/com_users.xml sef_ext/com_weblinks.php sef_ext/com_weblinks.xml sef_ext/com_wrapper.php sef_ext/com_wrapper.xml sef_ext/index.html sef_ext/elements/index.html sef_ext/elements/sefcategoryedit.php assets controllers COM_SEF COM_SEF_CPANEL COM_SEF_CONFIG COM_SEF_EXTENSIONS COM_SEF_HTACCESS COM_SEF_SEPARATOR1 COM_SEF_SEFURLS COM_SEF_METATAGS COM_SEF_SITEMAP COM_SEF_REDIRECTS COM_SEF_STATISTICS COM_SEF_SEPARATOR2 COM_SEF_UPGRADE COM_SEF_HELP_AND_SUPPORT language/en-GB/en-GB.com_sef.ini language/en-GB/en-GB.com_sef.sys.ini language/en-GB/en-GB.plg_content_joomsef.ini language/en-GB/en-GB.plg_content_joomsef.sys.ini language/en-GB/en-GB.plg_extension_joomsefinstall.ini language/en-GB/en-GB.plg_extension_joomsefinstall.sys.ini language/en-GB/en-GB.plg_system_joomsef.ini language/en-GB/en-GB.plg_system_joomsef.sys.ini language/en-GB/en-GB.plg_system_joomseflang.ini language/en-GB/en-GB.plg_system_joomseflang.sys.ini language/cs-CZ/cs-CZ.com_sef.ini language/cs-CZ/cs-CZ.com_sef.sys.ini language/cs-CZ/cs-CZ.plg_content_joomsef.ini language/cs-CZ/cs-CZ.plg_content_joomsef.sys.ini language/cs-CZ/cs-CZ.plg_extension_joomsefinstall.ini language/cs-CZ/cs-CZ.plg_extension_joomsefinstall.sys.ini language/cs-CZ/cs-CZ.plg_system_joomsef.ini language/cs-CZ/cs-CZ.plg_system_joomsef.sys.ini language/cs-CZ/cs-CZ.plg_system_joomseflang.ini language/cs-CZ/cs-CZ.plg_system_joomseflang.sys.ini config.xml controller.php extensions_params.xml changelog.txt index.html install.sql model.php sef.php uninstall.sql view.php adapters assets classes controllers models tables views plugin helpers libs sql http://www.artio.net/joomla-updates/list/com_joomsef4.xml components/com_sef/helpers/html/statistic.php000066600000001065150771655450015517 0ustar00".$text.""; } } ?> components/com_sef/helpers/html/index.html000066600000000054150771655450014771 0ustar00components/com_sef/helpers/ipaddress.php000066600000004023150771655450014517 0ustar00= $min) && (ip2long($ip) <= $max)) return false; } return true; } else { return false; } } static function getip() { if (self::validip(@$_SERVER["HTTP_CLIENT_IP"])) { return $_SERVER["HTTP_CLIENT_IP"]; } foreach (explode(",", @$_SERVER["HTTP_X_FORWARDED_FOR"]) as $ip) { if (self::validip(trim($ip))) { return $ip; } } if (self::validip(@$_SERVER["HTTP_X_FORWARDED"])) { return $_SERVER["HTTP_X_FORWARDED"]; } elseif (self::validip(@$_SERVER["HTTP_FORWARDED_FOR"])) { return $_SERVER["HTTP_FORWARDED_FOR"]; } elseif (self::validip(@$_SERVER["HTTP_FORWARDED"])) { return $_SERVER["HTTP_FORWARDED"]; } elseif (self::validip(@$_SERVER["HTTP_X_FORWARDED"])) { return $_SERVER["HTTP_X_FORWARDED"]; } else { return $_SERVER["REMOTE_ADDR"]; } } } ?> components/com_sef/helpers/index.html000066600000000054150771655450014025 0ustar00components/com_sef/helpers/artio-update.php000066600000024137150771655450015147 0ustar00getQuery(true); $query->select('location')->from('#__update_sites')->where('name = '.$db->quote($componentName)); $db->setQuery($query); $origLocation = $location = $db->loadResult(); $location_match = array(); // if some ID is already set, update or remove it if (preg_match("/(-([A-Za-z0-9]*)).xml/", $location, $location_match)) { // update existing download ID if (strlen($downloadID)) { $location = str_replace($location_match[0], '-' . $downloadID.'.xml', $location); // or remove it, if not set } else { $location = str_replace($location_match[0], '.xml', $location); } // if not set yet but just entered, attach it } else if (strlen($downloadID)) { $location = str_replace('.xml', '-'.$downloadID.'.xml', $location); } // if location string has changed, update it in DB if ($location != $origLocation) { $query = "UPDATE #__update_sites SET location = " . $db->quote($location)." WHERE name = " . $db->quote($componentName); $db->setQuery($query); // write to DB if (!$db->query()) { $this->setError($db->stderr(true)); return false; } } return true; } /** * @param string $componentName * @param string $downloadID * @param string $errMsg * @return boolean */ static function isCompatible($componentName, $downloadId, &$errMsg) { if (empty($downloadId) || trim($downloadId) == '') { $errMsg = 'ERR_NO_DOWNLOAD_ID'; return false; } $data = array('download_id' => trim($downloadId), 'cat' => $componentName); $response = self::PostRequest(self::$url, null, $data); if (($response === false) || ($response->code != 200)) { $errMsg = 'ERR_CONNECT'; return false; } else { // Parse the response - get individual lines $lines = explode("\n", $response->content); // Get the code $pos = strpos($lines[0], ' '); if ($pos === false) { $errMsg = 'ERR_CONNECT'; return false; } $regInfo->code = intval(substr($lines[0], 0, $pos)); if (($regInfo->code == 10)) { // OK return true; } else if ($regInfo->code == 20) { $errMsg = 'ERR_EXPIRED'; return false; } else if ($regInfo->code == 30) { $errMsg = 'ERR_NOT_ACTIVATED'; return false; } else if ($regInfo->code == 40) { $errMsg = 'ERR_DOMAIN_NOT_MATCH'; return false; } else if ($regInfo->code == 50) { $errMsg = 'ERR_INVALID_DOWNLOAD_ID'; return false; } else if ($regInfo->code == 90) { $errMsg = 'ERR_DOWNLOAD_ID_NOT_FOUND'; return false; } else { $errMsg = 'ERR_CONNECT'; return false; } } return false; } /** * Sends the POST request * * @param string $url * @param string $referer * @param array $_data * @return object */ static function PostRequest($url, $referer = null, $_data = null, $method = 'post', $userAgent = null, $headers = null) { // convert variables array to string: $data = ''; if (is_array($_data) && count($_data) > 0) { // format --> test1=a&test2=b etc. $data = array(); while( list($n, $v) = each($_data) ) { $data[] = "$n=$v"; } $data = implode('&', $data); $contentType = "Content-type: application/x-www-form-urlencoded\r\n"; } else { $data = $_data; $contentType = "Content-type: text/xml\r\n"; } if (is_null($referer)) { $referer = JURI::root(); } // parse the given URL $url = parse_url($url); if (!isset($url['scheme'])) { return false; } // extract host and path: $host = $url['host']; $path = isset($url['path']) ? $url['path'] : '/'; // Prepare host and port to connect to $connhost = $host; $port = 80; // Workaround for some PHP versions, where fsockopen can't connect to // 'localhost' string on Windows servers if ($connhost == 'localhost') { $connhost = gethostbyname('localhost'); } // Handle scheme if ($url['scheme'] == 'https') { $connhost = 'ssl://'.$connhost; $port = 443; } else if ($url['scheme'] != 'http') { return false; } // open a socket connection $errno = null; $errstr = null; $fp = @fsockopen($connhost, $port, $errno, $errstr, 5); if (!is_resource($fp) || ($fp === false)) { return false; } if (!is_null($userAgent)) { $userAgent = "User-Agent: ".$userAgent."\r\n"; } // send the request if ($method == 'post') { // Check the first fputs, sometimes fsockopen doesn't fail, but fputs doesn't work if (!@fputs($fp, "POST $path HTTP/1.1\r\n")) { @fclose($fp); return false; } if (!is_null($userAgent)) { fputs($fp, $userAgent); } fputs($fp, "Host: $host\r\n"); fputs($fp, "Referer: $referer\r\n"); fputs($fp, $contentType); fputs($fp, "Content-length: ". strlen($data) ."\r\n"); // Send additional headers if set if (is_array($headers)) { foreach ($headers as $h) { $h = rtrim($h); $h .= "\r\n"; fputs($fp, $h); } } fputs($fp, "Connection: close\r\n\r\n"); fputs($fp, $data); } elseif ($method == 'get') { $query = ''; if (isset($url['query'])) { $query = '?'.$url['query']; } // Check the first fputs, sometimes fsockopen doesn't fail, but fputs doesn't work if (!@fputs($fp, "GET {$path}{$query} HTTP/1.1\r\n")) { @fclose($fp); return false; } if (!is_null($userAgent)) { fputs($fp, $userAgent); } fputs($fp, "Host: $host\r\n"); // Send additional headers if set if (is_array($headers)) { foreach ($headers as $h) { $h = rtrim($h); $h .= "\r\n"; fputs($fp, $h); } } fputs($fp, "Connection: close\r\n\r\n"); } $result = ''; while (!feof($fp)) { // receive the results of the request $result .= fgets($fp, 128); } // close the socket connection: fclose($fp); // split the result header from the content $result = explode("\r\n\r\n", $result, 2); $header = isset($result[0]) ? $result[0] : ''; $content = isset($result[1]) ? $result[1] : ''; $response = new stdClass(); $response->header = $header; $response->content = $content; // Handle chunked transfer if needed if (strpos(strtolower($response->header), 'transfer-encoding: chunked') !== false) { $parsed = ''; $left = $response->content; while (true) { $pos = strpos($left, "\r\n"); if ($pos === false) { return $response; } $chunksize = substr($left, 0, $pos); $pos += strlen("\r\n"); $left = substr($left, $pos); $pos = strpos($chunksize, ';'); if ($pos !== false) { $chunksize = substr($chunksize, 0, $pos); } $chunksize = hexdec($chunksize); if ($chunksize == 0) { break; } $parsed .= substr($left, 0, $chunksize); $left = substr($left, $chunksize + strlen("\r\n")); } $response->content = $parsed; } // Get the response code from header $headerLines = explode("\n", $response->header); $header1 = explode(' ', trim($headerLines[0])); $code = intval($header1[1]); $response->code = $code; return $response; } } ?>components/com_sef/install.php000066600000100412150771655450012544 0ustar00get("manifest"); $minVersion = (string) $xml['version']; if (!$jversion->isCompatible($minVersion)) { JError::raiseWarning('100', JText::sprintf('COM_SEF_ERR_MIN_JOOMLA_VERSION', $minVersion)); return false; } if($action=='update') { if(JFile::exists(JPATH_ADMINISTRATOR.'/components/com_sef/configuration.php')) { $tmp_path=JFactory::getApplication()->getCfg('tmp_path'); JFile::copy(JPATH_ADMINISTRATOR.'/components/com_sef/configuration.php',$tmp_path.'/joomsef-configuration.php'); } } $db = JFactory::getDBO(); $query = "SELECT extension_id FROM #__extensions WHERE name=".$db->quote('com_sef'); $db->setQuery($query); $extId = $db->loadResult(); if (!is_null($extId)) { $query = "SELECT COUNT(*) FROM #__schemas WHERE extension_id = ".$db->quote($extId); $db->setQuery($query); $cnt = $db->loadResult(); if ($cnt == 0) { $query = "INSERT INTO #__schemas SET version_id = ".$db->quote('4.1.0').", extension_id = ".$db->quote($extId); $db->setQuery($query); $db->query(); } } } public function postflight($action, $installer) { if ($action == 'install') { $db = JFactory::getDBO(); // Get component ID $db->setQuery("SELECT `extension_id` FROM `#__extensions` WHERE `type` = 'component' AND `element` = 'com_sef'"); $id = $db->loadResult(); if (!$id) { return; } // Fix separator links $db->setQuery("UPDATE `#__menu` SET `link` = '#' WHERE `type` = 'component' AND `img` = 'separator' AND `component_id` = '{$id}'"); $db->query(); } if($action=='update') { $tmp_path=JFactory::getApplication()->getCfg('tmp_path'); if(JFile::exists($tmp_path.'/joomsef-configuration.php')) { JFile::copy($tmp_path.'/joomsef-configuration.php',JPATH_ADMINISTRATOR.'/components/com_sef/configuration.php'); JFile::delete($tmp_path.'/joomsef-configuration.php'); } } } private function getElement($xml) { if(isset($xml->files)) { if (count($xml->files->children())) { foreach ($xml->files->children() as $file) { if ((string)$file->attributes()->sef_ext) { $element = (string)$file->attributes()->sef_ext; if(substr($element,0,13)!='ext_joomsef4_') { $element='ext_joomsef4_'.$element; } return $element; } } } } return ''; } function installPlugins() { $db=JFactory::getDBO(); // Install JoomSEF plugins $plugins=array(); $plugins['content']=array('joomsef'); $plugins['extension']=array('joomsefinstall'); //$plugins['system']=array('joomsef','joomsefgoogle','joomseflang','joomsefurl'); $plugins['system']=array('joomsef','joomsefgoogle','joomseflang'); foreach($plugins as $type=>$items) { foreach($items as $item) { $src = JPATH_ADMINISTRATOR.'/components/com_sef/plugin/'.$type.'/'.$item.'/'; $dest = JPATH_ROOT.'/plugins/'.$type.'/'.$item.'/'; $res = JFolder::create($dest); $res = $res && JFile::copy($src.$item.'.php', $dest.$item.'.php'); $res = $res && JFile::copy($src.$item.'.xml', $dest.$item.'.xml'); $query="SELECT COUNT(*) \n"; $query.="FROM #__extensions \n"; $query.="WHERE type=".$db->quote('plugin')." AND element=".$db->quote($item)." AND folder=".$db->quote($type); $db->setQuery($query); $cnt=$db->loadResult(); $min = null; if ($type == 'system' && $item == 'joomsef') { $db->setQuery("SELECT MIN(`ordering`) FROM `#__extensions` WHERE `type` = 'plugin' AND `folder` = 'system'"); $min = $db->loadResult(); $min -= 10; $min = min(-10, $min); } $xml=JApplicationHelper::parseXMLInstallFile($src.$item.'.xml'); $cache=json_encode($xml); if($cnt==0) { $db->setQuery("INSERT INTO `#__extensions` (name, type, element, folder, client_id, enabled, access, protected, manifest_cache, params, custom_data, system_data, checked_out, checked_out_time, ordering, state) VALUES ('".$xml["name"]."', 'plugin', '".$item."', '".$type."', 0, 1, 1, 0, '".$cache."', '{}', '', '', 0, '0000-00-00 00:00:00', '".(isset($min)?$min:'')."', 0)"); $res = $res && $db->query(); } else { $query="UPDATE #__extensions SET manifest_cache=".$db->quote($cache)." \n"; $query.="WHERE name=".$db->quote($xml["name"])." AND element=".$db->quote('plugin')." AND folder=".$db->quote($item); $db->setQuery($query); $res = $res && $db->query(); } if (!$res) { JError::raiseWarning(100, JText::_('COM_SEF_WARNING_PLUGIN_NOT_INSTALLED').': '.$src); } } } } public function install($installer) { require_once JPATH_ADMINISTRATOR.'/components/com_sef/classes/seftools.php'; $db = JFactory::getDBO(); // Create the default 404 page if it doesn't already exist $db->setQuery("SELECT `id` FROM `#__content` WHERE `title` = '404'"); $id = $db->loadResult(); if (empty($id)) { // Get user ID $user = JFactory::getUser(); $introtext = "

    404: Not Found

    \n

    Sorry, but the content you requested could not be found

    "; $sql = 'INSERT INTO #__content (title, alias, introtext, `fulltext`, state, catid, created, created_by, publish_up, images, urls, ordering, metakey, metadesc, access, hits, language) '. 'VALUES ("404", "404", "'.$introtext.'", "", "1", "0", "'.date('Y-m-d H:i:s').'", "'.$user->id.'", "2001-01-01 00:00:00", "", "", "0", "", "", "1", "0", "*");'; $db->setQuery($sql); $res = $db->query(); if (!$res) { JError::raiseWarning(100, JText::_('COM_SEF_ERROR_DEFAULT_404_PAGE')); } } $this->installPlugins(); // 20.8.2013 dajo: adapters don't need installation anymore, they're registered using our system plugin // Install the extension installer adapter if possible /*$adapterSrc = JPATH_ADMINISTRATOR.'/components/com_sef/adapters/sef_ext.php'; $adapterDest = JPATH_LIBRARIES.'/joomla/installer/adapters/sef_ext.php'; $adapterInstalled = false; if( is_writable(dirname($adapterDest)) ) { if( @copy($adapterSrc, $adapterDest) ) { $adapterInstalled = true; } } $adapterSrc2 = JPATH_ADMINISTRATOR.'/components/com_sef/adapters/sef_update.php'; $adapterDest2 = JPATH_LIBRARIES.'/joomla/updater/adapters/sef_update.php'; $adapterInstalled2 = false; if( is_writable(dirname($adapterDest2)) ) { if( @copy($adapterSrc2, $adapterDest2) ) { $adapterInstalled2 = true; } }*/ $ext_errs=array(); $list=JFolder::files(JPATH_SITE.'/components/com_sef/sef_ext'); JTable::addIncludePath(JPATH_LIBRARIES.'/joomla/database/table'); foreach($list as $sef) { if ((substr($sef, -4) != '.xml') || (substr($sef, 0, 4) != 'com_')) { continue; } $xml=simplexml_load_file(JPATH_SITE.'/components/com_sef/sef_ext/'.$sef); $element=$this->getElement($xml); $query="SELECT COUNT(*) FROM #__extensions WHERE type=".$db->quote('sef_ext')." AND element=".$db->quote($element); $db->setQuery($query); $cnt=$db->loadResult(); if($cnt>0) { continue; } $ext_table=JTable::getInstance('extension'); $ext_table->name=(string)$xml->name; $ext_table->type='sef_ext'; $ext_table->element=$element; $ext_table->enabled=1; $ext_table->protected=1; // Make core JoomSEF extensions protected $ext_table->access=1; $ext_table->client_id=0; if(isset($xml->install->defaultParams)) { $ext_table->params=SEFTools::getDefaultParams($xml->install->defaultParams); } if(isset($xml->install->defaultFilters)) { $ext_table->custom_data=SEFTools::getDefaultFilters($xml->install->defaultFilters); } $ext_table->manifest_cache=json_encode(JApplicationHelper::parseXMLInstallFile(JPATH_SITE.'/components/com_sef/sef_ext/'.$sef)); if(!$ext_table->store()) { $ext_errs[]=$db->stderr(true); } $query="INSERT INTO #__schemas SET extension_id=".$ext_table->extension_id.", version_id=".$db->quote((string)$xml->version); $db->setQuery($query); $db->query(); if(isset($xml->updateservers->server)) { $query="INSERT INTO #__update_sites SET name=".$db->quote((string)$xml->updateservers->server['name']).", type=".$db->quote((string)$xml->updateservers->server['type']).", \n"; $query.="location=".$db->quote((string)$xml->updateservers->server).", enabled=1 \n"; $db->setQuery($query); $db->query(); $id=$db->insertId(); $query="INSERT INTO #__update_sites_extensions SET update_site_id=".$id.", extension_id=".$ext_table->extension_id." \n"; $db->setQuery($query); $db->query(); } } // Check former AceSEF and sh404SEF installations $formerSEF = false; $tables=$db->getTableList(); $prefix=JFactory::getApplication()->getCfg('dbprefix'); // AceSEF if(in_array(str_replace('#__',$prefix,'#__acesef_urls'),$tables)) { $query="SELECT COUNT(*) FROM #__acesef_urls \n"; $db->setQUery($query); $cnt=$db->loadResult(); if($cnt>0) { $formerSEF = true; } } // sh404SEF if( !$formerSEF ) { if(in_array(str_replace('#__',$prefix,'#__sh404sef_urls'),$tables)) { $query="SELECT COUNT(*) FROM #__sh404sef_urls \n"; $db->setQUery($query); $cnt=$db->loadResult(); if($cnt>0) { $formerSEF = true; } } } ob_start(); echo '
    '; echo '

    '.JText::_('COM_SEF_INSTALL_SUCCESS').'

    '; if ($formerSEF) { echo '

    '.JText::sprintf('COM_SEF_INSTALL_FORMER_SEF', '', '').'


    '; } if(count($ext_errs)) { ?>


    ", $ext_errs); ?>

    getHost(); if (substr($host, 0, 4) == 'www.') { // Import the SEF config file if (!class_exists('SEFConfig')) { include(JPATH_ADMINISTRATOR.'/components/com_sef/classes/config.php'); } $sefConfig = SEFConfig::getConfig(); $sefConfig->wwwHandling = _COM_SEF_WWW_USE_WWW; $sefConfig->saveConfig(); } echo '

    '.JText::_('COM_SEF_INSTALL_ACTIVATE_CONFIG').'

    '; $readdocs = '

    '.JText::sprintf('COM_SEF_INSTALL_EXTRA_CONFIG', '', ''); if (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false) { echo $readdocs.'IIS.

    '; } else { // Get the correct rewrite base $base = JURI::root(true); if( $base == '' ) { $base = '/'; } // Create htaccess content $htaccess = ' DirectoryIndex index.php RewriteEngine On RewriteBase ' . $base . ' ########## Begin - Rewrite rules to block out some common exploits ## If you experience problems on your site block out the operations listed below ## This attempts to block the most common type of exploit `attempts` to Joomla! # ## Deny access to extension xml files (uncomment out to activate) # #Order allow,deny #Deny from all #Satisfy all # ## End of deny access to extension xml files # Block out any script trying to set a mosConfig value through the URL RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR] # Block out any script trying to base64_encode crap to send via URL RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR] # Block out any script that includes a \n"; exit(); } // Check the domains configuration if( count($sefConfig->jfSubDomains) ) { foreach($sefConfig->jfSubDomains as $code => $domain) { $domain = str_replace(array('http://', 'https://'), '', $domain); $domain = preg_replace('#/.*$#', '', $domain); $sefConfig->jfSubDomains[$code] = $domain; } } $subdomains=JRequest::getVar('subdomain',array(),'post','array'); $query="DELETE FROM #__sef_subdomains \n"; $query.="WHERE `option`=".$this->_db->quote(""); $this->_db->setQuery($query); if(!$this->_db->query()) { $this->setError($this->_db->stderr(true)); return false; } if (isset($subdomains['title']) && is_array($subdomains['title'])) { foreach($subdomains["title"] as $lang=>$items) { foreach($items as $i=>$item) { $query="INSERT INTO #__sef_subdomains SET subdomain=".$this->_db->quote($item).", Itemid=".$this->_db->quote(implode(",",$subdomains["Itemid"][$lang][$i])).", \n"; $query.="Itemid_titlepage=".$this->_db->quote($subdomains["titlepage"][$lang][$i]).", lang=".$this->_db->quote($lang)." \n"; $this->_db->setQuery($query); if(!$this->_db->query()) { $this->setError($this->_db->stderr(true)); return false; } } } } if (!AUpdateHelper::setUpdateLink('com_joomsef', $sefConfig->artioDownloadId)) { return false; } $config_written = $sefConfig->saveConfig(0); if( $config_written != 0 ) { if($sefConfig->langEnable) { $query=$db->getQuery(true); $query->select('enabled')->from('#__extensions')->where('element='.$db->quote('languagefilter')); $db->setQuery($query); $enabled=$db->loadResult(); if($enabled==1) { JError::raiseWarning('',JText::_('COM_JOOMSEF_DISABLE_LANGUAGEFILTER')); } } return true; } else { return false; } } /** * Fixed version of JHtmlMenu::linkoptions() for Joomla 3.0 * until the bug with missing m.ordering column is fixed */ protected function linkoptions($all = false, $unassigned = false) { if (!class_exists('JHtmlMenu')) { require_once(JPATH_LIBRARIES.'/joomla/html/html/menu.php'); } $db = JFactory::getDbo(); $query = $db->getQuery(true); // Get a list of the menu items $query->select('m.id, m.parent_id, m.title, m.menutype'); $query->from($db->quoteName('#__menu') . ' AS m'); $query->where($db->quoteName('m.published') . ' = 1'); $query->order('m.menutype, m.parent_id, m.lft'); $db->setQuery($query); $mitems = $db->loadObjectList(); if (!$mitems) { $mitems = array(); } // Establish the hierarchy of the menu $children = array(); // First pass - collect children foreach ($mitems as $v) { $pt = $v->parent_id; $list = @$children[$pt] ? $children[$pt] : array(); array_push($list, $v); $children[$pt] = $list; } // Second pass - get an indent list of the items $list = JHtmlMenu::TreeRecurse((int) $mitems[0]->parent_id, '', array(), $children, 9999, 0, 0); // Code that adds menu name to Display of Page(s) $mitems = array(); if ($all | $unassigned) { $mitems[] = JHtml::_('select.option', '', JText::_('JOPTION_MENUS')); if ($all) { $mitems[] = JHtml::_('select.option', 0, JText::_('JALL')); } if ($unassigned) { $mitems[] = JHtml::_('select.option', -1, JText::_('JOPTION_UNASSIGNED')); } $mitems[] = JHtml::_('select.option', ''); } $lastMenuType = null; $tmpMenuType = null; foreach ($list as $list_a) { if ($list_a->menutype != $lastMenuType) { if ($tmpMenuType) { $mitems[] = JHtml::_('select.option', ''); } $mitems[] = JHtml::_('select.option', '', $list_a->menutype); $lastMenuType = $list_a->menutype; $tmpMenuType = $list_a->menutype; } $mitems[] = JHtml::_('select.option', $list_a->id, $list_a->title); } if ($lastMenuType !== null) { $mitems[] = JHtml::_('select.option', ''); } return $mitems; } } ?>components/com_sef/models/cron.php000066600000000622150771655450013324 0ustar00artioFeedDisplay) { return ''; } // Load feed from URL $response = SEFTools::PostRequest($sefConfig->artioFeedUrl, null, null, 'get'); if (!$response || ($response->code != 200)) { return JText::_('COM_SEF_ERROR_CONNECTING_TO_RSS_FEED'); } $feed = $response->content; // Parse XML $xml = simplexml_load_string($feed); if ($xml === false) { return JText::_('COM_SEF_NO_ITEMS_TO_DISPLAY'); } if (count($xml->channel->item) == 0) { return JText::_('COM_SEF_NO_ITEMS_TO_DISPLAY'); } // Build HTML $txt = ''; foreach ($xml->channel->item as $item) { $title = (string)$item->title; $link = (string)$item->link; $desc = (string)$item->description; //$date = date('j. F Y', strtotime((string)$item->pubDate)); //$author = (string)$item->author; $txt .= '
    '; $txt .= ''; $txt .= '
    '.$desc.'
    '; $txt .= '
    '; } return $txt; } public function checkLanguagePlugins() { // Check that the language filter plugin is disabled if (JPluginHelper::isEnabled('system', 'languagefilter')) { JError::raiseWarning(0, JText::sprintf('COM_SEF_WARNING_LANGUAGEFILTER_ENABLED', ''.JText::_('COM_SEF_PLUG_IN_MANAGER').'')); } } public function clearCache($option = null) { $this->cleanCache($option, 0); $this->cleanCache($option, 1); } } ?>components/com_sef/models/urls.php000066600000013667150771655450013365 0ustar00_getTableWhere($table, $where) === false ) { return false; } $db = JFactory::getDBO(); $sql = "DELETE FROM $table" . (!empty($where) ? " WHERE $where" : ''); $db->setQuery($sql); return $db->query(); } /** * 0 - SEF * 1 - 404 * 2 - Custom * 3 - Moved * 4 - Disabled * 5 - Not SEFed * 6 - Locked * 7 - Cached * * @param int $type * @return int */ function getCount($type = null) { if( $this->_getTableWhere($table, $where, $type) === false ) { return 0; } $db = JFactory::getDBO(); $sql = "SELECT COUNT(*) FROM $table" . (!empty($where) ? " WHERE $where" : ''); $db->setQuery($sql); $this->_count = $db->loadResult(); return $this->_count; } function getStatistics() { $sefConfig = SEFConfig::getConfig(); $stats = array(); $stat = new stdClass(); $stat->text = JText::_('COM_SEF_AUTOMATIC_SEF_URLS'); $stat->value = $this->getCount(0); $stat->link = 'index.php?option=com_sef&controller=sefurls&viewmode=0'; $stats[] = $stat; $stat = new stdClass(); $stat->text = JText::_('COM_SEF_CUSTOM_SEF_URLS'); $stat->value = $this->getCount(2); $stat->link = 'index.php?option=com_sef&controller=sefurls&viewmode=2'; $stats[] = $stat; $stat = new stdClass(); $stat->text = JText::_('COM_SEF_404_URLS'); $stat->value = $this->getCount(1); $stat->link = 'index.php?option=com_sef&controller=sefurls&viewmode=1'; $stats[] = $stat; $stat = new stdClass(); $stat->text = JText::_('COM_SEF_MOVED_URLS'); $stat->value = $this->getCount(3); $stat->link = 'index.php?option=com_sef&controller=movedurls'; $stats[] = $stat; $stat = new stdClass(); $stat->text = JText::_('COM_SEF_TOTAL_URLS'); $stat->value = $stats[0]->value + $stats[1]->value + $stats[2]->value + $stats[3]->value; $stats[] = $stat; $stat = new stdClass(); $stat->text = ''; $stats[] = $stat; $stat = new stdClass(); $stat->text = JText::_('COM_SEF_DISABLED_URLS'); $stat->value = $this->getCount(4); $stats[] = $stat; $stat = new stdClass(); $stat->text = JText::_('COM_SEF_NOT_SEFED_URLS'); $stat->value = $this->getCount(5); $stats[] = $stat; $stat = new stdClass(); $stat->text = JText::_('COM_SEF_LOCKED_URLS'); $stat->value = $this->getCount(6); $stats[] = $stat; $stat = new stdClass(); $stat->text = JText::_('COM_SEF_CACHE_ENTRIES'); if ($sefConfig->useCache) { $cache = sefCache::getInstance(); $stat->value = $cache->getCount(); } else { $stat->value = JText::_('COM_SEF_CACHE_DISABLED'); } $stats[] = $stat; $stat = new stdClass(); $stat->text = ''; $stats[] = $stat; $stat = new stdClass(); $stat->text = JText::_('COM_SEF_ERRORS_LOGGED'); $stat->value = $this->getCount(7); $stat->link = 'index.php?option=com_sef&controller=logger'; $stats[] = $stat; return $stats; } function _getTableWhere(&$table, &$where, $type = null) { if (is_null($type)) { $type = JRequest::getInt('type', null); if (!is_null($type) && (($type < 0) || ($type > 3))) { // Can purge only types 0 - 3 $type = null; } } if( is_null($type) ) { return false; } if( ($type >= 0) && ($type <= 2) ) { $table = '`#__sefurls`'; if( $type == 0 ) { // Automatic SEF $where = "`dateadd` = '0000-00-00' AND `locked` = '0'"; } elseif( $type == 1 ) { // 404 $where = "`dateadd` > '0000-00-00' and `origurl` = '' AND `locked` = '0'"; } elseif( $type == 2 ) { // Custom $where = "`dateadd` > '0000-00-00' and `origurl` != '' AND `locked` = '0'"; } } elseif ( $type == 3 ) { // Moved $table = '`#__sefmoved`'; $where = ''; } elseif (($type >= 4) && ($type <= 6)) { $table = '`#__sefurls`'; if ($type == 4) { // Disabled $where = "`enabled` = '0'"; } elseif ($type == 5) { // Not SEFed $where = "`sef` = '0'"; } elseif ($type == 6) { // Locked $where = "`locked` = '1'"; } } elseif ($type == 7) { // Errors logged $table = '`#__seflog`'; $where = ''; } else { return false; } return true; } } ?>components/com_sef/models/sitemap.php000066600000000757150771655450014036 0ustar00components/com_sef/models/sefurl.php000066600000045077150771655450013700 0ustar00setId((int)$array[0]); } function setId($id) { // Set id and wipe data $this->_id = $id; $this->_data = null; } function &getData() { // Load the data if (empty($this->_data)) { if(JRequest::getInt('viewmode')==6) { $cid=JRequest::getVar('cid',array(),'request','array'); $cache=SEFCache::getInstance(); $this->_data=$cache->getNonSEFURL($cid[0]); } else { if ($this->_id != 0) { $query = "SELECT * FROM `#__sefurls` WHERE `id` = '{$this->_id}'"; $this->_db->setQuery($query); $this->_data = $this->_db->loadObject(); if (isset($this->_data->metacustom)) { $this->_data->metacustom = @unserialize($this->_data->metacustom); } } } } if (!$this->_data) { $sefConfig = SEFConfig::getConfig(); $this->_data = new stdClass(); $this->_data->id = 0; $this->_data->cpt = null; $this->_data->sefurl = null; $this->_data->origurl = null; $this->_data->Itemid = null; $this->_data->metadesc = null; $this->_data->metakey = null; $this->_data->metatitle = null; $this->_data->metalang = null; $this->_data->metarobots = null; $this->_data->metagoogle = null; $this->_data->metacustom = null; $this->_data->canonicallink = null; $this->_data->dateadd = null; $this->_data->enabled = 1; $this->_data->locked = 0; $this->_data->sef = 1; $this->_data->sm_indexed = ($sefConfig->sitemap_indexed ? 1 : 0); $this->_data->sm_date = date('Y-m-d'); $this->_data->sm_frequency = $sefConfig->sitemap_frequency; $this->_data->sm_priority = $sefConfig->sitemap_priority; $this->_data->aliases = null; $this->_data->host = null; $this->_data->showsitename = _COM_SEF_SITENAME_GLOBAL; } else { // Get the aliases $query = "SELECT * FROM `#__sefaliases` WHERE `url` = '{$this->_id}'"; $this->_db->setQuery($query); $objs = $this->_db->loadObjectList(); $aliases = array(); if ($objs) { foreach ($objs as $obj) { $aliases[] = $this->_aliasToString($obj); } } $this->_data->aliases = implode("\n", $aliases); } return $this->_data; } function _aliasToString($row) { $alias = $row->alias; if (!empty($row->vars)) { $vars = trim(str_replace("\n", '&', $row->vars)); $alias .= '?'.$vars; } return $alias; } function getLists() { $lists = array(); if (empty($this->_data)) { $this->getData(); } $lists['customurl'] = $this->booleanRadio('customurl', 'class="inputbox"', 1); $lists['enabled'] = $this->booleanRadio('enabled', 'class="inputbox"', $this->_data->enabled); $lists['sef'] = $this->booleanRadio('sef', 'class="inputbox"', $this->_data->sef); $lists['locked'] = $this->booleanRadio('locked', 'class="inputbox"', $this->_data->locked); $useSitenameOpts[] = JHTML::_('select.option', _COM_SEF_SITENAME_GLOBAL, JText::_('COM_SEF_USE_GLOBAL_CONFIG')); $useSitenameOpts[] = JHTML::_('select.option', _COM_SEF_SITENAME_BEFORE, JText::_('COM_SEF_BEFORE_PAGE_TITLE')); $useSitenameOpts[] = JHTML::_('select.option', _COM_SEF_SITENAME_AFTER, JText::_('COM_SEF_AFTER_PAGE_TITLE')); $useSitenameOpts[] = JHTML::_('select.option', _COM_SEF_SITENAME_NO, JText::_('COM_SEF_NO')); $lists['showsitename'] = JHTML::_('select.genericlist', $useSitenameOpts, 'showsitename', 'class="inputbox" size="1"', 'value', 'text', $this->_data->showsitename); return $lists; } function _getWords() { $words = array(); if ($this->_id != 0) { $query = "SELECT `w`.`id`, `w`.`word` FROM `#__sefwords` AS `w` INNER JOIN `#__sefurlword_xref` AS `x` ON `w`.`id` = `x`.`word` WHERE `x`.`url` = '{$this->_id}'"; $this->_db->setQuery($query); $words = $this->_db->loadObjectList(); } return $words; } function fixOrigurlPost(&$data) { if (isset($data['origurl'])) { $origurl = $data['origurl']; if (substr($origurl, 0, 10) == 'index.php?') { $origurl = substr($origurl, 10); $origvars = array(); parse_str($origurl, $origvars); if (!empty($origvars)) { // Handle Itemid if (isset($origvars['Itemid'])) { $Itemid = $origvars['Itemid']; unset($origvars['Itemid']); if (!isset($data['Itemid']) || ($data['Itemid'] == '')) { $data['Itemid'] = $Itemid; JRequest::setVar('Itemid', $Itemid, 'post'); } } // Sort vars and move option to beginning if (isset($origvars['option'])) { $opt = $origvars['option']; unset($origvars['option']); } JoomSEF::ksort_deep($origvars); if (isset($opt)) { $origvars = array_merge(array('option' => $opt), $origvars); } // Build the origurl again $origurl = 'index.php?'; $origurl .= urldecode(http_build_query($origvars)); // Update value $data['origurl'] = $origurl; JRequest::setVar('origurl', $origurl, 'post'); } } } } function store() { $row = $this->getTable(); $data = JRequest::get('post', 2); // Make sure origurl follows the rules $this->fixOrigurlPost($data); // Handle the enabled, sef and locked checkboxes if (!isset($data['enabled'])) { $data['enabled'] = '0'; } if (!isset($data['sef'])) { $data['sef'] = '0'; } if (!isset($data['locked'])) { $data['locked'] = '0'; } // Create the array of custom meta tags if (isset($data['metanames']) && is_array($data['metanames'])) { for ($i = 0, $n = count($data['metanames']); $i < $n; $i++) { if (empty($data['metanames'][$i])) { unset($data['metanames'][$i]); if (isset($data['metacontents'][$i])) { unset($data['metacontents'][$i]); } } } // Create the associative array of custom meta tags $data['metacustom'] = array_combine($data['metanames'], $data['metacontents']); } else { // No meta tags $data['metacustom'] = array(); } $data['metacustom'] = serialize($data['metacustom']); // Bind the form fields to the table if (!$row->bind($data)) { $this->setError($this->_db->getErrorMsg()); return false; } // Make sure the record is valid if (!$row->check()) { $this->setError($row->_error); return false; } // Set the priority according to Itemid if ($row->Itemid != '') { $row->priority = _COM_SEF_PRIORITY_DEFAULT_ITEMID; } else { $row->priority = _COM_SEF_PRIORITY_DEFAULT; } // Store the table to the database if (!$row->store()) { $this->setError( $row->getError() ); return false; } // Handle the aliases references // remove the current bindings $this->_db->setQuery("DELETE FROM `#__sefaliases` WHERE `url` = '{$row->id}'"); if (!$this->_db->query()) { $this->setError($this->_db->getErrorMsg()); return false; } // add all the aliases for current URL $data['aliases'] = trim($data['aliases']); if (!empty($data['aliases'])) { $aliases = str_replace("\r", '', $data['aliases']); $aliases = explode("\n", $aliases); $vals = array(); foreach ($aliases as $arow) { if (strpos($arow, '?') !== false) { list($alias, $vars) = explode('?', $arow); $vars = str_replace('&', "\n", $vars); } else { $alias = $arow; $vars = ''; } $alias = ltrim($alias, '/'); $vals[] = '(' . $this->_db->Quote($alias) . ', ' . $this->_db->Quote($vars) . ", '{$row->id}')"; } $query = "INSERT INTO `#__sefaliases` (`alias`, `vars`, `url`) VALUES " . implode(', ', $vals); $this->_db->setQuery($query); if (!$this->_db->query()) { $this->setError($this->_db->getErrorMsg()); return false; } } // check if there's old url to save to Moved Permanently table $unchanged = JRequest::getVar('unchanged'); if ($data["addtosefmoved"]) { $row = $this->getTable('MovedUrl'); $row->old = $unchanged; $row->new = JRequest::getVar('sefurl'); // pre-save checks if (!$row->check()) { $this->setError($row->getError()); return false; } // save the changes if (!$row->store()) { $this->setError($row->getError()); return false; } } $config=SEFConfig::getConfig(); if($config->useCache) { $data=(object)$data; $cache=SEFCache::getInstance(); $nonsefcache=$cache->getNonSEFURL($data->unchanged); if($nonsefcache) { $cache->changeUrl($row->id, $data->origurl,$data->sefurl,0,$data->Itemid,$data->metatitle,$data->metadesc,$data->metakey,$data->metalang,$data->metarobots,$data->metagoogle,$data->canonicallink,$data->metacustom,$data->enabled,$data->sef,true,$row->host,$row->showsitename); } } return true; } function storeCache() { $data=(object)JRequest::get('post'); $cache=SEFCache::getInstance(); $cache->changeUrl($data->id, $data->origurl,$data->sefurl,0,$data->Itemid,$data->metatitle,$data->metadesc,$data->metakey,$data->metalang,$data->metarobots,$data->metagoogle,$data->canonicallink,$data->metacustom,$data->enabled,$data->sef,true,$data->host,$data->showsitename); if($data->addtosefmoved) { $query="INSERT INTO #__sefmoved \n"; $query.="SET old=".$this->_db->quote($data->unchanged).", "; $query.="new=".$this->_db->quote($data->sefurl)." \n"; $this->_db->setQuery($query); if(!$this->_db->query()) { $this->setError($this->_db->stderr(true)); return false; } } if($data->urlchanged) { $query="SELECT COUNT(*) \n"; $query.="FROM #__sefurls \n"; $query.="WHERE origurl=".$this->_db->quote($data->origurl)." \n"; $this->_db->setQuery($query); $cnt=$this->_db->loadResult(); if($cnt) { $query="UPDATE #__sefurls \n"; $query.="SET sefurl=".$this->_db->quote($data->sefurl)." \n"; $query.="WHERE origurl=".$this->_db->quote($data->origurl)." \n"; $this->_db->setQUery($query); if(!$this->_db->query()) { $this->setError($this->_db->stderr(true)); return false; } } } return true; } function delete() { $cids = JRequest::getVar('cid', array(0), 'post', 'array'); if(JRequest::getInt('viewmode')!=6) { if (count($cids)) { // Remove URL $ids = implode(',', $cids); $query = "DELETE FROM `#__sefurls` WHERE `id` IN ($ids) AND `locked` = '0'"; $this->_db->setQuery($query); if (!$this->_db->query()) { $this->setError($this->_db->getErrorMsg()); return false; } // Remove aliases $query = "DELETE FROM `#__sefaliases` WHERE `url` IN ($ids)"; $this->_db->setQuery($query); if (!$this->_db->query()) { $this->setError($this->_db->getErrorMsg()); return false; } // Remove words references $query = "DELETE FROM `#__sefurlword_xref` WHERE `url` IN ($ids)"; $this->_db->setQuery($query); if (!$this->_db->query()) { $this->setError($this->_db->getErrorMsg()); return false; } } } else { $cache=SEFCache::getInstance(); foreach($cids as $url) { $cache->removeSEF($url); } } return true; } function setActive() { if ($this->_id == 0) { return false; } // Get the SEF URL for given id $row =& $this->getData(); $states = array(); $states[$this->_id] = 0; // Set priority to 0 for given id $query = "UPDATE `#__sefurls` SET `priority` = '0' WHERE `id` = '{$this->_id}' LIMIT 1"; $this->_db->setQuery($query); if( !$this->_db->query() ) { $this->setError($this->_db->getErrorMsg()); return false; } // Get all other IDs $query = "SELECT `id` FROM `#__sefurls` WHERE (`sefurl` = '{$row->sefurl}') AND (`id` != '{$this->_id}')"; $this->_db->setQuery($query); $ids = $this->_db->loadColumn(); if (count($ids) > 0) { foreach ($ids as $id) { $states[$id] = 100; } // Set priority to 100 for every other same SEF URL $where = implode(',', $ids); $query = "UPDATE `#__sefurls` SET `priority` = '100' WHERE `id` IN ({$where})"; $this->_db->setQuery($query); if( !$this->_db->query() ) { $this->setError($this->_db->getErrorMsg()); return false; } } return $states; } function setOrigurl() { if ($this->_id == 0) { return false; } $data = JRequest::get('post'); // Make sure origurl follows the rules $this->fixOrigurlPost($data); $row = $this->getTable(); if (!$row->load($this->_id)) { return false; } $row->origurl = $data['origurl']; $row->Itemid = $data['Itemid']; if (!$row->check()) { return false; } if (!$row->store()) { return false; } $origurl = $data['origurl']; $Itemid = trim($data['Itemid']); if (strlen($Itemid) > 0) { if (strpos($origurl, '?') !== false) { $origurl .= '&Itemid='.intval($data['Itemid']); } else { $origurl .= '?Itemid='.intval($data['Itemid']); } } return $origurl; } function setSefurl() { if ($this->_id == 0) { return false; } $row = $this->getTable(); if (!$row->load($this->_id)) { return false; } $row->sefurl = JRequest::getVar('sefurl', '', 'post'); if (!$row->check()) { return false; } if (!$row->store()) { return false; } return $row->sefurl; } function copyToCache() { $selection=JRequest::getString('selection'); if($selection=='selected') { $ids=JRequest::getVar('cid',array(),'request','array'); } else { require_once JPATH_COMPONENT_ADMINISTRATOR.'/models/sefurls.php'; $model=new SEFModelSEFUrls(); $where=$model->_getWhere(); $query="SELECT id FROM #__sefurls \n"; $query.="WHERE ".$where; $this->_db->setQuery($query); $ids=$this->_db->loadColumn(); } $cache=SEFCache::getInstance(); $query = "SELECT * \n"; $query .= "FROM #__sefurls \n"; $query .= "WHERE id IN(".implode(",", $ids).") \n"; $this->_db->setQuery($query); $urls = $this->_db->loadObjectList(); foreach ($urls as $url) { if (!$cache->getSEFURLExists($url->origurl)) { $cache->addURL($url->id, $url->origurl,$url->sefurl,$url->cpt,$url->Itemid,$url->metatitle,$url->metadesc,$url->metakey,$url->metalang,$url->metarobots,$url->metagoogle,$url->metaauthor,$url->canonicallink,$url->metacustom,$url->enabled,$url->sef,true,$url->host,$url->showsitename); } } return true; } } ?>components/com_sef/models/statistics.php000066600000001015150771655450014552 0ustar00components/com_sef/models/movedurls.php000066600000013732150771655450014411 0ustar00_getVars(); } function _getVars() { $mainframe = JFactory::getApplication(); //$this->sortby = $mainframe->getUserStateFromRequest("sef.movedurls.sortby", 'sortby', 0); $this->filterOld = $mainframe->getUserStateFromRequest("sef.movedurls.filterOld", 'filterOld', ''); $this->filterNew = $mainframe->getUserStateFromRequest("sef.movedurls.filterNew", 'filterNew', ''); $this->filterDays = $mainframe->getUserStateFromRequest("sef.movedurls.filterDays", 'filterDays', 0); $this->filterOrder = $mainframe->getUserStateFromRequest('sef.movedurls.filter_order', 'filter_order', 'old'); $this->filterOrderDir = $mainframe->getUserStateFromRequest('sef.movedurls.filter_order_Dir', 'filter_order_Dir', 'asc'); $this->limit = $mainframe->getUserStateFromRequest('global.list.limit', 'limit', $mainframe->getCfg('list_limit'), 'int'); $this->limitstart = $mainframe->getUserStateFromRequest('sef.movedurls.limitstart', 'limitstart', 0, 'int'); // In case limit has been changed, adjust limitstart accordingly $this->limitstart = ( $this->limit != 0 ? (floor($this->limitstart / $this->limit) * $this->limit) : 0 ); /* $total = $this->getTotal(); if( ($this->limitstart + $this->limit - 1) > $total ) { $this->limitstart = max(($total - $this->limit + 1), 0); } */ } /** * Returns the query * @return string The query to be used to retrieve the rows from the database */ function _buildQuery() { $limit = ''; if( ($this->limit != 0) || ($this->limitstart != 0) ) { $limit = " LIMIT {$this->limitstart},{$this->limit}"; } $query = "SELECT * FROM `#__sefmoved` ".$this->_getWhere()." ORDER BY ".$this->_getSort().$limit; return $query; } function _getSort() { if( !isset($this->_sort) ) { /* switch ($this->sortby) { case 1: $this->_sort = "`old` DESC"; break; case 2: $this->_sort = "`new`"; break; case 3: $this->_sort = "`new` DESC"; break; case 4: $this->_sort = "`lastHit` DESC"; break; case 5: $this->_sort = "`lastHit`"; break; default: $this->_sort = "`old`"; break; } */ $this->_sort = '`' . $this->filterOrder . '` ' . $this->filterOrderDir; } return $this->_sort; } function _getWhere() { if( empty($this->_where) ) { $where = ''; // Filter URLs if( $this->filterOld != '' ) $where .= ($where != '' ? 'AND ' : '') . "`old` LIKE '%{$this->filterOld}%' "; if( $this->filterNew != '' ) $where .= ($where != '' ? 'AND ' : '') . "`new` LIKE '%{$this->filterNew}%' "; if( $this->filterDays != '' ) $where .= ($where != '' ? 'AND ' : '') . "`lastHit` < DATE_SUB(NOW(), INTERVAL '{$this->filterDays}' DAY) "; if( !empty($where) ) { $where = "WHERE " . $where; } $this->_where = $where; } return $this->_where; } function getTotal() { if( !isset($this->_total) ) { $this->_db->setQuery("SELECT COUNT(*) FROM `#__sefmoved` ".$this->_getWhere()); $this->_total = $this->_db->loadResult(); } return $this->_total; } /** * Retrieves the data */ function getData() { // Lets load the data if it doesn't already exist if (empty( $this->_data )) { $query = $this->_buildQuery(); $this->_data = $this->_getList( $query ); } return $this->_data; } function getLists() { // Make the input boxes for hits filter $lists['filterDays'] = "filterDays}\" style=\"width: 120px;\" size=\"10\" maxlength=\"10\" onkeydown=\"return handleKeyDown(event);\" />"; // make the filter text boxes $lists['filterOld'] = "filterOld}\" size=\"40\" maxlength=\"255\" onkeydown=\"return handleKeyDown(event);\" title=\"".JText::_('COM_SEF_TT_FILTER_OLD')."\" />"; $lists['filterNew'] = "filterNew}\" size=\"40\" maxlength=\"255\" onkeydown=\"return handleKeyDown(event);\" title=\"".JText::_('COM_SEF_TT_FILTER_NEW')."\" />"; $lists['filterReset'] = ''; // Ordering $lists['filter_order'] = $this->filterOrder; $lists['filter_order_Dir'] = $this->filterOrderDir; return $lists; } function getPagination() { jimport('joomla.html.pagination'); $pagination = new JPagination($this->getTotal(), $this->limitstart, $this->limit); return $pagination; } function deleteFiltered() { $query = "DELETE FROM `#__sefmoved` ".$this->_getWhere(); $this->_db->setQuery($query); if (!$this->_db->query()) { $this->setError( $this->_db->getErrorMsg() ); return false; } return true; } } ?>components/com_sef/models/sitemap.php.backup000066600000100237150771655450015274 0ustar00_getVars(); } function _getVars() { $mainframe =& JFactory::getApplication(); $this->filterComponent = $mainframe->getUserStateFromRequest("sef.sitemap.comFilter", 'comFilter', ''); $this->filterSEF = $mainframe->getUserStateFromRequest("sef.sitemap.filterSEF", 'filterSEF', ''); $this->filterReal = $mainframe->getUserStateFromRequest("sef.sitemap.filterReal", 'filterReal', ''); $this->filterLang = $mainframe->getUserStateFromRequest('sef.sitemap.filterLang', 'filterLang', ''); $this->filterIndexed = $mainframe->getUserStateFromRequest("sef.sitemap.filterIndexed", 'filterIndexed', ''); $this->filterFrequency = $mainframe->getUserStateFromRequest("sef.sitemap.filterFrequency", 'filterFrequency', ''); $this->filterPriority = $mainframe->getUserStateFromRequest("sef.sitemap.filterPriority", 'filterPriority', ''); $this->filterOrder = $mainframe->getUserStateFromRequest('sef.sitemap.filter_order', 'filter_order', 'sefurl'); $this->filterOrderDir = $mainframe->getUserStateFromRequest('sef.sitemap.filter_order_Dir', 'filter_order_Dir', 'asc'); $this->limit = $mainframe->getUserStateFromRequest('global.list.limit', 'limit', $mainframe->getCfg('list_limit'), 'int'); $this->limitstart = $mainframe->getUserStateFromRequest('sef.sitemap.limitstart', 'limitstart', 0, 'int'); // In case limit has been changed, adjust limitstart accordingly $this->limitstart = ( $this->limit != 0 ? (floor($this->limitstart / $this->limit) * $this->limit) : 0 ); } /** * Returns the query * @return string The query to be used to retrieve the rows from the database */ function _buildQuery() { $limit = ''; if( ($this->limit != 0) || ($this->limitstart != 0) ) { $limit = " LIMIT {$this->limitstart},{$this->limit}"; } $query = "SELECT * FROM `#__sefurls` ".$this->_getWhere()." ORDER BY ".$this->_getSort().$limit; return $query; } function _getSort() { if( !isset($this->_sort) ) { $this->_sort = '`' . $this->filterOrder . '` ' . $this->filterOrderDir; } return $this->_sort; } function _getWhereIds() { $ids = JRequest::getVar('cid', array(), 'post', 'array'); $where = ''; if( count($ids) > 0 ) { $where = 'WHERE `id` IN (' . implode(',', $ids) . ')'; } return $where; } function _getWhere() { if( empty($this->_where) ) { $where = "`origurl` != '' "; $db =& JFactory::getDBO(); // filter URLs if ($this->filterComponent != '') { $where .= "AND (`origurl` LIKE '%option={$this->filterComponent}&%' OR `origurl` LIKE '%option={$this->filterComponent}') "; } if ($this->filterLang != '' ) { $where .= "AND (`origurl` LIKE '%lang={$this->filterLang}%') "; } if ($this->filterSEF != '') { if( substr($this->filterSEF, 0, 4) == 'reg:' ) { $val = substr($this->filterSEF, 4); if( $val != '' ) { // Regular expression search $val = $db->Quote($val); $where .= "AND `sefurl` REGEXP $val "; } } else { $val = $db->Quote('%'.$this->filterSEF.'%'); $where .= "AND `sefurl` LIKE $val "; } } if ($this->filterReal != '') { if( substr($this->filterReal, 0, 4) == 'reg:' ) { $val = substr($this->filterReal, 4); if( $val != '' ) { // Regular expression search $val = $db->Quote($val); $where .= "AND `origurl` REGEXP $val "; } } else { $val = $db->Quote('%'.$this->filterReal.'%'); $where .= "AND `origurl` LIKE $val "; } } // filter sitemap data if ($this->filterIndexed != 0) { if ($this->filterIndexed == 1) { $where .= "AND `sm_indexed` = '1' "; } elseif ($this->filterIndexed == 2) { $where .= "AND `sm_indexed` = '0' "; } } if ($this->filterFrequency != '') { $where .= "AND `sm_frequency` = '{$this->filterFrequency}' "; } if ($this->filterPriority != '') { $where .= "AND `sm_priority` = '{$this->filterPriority}' "; } if( !empty($where) ) { $where = "WHERE " . $where; } $this->_where = $where; } return $this->_where; } function getTotal() { if( !isset($this->_total) ) { $this->_db->setQuery("SELECT COUNT(*) FROM `#__sefurls` ".$this->_getWhere()); $this->_total = $this->_db->loadResult(); } return $this->_total; } /** * Retrieves the data */ function getData() { // Lets load the data if it doesn't already exist if (empty( $this->_data )) { $query = $this->_buildQuery(); $this->_data = $this->_getList( $query ); } return $this->_data; } function getLists() { // make the select list for the component filter $comList[] = JHTML::_('select.option', '', JText::_('COM_SEF_ALL')); $rows = SEFTools::getInstalledComponents(); foreach(array_keys($rows) as $i) { $row = &$rows[$i]; $comList[] = JHTML::_('select.option', $row->option, $row->name ); } $lists['comList'] = JHTML::_( 'select.genericlist', $comList, 'comFilter', "class=\"inputbox\" onchange=\"document.adminForm.submit();\" size=\"1\"", 'value', 'text', $this->filterComponent); // make the filter text boxes $lists['filterSEF'] = "filterSEF}\" size=\"40\" maxlength=\"255\" onkeydown=\"return handleKeyDown(event);\" title=\"".JText::_('COM_SEF_TT_FILTER_SEF')."\" />"; $lists['filterReal'] = "filterReal}\" size=\"40\" maxlength=\"255\" onkeydown=\"return handleKeyDown(event);\" title=\"".JText::_('COM_SEF_TT_FILTER_REAL')."\" />"; $lists['filterSEFRE'] = JText::_('COM_SEF_USE_RE').' filterSEF, 0, 4) == 'reg:') ? 'checked="checked"' : '') . ' onclick="useRE(this, document.adminForm.filterSEF);" />'; $lists['filterRealRE'] = JText::_('COM_SEF_USE_RE').' filterReal, 0, 4) == 'reg:') ? 'checked="checked"' : '') . ' onclick="useRE(this, document.adminForm.filterReal);" />'; // Filter Indexed state $indexes[] = JHTML::_('select.option', 0, JText::_('COM_SEF_ALL')); $indexes[] = JHTML::_('select.option', 1, JText::_('COM_SEF_INDEXED')); $indexes[] = JHTML::_('select.option', 2, JText::_('COM_SEF_NOT_INDEXED')); $lists['filterIndexed'] = JHTML::_('select.genericlist', $indexes, 'filterIndexed', 'class="inputbox" onchange="document.adminForm.submit();" style="width: 120px;" size="1"', 'value', 'text', $this->filterIndexed); // Filter Frequency state $freqs[] = JHTML::_('select.option', '', JText::_('COM_SEF_ALL')); $freqs[] = JHTML::_('select.option', 'always', 'always'); $freqs[] = JHTML::_('select.option', 'hourly', 'hourly'); $freqs[] = JHTML::_('select.option', 'daily', 'daily'); $freqs[] = JHTML::_('select.option', 'weekly', 'weekly'); $freqs[] = JHTML::_('select.option', 'monthly', 'monthly'); $freqs[] = JHTML::_('select.option', 'yearly', 'yearly'); $freqs[] = JHTML::_('select.option', 'never', 'never'); $lists['filterFrequency'] = JHTML::_('select.genericlist', $freqs, 'filterFrequency', 'class="inputbox" onchange="document.adminForm.submit();" style="width: 120px;" size="1"', 'value', 'text', $this->filterFrequency); // Filter Priority state $priorities[] = JHTML::_('select.option', '', JText::_('COM_SEF_ALL')); $priorities[] = JHTML::_('select.option', '0.0', '0.0'); $priorities[] = JHTML::_('select.option', '0.1', '0.1'); $priorities[] = JHTML::_('select.option', '0.2', '0.2'); $priorities[] = JHTML::_('select.option', '0.3', '0.3'); $priorities[] = JHTML::_('select.option', '0.4', '0.4'); $priorities[] = JHTML::_('select.option', '0.5', '0.5'); $priorities[] = JHTML::_('select.option', '0.6', '0.6'); $priorities[] = JHTML::_('select.option', '0.7', '0.7'); $priorities[] = JHTML::_('select.option', '0.8', '0.8'); $priorities[] = JHTML::_('select.option', '0.9', '0.9'); $priorities[] = JHTML::_('select.option', '1.0', '1.0'); $lists['filterPriority'] = JHTML::_('select.genericlist', $priorities, 'filterPriority', 'class="inputbox" onchange="document.adminForm.submit();" style="width: 120px;" size="1"', 'value', 'text', $this->filterPriority); // Language filter $sefConfig = SEFConfig::getConfig(); if ($sefConfig->langEnable) { $langs = JLanguageHelper::getLanguages(); $langList = array(); $langList[] = JHTML::_('select.option', '', JText::_('COM_SEF_ALL')); foreach ($langs as $lng) { $langList[] = JHTML::_('select.option', $lng->sef, $lng->title); } $lists['filterLang'] = JHTML::_('select.genericlist', $langList, 'filterLang', 'class="inputbox" onchange="document.adminForm.submit();" size="1"', 'value', 'text', $this->filterLang); } $lists['filterReset'] = ''; // Ordering $lists['filter_order'] = $this->filterOrder; $lists['filter_order_Dir'] = $this->filterOrderDir; // Selection $sel[] = JHTML::_('select.option', 'selected', JText::_('COM_SEF_ONLY_SELECTED')); $sel[] = JHTML::_('select.option', 'filtered', JText::_('COM_SEF_ALL_FILTERED')); $lists['selection'] = JHTML::_('select.genericlist', $sel, 'sef_selection', 'class="inputbox" size="1"'); // Actions $acts[] = JHTML::_('select.option', 'index', JText::_('COM_SEF_INDEX')); $acts[] = JHTML::_('select.option', 'unindex', JText::_('COM_SEF_UNINDEX')); $acts[] = JHTML::_('select.option', 'indexpublished', JText::_('COM_SEF_INDEXED_FROM_PUBLISHED')); $acts[] = JHTML::_('select.option', 'setdate', JText::_('COM_SEF_SET_DATE')); $acts[] = JHTML::_('select.option', 'setfrequency', JText::_('COM_SEF_SET_FREQUENCY')); $acts[] = JHTML::_('select.option', 'setpriority', JText::_('COM_SEF_SET_PRIORITY')); $lists['actions'] = JHTML::_('select.genericlist', $acts, 'sef_actions', 'class="inputbox" size="1" onchange="showInput();"'); $sefConfig =& SEFConfig::getConfig(); $lists['newdate'] = ''; $lists['newpriority'] = ''; $lists['newfrequency'] = ''; return $lists; } function getPagination() { jimport('joomla.html.pagination'); $pagination = new JPagination($this->getTotal(), $this->limitstart, $this->limit); return $pagination; } function store() { $ids = JRequest::getVar('id'); $smindexed = JRequest::getVar('sm_indexed'); $smdate = JRequest::getVar('sm_date'); $smfrequency = JRequest::getVar('sm_frequency'); $smpriority = JRequest::getVar('sm_priority'); if (is_array($ids)) { foreach ($ids as $id) { if (!is_numeric($id)) { continue; } $indexed = isset($smindexed[$id]) ? '1' : '0'; $date = isset($smdate[$id]) ? $smdate[$id] : '0000-00-00'; $frequency = isset($smfrequency[$id]) ? $smfrequency[$id] : 'never'; $priority = isset($smpriority[$id]) ? $smpriority[$id] : '0.0'; $query = "UPDATE `#__sefurls` SET `sm_indexed` = ".$this->_db->Quote($indexed).", `sm_date` = ".$this->_db->Quote($date).", `sm_frequency` = ".$this->_db->Quote($frequency).", `sm_priority` = ".$this->_db->Quote($priority)." WHERE `id` = '{$id}' LIMIT 1"; $this->_db->setQuery($query); if (!$this->_db->query()) { $this->setError($this->_db->getErrorMsg()); return false; } } } // Set the sitemap changed flag $sefConfig =& SEFConfig::getConfig(); if (!$sefConfig->sitemap_changed) { $sefConfig->sitemap_changed = true; $sefConfig->saveConfig(); } return true; } function _setState($state, $value, $where) { if (empty($where)) { return true; } $query = "UPDATE `#__sefurls` SET `{$state}` = '{$value}' $where"; $this->_db->setQuery($query); if (!$this->_db->query()) { $this->setError( $this->_db->getErrorMsg() ); return false; } // Set the sitemap changed flag $sefConfig =& SEFConfig::getConfig(); if (!$sefConfig->sitemap_changed) { $sefConfig->sitemap_changed = true; $sefConfig->saveConfig(); } return true; } function setIndex($state, $where) { return $this->_setState('sm_indexed', $state, $where); } function setDate($state, $where) { return $this->_setState('sm_date', $state, $where); } function setFrequency($state, $where) { return $this->_setState('sm_frequency', $state, $where); } function setPriority($state, $where) { return $this->_setState('sm_priority', $state, $where); } function indexPublished($where = '') { $where2 = "`origurl` REGEXP 'option=com_content&.*view=article'"; $where = trim($where); if ($where == '') { $where = 'WHERE '.$where2; } else { $where .= ' AND ('.$where2.')'; } $db =& JFactory::getDBO(); $query = "SELECT `id`, `origurl`, `sm_indexed` FROM `#__sefurls` ".$where; $db->setQuery($query); $rows = $db->loadObjectList(); if (is_null($rows)) { return true; } $matches = array(); $trueUpdates = array(); $falseUpdates = array(); $states = array(); $now =& JFactory::getDate(); $nullDate = $db->getNullDate(); foreach ($rows as &$row) { // Get article ID preg_match('/&id=([^&]+)/', $row->origurl, $matches); if (!isset($matches[1])) { continue; } $id = $matches[1]; // Get article published state if (!isset($states[$id])) { $db->setQuery("SELECT `state`, `publish_down` FROM `#__content` WHERE `id` = '{$id}' LIMIT 1"); $publish = $db->loadObject(); if (is_null($publish)) { $states[$id] = false; } else { if (intval($publish->state) <= 0) { $states[$id] = false; } else { $to =& JFactory::getDate($publish->publish_down); if ($now->toUnix() <= $to->toUnix() || $publish->publish_down == $nullDate) { $states[$id] = true; } else { $states[$id] = false; } } } } // Check the state change if (((bool)$row->sm_indexed) != $states[$id]) { // State changed if ($states[$id]) { $trueUpdates[] = $row->id; } else { $falseUpdates[] = $row->id; } } } $ret = true; $changed = false; // Execute the true updates if (count($trueUpdates) > 0) { $db->setQuery("UPDATE `#__sefurls` SET `sm_indexed` = '1' WHERE `id` IN (".implode(',', $trueUpdates).')'); if (!$db->query()) { $ret = false; } $changed = true; } // Execute the false updates if (count($falseUpdates) > 0) { $db->setQuery("UPDATE `#__sefurls` SET `sm_indexed` = '0' WHERE `id` IN (".implode(',', $falseUpdates).')'); if (!$db->query()) { $ret = false; } $changed = true; } // Set the sitemap changed flag if ($changed) { $sefConfig =& SEFConfig::getConfig(); if (!$sefConfig->sitemap_changed) { $sefConfig->sitemap_changed = true; $sefConfig->saveConfig(); } } return $ret; } private function prepareDomain($domain, $wwwHandle) { $sefConfig = SEFConfig::getConfig(); // Remove scheme $pos = strpos($domain, '://'); if ($pos !== false) { $domain = substr($domain, $pos + 3); } // Remove everything after host (also port if present) $pos = strpos($domain, '/'); $pos2 = strpos($domain, ':'); if ($pos === false || ($pos2 !== false && $pos2 < $pos)) { $pos = $pos2; } if ($pos !== false) { $domain = substr($domain, 0, $pos); } // Handle scheme if ($sefConfig->sitemap_ssl) { $domain = 'https://'.$domain; } else { $domain = 'http://'.$domain; } // Adjust domain according to www handling if ($wwwHandle) { if ($sefConfig->wwwHandling != _COM_SEF_WWW_NONE) { if ($sefConfig->wwwHandling == _COM_SEF_WWW_USE_WWW) { if (strpos($domain, '://www.') === false) { $domain = str_replace('://', '://www.', $domain); } } else if ($sefConfig->wwwHandling == _COM_SEF_WWW_USE_NONWWW) { $domain = str_replace('://www.', '://', $domain); } } } // Add base $domain .= JURI::root(true); // Add slash if(substr($domain, -1) != '/') { $domain .= '/'; } return $domain; } protected function _createXmlFile($file) { // Check that the file is writable if (!file_exists($file)) { // Try to create the file $f = @fopen($file, 'w'); if ($f === false) { $this->setError(JText::_('COM_SEF_ERROR_CREATE_XML')); return false; } fclose($f); // Chmod the file, so it is writable JPath::setPermissions($file, '0666'); } if (!is_writable($file)) { $this->setError(JText::_('COM_SEF_ERROR_XML_NOT_WRITABLE')); return false; } return true; } function generateXml() { $sefConfig =& SEFConfig::getConfig(); // Whether multiple sitemaps for different domains are used $multiple = ($sefConfig->langEnable && $sefConfig->langPlacementJoomla == _COM_SEF_LANG_DOMAIN && $sefConfig->multipleSitemaps); // Prepare file(s) and headers if (!$multiple) { $file = JPATH_ROOT.'/'.$sefConfig->sitemap_filename.'.xml'; if (!$this->_createXmlFile($file)) { return false; } $text = ' '; } else { $langs = JLanguageHelper::getLanguages(); $texts = array(); $files = array(); foreach ($langs as $lang) { if (isset($sefConfig->multipleSitemapsFilenames[$lang->sef])) { $file = JPATH_ROOT.'/'.$sefConfig->multipleSitemapsFilenames[$lang->sef].'.xml'; } else { $file = JPATH_ROOT.'/sitemap_'.$lang->sef.'.xml'; } if (!$this->_createXmlFile($file)) { return false; } $files[$lang->sef] = $file; $texts[$lang->sef] = ' '; } } // Prepare default domain $domain = $this->prepareDomain(JURI::root(), true); // Prepare domains for languages $langDomains = array(); if ($sefConfig->langEnable && $sefConfig->langPlacementJoomla == _COM_SEF_LANG_DOMAIN) { foreach ($sefConfig->subDomainsJoomla as $lang => $host) { $langDomains[$lang] = $this->prepareDomain($host, false); } } // Get number of URLs $query = "SELECT `sefurl`, `origurl`, `sm_date`, `sm_frequency`, `sm_priority` FROM `#__sefurls` WHERE `sm_indexed` = '1' AND `origurl` != '' ORDER BY `sefurl`"; $total = $this->_getListCount($query); $batchSize = 100; $start = 0; // Process URLs in batches if ($total > 0) { while ($start < $total) { $urls = $this->_getList($query, $start, $batchSize); foreach ($urls as $url) { $url->sefurl = str_replace('&', '&', $url->sefurl); // Handle multilanguage domains $urlDomain = $domain; $urlLang = null; if ($sefConfig->langEnable && $sefConfig->langPlacementJoomla == _COM_SEF_LANG_DOMAIN) { $matches = array(); if (preg_match('/[?&]lang=([^&]+)/', $url->origurl, $matches)) { $urlLang = $matches[1]; if (isset($langDomains[$urlLang])) { $urlDomain = $langDomains[$urlLang]; } } } $urlText = " \n"; $urlText .= " {$urlDomain}{$url->sefurl}\n"; if ($sefConfig->sitemap_show_date) { if ($url->sm_date == '0000-00-00' || $url->sm_date == ''){ $url->sm_date = date('Y-m-d'); } $urlText .= " {$url->sm_date}\n"; } if ($sefConfig->sitemap_show_frequency) { if ($url->sm_frequency == '') { $url->sm_frequency = $sefConfig->sitemap_frequency; } $urlText .= " {$url->sm_frequency}\n"; } if ($sefConfig->sitemap_show_priority) { if ($url->sm_priority == '') { $url->sm_priority = $sefConfig->sitemap_priority; } $urlText .= " {$url->sm_priority}\n"; } $urlText .= " \n"; // Add to correct file if ($multiple) { if (!is_null($urlLang) && isset($texts[$urlLang])) { $texts[$urlLang] .= $urlText; } } else { $text .= $urlText; } } $start += $batchSize; } } // Write the file(s) if ($multiple) { foreach ($langs as $lang) { $texts[$lang->sef] .= ''; if (!JFile::write($files[$lang->sef], $texts[$lang->sef])) { $this->setError(JText::_('COM_SEF_ERROR_SAVE_XML')); return false; } } } else { $text .= ''; if (!JFile::write($file, $text)) { $this->setError(JText::_('COM_SEF_ERROR_SAVE_XML')); return false; } } // Unset the sitemap changed flag if ($sefConfig->sitemap_changed) { $sefConfig->sitemap_changed = false; $sefConfig->saveConfig(); } // Ping search engines if set to if ($sefConfig->sitemap_pingauto) { $this->pingGoogle(); //$this->pingYahoo(); $this->pingBing(); } return true; } protected function _pingUrl($urlPattern) { $sefConfig =& SEFConfig::getConfig(); if ($sefConfig->langEnable && $sefConfig->langPlacementJoomla == _COM_SEF_LANG_DOMAIN && $sefConfig->multipleSitemaps) { // Multiple sitemaps $langs = JLanguageHelper::getLanguages(); foreach ($langs as $lang) { $domain = $this->prepareDomain($sefConfig->subDomainsJoomla[$lang->sef], false); $file = $domain.$sefConfig->multipleSitemapsFilenames[$lang->sef].'.xml'; $url = str_replace('%s', urlencode($file), $urlPattern); $response = SEFTools::PostRequest($url, null, null, 'get'); if ($response->code != 200) { return false; } } } else { $domain = $this->prepareDomain(JURI::root(), true); $file = $domain.$sefConfig->sitemap_filename.'.xml'; $url = str_replace('%s', urlencode($file), $urlPattern); $response = SEFTools::PostRequest($url, null, null, 'get'); if ($response->code != 200) { return false; } } return true; } function pingGoogle() { if (!$this->_pingUrl('http://www.google.com/webmasters/tools/ping?sitemap=%s')) { JError::raiseWarning(100, JText::_('COM_SEF_COULD_NOT_PING').' '.JText::_('COM_SEF_GOOGLE')); return false; } else { JError::raiseNotice(100, JText::_('COM_SEF_GOOGLE').' '.JText::_('COM_SEF_PINGED')); return true; } } function pingYahoo() { $sefConfig = SEFConfig::getConfig(); $appid = trim($sefConfig->sitemap_yahooId); if ($appid == '') { JError::raiseWarning(100, JText::_('COM_SEF_YAHOO_ID_NOT_SET')); return false; } if (!$this->_pingUrl('http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid='.$appid.'&url=%s')) { JError::raiseWarning(100, JText::_('COM_SEF_COULD_NOT_PING').' '.JText::_('COM_SEF_YAHOO')); return false; } else { JError::raiseNotice(100, JText::_('COM_SEF_YAHOO').' '.JText::_('COM_SEF_PINGED')); return true; } } function pingBing() { if (!$this->_pingUrl('http://www.bing.com/webmaster/ping.aspx?siteMap=%s')) { JError::raiseWarning(100, JText::_('COM_SEF_COULD_NOT_PING').' '.JText::_('COM_SEF_BING')); return false; } else { JError::raiseNotice(100, JText::_('COM_SEF_BING').' '.JText::_('COM_SEF_PINGED')); return true; } } function pingServices() { $sefConfig =& SEFConfig::getConfig(); if (!is_array($sefConfig->sitemap_services) || count($sefConfig->sitemap_services) == 0) { return; } // Get domain $domain = JURI::root(); // Add slash after domain if (substr($domain, -1) != '/') { $domain .= '/'; } $file = $domain.$sefConfig->sitemap_filename.'.xml'; // Site name $config = &JFactory::getConfig(); $sitename = $config->get('sitename'); $data = "\r\n". " \r\n". " weblogUpdates.ping\r\n". " \r\n". " \r\n". " $sitename\r\n". " \r\n". " \r\n". " $file\r\n". " \r\n". " \r\n". " "; // loop through services and try to ping them foreach ($sefConfig->sitemap_services as $service) { $response = SEFTools::PostRequest($service, null, $data, 'post', 'Joomla! Ping/1.0'); if ($response->code != 200) { JError::raiseWarning(100, JText::_('COM_SEF_COULD_NOT_PING').' '.$service); continue; } // Parse the response $xml = @simplexml_load_string($response->content); if ($xml === false) { JError::raiseWarning(100, $service.' | '.JText::_('COM_SEF_COULD_NOT_PARSE_RESPONSE')); continue; } $m1 = $xml->params->param->value->struct->member[0]; $m2 = $xml->params->param->value->struct->member[1]; if (empty($m1) || empty($m2)) { JError::raiseWarning(100, $service.' | '.JText::_('COM_SEF_COULD_NOT_PARSE_RESPONSE')); continue; } if (empty($m1->value) || empty($m2->value)) { JError::raiseWarning(100, $service.' | '.JText::_('COM_SEF_COULD_NOT_PARSE_RESPONSE')); continue; } if (((string)($m1->name)) == 'flerror') { $err = (int)($m1->value->boolean); if (!empty($m2->value->string)) { $msg = (string)($m2->value->string); } else { $msg = (string)($m2->value); } } else { $err = (int)($m2->value->boolean); if (!empty($m2->value->string)) { $msg = (string)($m1->value->string); } else { $msg = (string)($m1->value); } } JError::raiseNotice(100, $service.' | '.$err.' - '.$msg); } } } ?> components/com_sef/sef.php000066600000003657150771655450011670 0ustar00authorise('core.manage', 'com_sef')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } // Load language $lang = JFactory::getLanguage(); $source = JPATH_ADMINISTRATOR . '/components/com_sef'; $lang->load("com_sef.sys", JPATH_ADMINISTRATOR, null, false, false) || $lang->load("com_sef.sys", $source, null, false, false) || $lang->load("com_sef.sys", JPATH_ADMINISTRATOR, $lang->getDefault(), false, false) || $lang->load("com_sef.sys", $source, $lang->getDefault(), false, false); // Load the CSS $document = JFactory::getDocument(); $document->addStyleSheet('components/com_sef/assets/css/default.css'); if (version_compare(JVERSION, '3.0', '>=')) { $document->addStyleSheet('components/com_sef/assets/css/joomla3.css'); } // Require the base classes require_once (JPATH_COMPONENT.'/controller.php'); require_once (JPATH_COMPONENT.'/model.php'); require_once (JPATH_COMPONENT.'/view.php'); require_once (JPATH_COMPONENT.'/classes/config.php'); require_once (JPATH_COMPONENT.'/classes/seftools.php'); // Require specific controller if requested if($controller = JRequest::getVar('controller')) { $path = JPATH_COMPONENT.'/controllers/'.$controller.'.php'; if( file_exists($path) ) { require_once($path); } else { $controller = ''; } } // Create the controller $classname = 'SEFController'.$controller; $controller = new $classname( ); // Perform the Request task $controller->execute( JRequest::getVar('task') ); // Redirect if set by the controller $controller->redirect(); ?>components/com_sef/plugin/extension/index.html000066600000000054150771655450015675 0ustar00components/com_sef/plugin/extension/joomsefinstall/index.html000066600000000054150771655450020726 0ustar00components/com_sef/plugin/extension/joomsefinstall/joomsefinstall.xml000066600000001204150771655450022502 0ustar00 Extension Install - ARTIO JoomSEF ARTIO s.r.o. 21. October 2011 ARTIO s.r.o. GNU/GPLv3 http://www.artio.net/license/gnu-general-public-license info@artio.net www.artio.net 4.1.1 PLG_JOOMSEFINSTALL_XML_DESCRIPTION joomsefinstall.php components/com_sef/plugin/extension/joomsefinstall/joomsefinstall.php000066600000004577150771655450022511 0ustar00_processUpdateSites($installer->manifest); } function onExtensionAfterUpdate($installer,$eid) { $this->_processUpdateSites($installer->manifest); } private function _processUpdateSites($xml) { if (!is_object($xml)) { return; } $db=JFactory::getDBO(); $free=false; $freecnt=array(); $pay=false; if((string)$xml->name=='com_sef' || (string)$xml['type']=='sef_ext') { if((string)$xml->name=='com_sef') { $name='com_joomsef'; } else { if (count($xml->files->children())) { foreach ($xml->files->children() as $file) { if ((string)$file->attributes()->sef_ext) { $element = (string)$file->attributes()->sef_ext; if(substr($element,0,13)!='ext_joomsef4_') { $element='ext_joomsef4_'.$element; } break; } } } $name=$element; } $query=$db->getQuery(true); $query->select('update_site_id, location')->from('#__update_sites')->where('name='.$db->quote($name)); $db->setQuery($query); $updates=$db->loadObjectList(); if(count($updates)>0) { for($i=0;$ilocation==(string)$xml->updateservers->server) { $free=true; $freecnt[]=$updates[$i]->update_site_id; } if($updates[$i]->location!=(string)$xml->updateservers->server) { $pay=true; } } } if($free==true && $pay==true) { $query=$db->getQuery(true); $query->delete('#__update_sites')->where('location='.$db->quote((string)$xml->updateservers->server)); $db->setQUery($query); $db->query(); } else if(count($freecnt)>1) { array_shift($freecnt); $query=$db->getQuery($query); $query->delete('#__update_sites')->where('update_site_id IN('.implode(",",$freecnt).')'); $db->setQuery($query); $db->query(); } } } } ?>components/com_sef/plugin/system/joomsefgoogle/index.html000066600000000054150771655450020044 0ustar00components/com_sef/plugin/system/joomsefgoogle/joomsefgoogle.xml000066600000001221150771655450021425 0ustar00 System - ARTIO JoomSEF Google Analytics ARTIO s.r.o. 31. October 2011 ARTIO s.r.o. GNU/GPLv3 http://www.artio.net/license/gnu-general-public-license info@artio.net www.artio.net 4.0.0 Plugin which add Google Adsense Code to Pages. joomsefgoogle.php components/com_sef/plugin/system/joomsefgoogle/joomsefgoogle.php000066600000004331150771655450021421 0ustar00isAdmin()) { return; } if(JFactory::getApplication()->getCfg('sef')==0) { return; } if(JFactory::getURI()->getVar('tmpl')=='component') { return; } $config=SEFConfig::getConfig(); if (!$config->enabled) { return; } if ($config->google_enable == 0 || !$config->google_id) { return; } if (JRequest::getInt('google_analytics_exclude', 0, 'cookie') == 1) { return; } $ips_exclude = explode("\r\n", $config->google_exclude_ip); if (in_array(IPAddressHelper::getip(), $ips_exclude)) { return; } $groups = null; $user = JFactory::getUser(); if ($user) { $groups = $user->get('groups'); } if (is_array($groups)) { foreach ($groups as $group) { if (in_array($group, $config->google_exclude_level)) { return; } } } $script = " (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); ga('create', '".$config->google_id."', 'auto'); ga('send', 'pageview'); "; JFactory::getDocument()->addScriptDeclaration($script); } } components/com_sef/plugin/system/index.html000066600000000054150771655450015205 0ustar00components/com_sef/plugin/system/joomsef/joomsef.php000066600000050167150771655450017037 0ustar00_plugin = JPluginHelper::getPlugin('system', 'joomsef'); $this->_params = new JRegistry($this->_plugin->params); if($this->_isEnabled()) { require_once( JPATH_ROOT.'/components/com_sef/joomsef.php' ); JoomSEF::getLanguage(JFactory::getURI()); } } function onAfterInitialise() { $sefConfig = SEFConfig::getConfig(); $mainframe = JFactory::getApplication(); // Enable menu associations if set to $joomlaVersion = new JVersion(); if ($joomlaVersion->isCompatible('3.2')) { // 3.2 if ($sefConfig->langMenuAssociations) { JLoader::register('JLanguageMultilang', JPATH_ROOT.'/administrator/components/com_sef/libs/cms/language/multilang.php'); JLoader::register('JLanguageAssociations', JPATH_ROOT.'/administrator/components/com_sef/libs/cms/language/associations.php'); } } else if ($joomlaVersion->isCompatible('3.0')) { // 3.0 $mainframe->item_associations = $sefConfig->langMenuAssociations ? 1 : 0; } else { // 2.5 $mainframe->set('menu_associations', $sefConfig->langMenuAssociations ? 1 : 0); } // Register installer and updater adapters in admin area $this->registerAdapters(); // Check if JoomSEF should be run if (!self::_isEnabled()) { return true; } // Store the router for later use $router = $mainframe->getRouter(); JoomSEF::set('sef.global.jrouter', $router); // Load JoomSEF language file $jLang = JFactory::getLanguage(); $jLang->load('com_sef', JPATH_ADMINISTRATOR); require_once(JPATH_ROOT.'/components/com_sef/sef.router.php'); $jsRouter = new JRouterJoomsef(); $router->attachParseRule(array($jsRouter, 'parseSef')); $router->attachBuildRule(array($jsRouter, 'buildSef')); // Disable global "Add suffix to URLs" before parsing and store current config $config = JFactory::getConfig(); $oldSuffix = $config->get('sef_suffix', 0); $config->set('sef_suffix', 0); JoomSEF::set('sef.global.orig_sef_suffix', $oldSuffix); // Get all configured subdomains $subdomains = SEFTools::getAllSubdomains(); // Redirect only when there's no POST variables if (($sefConfig->wwwHandling != _COM_SEF_WWW_NONE) && empty($_POST)) { // Handle www and non-www domain $uri = JURI::getInstance(); $host = $uri->getHost(); $redirect = false; // Check if host is only IP $isIP = preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\z/', $host); if ($sefConfig->wwwHandling == _COM_SEF_WWW_USE_WWW && !$isIP && strpos($host, 'www.') !== 0) { // Check if host starts with one of our subdomains if (isset($subdomains['*']) && (count($subdomains['*']) > 0)) { $parts = explode('.', $host); $domain = $parts[0]; $found = false; foreach ($subdomains['*'] as $sub) { if ($domain == $sub->subdomain) { $found = true; break; } } if (!$found) { // Redirect to www form $redirect = true; $uri->setHost('www.'.$host); } } else { // Redirect to www form $redirect = true; $uri->setHost('www.'.$host); } } else if ($sefConfig->wwwHandling == _COM_SEF_WWW_USE_NONWWW && strpos($host, 'www.') === 0) { // host must not begin with www. $redirect = true; $uri->setHost(substr($host, 4)); } // Redirect if needed if ($redirect) { $url = $uri->toString(); SEFTools::redirect($url, true); jexit(); } } return true; } function registerAdapters() { $app = JFactory::getApplication(); // Register adapters only in admin area if (!$app->isAdmin()) { return; } // Include adapter files require_once(JPATH_ADMINISTRATOR.'/components/com_sef/adapters/sef_ext.php'); require_once(JPATH_ADMINISTRATOR.'/components/com_sef/adapters/sef_update.php'); // Set installer adapter $installer = JInstaller::getInstance(); $adapterSefExt = new JInstallerAdapterSef_ext($installer); $installer->setAdapter('sef_ext', $adapterSefExt); // Set updater adapter $updater = JUpdater::getInstance(); $db = $updater->getDBO(); $adapterSefUpdate = new JUpdaterSEF_Update($updater, $db); $updater->setAdapter('sef_update', $adapterSefUpdate); } function onAfterDispatch() { $mainframe = JFactory::getApplication(); if ($mainframe->isAdmin()) { // Add code to prevent separators in admin menu from // creating new URLs and generating 404's $doc = JFactory::getDocument(); if ($doc->getType() == 'html') { $doc->addStyleDeclaration('.icon-16-separator { background: none !important; background-image: none !important; }'); } } // Check if JoomSEF should be run if (!self::_isEnabled() || !class_exists('JoomSEF') || !JoomSEF::enabled($this)) { return true; } // Check page base href value $this->_checkBaseHref(); // Remove Joomla generated canonical links if set to $sefConfig = SEFConfig::getConfig(); if ($sefConfig->canonicalsRemove) { $this->_removeCanonicals(); } // Do not run plugin if metadata generation is disabled if ($sefConfig->enable_metadata > 0) { // generate page title $this->_checkSEFTitle(); // generate page metadata $this->_generateMeta(); } // Fix canonical links if set to if ($sefConfig->canonicalsFix) { $this->_fixCanonicals(); } return true; } function onAfterRender() { // Check if JoomSEF should be run if (!self::_isEnabled() || !class_exists('JoomSEF') || !JoomSEF::enabled($this)) { return; } // Change the index.php links to / $sefConfig = SEFConfig::getConfig(); if ($sefConfig->fixIndexPhp) { $this->_fixIndexLinks(); } //$this->_fixSubDomains(); } function _isEnabled() { // Do not run plugin in administration area $mainframe = JFactory::getApplication(); if ($mainframe->isAdmin()) { return false; } // Do not run plugin if SEF is disabled $config = JFactory::getConfig(); if (!$config->get('sef')) { return false; } // Check if JoomSEF is enabled $sefConfig = SEFConfig::getConfig(); if (!$sefConfig->enabled) { return false; } // Check if JoomSEF plugin is enabled if (!JPluginHelper::isEnabled('system', 'joomsef')) { return false; } // Check format // // 22.3.2012, dajo: // Removed, JoomSEF should be run, but such URLs shouldn't be // SEFed in the JoomSEF::build() function /* $format = JRequest::getVar('format'); $tmpl = JRequest::getVar('tmpl'); if ($format == 'raw' || $format == 'json' || $format == 'xml' || $tmpl == 'raw') { return false; } */ return true; } /** * Generate metadata */ function _generateMeta() { $mainframe = JFactory::getApplication(); $document = JFactory::getDocument(); $sefConfig = SEFConfig::getConfig(); $rewriteKey = $sefConfig->rewrite_keywords; $rewriteDesc = $sefConfig->rewrite_description; $metadesc = str_replace('"', '"', JoomSEF::get('sef.meta.desc')); $metakey = str_replace('"', '"', JoomSEF::get('sef.meta.key')); $metalang = str_replace('"', '"', JoomSEF::get('sef.meta.lang')); $metarobots = str_replace('"', '"', JoomSEF::get('sef.meta.robots')); $metagoogle = str_replace('"', '"', JoomSEF::get('sef.meta.google')); $canonicallink = str_replace('"', '"', JoomSEF::get('sef.link.canonical')); $metacustom = JoomSEF::get('sef.meta.custom'); $generator = str_replace('"', '"', $sefConfig->tag_generator); $googlekey = str_replace('"', '"', $sefConfig->tag_googlekey); $livekey = str_replace('"', '"', $sefConfig->tag_livekey); $yahookey = str_replace('"', '"', $sefConfig->tag_yahookey); // Global custom meta tags if (is_array($sefConfig->customMetaTags)) { foreach($sefConfig->customMetaTags as $name => $content) { $content = str_replace('"', '"', $content); $document->setMetaData($name, $content); } } // description metatag if (!empty($metadesc)) { // get original description $oldDesc = $document->getDescription(); // override by JoomSEF desc if ($rewriteDesc == _COM_SEF_META_PR_JOOMSEF || $oldDesc == '') { $document->setDescription($metadesc); // or join both } elseif ($rewriteDesc == _COM_SEF_META_PR_JOIN && $oldDesc != '') { $document->setDescription($metadesc . ', ' . $oldDesc); } // otherwise leave intact } // keywords metatag if (!empty($metakey)) { // get original keywords $oldKey = $document->getMetaData('keywords'); // override by JoomSEF keys if ($rewriteKey == _COM_SEF_META_PR_JOOMSEF || $oldKey == '') { $document->setMetaData('keywords', $metakey); // or join both } elseif ($rewriteKey == _COM_SEF_META_PR_JOIN && $oldKey != '') { $document->setMetaData('keywords', $metakey . ', ' . $oldKey); } // otherwise leave intact } if (!empty($metalang)) $document->setMetaData('lang', $metalang); if (!empty($metarobots)) $document->setMetaData('robots', $metarobots); if (!empty($metagoogle)) $document->setMetaData('google', $metagoogle); if (!empty($generator)) $document->setGenerator($generator); if (!empty($googlekey)) $document->setMetaData('google-site-verification', $googlekey); if (!empty($livekey)) $document->setMetaData('msvalidate.01', $livekey); if (!empty($yahookey)) $document->setMetaData('y_key', $yahookey); // URL custom meta tags if (is_array($metacustom)) { foreach ($metacustom as $name => $content) { $content = str_replace('"', '"', $content); $document->setMetaData($name, $content); } } if (method_exists($document, 'addHeadLink')) { if (!empty($canonicallink)) { // Always remove previous canonical links if adding our own $this->_removeCanonicals(); // Add our own canonical link $document->addHeadLink($canonicallink, 'canonical'); } } } /** * Removes all the canonical links currently set */ function _removeCanonicals() { // Handle canonicals only in HTML document $doc = JFactory::getDocument(); if ($doc->getType() != 'html') { return; } // Check if there are any links if (!isset($doc->_links) || !is_array($doc->_links)) { return; } // Remove canonical links foreach ($doc->_links as $url => $link) { if ($link['relation'] == 'canonical') { unset($doc->_links[$url]); } } } /** * Fixes duplicate domain in canonical links */ function _fixCanonicals() { // Handle canonicals only in HTML document $doc = JFactory::getDocument(); if ($doc->getType() != 'html') { return; } // Check if there are any links if (!isset($doc->_links) || !is_array($doc->_links)) { return; } // Fix canonical links foreach ($doc->_links as $url => $link) { if ($link['relation'] != 'canonical') continue; // Fix canonical link $fixed = preg_replace('|^https?://.*(https?://)|i', '$1', $url); // Always unset and set the link again, otherwise we'd change the ordering unset($doc->_links[$url]); $doc->_links[$fixed] = $link; } } /** * Check page title. */ function _checkSEFTitle() { $mainframe = JFactory::getApplication(); $document = JFactory::getDocument(); $config = JFactory::getConfig(); $sefConfig = SEFConfig::getConfig(); $sitename = $config->get('sitename'); $preferTitle = $sefConfig->prefer_joomsef_title; $sitenameSep = ' '.trim($sefConfig->sitename_sep).' '; $preventDupl = $sefConfig->prevent_dupl; $useSitename = JoomSEF::get('sef.meta.showsitename', _COM_SEF_SITENAME_GLOBAL); if ($useSitename == _COM_SEF_SITENAME_GLOBAL) { $useSitename = $sefConfig->use_sitename; } if ($sitenameSep == ' ') $sitenameSep = ' '; // Page title $pageTitle = JoomSEF::get('sef.meta.title'); if (empty($pageTitle)) { $pageTitle = $document->getTitle(); // Dave: replaced regular expression as it was causing problems // with site names like [ index-i.cz ] with str_replace // Dave: 3.2.9 fix - added check for !empty($sitename) - was causing // problems with empty site names /*$pageSep = '( - |'.$sitenameSep.')'; if (preg_match('/('.$GLOBALS['mosConfig_sitename'].$pageSep.')?(.*)?/', $pageTitle, $matches) > 0) { $pageTitle = strtr($pageTitle, array($matches[1] => '')); }*/ if (!empty($sitename)) { $pageTitle = str_replace(array($sitename.' - ', ' - '.$sitename, $sitename.$sitenameSep, $sitenameSep.$sitename), '', $pageTitle); } } if ($preferTitle) { $pageTitle = trim($pageTitle); // Prevent name duplicity if set to if ($preventDupl && strcmp($pageTitle, trim($sitename)) == 0) { $pageTitle = ''; } if (empty($pageTitle)) $sitenameSep = ''; if ($useSitename == _COM_SEF_SITENAME_BEFORE && $sitename) { $pageTitle = $sitename . $sitenameSep . $pageTitle; } elseif ($useSitename == _COM_SEF_SITENAME_AFTER && $sitename) { $pageTitle .= $sitenameSep . $sitename; } // set page title and (optionally) meta title tag if ($pageTitle) { // Joomla escapes the title automatically $document->setTitle($pageTitle); } } } function _checkBaseHref() { $sefConfig = SEFConfig::getConfig(); $checkBaseHref = $sefConfig->check_base_href; // now we can set base href $document = JFactory::getDocument(); if ($checkBaseHref == _COM_SEF_BASE_HOMEPAGE) { $uri = JURI::getInstance(); $curUri = clone($uri); $domain = JoomSEF::get('real_domain'); if ($domain) { $curUri->setHost($domain); } // dajo 10.9.2012: Make sure base ends with a slash $base = $curUri->toString(array('scheme', 'host', 'port')).JURI::base(true); $base = rtrim($base, '/').'/'; $document->setBase($base); } elseif ($checkBaseHref == _COM_SEF_BASE_CURRENT) { $uri = JURI::getInstance(); $curUri = clone($uri); $domain = JoomSEF::get('real_domain'); if ($domain) { $curUri->setHost($domain); } $document->setBase(htmlspecialchars($curUri->toString(array('scheme', 'host', 'port', 'path')))); } elseif ($checkBaseHref == _COM_SEF_BASE_NONE) { $document->setBase(''); } else return; } function _fixIndexLinks() { // Check the document type $document = JFactory::getDocument(); if ($document->getType() != 'html') { return; } // Get the response body $body = JResponse::getBody(); // Get the root URL $url = JURI::root(); if (substr($url, -1) != '/') { $url .= '/'; } // Replace the index.php links in "]*)href="/?index\\.php"|', ']*)href="'.$url.'index\\.php"|', ']*)action="/?index\\.php"|', ']*)action="'.$url.'index\\.php"|', 'getType() != 'html') { return; } // Get the response body $body = JResponse::getBody(); $url = JURI::root(); if (substr($url, -1) != '/') { $url .= '/'; } //echo JFactory::getUri()->getHost(); $body = preg_replace_callback('|<(a)(\\s*[^>]*)href="([/\-\.a-z0-9]*)"(\\s*[^>]*)>|', array($this,"_replaceLink"), $body); $body = preg_replace_callback('|<(form)(\\s*[^>]*)action="([/\-\.a-z0-9]*)"(\\s*[^>]*)>|', array($this,"_replaceLink"), $body); JResponse::setBody($body); } private function _replaceLink($matches) { $host=JFactory::getUri()->getHost(); $db=JFactory::getDBO(); $query=$db->getQuery(true); $query->select('Itemid')->from('#__sefurls')->where('sefurl='.$db->quote(ltrim(str_replace(JFactory::getUri()->base(true),"",$matches[3]),"/"))); $db->setQuery($query); $Itemid=$db->loadResult(); //echo $matches[3]."\t".$Itemid."
    "; if(strlen($Itemid)) { $query=$db->getQuery(true); $query->select('subdomain')->from('#__sef_subdomains')->where('Itemid='.$Itemid); $db->setQuery($query); $subdomain=$db->loadResult(); if(strlen($subdomain)) { $host=$subdomain.".".$host; } } switch($matches[1]) { case 'a': return ''; break; case 'form': return ''; break; } } } components/com_sef/plugin/system/joomsef/joomsef.xml000066600000001141150771655450017034 0ustar00 System - ARTIO JoomSEF ARTIO s.r.o. 2. November 2011 ARTIO s.r.o. GNU/GPLv3 http://www.artio.net/license/gnu-general-public-license info@artio.net www.artio.net 4.0.1 PLG_JOOMSEF_XML_DESCRIPTION joomsef.php components/com_sef/plugin/system/joomsef/index.html000066600000000054150771655450016647 0ustar00components/com_sef/plugin/system/joomseflang/joomseflang.php000066600000001167150771655450020537 0ustar00isAdmin()==false) { return true; } JFactory::getLanguage()->load('com_sef',JPATH_ADMINISTRATOR); } } ?>components/com_sef/plugin/system/joomseflang/index.html000066600000000054150771655450017511 0ustar00components/com_sef/plugin/system/joomseflang/joomseflang.xml000066600000001164150771655450020545 0ustar00 System Language - ARTIO JoomSEF ARTIO s.r.o. 1. August 2011 ARTIO s.r.o. GNU/GPLv3 http://www.artio.net/license/gnu-general-public-license info@artio.net www.artio.net 4.1.0 PLG_JOOMSEFLANG_XML_DESCRIPTION joomseflang.php components/com_sef/plugin/system/joomsefurl/index.html000066600000000054150771655450017372 0ustar00components/com_sef/plugin/system/joomsefurl/joomsefurl.php000066600000003123150771655450020273 0ustar00isAdmin()) { return; } if(JFactory::getApplication()->getCfg('sef')==0) { return; } if (JRequest::getVar('tmpl') == 'component') { return; } if (JRequest::getVar('format', 'html') != 'html') { return; } $body=JResponse::getBody(); $doc=new DomDocument("1.0"); $doc->loadHTML($body); $xpath=new DomXPath($doc); $hrefs=$xpath->query("//a"); foreach($hrefs as $href) { $link=$href->getAttribute('href'); if(JFactory::getURI()->isInternal($link)==false) { continue; } $link=substr($link,1); if($this->params->get('raw')) { $origurl=JoomSEF::_createUri(new JURI($link)); } else { $origurl=JoomSEF::getNonSEFURL($link); } if(strlen($origurl)) { $href->setAttribute('class','link_tip'); $href->setAttribute('title',$origurl); } } $body=$doc->saveHTML(); JResponse::setBody($body); } } ?>components/com_sef/plugin/system/joomsefurl/joomsefurl.xml000066600000001747150771655450020316 0ustar00 System - ARTIO JoomSEFURL ARTIO s.r.o. 29. August 2010 ARTIO s.r.o. GNU/GPLv3 http://www.artio.net/license/gnu-general-public-license info@artio.net www.artio.net 4.0.0 Plugin which shows NonSEF URL tooltip. Can be used for simplify JoomSEF plugin development and detecting errors in badly created URLs. joomsefurl.php
    components/com_sef/plugin/index.html000066600000000054150771655450013661 0ustar00components/com_sef/plugin/content/index.html000066600000000054150771655450015333 0ustar00components/com_sef/plugin/content/joomsef/joomsef.php000066600000002066150771655450017160 0ustar00_checkURLs($option,$item); } } function onContentAfterDelete($context,$item) { $context=explode(".",$context); $option=$context[0]; JoomSEF::_removeURL($option,$item); } } ?>components/com_sef/plugin/content/joomsef/joomsef.xml000066600000001150150771655450017162 0ustar00 Content - ARTIO JoomSEF ARTIO s.r.o. 12. June 2010 ARTIO s.r.o. GNU/GPLv3 http://www.artio.net/license/gnu-general-public-license info@artio.net www.artio.net 4.0.0 PLG_CONTENT_JOOMSEF_XML_DESCRIPTION joomsef.php components/com_sef/plugin/content/joomsef/index.html000066600000000054150771655450016775 0ustar00components/com_sef/libs/cacert.pem000066600000654337150771655450013306 0ustar00## ## ca-bundle.crt -- Bundle of CA Root Certificates ## ## Certificate data from Mozilla as of: Sun Feb 19 04:03:37 2012 ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates ## file (certdata.txt). This file can be found in the mozilla source tree: ## http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1 ## ## It contains the certificates in PEM format and therefore ## can be directly used with curl / libcurl / php_curl, or with ## an Apache+mod_ssl webserver for SSL client authentication. ## Just configure this file as the SSLCACertificateFile. ## # ***** BEGIN LICENSE BLOCK ***** # Version: MPL 1.1/GPL 2.0/LGPL 2.1 # # The contents of this file are subject to the Mozilla Public License Version # 1.1 (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # http://www.mozilla.org/MPL/ # # Software distributed under the License is distributed on an "AS IS" basis, # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License # for the specific language governing rights and limitations under the # License. # # The Original Code is the Netscape security libraries. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1994-2000 # the Initial Developer. All Rights Reserved. # # Contributor(s): # # Alternatively, the contents of this file may be used under the terms of # either the GNU General Public License Version 2 or later (the "GPL"), or # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), # in which case the provisions of the GPL or the LGPL are applicable instead # of those above. If you wish to allow use of your version of this file only # under the terms of either the GPL or the LGPL, and not to allow others to # use your version of this file under the terms of the MPL, indicate your # decision by deleting the provisions above and replace them with the notice # and other provisions required by the GPL or the LGPL. If you do not delete # the provisions above, a recipient may use your version of this file under # the terms of any one of the MPL, the GPL or the LGPL. # # ***** END LICENSE BLOCK ***** # @(#) $RCSfile: certdata.txt,v $ $Revision: 1.82 $ $Date: 2012/02/18 21:41:46 $ GTE CyberTrust Global Root ========================== -----BEGIN CERTIFICATE----- MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg Q29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEG A1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEz MjM1OTAwWjB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQL Ex5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0 IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4u sJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcql HHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8FLztimQID AQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMW M4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OF NMQkpw0PlZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ -----END CERTIFICATE----- Thawte Server CA ================ -----BEGIN CERTIFICATE----- MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UE AxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5j b20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNV BAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29u c3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcG A1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0 ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl /Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg7 1CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzAR MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9J GubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZ GCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc= -----END CERTIFICATE----- Thawte Premium Server CA ======================== -----BEGIN CERTIFICATE----- MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2 aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2 aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/ qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf 8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t UCemDaYj+bvLpgcUQg== -----END CERTIFICATE----- Equifax Secure CA ================= -----BEGIN CERTIFICATE----- MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW 8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961 zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95 70+sB3c4 -----END CERTIFICATE----- Digital Signature Trust Co. Global CA 1 ======================================= -----BEGIN CERTIFICATE----- MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMTAeFw05ODEy MTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUA A4GLADCBhwKBgQCgbIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJE NySZj9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlVSn5JTe2i o74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0 dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw IoAPMTk5ODEyMTAxODEwMjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQY MBaAFGp5fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i+DAM BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB ACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lNQseSJqBcNJo4cvj9axY+IO6CizEq kzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4 RbyhkwS7hp86W0N6w4pl -----END CERTIFICATE----- Digital Signature Trust Co. Global CA 3 ======================================= -----BEGIN CERTIFICATE----- MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMjAeFw05ODEy MDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUA A4GLADCBhwKBgQC/k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGOD VvsoLeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3oTQPMx7JS xhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0 dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw IoAPMTk5ODEyMDkxOTE3MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQY MBaAFB6CTShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5WzAM BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB AEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHRxdf0CiUPPXiBng+xZ8SQTGPdXqfi up/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVLB3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1 mPnHfxsb1gYgAlihw6ID -----END CERTIFICATE----- Verisign Class 3 Public Primary Certification Authority ======================================================= -----BEGIN CERTIFICATE----- MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf Tqj/ZA1k -----END CERTIFICATE----- Verisign Class 3 Public Primary Certification Authority - G2 ============================================================ -----BEGIN CERTIFICATE----- MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71 lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT 1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9 -----END CERTIFICATE----- GlobalSign Root CA ================== -----BEGIN CERTIFICATE----- MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== -----END CERTIFICATE----- GlobalSign Root CA - R2 ======================= -----BEGIN CERTIFICATE----- MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp 9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu 01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== -----END CERTIFICATE----- ValiCert Class 1 VA =================== -----BEGIN CERTIFICATE----- MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP Orf1LXLI -----END CERTIFICATE----- ValiCert Class 2 VA =================== -----BEGIN CERTIFICATE----- MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8 W9ViH0Pd -----END CERTIFICATE----- RSA Root Certificate 1 ====================== -----BEGIN CERTIFICATE----- MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw MjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMg UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA A4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td 3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89H BFx1cQqYJJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs 3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0WuPIqpsHEzXcjF V9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/APhmcGcwTTYJBtYze4D1gCCAPRX5r on+jjBXu -----END CERTIFICATE----- Verisign Class 3 Public Primary Certification Authority - G3 ============================================================ -----BEGIN CERTIFICATE----- MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1 EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj 055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0 xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== -----END CERTIFICATE----- Verisign Class 4 Public Primary Certification Authority - G3 ============================================================ -----BEGIN CERTIFICATE----- MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM 8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== -----END CERTIFICATE----- Entrust.net Secure Server CA ============================ -----BEGIN CERTIFICATE----- MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMCVVMxFDASBgNV BAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkg cmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRl ZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhv cml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIG A1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBi eSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1p dGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0 aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQ aO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5 gXpa0zf3wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcw ggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHYpIHVMIHSMQsw CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5l dC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkw NTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0Bow HQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyN Ewr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9 n9cd2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= -----END CERTIFICATE----- Entrust.net Premium 2048 Secure Server CA ========================================= -----BEGIN CERTIFICATE----- MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx NzUwNTFaFw0xOTEyMjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo3QwcjARBglghkgBhvhC AQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGAvtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdER gL7YibkIozH5oSQJFrlwMB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0B AQUFAAOCAQEAWUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQh7A6tcOdBTcS o8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18f3v/rxzP5tsHrV7bhZ3QKw0z 2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfNB/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjX OP/swNlQ8C5LWK5Gb9Auw2DaclVyvUxFnmG6v4SBkgPR0ml8xQ== -----END CERTIFICATE----- Baltimore CyberTrust Root ========================= -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE----- Equifax Secure Global eBusiness CA ================================== -----BEGIN CERTIFICATE----- MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV -----END CERTIFICATE----- Equifax Secure eBusiness CA 1 ============================= -----BEGIN CERTIFICATE----- MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ 1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5 lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+ KpYrtWKmpj29f5JZzVoqgrI3eQ== -----END CERTIFICATE----- Equifax Secure eBusiness CA 2 ============================= -----BEGIN CERTIFICATE----- MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEXMBUGA1UE ChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0y MB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoT DkVxdWlmYXggU2VjdXJlMSYwJAYDVQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCB nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn 2Z0GvxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/BPO3QSQ5 BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0CAwEAAaOCAQkwggEFMHAG A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUx JjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoG A1UdEAQTMBGBDzIwMTkwNjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9e uSBIplBqy/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQFMAMB Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAAyGgq3oThr1 jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia 78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUm V+GRMOrN -----END CERTIFICATE----- AddTrust Low-Value Services Root ================================ -----BEGIN CERTIFICATE----- MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6 54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1 Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= -----END CERTIFICATE----- AddTrust External Root ====================== -----BEGIN CERTIFICATE----- MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 +iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy 2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= -----END CERTIFICATE----- AddTrust Public Services Root ============================= -----BEGIN CERTIFICATE----- MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB /zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4 JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL +YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9 Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H EufOX1362KqxMy3ZdvJOOjMMK7MtkAY= -----END CERTIFICATE----- AddTrust Qualified Certificates Root ==================================== -----BEGIN CERTIFICATE----- MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG 9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx 64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3 KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/ BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE= -----END CERTIFICATE----- Entrust Root Certification Authority ==================================== -----BEGIN CERTIFICATE----- MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 -----END CERTIFICATE----- RSA Security 2048 v3 ==================== -----BEGIN CERTIFICATE----- MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7 Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP +Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/ MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj 0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395 nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA pKnXwiJPZ9d37CAFYd4= -----END CERTIFICATE----- GeoTrust Global CA ================== -----BEGIN CERTIFICATE----- MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet 8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4 d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2 mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm Mw== -----END CERTIFICATE----- GeoTrust Global CA 2 ==================== -----BEGIN CERTIFICATE----- MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/ NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7 srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF H4z1Ir+rzoPz4iIprn2DQKi6bA== -----END CERTIFICATE----- GeoTrust Universal CA ===================== -----BEGIN CERTIFICATE----- MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1 MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs 7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d 8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08 ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0 XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2 qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2 DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI P/rmMuGNG2+k5o7Y+SlIis5z/iw= -----END CERTIFICATE----- GeoTrust Universal CA 2 ======================= -----BEGIN CERTIFICATE----- MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0 MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0 DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17 j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2 WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP 20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG 8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2 +/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ 4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+ mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS -----END CERTIFICATE----- America Online Root Certification Authority 1 ============================================= -----BEGIN CERTIFICATE----- MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp Y2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkG A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CG v2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44z DyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145LcxVR5lu9Rh sCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP 8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0T AQH/BAUwAwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Z o/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQB8itEf GDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkFZu90821fnZmv9ov761KyBZiibyrF VL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft 3OJvx8Fi8eNy1gTIdGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7 -----END CERTIFICATE----- America Online Root Certification Authority 2 ============================================= -----BEGIN CERTIFICATE----- MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp Y2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkG A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQAD ggIPADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC206B89en fHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8 f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2JxhP7JsowtS013wMPgwr38oE18aO6lhO qKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JN RvCAOVIyD+OEsnpD8l7eXz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0 gBe4lL8BPeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67Xnfn 6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEqZ8A9W6Wa6897Gqid FEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZo2C7HK2JNDJiuEMhBnIMoVxtRsX6 Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnj B453cMor9H124HhnAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3Op aaEg5+31IqEjFNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmnxPBUlgtk87FY T15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2LHo1YGwRgJfMqZJS5ivmae2p +DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXg JXUjhx5c3LqdsKyzadsXg8n33gy8CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//Zoy zH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgO ZtMADjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh 1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUXOm/9riW99XJZZLF0Kjhf GEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPbAZO1XB4Y3WRayhgoPmMEEf0cjQAPuDff Z4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQlZvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuP cX/9XhmgD0uRuMRUvAawRY8mkaKO/qk= -----END CERTIFICATE----- Visa eCommerce Root =================== -----BEGIN CERTIFICATE----- MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2 WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0 TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI /k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt 398znM/jra6O1I7mT1GvFpLgXPYHDw== -----END CERTIFICATE----- Certum Root CA ============== -----BEGIN CERTIFICATE----- MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ 89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+ GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/ 0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw== -----END CERTIFICATE----- Comodo AAA Services root ======================== -----BEGIN CERTIFICATE----- MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm 7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z 8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C 12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== -----END CERTIFICATE----- Comodo Secure Services root =========================== -----BEGIN CERTIFICATE----- MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP 9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm 4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H RR3B7Hzs/Sk= -----END CERTIFICATE----- Comodo Trusted Services root ============================ -----BEGIN CERTIFICATE----- MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7 3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y /9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6 juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB /zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O 9y5Xt5hwXsjEeLBi -----END CERTIFICATE----- QuoVadis Root CA ================ -----BEGIN CERTIFICATE----- MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7 MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0 aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6 tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi 5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi 5nrQNiOKSnQ2+Q== -----END CERTIFICATE----- QuoVadis Root CA 2 ================== -----BEGIN CERTIFICATE----- MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6 XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt 66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3 UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK +JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1 WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II 4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8 VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u -----END CERTIFICATE----- QuoVadis Root CA 3 ================== -----BEGIN CERTIFICATE----- MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8 nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4 ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2 Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp 8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= -----END CERTIFICATE----- Security Communication Root CA ============================== -----BEGIN CERTIFICATE----- MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw 8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX 5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g 0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ 6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi FL39vmwLAw== -----END CERTIFICATE----- Sonera Class 2 Root CA ====================== -----BEGIN CERTIFICATE----- MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3 /Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt 0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH llpwrN9M -----END CERTIFICATE----- Staat der Nederlanden Root CA ============================= -----BEGIN CERTIFICATE----- MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6 22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== -----END CERTIFICATE----- TDC Internet Root CA ==================== -----BEGIN CERTIFICATE----- MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJESzEVMBMGA1UE ChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTAeFw0wMTA0MDUx NjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJu ZXQxHTAbBgNVBAsTFFREQyBJbnRlcm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEAxLhAvJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20j xsNuZp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a0vnRrEvL znWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc14izbSysseLlJ28TQx5yc 5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGNeGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6 otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcDR0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZI AYb4QgEBBAQDAgAHMGUGA1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMM VERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxMEQ1JM MTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3WjALBgNVHQ8EBAMC AQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAwHQYDVR0OBBYEFGxkAcf9hW2syNqe UAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0G CSqGSIb3DQEBBQUAA4IBAQBOQ8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540m gwV5dOy0uaOXwTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+ 2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm899qNLPg7kbWzb O0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0jUNAE4z9mQNUecYu6oah9jrU Cbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38aQNiuJkFBT1reBK9sG9l -----END CERTIFICATE----- TDC OCES Root CA ================ -----BEGIN CERTIFICATE----- MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJESzEMMAoGA1UE ChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEwODM5MzBaFw0zNzAyMTEwOTA5 MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNUREMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIB IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuH nEz9pPPEXyG9VhDr2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0 zY0s2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItUGBxIYXvV iGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKjdGqPqcNiKXEx5TukYBde dObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+rTpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO 3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB 5DCB4TCB3gYIKoFQgSkBAQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5k ay9yZXBvc2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRlciBm cmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4xLiBDZXJ0aWZp Y2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4x LjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1UdHwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEM MAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYm aHR0cDovL2NybC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZJ2cdUBVLc647 +RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6 NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACromJkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4 A9G28kNBKWKnctj7fAXmMXAnVBhOinxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYsc A+UYyAFMP8uXBV2YcaaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9 AOoBmbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQYqbsFbS1 AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9BKNDLdr8C2LqL19iUw== -----END CERTIFICATE----- UTN DATACorp SGC Root CA ======================== -----BEGIN CERTIFICATE----- MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UE BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZ BgNVBAMTElVUTiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBa MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ys raP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlo wHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA 9P4yPykqlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv 33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4GrMIGoMAsGA1Ud DwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRTMtGzz3/64PGgXYVOktKeRR20TzA9 BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dD LmNybDAqBgNVHSUEIzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3 DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0 I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXx EZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwP DPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI -----END CERTIFICATE----- UTN USERFirst Hardware Root CA ============================== -----BEGIN CERTIFICATE----- MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0 eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3 DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8 i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM //bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2 lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67 nfhmqA== -----END CERTIFICATE----- Camerfirma Chambers of Commerce Root ==================================== -----BEGIN CERTIFICATE----- MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1 erfutGWaIZDgqtCYvDi1czyL+Nw= -----END CERTIFICATE----- Camerfirma Global Chambersign Root ================================== -----BEGIN CERTIFICATE----- MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J 1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl 6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c 8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/ BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4 IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== -----END CERTIFICATE----- NetLock Notary (Class A) Root ============================= -----BEGIN CERTIFICATE----- MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC /tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7 tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6 4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0 ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5 ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM 8CgHrTwXZoi1/baI -----END CERTIFICATE----- NetLock Business (Class B) Root =============================== -----BEGIN CERTIFICATE----- MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUxETAPBgNVBAcT CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV BAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQDEylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikg VGFudXNpdHZhbnlraWFkbzAeFw05OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYD VQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRv bnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5ldExvY2sg VXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB iQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xKgZjupNTKihe5In+DCnVMm8Bp2GQ5o+2S o/1bXHQawEfKOml2mrriRBf8TKPV/riXiK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr 1nGTLbO/CVRY7QbrqHvcQ7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV HQ8BAf8EBAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZ RUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRh dGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0 ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRv c2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUg YXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBz Oi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNA bmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhl IHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2 YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBj cHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06sPgzTEdM 43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXan3BukxowOR0w2y7jfLKR stE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKSNitjrFgBazMpUIaD8QFI -----END CERTIFICATE----- NetLock Express (Class C) Root ============================== -----BEGIN CERTIFICATE----- MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUxETAPBgNVBAcT CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV BAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQDEytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBD KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJ BgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMrTmV0TG9j ayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzANBgkqhkiG9w0BAQEFAAOB jQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNAOoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3Z W3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63 euyucYT2BDMIJTLrdKwWRMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQw DgYDVR0PAQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEWggJN RklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0YWxhbm9zIFN6b2xn YWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBB IGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBOZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1i aXp0b3NpdGFzYSB2ZWRpLiBBIGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0 ZWxlIGF6IGVsb2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25sYXBqYW4gYSBo dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kga2VyaGV0byBheiBlbGxlbm9y emVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4gSU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5k IHRoZSB1c2Ugb2YgdGhpcyBjZXJ0aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQ UyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwg YXQgY3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmYta3UzbM2 xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2gpO0u9f38vf5NNwgMvOOW gyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4Fp1hBWeAyNDYpQcCNJgEjTME1A== -----END CERTIFICATE----- XRamp Global CA Root ==================== -----BEGIN CERTIFICATE----- MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc /Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz 8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= -----END CERTIFICATE----- Go Daddy Class 2 CA =================== -----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv 2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b vZ8= -----END CERTIFICATE----- Starfield Class 2 CA ==================== -----BEGIN CERTIFICATE----- MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 QBFGmh95DmK/D5fs4C8fF5Q= -----END CERTIFICATE----- StartCom Certification Authority ================================ -----BEGIN CERTIFICATE----- MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt 2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z 6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT 37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0 Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5 LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh 3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3 fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl 1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/ lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro g14= -----END CERTIFICATE----- Taiwan GRCA =========== -----BEGIN CERTIFICATE----- MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5 BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O 1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7 Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8 lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2 09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2 Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk 7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy +fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS -----END CERTIFICATE----- Firmaprofesional Root CA ======================== -----BEGIN CERTIFICATE----- MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMxIjAgBgNVBAcT GUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1dG9yaWRhZCBkZSBDZXJ0aWZp Y2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FA ZmlybWFwcm9mZXNpb25hbC5jb20wHhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTEL MAkGA1UEBhMCRVMxIjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMT OUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2 ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20wggEiMA0GCSqGSIb3DQEB AQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5uCp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5V j1H5WuretXDE7aTt/6MNbg9kUDGvASdYrv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJH lShbz++AbOCQl4oBPB3zhxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf 3H5idPayBQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcLiam8 NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcbAgMBAAGjgZ8wgZww KgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lvbmFsLmNvbTASBgNVHRMBAf8ECDAG AQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1Ud DwEB/wQEAwIBBjAdBgNVHQ4EFgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQAD ggEBAEdz/o0nVPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36mhoEyIwOdyPdf wUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzflZKG+TQyTmAyX9odtsz/ny4Cm 7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBpQWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YG VM+h4k0460tQtcsm9MracEpqoeJ5quGnM/b9Sh/22WA= -----END CERTIFICATE----- Wells Fargo Root CA =================== -----BEGIN CERTIFICATE----- MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMCVVMxFDASBgNV BAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhv cml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN MDAxMDExMTY0MTI4WhcNMjEwMTE0MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dl bGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEv MC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n135zHCLielTWi5MbqNQ1mX x3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHESxP9cMIlrCL1dQu3U+SlK93OvRw6esP3 E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4OJgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5 OEL8pahbSCOz6+MlsoCultQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4j sNtlAHCEAQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMBAAGj YTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcBCzAyMDAGCCsGAQUF BwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRwb2xpY3kwDQYJKoZIhvcNAQEFBQAD ggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrv m+0fazbuSCUlFLZWohDo7qd/0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0R OhPs7fpvcmR7nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ33ZwmVxwQ023 tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s= -----END CERTIFICATE----- Swisscom Root CA 1 ================== -----BEGIN CERTIFICATE----- MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4 MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn 7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5 haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9 MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3 1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW NY6E0F/6MBr1mmz0DlP5OlvRHA== -----END CERTIFICATE----- DigiCert Assured ID Root CA =========================== -----BEGIN CERTIFICATE----- MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO 9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW /lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF 66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i 8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== -----END CERTIFICATE----- DigiCert Global Root CA ======================= -----BEGIN CERTIFICATE----- MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H 4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y 7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm 8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= -----END CERTIFICATE----- DigiCert High Assurance EV Root CA ================================== -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K -----END CERTIFICATE----- Certplus Class 2 Primary CA =========================== -----BEGIN CERTIFICATE----- MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR 5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+ 7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW //1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 l7+ijrRU -----END CERTIFICATE----- DST Root CA X3 ============== -----BEGIN CERTIFICATE----- MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ -----END CERTIFICATE----- DST ACES CA X6 ============== -----BEGIN CERTIFICATE----- MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2 5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3 oKfN5XozNmr6mis= -----END CERTIFICATE----- TURKTRUST Certificate Services Provider Root 1 ============================================== -----BEGIN CERTIFICATE----- MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOcUktUUlVTVCBF bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGDAJUUjEP MA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykgMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0 acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMx MDI3MTdaFw0xNTAzMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsg U2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYDVQQHDAZB TktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBC aWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GX yGl8hMW0kWxsE2qkVa2kheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8i Si9BB35JYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5CurKZ 8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1JuTm5Rh8i27fbMx4 W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51b0dewQIDAQABoxAwDjAMBgNVHRME BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46 sWrv7/hg0Uw2ZkUd82YCdAR7kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxE q8Sn5RTOPEFhfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdAaLX/7KfS0zgY nNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKSRGQDJereW26fyfJOrN3H -----END CERTIFICATE----- TURKTRUST Certificate Services Provider Root 2 ============================================== -----BEGIN CERTIFICATE----- MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBF bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP MA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcN MDUxMTA3MTAwNzU3WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVr dHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEPMA0G A1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqe LCDe2JAOCtFp0if7qnefJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKI x+XlZEdhR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJQv2g QrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGXJHpsmxcPbe9TmJEr 5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1pzpwACPI2/z7woQ8arBT9pmAPAgMB AAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58SFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8G A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/ntt Rbj2hWyfIvwqECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4 Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFzgw2lGh1uEpJ+ hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotHuFEJjOp9zYhys2AzsfAKRO8P 9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LSy3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5 UrbnBEI= -----END CERTIFICATE----- SwissSign Gold CA - G2 ====================== -----BEGIN CERTIFICATE----- MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR 7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64 OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm 5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr 44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ -----END CERTIFICATE----- SwissSign Silver CA - G2 ======================== -----BEGIN CERTIFICATE----- MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG 9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm +/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH 6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P 4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L 3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx /uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u -----END CERTIFICATE----- GeoTrust Primary Certification Authority ======================================== -----BEGIN CERTIFICATE----- MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9 nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG 1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= -----END CERTIFICATE----- thawte Primary Root CA ====================== -----BEGIN CERTIFICATE----- MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3 MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ 1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89 jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA== -----END CERTIFICATE----- VeriSign Class 3 Public Primary Certification Authority - G5 ============================================================ -----BEGIN CERTIFICATE----- MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/ BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+ X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq -----END CERTIFICATE----- SecureTrust CA ============== -----BEGIN CERTIFICATE----- MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b 01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR 3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= -----END CERTIFICATE----- Secure Global CA ================ -----BEGIN CERTIFICATE----- MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g 8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi 0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW -----END CERTIFICATE----- COMODO Certification Authority ============================== -----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH +7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV 4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA 1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN +8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== -----END CERTIFICATE----- Network Solutions Certificate Authority ======================================= -----BEGIN CERTIFICATE----- MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc /Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q 4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey -----END CERTIFICATE----- WellsSecure Public Root Certificate Authority ============================================= -----BEGIN CERTIFICATE----- MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1 iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13 i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8 bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0 bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ tylv2G0xffX8oRAHh84vWdw+WNs= -----END CERTIFICATE----- COMODO ECC Certification Authority ================================== -----BEGIN CERTIFICATE----- MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X 4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= -----END CERTIFICATE----- IGC/A ===== -----BEGIN CERTIFICATE----- MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2 TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF 0mBWWg== -----END CERTIFICATE----- Security Communication EV RootCA1 ================================= -----BEGIN CERTIFICATE----- MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO /VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4 bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK 9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 -----END CERTIFICATE----- OISTE WISeKey Global Root GA CA =============================== -----BEGIN CERTIFICATE----- MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5 IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9 Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ /yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4 +vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= -----END CERTIFICATE----- Microsec e-Szigno Root CA ========================= -----BEGIN CERTIFICATE----- MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0 MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3 LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA 4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6 Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a 86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= -----END CERTIFICATE----- Certigna ======== -----BEGIN CERTIFICATE----- MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY 1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== -----END CERTIFICATE----- AC Ra\xC3\xADz Certic\xC3\xA1mara S.A. ====================================== -----BEGIN CERTIFICATE----- MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNVBAYT AkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpw7NuIERpZ2l0YWwg LSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwaQUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4w HhcNMDYxMTI3MjA0NjI5WhcNMzAwNDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+ U29jaWVkYWQgQ2FtZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJh IFMuQS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkqhkiG9w0B AQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeGqentLhM0R7LQcNzJPNCN yu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzLfDe3fezTf3MZsGqy2IiKLUV0qPezuMDU 2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQY5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU3 4ojC2I+GdV75LaeHM/J4Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP 2yYe68yQ54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+bMMCm 8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48jilSH5L887uvDdUhf HjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++EjYfDIJss2yKHzMI+ko6Kh3VOz3vCa Mh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/ztA/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK 5lw1omdMEWux+IBkAC1vImHFrEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1b czwmPS9KvqfJpxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCBlTCBkgYEVR0g ADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vZHBjLzBaBggrBgEF BQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW507WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2Ug cHVlZGVuIGVuY29udHJhciBlbiBsYSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEf AygPU3zmpFmps4p6xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuX EpBcunvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/Jre7Ir5v /zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dpezy4ydV/NgIlqmjCMRW3 MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42gzmRkBDI8ck1fj+404HGIGQatlDCIaR4 3NAvO2STdPCWkPHv+wlaNECW8DYSwaN0jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wk eZBWN7PGKX6jD/EpOe9+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f /RWmnkJDW2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/RL5h RqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35rMDOhYil/SrnhLecU Iw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxkBYn8eNZcLCZDqQ== -----END CERTIFICATE----- TC TrustCenter Class 2 CA II ============================ -----BEGIN CERTIFICATE----- MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy IENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYw MTEyMTQzODQzWhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UE AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jftMjWQ+nEdVl//OEd+DFw IxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKguNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2 xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2JXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQ Xa7pIXSSTYtZgo+U4+lK8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7u SNQZu+995OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1UdEwEB /wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3kUrL84J6E1wIqzCB 7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU cnVzdENlbnRlciUyMENsYXNzJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iSGNn3Bzn1LL4G dXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprtZjluS5TmVfwLG4t3wVMTZonZ KNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8au0WOB9/WIFaGusyiC2y8zl3gK9etmF1Kdsj TYjKUCjLhdLTEKJZbtOTVAB6okaVhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kP JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk vQ== -----END CERTIFICATE----- TC TrustCenter Class 3 CA II ============================ -----BEGIN CERTIFICATE----- MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo 6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk 2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB /wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB 7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8 yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9 IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal 092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc 5A== -----END CERTIFICATE----- TC TrustCenter Universal CA I ============================= -----BEGIN CERTIFICATE----- MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMC REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy IFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcN MDYwMzIyMTU1NDI4WhcNMjUxMjMxMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMg VHJ1c3RDZW50ZXIgR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYw JAYDVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSRJJZ4Hgmgm5qVSkr1YnwC qMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3TfCZdzHd55yx4Oagmcw6iXSVphU9VDprv xrlE4Vc93x9UIuVvZaozhDrzznq+VZeujRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtw ag+1m7Z3W0hZneTvWq3zwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9O gdwZu5GQfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYDVR0j BBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0GCSqGSIb3DQEBBQUAA4IBAQAo0uCG 1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X17caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/Cy vwbZ71q+s2IhtNerNXxTPqYn8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3 ghUJGooWMNjsydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/2TYcuiUaUj0a 7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY -----END CERTIFICATE----- Deutsche Telekom Root CA 2 ========================== -----BEGIN CERTIFICATE----- MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5 MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5 bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8 rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU Cm26OWMohpLzGITY+9HPBVZkVw== -----END CERTIFICATE----- ComSign Secured CA ================== -----BEGIN CERTIFICATE----- MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAwPDEbMBkGA1UE AxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0w NDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBD QTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ggEKAoIBAQDGtWhfHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs 49ohgHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sWv+bznkqH 7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ueMv5WJDmyVIRD9YTC2LxB kMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d1 9guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUw AwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29t U2lnblNlY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58ADsA j8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkqhkiG9w0BAQUFAAOC AQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7piL1DRYHjZiM/EoZNGeQFsOY3wo3a BijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtCdsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtp FhpFfTMDZflScZAmlaxMDPWLkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP 51qJThRv4zdLhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== -----END CERTIFICATE----- Cybertrust Global Root ====================== -----BEGIN CERTIFICATE----- MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW 0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin 89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT 8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi 5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW WL1WMRJOEcgh4LMRkWXbtKaIOM5V -----END CERTIFICATE----- ePKI Root Certification Authority ================================= -----BEGIN CERTIFICATE----- MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX 12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= -----END CERTIFICATE----- T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3 ============================================================================================================================= -----BEGIN CERTIFICATE----- MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4 MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1 xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR 6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4 N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI= -----END CERTIFICATE----- Buypass Class 2 CA 1 ==================== -----BEGIN CERTIFICATE----- MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2 MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83 0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4 0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV 1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt 7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2 fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho -----END CERTIFICATE----- Buypass Class 3 CA 1 ==================== -----BEGIN CERTIFICATE----- MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAxMB4XDTA1 MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKx ifZgisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//zNIqeKNc0 n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI+MkcVyzwPX6UvCWThOia AJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2RhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c 1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNC MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0P AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFPBdy7 pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27sEzNxZy5p+qksP2bA EllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2mSlf56oBzKwzqBwKu5HEA6BvtjT5 htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yCe/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQj el/wroQk5PMr+4okoyeYZdowdXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915 -----END CERTIFICATE----- EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 ========================================================================== -----BEGIN CERTIFICATE----- MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNVBAMML0VCRyBF bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMTcwNQYDVQQKDC5FQkcg QmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXptZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAe Fw0wNjA4MTcwMDIxMDlaFw0xNjA4MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25p ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2lt IFRla25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIiMA0GCSqG SIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h4fuXd7hxlugTlkaDT7by X3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAktiHq6yOU/im/+4mRDGSaBUorzAzu8T2b gmmkTPiab+ci2hC6X5L8GCcKqKpE+i4stPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfr eYteIAbTdgtsApWjluTLdlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZ TqNGFav4c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8UmTDGy Y5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z+kI2sSXFCjEmN1Zn uqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0OLna9XvNRiYuoP1Vzv9s6xiQFlpJI qkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMWOeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vm ExH8nYQKE3vwO9D8owrXieqWfo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0 Nokb+Clsi7n2l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB /wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgwFoAU587GT/wW Z5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+8ygjdsZs93/mQJ7ANtyVDR2t FcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgm zJNSroIBk5DKd8pNSe/iWtkqvTDOTLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64k XPBfrAowzIpAoHMEwfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqT bCmYIai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJnxk1Gj7sU RT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4QDgZxGhBM/nV+/x5XOULK 1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9qKd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt 2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11thie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQ Y9iJSrSq3RZj9W6+YKH47ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9 AahH3eU7QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT -----END CERTIFICATE----- certSIGN ROOT CA ================ -----BEGIN CERTIFICATE----- MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD 0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD -----END CERTIFICATE----- CNNIC ROOT ========== -----BEGIN CERTIFICATE----- MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5 Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8 BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2 G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m mxE= -----END CERTIFICATE----- ApplicationCA - Japanese Government =================================== -----BEGIN CERTIFICATE----- MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4 fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g /DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL rosot4LKGAfmt1t06SAZf7IbiVQ= -----END CERTIFICATE----- GeoTrust Primary Certification Authority - G3 ============================================= -----BEGIN CERTIFICATE----- MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0 IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr 2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9 cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt -----END CERTIFICATE----- thawte Primary Root CA - G2 =========================== -----BEGIN CERTIFICATE----- MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5 8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== -----END CERTIFICATE----- thawte Primary Root CA - G3 =========================== -----BEGIN CERTIFICATE----- MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC +BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY 7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC 8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A= -----END CERTIFICATE----- GeoTrust Primary Certification Authority - G2 ============================================= -----BEGIN CERTIFICATE----- MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1 OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+ EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2 npaqBA+K -----END CERTIFICATE----- VeriSign Universal Root Certification Authority =============================================== -----BEGIN CERTIFICATE----- MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0 aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj 1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72 9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3 Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4 mJO37M2CYfE45k+XmCpajQ== -----END CERTIFICATE----- VeriSign Class 3 Public Primary Certification Authority - G4 ============================================================ -----BEGIN CERTIFICATE----- MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3 b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5 IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8 Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB /zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== -----END CERTIFICATE----- NetLock Arany (Class Gold) Főtanúsítvány ============================================ -----BEGIN CERTIFICATE----- MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu 0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw /HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= -----END CERTIFICATE----- Staat der Nederlanden Root CA - G2 ================================== -----BEGIN CERTIFICATE----- MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ 5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65 48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737 qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz +51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm 66+KAQ== -----END CERTIFICATE----- CA Disig ======== -----BEGIN CERTIFICATE----- MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3 DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3 mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/ CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA 4Z7CRneC9VkGjCFMhwnN5ag= -----END CERTIFICATE----- Juur-SK ======= -----BEGIN CERTIFICATE----- MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC +Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678 IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2 yyqcjg== -----END CERTIFICATE----- Hongkong Post Root CA 1 ======================= -----BEGIN CERTIFICATE----- MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== -----END CERTIFICATE----- SecureSign RootCA11 =================== -----BEGIN CERTIFICATE----- MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= -----END CERTIFICATE----- ACEDICOM Root ============= -----BEGIN CERTIFICATE----- MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4 MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2 3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9 2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz 4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU 9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1 ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA== -----END CERTIFICATE----- Verisign Class 3 Public Primary Certification Authority ======================================================= -----BEGIN CERTIFICATE----- MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/ D/xwzoiQ -----END CERTIFICATE----- Microsec e-Szigno Root CA 2009 ============================== -----BEGIN CERTIFICATE----- MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG 0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm 1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi LXpUq3DDfSJlgnCW -----END CERTIFICATE----- E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi =================================================== -----BEGIN CERTIFICATE----- MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG EwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLjE8MDoGA1UEAxMz ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3 MDEwNDExMzI0OFoXDTE3MDEwNDExMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0 cm9uaWsgQmlsZ2kgR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9u aWsgU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdUMZTe1RK6UxYC6lhj71vY 8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlTL/jDj/6z/P2douNffb7tC+Bg62nsM+3Y jfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAI JjjcJRFHLfO6IxClv7wC90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk 9Ok0oSy1c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/BAQD AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoEVtstxNulMA0GCSqG SIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLPqk/CaOv/gKlR6D1id4k9CnU58W5d F4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwq D2fK/A+JYZ1lpTzlvBNbCNvj/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4 Vwpm+Vganf2XKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX -----END CERTIFICATE----- GlobalSign Root CA - R3 ======================= -----BEGIN CERTIFICATE----- MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ 0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r kpeDMdmztcpHWD9f -----END CERTIFICATE----- TC TrustCenter Universal CA III =============================== -----BEGIN CERTIFICATE----- MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezELMAkGA1UEBhMC REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy IFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAe Fw0wOTA5MDkwODE1MjdaFw0yOTEyMzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNU QyBUcnVzdENlbnRlciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0Ex KDAmBgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqGSIb3DQEB AQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF5+cvAqBNLaT6hdqbJYUt QCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYvDIRlzg9uwliT6CwLOunBjvvya8o84pxO juT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8vzArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+Eut CHnNaYlAJ/Uqwa1D7KRTyGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1 M4BDj5yjdipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBhMB8G A1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI4jANBgkqhkiG9w0BAQUFAAOCAQEA g8ev6n9NCjw5sWi+e22JLumzCecYV42FmhfzdkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+ KGwWaODIl0YgoGhnYIg5IFHYaAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhK BgePxLcHsU0GDeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPHLQNjO9Po5KIq woIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg== -----END CERTIFICATE----- Autoridad de Certificacion Firmaprofesional CIF A62634068 ========================================================= -----BEGIN CERTIFICATE----- MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY 7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx 51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi 6Et8Vcad+qMUu2WFbm5PEn4KPJ2V -----END CERTIFICATE----- Izenpe.com ========== -----BEGIN CERTIFICATE----- MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ 03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU +zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK 0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ 0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== -----END CERTIFICATE----- Chambers of Commerce Root - 2008 ================================ -----BEGIN CERTIFICATE----- MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/ ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331 lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ 0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2 EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1 wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH 3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6 M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1 YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF 9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ -----END CERTIFICATE----- Global Chambersign Root - 2008 ============================== -----BEGIN CERTIFICATE----- MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0 ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB /gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp 1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0 dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG /5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6 ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg 9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z 09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B -----END CERTIFICATE----- Go Daddy Root Certificate Authority - G2 ======================================== -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq 9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD +qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r 5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 -----END CERTIFICATE----- Starfield Root Certificate Authority - G2 ========================================= -----BEGIN CERTIFICATE----- MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx 4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 -----END CERTIFICATE----- Starfield Services Root Certificate Authority - G2 ================================================== -----BEGIN CERTIFICATE----- MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 -----END CERTIFICATE----- AffirmTrust Commercial ====================== -----BEGIN CERTIFICATE----- MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv 0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= -----END CERTIFICATE----- AffirmTrust Networking ====================== -----BEGIN CERTIFICATE----- MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 /PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 /ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= -----END CERTIFICATE----- AffirmTrust Premium =================== -----BEGIN CERTIFICATE----- MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV 5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs +7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 /bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo +Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB /wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC 6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK +4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== -----END CERTIFICATE----- AffirmTrust Premium ECC ======================= -----BEGIN CERTIFICATE----- MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X 57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM eQ== -----END CERTIFICATE----- Certum Trusted Network CA ========================= -----BEGIN CERTIFICATE----- MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI 03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= -----END CERTIFICATE----- Certinomis - Autorité Racine ============================= -----BEGIN CERTIFICATE----- MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw 2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g 530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna 4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40 nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/ vgt2Fl43N+bYdJeimUV5 -----END CERTIFICATE----- Root CA Generalitat Valenciana ============================== -----BEGIN CERTIFICATE----- MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJFUzEfMB0GA1UE ChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290 IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcNMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3 WjBoMQswCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UE CxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+WmmmO3I2 F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKjSgbwJ/BXufjpTjJ3Cj9B ZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGlu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQ D0EbtFpKd71ng+CT516nDOeB0/RSrFOyA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXte JajCq+TA81yc477OMUxkHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMB AAGjggM7MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBraS5n dmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIICIwYKKwYBBAG/VQIB ADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBl AHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIAYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIA YQBsAGkAdABhAHQAIABWAGEAbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQBy AGEAYwBpAPMAbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMAaQBvAG4AYQBt AGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQAZQAgAEEAdQB0AG8AcgBpAGQA YQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBu AHQAcgBhACAAZQBuACAAbABhACAAZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAA OgAvAC8AdwB3AHcALgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0 dHA6Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+yeAT8MIGV BgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQswCQYDVQQGEwJFUzEfMB0G A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5S b290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRh TvW1yEICKrNcda3FbcrnlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdz Ckj+IHLtb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg9J63 NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XFducTZnV+ZfsBn5OH iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt +GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= -----END CERTIFICATE----- A-Trust-nQual-03 ================ -----BEGIN CERTIFICATE----- MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJBVDFIMEYGA1UE Cgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy a2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5R dWFsLTAzMB4XDTA1MDgxNzIyMDAwMFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgw RgYDVQQKDD9BLVRydXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0 ZW52ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMMEEEtVHJ1 c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtPWFuA/OQO8BBC4SA zewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUjlUC5B3ilJfYKvUWG6Nm9wASOhURh73+n yfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZznF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPE SU7l0+m0iKsMrmKS1GWH2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4 iHQF63n1k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs2e3V cuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECERqlWdV eRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAVdRU0VlIXLOThaq/Yy/kgM40 ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fGKOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmr sQd7TZjTXLDR8KdCoLXEjq/+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZd JXDRZslo+S4RFGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmEDNuxUCAKGkq6 ahq97BvIxYSazQ== -----END CERTIFICATE----- TWCA Root Certification Authority ================================= -----BEGIN CERTIFICATE----- MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP 4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG 9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== -----END CERTIFICATE----- Security Communication RootCA2 ============================== -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ +T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R 3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk 3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 -----END CERTIFICATE----- EC-ACC ====== -----BEGIN CERTIFICATE----- MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7 MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4 HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw 0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0 Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2 E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D 5EI= -----END CERTIFICATE----- components/com_sef/libs/google_analytics/google_analytics.php000066600000015037150771655450020705 0ustar00_config=SEFConfig::getConfig(); $auth_url="https://www.google.com/accounts/ClientLogin"; $auth_params=array(); $auth_params["accountType"]="GOOGLE"; $auth_params["Email"]=$this->_config->google_email; $auth_params["Passwd"]=$this->_config->google_password; $auth_params["service"]="analytics"; $auth_params["source"]=JFactory::getApplication()->getCfg('sitename')."-joomsef-4.1.2"; $this->_certFile = realpath(dirname(__FILE__).'/../cacert.pem'); if (function_exists('curl_init')) { // Use CURL $c=curl_init($auth_url); curl_setopt($c,CURLOPT_RETURNTRANSFER,1); curl_setopt($c,CURLOPT_POST,1); curl_setopt($c,CURLOPT_POSTFIELDS,$auth_params); curl_setopt($c, CURLOPT_CAINFO, $this->_certFile); $data=curl_exec($c); curl_close($c); } else { // Try to use OpenSSL $response = SEFTools::PostRequest($auth_url, null, $auth_params); if ($response === false) { return; } $data = $response->content; } if (!$data) { return; } $data=(explode("\n",$data)); array_pop($data); $this->_info = array(); for ($i = 0; $i < count($data); $i++) { $row = explode("=", $data[$i]); if (count($row) == 2) { $this->_info[$row[0]] = $row[1]; } } } static function getInstance() { static $instance; if(empty($instance)) { $instance=new Google_Analytics(); } if(isset($instance->_info["Error"])) { return false; } if(!isset($instance->_info["Auth"])) { return false; } return $instance; } function getAccounts() { $google_url=$this->_accounts_url; $headers=array(); $headers[]="Authorization: GoogleLogin auth=".$this->_info["Auth"]; $url_params["prettyprint"]="true"; $google_url.="?".http_build_query($url_params); if (function_exists('curl_init')) { // Use CURL $c=curl_init($google_url); curl_setopt($c,CURLOPT_RETURNTRANSFER,1); curl_setopt($c,CURLOPT_HTTPHEADER,$headers); curl_setopt($c, CURLOPT_CAINFO, $this->_certFile); $data=curl_exec($c); curl_close($c); } else { // Try to use OpenSSL $response = SEFTools::PostRequest($google_url, null, null, 'get', null, $headers); if ($response === false) { return array(); } $data = $response->content; } if (!$data) { return array(); } $xml=new DomDocument("1.0"); if ($xml->loadXML($data) === false) { return array(); } $accounts=array(); foreach($xml->getElementsByTagName('entry') as $item) { $account=new stdClass(); foreach($item->getElementsByTagName('property') as $property) { switch($property->getAttribute('name')) { case 'ga:profileId': $account->id = $property->getAttribute('value'); break; case 'ga:profileName': $account->title=$property->getAttribute('value'); break; case 'ga:webPropertyId': $account->webId = $property->getAttribute('value'); break; } } if ($account->webId == $this->_config->google_id) { $this->_default_id=$account->id; } $accounts[]=$account; } return $accounts; } function getDefaultId() { return $this->_default_id; } function getData($metrics,$dimensions="",$sort="",$max_results="50") { $google_url=$this->_data_url; $headers=array(); $headers[]="Authorization: GoogleLogin auth=".$this->_info["Auth"]; $url_params=array(); $url_params["ids"]="ga:".JRequest::getInt('account_id',$this->_default_id); $url_params["start-date"]=JRequest::getString('start_date',JFactory::getDate((JFactory::getDate()->toUnix()-(60*60*24*7)))->format("Y-m-d")); $url_params["end-date"]=JRequest::getString('end_date',JFactory::getDate()->format("Y-m-d")); $url_params["prettyprint"]="true"; $url_params["metrics"]=$metrics; $url_params["dimensions"]=$dimensions; if (empty($sort)) { $sort = $metrics; } $url_params["sort"]=$sort; $url_params["max-results"]=$max_results; $google_url.="?".http_build_query($url_params); if (function_exists('curl_init')) { // Use CURL $c=curl_init($google_url); curl_setopt($c,CURLOPT_RETURNTRANSFER,1); curl_setopt($c,CURLOPT_HTTPHEADER,$headers); curl_setopt($c, CURLOPT_CAINFO, $this->_certFile); $data=curl_exec($c); curl_close($c); } else { // Try to use OpenSSL $response = SEFTools::PostRequest($google_url, null, null, 'get', null, $headers); if ($response === false) { return array(); } $data = $response->content; } if (!$data) { return array(); } $xml=new DomDocument("1.0"); if ($xml->loadXML($data) === false) { return array(); } return $this->_processData($xml->getElementsByTagName('entry')); } private function _processData($entry) { $data=array(); $i=0; foreach($entry as $item) { foreach($item->getElementsByTagName('metric') as $value) { $data[$i][str_replace("ga:","",$value->getAttribute('name'))]=$value->getAttribute('value'); } foreach($item->getElementsByTagName('dimension') as $value) { $data[$i][str_replace("ga:","",$value->getAttribute('name'))]=$value->getAttribute('value'); } $i++; } return $data; } } ?> components/com_sef/libs/google_analytics/index.html000066600000000054150771655450016637 0ustar00components/com_sef/libs/google_analytics/google_analytics.php.backup000066600000014720150771655450022147 0ustar00_config=SEFConfig::getConfig(); $auth_url="https://www.google.com/accounts/ClientLogin"; $auth_params=array(); $auth_params["accountType"]="GOOGLE"; $auth_params["Email"]=$this->_config->google_email; $auth_params["Passwd"]=$this->_config->google_password; $auth_params["service"]="analytics"; $auth_params["source"]=JFactory::getApplication()->getCfg('sitename')."-joomsef-4.1.2"; $this->_certFile = realpath(dirname(__FILE__).'/../cacert.pem'); if (function_exists('curl_init')) { // Use CURL $c=curl_init($auth_url); curl_setopt($c,CURLOPT_RETURNTRANSFER,1); curl_setopt($c,CURLOPT_POST,1); curl_setopt($c,CURLOPT_POSTFIELDS,$auth_params); curl_setopt($c, CURLOPT_CAINFO, $this->_certFile); $data=curl_exec($c); curl_close($c); } else { // Try to use OpenSSL $response = SEFTools::PostRequest($auth_url, null, $auth_params); if ($response === false) { return; } $data = $response->content; } if (!$data) { return; } $data=(explode("\n",$data)); array_pop($data); $this->_info=array(); for($i=0;$i_info[$row[0]]=$row[1]; } } static function getInstance() { static $instance; if(empty($instance)) { $instance=new Google_Analytics(); } if(isset($instance->_info["Error"])) { return false; } if(!isset($instance->_info["Auth"])) { return false; } return $instance; } function getAccounts() { $google_url=$this->_accounts_url; $headers=array(); $headers[]="Authorization: GoogleLogin auth=".$this->_info["Auth"]; $url_params["prettyprint"]="true"; $google_url.="?".http_build_query($url_params); if (function_exists('curl_init')) { // Use CURL $c=curl_init($google_url); curl_setopt($c,CURLOPT_RETURNTRANSFER,1); curl_setopt($c,CURLOPT_HTTPHEADER,$headers); curl_setopt($c, CURLOPT_CAINFO, $this->_certFile); $data=curl_exec($c); curl_close($c); } else { // Try to use OpenSSL $response = SEFTools::PostRequest($google_url, null, null, 'get', null, $headers); if ($response === false) { return array(); } $data = $response->content; } if (!$data) { return array(); } $xml=new DomDocument("1.0"); if ($xml->loadXML($data) === false) { return array(); } $accounts=array(); foreach($xml->getElementsByTagName('entry') as $item) { $account=new stdClass(); foreach($item->getElementsByTagName('property') as $property) { switch($property->getAttribute('name')) { case 'ga:profileId': $account->id = $property->getAttribute('value'); break; case 'ga:profileName': $account->title=$property->getAttribute('value'); break; case 'ga:webPropertyId': $account->webId = $property->getAttribute('value'); break; } } if ($account->webId == $this->_config->google_id) { $this->_default_id=$account->id; } $accounts[]=$account; } return $accounts; } function getDefaultId() { return $this->_default_id; } function getData($metrics,$dimensions="",$sort="",$max_results="50") { $google_url=$this->_data_url; $headers=array(); $headers[]="Authorization: GoogleLogin auth=".$this->_info["Auth"]; $url_params=array(); $url_params["ids"]="ga:".JRequest::getInt('account_id',$this->_default_id); $url_params["start-date"]=JRequest::getString('start_date',JFactory::getDate((JFactory::getDate()->toUnix()-(60*60*24*7)))->format("Y-m-d")); $url_params["end-date"]=JRequest::getString('end_date',JFactory::getDate()->format("Y-m-d")); $url_params["prettyprint"]="true"; $url_params["metrics"]=$metrics; $url_params["dimensions"]=$dimensions; if (empty($sort)) { $sort = $metrics; } $url_params["sort"]=$sort; $url_params["max-results"]=$max_results; $google_url.="?".http_build_query($url_params); if (function_exists('curl_init')) { // Use CURL $c=curl_init($google_url); curl_setopt($c,CURLOPT_RETURNTRANSFER,1); curl_setopt($c,CURLOPT_HTTPHEADER,$headers); curl_setopt($c, CURLOPT_CAINFO, $this->_certFile); $data=curl_exec($c); curl_close($c); } else { // Try to use OpenSSL $response = SEFTools::PostRequest($google_url, null, null, 'get', null, $headers); if ($response === false) { return array(); } $data = $response->content; } if (!$data) { return array(); } $xml=new DomDocument("1.0"); if ($xml->loadXML($data) === false) { return array(); } return $this->_processData($xml->getElementsByTagName('entry')); } private function _processData($entry) { $data=array(); $i=0; foreach($entry as $item) { foreach($item->getElementsByTagName('metric') as $value) { $data[$i][str_replace("ga:","",$value->getAttribute('name'))]=$value->getAttribute('value'); } foreach($item->getElementsByTagName('dimension') as $value) { $data[$i][str_replace("ga:","",$value->getAttribute('name'))]=$value->getAttribute('value'); } $i++; } return $data; } } ?> components/com_sef/libs/index.html000066600000000054150771655450013314 0ustar00components/com_sef/libs/seostats/LICENSE000066600000001311150771655450014166 0ustar00 ====================================================================== LICENSE This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License (GPL) as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. To read the license please visit http://www.gnu.org/copyleft/gpl.html ======================================================================components/com_sef/libs/seostats/index.html000066600000000054150771655450015161 0ustar00components/com_sef/libs/seostats/src/seostats.yahoo.php.backup000066600000005555150771655450020726 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) */ class SEOstats_Yahoo extends SEOstats { /** * Returns the total amount of pages for a Domain indexed at Yahoo! * * @access private * @link http://developer.yahoo.com/search/siteexplorer/ Get your own application ID here * @return integer Returns the total amount of pages for a Domain indexed at Yahoo! */ public static function yahooSiteindexTotal($uri) { $url = 'http://search.yahooapis.com/SiteExplorerService/V1/pageData?appid='; $url .= YAHOO_APP_ID; $url .= '&results=1&output=json&query=http://'.urlencode($uri); $str = SEOstats::cURL($url); $data = json_decode($str); return $data->ResultSet->totalResultsAvailable; } /** * Returns array, containing details about the pages indexed at Yahoo! * * @access private * @return array Returns array, containing details about the pages indexed at Yahoo! */ public static function yahooSiteindexArray($uri) { $tsv_url = 'http://siteexplorer.search.yahoo.com/de/export;_ylt=?p='. urlencode($uri).'&bwmf=s&fr=sfp&fr2=seo-rd-se'; $result = array(); foreach ( file($tsv_url) as $line ) { $tmp = explode("\t", $line); if ( isset($tmp[1]) && !empty($tmp[1]) && $tmp[1] != "URL" ) { $result[] = array( 'Title' => utf8_decode($tmp[0]), 'URL' => $tmp[1] ); } } return $result; } /** * Returns the total amount of Backlinks indexed at Yahoo! * * @access private * @link http://developer.yahoo.com/search/siteexplorer/ Get your own application ID here * @return integer Returns the total amount of backlinks indexed at Yahoo! */ public static function yahooBacklinksTotal($uri) { $url = 'http://search.yahooapis.com/SiteExplorerService/V1/inlinkData?appid='; $url .= YAHOO_APP_ID; $url .= '&results=1&output=json&query=http://'.urlencode($uri); $str = SEOstats::cURL($url); $data = json_decode($str); return $data->ResultSet->totalResultsAvailable; } /** * Returns an array containing details about the backlinks indexed at Yahoo! * * @access private * @return array Returns an array containing details about the backlinks indexed at Yahoo! */ public static function yahooBacklinksArray($uri) { $tsv_url = 'http://siteexplorer.search.yahoo.com/de/export;_ylt=?p='. urlencode($uri).'&bwm=i&bwmf=s&fr=sfp&fr2=seo-rd-se'; $result = array(); foreach ( file($tsv_url) as $line ) { $tmp = explode("\t", $line); if ( isset($tmp[1]) && !empty($tmp[1]) && $tmp[1] != "URL" ) { $result[] = array( 'URL' => $tmp[1], 'Anchortext' => utf8_decode($tmp[0]) ); } } return $result; } } ?> components/com_sef/libs/seostats/src/seostats.google.php000066600000020335150771655450017610 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) * * @filename ./seostats.google.php * @desc Child class of SEOstats, extending the main class * by methods for http://www.google.{@const:GOOGLE_TLD} * * @changelog * date author method: change(s) * 2011/08/04 Stephan Schmitz googleTotal2: Added if condition at return, to fix/avoid * errors when estimatedResultCount is not set. * 2011/10/07 Stephan Schmitz Google_PR: Updated the toolbar URL for Pagerank requests. */ defined('_JEXEC') or die('Restricted access'); class SEOstats_Google extends SEOstats { /** * Returns total amount of results for any Google search, * requesting the deprecated Websearch API. * * @access private * @param string $query String, containing the search query. * @param string $tld String, containing the desired Google top level domain. * @return integer Returns a total count. */ public static function googleTotal2($query) { $url = 'http://ajax.googleapis.com/ajax/services/search/web?v=1.0&rsz=1&q='.$query; $str = SEOstats::cURL($url); $data = json_decode($str); return (!isset($data->responseData->cursor->estimatedResultCount)) ? '0' : intval($data->responseData->cursor->estimatedResultCount); } /** * Returns total amount of results for any Google search. * * @access private * @param string $query String, containing the search query. * @param string $tld String, containing the desired Google top level domain. * @return integer Returns a total count. */ public static function googleTotal($query) { $url = 'http://www.google.'. GOOGLE_TLD .'/search?num=1&q='.$query; //echo $url; $str = SEOstats::cURL($url); preg_match_all('#
    ([A-Za-z]*) ([0-9,]*)#',$str,$matches); return $matches[2][0]; } /** * Returns array, containing detailed results for any Google search. * * @access private * @param string $query String, containing the search query. * @param string $tld String, containing the desired Google top level domain. * @return array Returns array, containing the keys 'URL', 'Title' and 'Description'. */ public static function googleArray($query) { $result = array (); $pages = 1; $delay = 0; for($start=0;$start<$pages;$start++) { $url = 'http://www.google.'. GOOGLE_TLD .'/custom?q='.$query.'&filter=0'. '&num=100'.(($start == 0) ? '' : '&start='.$start.'00'); $str = SEOstats::cURL($url); if (preg_match("#answer=86640#i", $str)) { $e = 'Please read: http://www.google.com/support/websearch/' . 'bin/answer.py?&answer=86640&hl=en'; throw new SEOstatsException($e); } else { $html = new DOMDocument(); @$html->loadHtml( $str ); $xpath = new DOMXPath( $html ); $links = $xpath->query( "//div[@class='g']//a" ); $descs = $xpath->query( "//td[@class='j']//div[@class='std']" ); $i = 0; foreach ( $links as $link ) { if(!preg_match('#cache#si',$link->textContent) && !preg_match('#similar#si',$link->textContent)) { $result []= array( 'url' => $link->getAttribute('href'), 'title' => utf8_decode($link->textContent), 'descr' => utf8_decode($descs->item($i)->textContent) ); $i++; } } if ( preg_match('#
    <\/div>#i', $str) || preg_match('#
    <\/div>#i', $str)) { $pages += 1; $delay += 200000; usleep($delay); } else { $pages -= 1; } } } return $result; } public static function performanceAnalysis($uri) { $url = 'http://pagespeed.googlelabs.com/run_pagespeed?url='.$uri.'&format=json'; $str = SEOstats::cURL($url); return json_decode($str); } public static function pageSpeedScore($uri) { $url = 'http://pagespeed.googlelabs.com/run_pagespeed?url='.$uri.'&format=json'; $str = SEOstats::cURL($url); $data = json_decode($str); return intval($data->results->score); } /** * Gets the 'GPR_awesomeHash' of the object URL. * * @access private * @param string $url String, containing the URL to hash. * @return string Returns hash. */ public static function genhash ($url) { $hash = 'Mining PageRank is AGAINST GOOGLE\'S TERMS OF SERVICE. Yes, I\'m talking to you, scammer.'; $c = 16909125; $length = strlen($url); $hashpieces = str_split($hash); $urlpieces = str_split($url); for ($d = 0; $d < $length; $d++) { $c = $c ^ (ord($hashpieces[$d]) ^ ord($urlpieces[$d])); $c = self::zerofill($c, 23) | $c << 9; } return '8' . self::hexencode($c); } /** * @return integer */ public static function zerofill($a,$b) { $z = hexdec(80000000); if ($z & $a) { $a = ($a>>1); $a &= (~$z); $a |= 0x40000000; $a = ($a>>($b-1)); } else { $a = ($a>>$b); } return $a; } /** * @return string */ public static function hexencode($str) { $out = self::hex8(self::zerofill($str, 24)); $out .= self::hex8(self::zerofill($str, 16) & 255); $out .= self::hex8(self::zerofill($str, 8 ) & 255); $out .= self::hex8($str & 255); return $out; } /** * @return integer */ public static function hex8 ($str) { $str = dechex($str); (strlen($str) == 1 ? $str = '0' . $str: null); return $str; } /** * Gets the Google Pagerank * * @access private * @return integer Returns the Google PageRank. */ public static function Google_PR($host) { $domain = 'http://'.$host; if(USE_PAGERANK_CHECKSUM_API == true) { $str = SEOstats::cURL( SEOstats::PAGERANK_CHECKSUM_API_URI . $domain ); $data = json_decode($str); $checksum = $data->CH; } else { $checksum = self::genhash($domain); } $googleurl = 'http://toolbarqueries.google.com/tbr?features=Rank&sourceid=navclient-ff&client=navclient-auto-ff'; $googleurl .= '&googleip=O;66.249.81.104;104&ch='.$checksum.'&q=info:'.urlencode($domain); $out = SEOstats::cURL($googleurl); $pagerank = trim(substr($out, 9)); if (!preg_match('/^[0-9]/',$pagerank)) { $pagerank = 'Failed to generate a valid hash for PR check.'; } return $pagerank; } } ?>components/com_sef/libs/seostats/src/class.seostats.php000066600000102256150771655450017444 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) * @link http://www.gnu.org/copyleft/gpl.html *======================================================================= * @filename ./class.seostats.php * @description SEOstats main class file that includes the child classes * and the config and contains all public methods. *======================================================================= * @changelog * date author method: change(s) * 2011/09/06 Stephan Schmitz Removed Majesticseo methods. * 2011/08/04 Stephan Schmitz Added method Bing_Siteindex_Total() * Added method Bing_Siteindex_Array() * Added method Bing() * Updated constant * PAGERANK_CHECKSUM_API_URI * Removed pre tags when output of the * print_array() method is json *======================================================================= * Note: The above changelog is related to this file only. Each file of * the package has it's own changelog in the head section. For a general * changelog, please see the CHANGELOG file. *======================================================================= * Copyright (c) 2010-present, Stephan Schmitz * All rights reserved. *======================================================================= * Project Contributors (Alphabetically by first names): * * |Chris Alvares * |-> contributed the BING child class * * |Florent Cima * |-> code fix for SEOstats_Majesticseo::report * * |http://code.google.com/u/@UxJTQFFRABFDXwZ%2F/ * |-> code fix for SEOstats_Google::googleTotal2 *======================================================================= * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Neither the name of the Author nor the name of the Product * may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ defined('_JEXEC') or die('Restricted access'); include_once('class.seostats.config.php'); include_once('modules.php'); class SEOstats { const BUILD_NO = '2.0.8.2'; const PAGERANK_CHECKSUM_API_URI = 'http://pagerank.bexton.net/?url='; /** * Object URL * * @access public * @var string */ public $url; /** * Constructor * * Checks for valid URL syntax and server response. * * @access public * @param string $url String, containing the initialized * object URL. */ public function __construct($url) { $url = str_replace(' ', '+', $url); $this->url = $url; $url_validation = $this->valid_url($this->url); if($url_validation == 'valid') { $valid_response_codes = array('200','301','302'); $curl_result = $this->get_status_code($this->url); if(in_array($curl_result,$valid_response_codes)) { $this->host = parse_url($this->url, PHP_URL_HOST); $this->protocol = parse_url($this->url, PHP_URL_SCHEME); } elseif($curl_result == '0') { $e = 'Invalid URL > '.$this->url.' returned no response for a HTTP HEAD request, at all. It seems like the Domain does not exist.'; $this->errlogtxt($e); throw new SEOstatsException($e); } else { $e = 'Invalid Request > '.$this->url.' returned a '.$curl_result.' status code.'; $this->errlogtxt($e); throw new SEOstatsException($e); } } else { $e = $url_validation; $this->errlogtxt($e); throw new SEOstatsException($e); } } function errlogtxt($errtxt) { $fp = fopen('errlog.txt','a+'); //ouvrir le fichier $newerr = date('Y-m-d\TH:i:sP') .' : ' . $errtxt."\r\n"; //creation du texte de l'erreur fwrite($fp,$newerr); //edition du fichier texte fclose($fp); //fermeture du fichier texte echo $newerr; } /** * HTTP GET request with curl. * * @access private * @param string $url String, containing the URL to curl. * @return string Returns string, containing the curl result. * */ public static function cURL($url) { $ch = curl_init($url); curl_setopt($ch,CURLOPT_USERAGENT,'GoogleHttpClient'); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,5); curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1); curl_setopt($ch,CURLOPT_MAXREDIRS,2); if(strtolower(parse_url($url, PHP_URL_SCHEME)) == 'https') { curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,1); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,1); } $str = curl_exec($ch); curl_close($ch); return $str; } /** * HTTP HEAD request with curl. * * @access private * @param string $url String, containing the * initialized object URL. * @return intval Returns a HTTP status code. */ private function get_status_code($url) { $ch = curl_init($url); curl_setopt($ch,CURLOPT_USERAGENT,'GoogleHttpClient'); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch,CURLOPT_NOBODY,1); curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,5); $str = curl_exec($ch); $int = curl_getinfo($ch,CURLINFO_HTTP_CODE); curl_close($ch); return intval($int); } /** * Validates the initialized object URL syntax. * * @access private * @param string $url String, containing the initialized object URL. * @return string Returns string, containing the validation result. */ private function valid_url($url) { $allowed_schemes = array('http','https'); $host = parse_url($url, PHP_URL_HOST); $scheme = parse_url($url, PHP_URL_SCHEME); if(!isset($url) || empty($url) || $url = '') { $e = 'Invalid Object > Requires an URL.'; } else { if(!in_array(strtolower($scheme),$allowed_schemes)) { $e = 'Invalid URL > SEOstats supports soley RFC compliant URL\'s with HTTP(/S) protocol.'; } elseif(empty($host) || $host == '') { $e = 'Invalid URL > Hostname undefined (or invalid URL syntax).'; } else { /** * Regex pattern found in and copied from the Nutch source * @url {http://nutch.apache.org/} * * Fyi: For the following reason, i decided to stay with preg_match. * * Testing 10k URL's, returned an average execution time (in seconds, per URL) of: * if(!preg_match($pattern,$this->url)) * 0.000104904174805 * if(!filter_var($this->url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED)) * 0.000140905380249 */ $pattern = '([A-Za-z][A-Za-z0-9+.-]{1,120}:[A-Za-z0-9/](([A-Za-z0-9$_.+!*,;/?:@&~=-])'; $pattern .= '|%[A-Fa-f0-9]{2}){1,333}(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*,;/?:@&~=%-]{0,1000}))?)'; if(!preg_match($pattern,$this->url)) { $e = 'Invalid URL > Invalid URL syntax.'; } else { $e = 'valid'; } } } return $e; } /** * Just a 'quicker' way to print an array of a method's result. * * @param string $method String, containing a method name. * @param string $output Optional Parameter. If set to json, * output will be a json encoded array. * @access public * @return string Prints an array within
     tags.
         */
        public function print_array($method,$output='json')
        {
            if($output=='json')
            {
                print_r (json_encode($this->$method()));
            }
            else
            {
                print '
    ';
                print_r ($this->$method());
                print '
    '; } } /** * @access public * @return integer Returns the Google PageRank. */ public function Google_Page_Rank() { return SEOstats_Google::Google_PR($this->host); } /** * @access public * @return integer Returns the total amount of results for a Google 'site:'-search on the object URL. */ public function Google_Siteindex_Total() { $q = urlencode('site:'.$this->host); return SEOstats_Google::googleTotal($q); } /** * @access public * @return integer Returns the total amount of results for a Google 'site:'-search on the object URL. */ public function Google_Siteindex_Total_API() { $q = urlencode('site:'.$this->host); return SEOstats_Google::googleTotal2($q); } /** * Limited to 1000 results, due to Google. * * @access public * @return array Returns array, containing foreach 'site:'-search result the keys 'URL', 'Title' and 'Description'. */ public function Google_Siteindex_Array() { $q = urlencode('site:'.$this->host); return SEOstats_Google::googleArray($q); } /** * @access public * @return integer Returns the total amount of results for a Google 'link:'-search on the object URL. */ public function Google_Backlinks_Total() { $q = urlencode('link:'.$this->host); return SEOstats_Google::googleTotal($q); } /** * @access public * @return integer Returns the total amount of results for a Google 'site:'-search on the object URL. */ public function Google_Backlinks_Total_API() { $q = urlencode('link:'.$this->host); return SEOstats_Google::googleTotal2($q); } /** * Limited to 1000 results, due to Google. * * @access public * @return array Returns array, containing foreach 'link:'-search result the keys 'URL', 'Title' and 'Description'. */ public function Google_Backlinks_Array() { $q = urlencode('link:'.$this->host); return SEOstats_Google::googleArray($q); } /** * @access public * @return integer Returns the total amount of results for an exact match Google search on the object URL. */ public function Google_Mentions_Total() { $q = urlencode('"'.$this->host.'" -site:'.$this->host.''); return SEOstats_Google::googleTotal($q); } /** * Limited to 1000 results, due to Google. * * @access public * @return array Returns array, containing foreach exact match search result the keys 'URL', 'Title' and 'Description'. */ public function Google_Mentions_Array() { $q = urlencode('"'.$this->host.'" -site:'.$this->host.''); return SEOstats_Google::googleArray($q); } /** * Returns Onsite Optimization Tips (for better page performance) by Google. * * @access public * @returun array Returns array, containing the page analysis results. */ public function Google_Performance_Analysis() { return SEOstats_Google::performanceAnalysis($this->host); } /** * Returns the Google Pagespeed Score. * Score is between 0 (worst) and 100 (best). * * @access public * @returun integer Returns a number between 0 - 100. */ public function Google_Pagespeed_Score() { return SEOstats_Google::pagespeedScore($this->host); } /** * @access public * @return integer Returns the total amount of pages for the domain, indexed at Yahoo!. */ public function Yahoo_Siteindex_Total() { return SEOstats_Yahoo::yahooSiteindexTotal($this->host); } /** * Limited to 100 results. * * @access public * @return integer Returns array, containing the keys 'Title', 'URL' and 'Click URL'. */ public function Yahoo_Siteindex_Array() { return SEOstats_Yahoo::yahooSiteindexArray($this->host); } /** * @access public * @return integer Returns the total amount of backlinks to the domain, listed at Yahoo!. */ public function Yahoo_Backlinks_Total() { return SEOstats_Yahoo::yahooBacklinksTotal($this->host); } /** * Limited to 100 results. * * @access public * @return integer Returns array, containing the keys 'URL' and 'Anchortext'. */ public function Yahoo_Backlinks_Array() { return SEOstats_Yahoo::yahooBacklinksArray($this->host); } /** * @access public * @return integer Returns the total amount of pages for the domain, indexed at Yahoo!. */ public function Bing_Siteindex_Total() { return SEOstats_Bing::bingSiteindexTotal($this->host); } /** * Limited to 50 results. * * @access public * @return integer Returns array, containing the keys 'Title', 'URL' and 'Click URL'. */ public function Bing_Siteindex_Array() { return SEOstats_Bing::bingSiteindexArray($this->host); } /** * @access public * @return array Returns array, containing the keys 'URL Authority', 'URL mozRank', 'Domain Authority' and 'Domain mozRank'. */ public function Seomoz_Domainauthority_Array() { return SEOstats_Seomoz::Seomoz_Authority($this->host); } /** * Limited to 25 links per source domain, due to using a free API key. * * @access public * @link http://apiwiki.seomoz.org/w/page/27002419/Glossary Response Format, Term Conventions * @return array Returns multi-array, containing backlink details. */ public function Seomoz_Linkdetails_Array() { return SEOstats_Seomoz::Seomoz_Links($this->host); } /** * @access public * @return integer Returns the Alexa Global Rank. */ public function Alexa_Global_Rank_Array() { return SEOstats_Alexa::extractSingle('div','id','rank','0',$this->host,true); } /** * @access public * @return integer Returns the Alexa Country Rank. */ public function Alexa_Country_Rank() { return SEOstats_Alexa::extractSingle('div','class','data','1',$this->host,false); } /** * @access public * @return array Returns multi-array, containing data from Alexa about the total pageviews. */ public function Alexa_Pageviews() { return SEOstats_Alexa::extractSingle('div','id','pageviews','0',$this->host,true); } /** * @access public * @return array Returns multi-array, containing data from Alexa about pageviews per user. */ public function Alexa_Pageviews_Per_User() { return SEOstats_Alexa::extractSingle('div','id','pageviews_per_user','0',$this->host,true); } /** * @access public * @return array Returns multi-array, containing data from Alexa about the reach. */ public function Alexa_Reach() { return SEOstats_Alexa::extractSingle('div','id','reach','0',$this->host,true); } /** * @access public * @return array Returns multi-array, containing data from Alexa about the bounce rate. */ public function Alexa_Bounce_Rate() { return SEOstats_Alexa::extractSingle('div','id','bounce','0',$this->host,true); } /** * @access public * @return array Returns multi-array, containing data from Alexa about the avg time, users stay on the site. */ public function Alexa_Time_On_Site() { return SEOstats_Alexa::extractSingle('div','id','time_on_site','0',$this->host,true); } /** * @access public * @return array Returns multi-array, containing data from Alexa about visitors from searches. */ public function Alexa_Search_Visits() { return SEOstats_Alexa::extractSingle('div','id','search','0',$this->host,true); } /** * @access public * @return array Returns multi-array, containing the Visits by Country. */ public function Alexa_Visits_By_Country() { return SEOstats_Alexa::Alexa_VBC($this->url); } /** * @access public * @return array Returns multi-array, containing the Alexa Rank, sorted by Country. */ public function Alexa_Rank_By_Country() { return SEOstats_Alexa::Alexa_RBC($this->url); } /** * @access public * @return array Returns multi-array, containing data from Alexa about keywords from search visits. */ public function Alexa_Search_Visits_Keywords() { return SEOstats_Alexa::Alexa_SV_Keywords($this->url); } /** * @access public * @return array Returns multi-array, containing data from Alexa about changes of incoming search terms. */ public function Alexa_Search_Visits_Changes() { return SEOstats_Alexa::Alexa_SV_Changes($this->url); } /** * @access public * @return string Returns string, containing the average load time of the URL from Alexa. */ public function Alexa_Avg_Load_Time() { return SEOstats_Alexa::Alexa_Load_Time($this->url); } /** * @access public * @param integer $type Specifies the graph type. Valid values are 1 to 6. * @param integer $width Specifies the graph width (in px). * @param integer $height Specifies the graph height (in px). * @param integer $period Specifies the displayed time period. Valid values are 1 to 12. * @return string Returns a string, containing the HTML code of an image, showing Alexa Statistics as Graph. */ public function Alexa_Graph($type='1',$width='660',$height='330',$period='1') { switch($type) { case 1: $gtype = 't'; break; case 2: $gtype = 'p'; break; case 3: $gtype = 'u'; break; case 4: $gtype = 's'; break; case 5: $gtype = 'b'; break; case 6: $gtype = 'q'; break; default:break; } $graph = 'Alexa Statistics Graph for '.$this->url.''; return $graph; } /** * @access public * @return integer Returns the total amount of Facebook pages mention the URL. */ public function Facebook_Mentions_Total() { return SEOstats_Facebook::getFacebookShares($this->url); } /** * Limited to 1000 results. * * @access public * @return array Returns array, containing detailed results about Facebook pages mention the URL. */ public function Facebook_Mentions_Array() { $q = urlencode('site:facebook.com "'.$this->host.'"'); return SEOstats_Google::googleArray($q); } /** * Returns the internal ID, the Facebook Graph API registers to - and uses for identifying - a Domain. * * @access public * @link http://developers.facebook.com/docs/reference/api/domain/ * @param host string The URL to get the ID for. * @return integer Returns 0, or the unique Domain-ID. */ public function Facebook_GraphApi_DomainId_ByHostname() { return SEOstats_Facebook::fbGraphApiIdByHost($this->host); } /** * @access public * @return integer Returns the total amount of Twitter pages mention the URL. */ public function Twitter_Mentions_Total() { return SEOstats_Twitter::getTweetCount($this->url); } /** * Limited to 1000 results. * * @access public * @return array Returns array, containing detailed results about Twitter pages mention the URL. */ public function Twitter_Mentions_Array() { $q = urlencode('site:twitter.com "'.$this->host.'"'); return SEOstats_Google::googleArray($q); } /** * @access public * @return array Returns multi-array, containing all Google data. */ public function Google() { $all = array( 'GOOGLE' => array( 'Google_Page_Rank' => $this->Google_Page_Rank(), 'Google_Siteindex_Total' => $this->Google_Siteindex_Total(), 'Google_Siteindex_Total_API' => $this->Google_Siteindex_Total_API(), 'Google_Siteindex_Array' => $this->Google_Siteindex_Array(), 'Google_Backlinks_Total' => $this->Google_Backlinks_Total(), 'Google_Backlinks_Total_API' => $this->Google_Backlinks_Total_API(), 'Google_Backlinks_Array' => $this->Google_Backlinks_Array(), 'Google_Mentions_Total' => $this->Google_Mentions_Total(), 'Google_Mentions_Array' => $this->Google_Mentions_Array() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * @access public * @return array Returns multi-array, containing all Yahoo! data. */ public function Yahoo() { $all = array( 'YAHOO' => array( 'Yahoo_Siteindex_Total' => $this->Yahoo_Siteindex_Total(), 'Yahoo_Siteindex_Array' => $this->Yahoo_Siteindex_Array(), 'Yahoo_Backlinks_Total' => $this->Yahoo_Backlinks_Total(), 'Yahoo_Backlinks_Array' => $this->Yahoo_Backlinks_Array() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * @access public * @return array Returns multi-array, containing all Bing data. */ public function Bing() { $all = array( 'YAHOO' => array( 'Bing_Siteindex_Total' => $this->Bing_Siteindex_Total(), 'Bing_Siteindex_Array' => $this->Bing_Siteindex_Array() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * @access public * @return array Returns multi-array, containing all SEOmoz data. */ public function Seomoz() { $all = array( 'SEOMOZ' => array( 'Seomoz_Domainauthority_Array' => $this->Seomoz_Domainauthority_Array(), 'Seomoz_Linkdetails_Array' => $this->Seomoz_Linkdetails_Array() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * @access public * @return array Returns multi-array, containing all Alexa data. */ public function Alexa() { $all = array( 'ALEXA' => array( 'Alexa_Global_Rank_Array' => $this->Alexa_Global_Rank_Array(), 'Alexa_Country_Rank' => $this->Alexa_Country_Rank(), 'Alexa_Rank_By_Country' => $this->Alexa_Rank_By_Country(), 'Alexa_Visits_By_Country' => $this->Alexa_Visits_By_Country(), 'Alexa_Pageviews' => $this->Alexa_Pageviews(), 'Alexa_Pageviews_Per_User' => $this->Alexa_Pageviews_Per_User(), 'Alexa_Reach' => $this->Alexa_Reach(), 'Alexa_Bounce_Rate' => $this->Alexa_Bounce_Rate(), 'Alexa_Time_On_Site' => $this->Alexa_Time_On_Site(), 'Alexa_Search_Visits' => $this->Alexa_Search_Visits(), 'Alexa_Search_Visits_Keywords' => $this->Alexa_Search_Visits_Keywords(), 'Alexa_Search_Visits_Changes' => $this->Alexa_Search_Visits_Changes(), 'Alexa_Avg_Load_Time' => $this->Alexa_Avg_Load_Time() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * @access public * @return array Returns multi-array, containing all Facebook data. */ public function Facebook() { $all = array( 'FACEBOOK' => array( 'Facebook_Mentions_Total' => $this->Facebook_Mentions_Total(), 'Facebook_Mentions_Array' => $this->Facebook_Mentions_Array() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * @access public * @return array Returns multi-array, containing all Twitter data. */ public function Twitter() { $all = array( 'TWITTER' => array( 'Twitter_Mentions_Total' => $this->Twitter_Mentions_Total(), 'Twitter_Mentions_Array' => $this->Twitter_Mentions_Array() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * @access public * @return integer Returns a global unique ID (useful for database integration) */ public function Guid() { return SEOstats_Guid::CreateGUID($this->varGUID); } /** * Method processing might take a few more seconds! * * @access public * @return array Returns multi-array, containing all data but without Linkdetails. */ public function All_Totals() { $all = array( 'GOOGLE' => array( 'Google_Page_Rank' => $this->Google_Page_Rank(), 'Google_Siteindex_Total' => $this->Google_Siteindex_Total(), 'Google_Siteindex_Total_API' => $this->Google_Siteindex_Total_API(), 'Google_Backlinks_Total' => $this->Google_Backlinks_Total(), 'Google_Backlinks_Total_API' => $this->Google_Backlinks_Total_API(), 'Google_Mentions_Total' => $this->Google_Mentions_Total() ), 'YAHOO' => array( 'Yahoo_Siteindex_Total' => $this->Yahoo_Siteindex_Total(), 'Yahoo_Backlinks_Total' => $this->Yahoo_Backlinks_Total() ), 'BING' => array( 'Bing_Siteindex_Total' => $this->Bing_Siteindex_Total() ), 'SEOMOZ' => array( 'Seomoz_Domainauthority_Array' => $this->Seomoz_Domainauthority_Array() ), 'ALEXA' => array( 'Alexa_Global_Rank_Array' => $this->Alexa_Global_Rank_Array(), 'Alexa_Country_Rank' => $this->Alexa_Country_Rank(), 'Alexa_Rank_By_Country' => $this->Alexa_Rank_By_Country(), 'Alexa_Visits_By_Country' => $this->Alexa_Visits_By_Country(), 'Alexa_Pageviews' => $this->Alexa_Pageviews(), 'Alexa_Pageviews_Per_User' => $this->Alexa_Pageviews_Per_User(), 'Alexa_Reach' => $this->Alexa_Reach(), 'Alexa_Bounce_Rate' => $this->Alexa_Bounce_Rate(), 'Alexa_Time_On_Site' => $this->Alexa_Time_On_Site(), 'Alexa_Search_Visits' => $this->Alexa_Search_Visits(), 'Alexa_Search_Visits_Keywords' => $this->Alexa_Search_Visits_Keywords(), 'Alexa_Search_Visits_Changes' => $this->Alexa_Search_Visits_Changes(), 'Alexa_Avg_Load_Time' => $this->Alexa_Avg_Load_Time() ), 'FACEBOOK' => array( 'Facebook_Mentions_Total' => $this->Facebook_Mentions_Total() ), 'TWITTER' => array( 'Twitter_Mentions_Total' => $this->Twitter_Mentions_Total() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * Method processing might take a few more seconds! * * @access public * @return array Returns multi-array, containing all data. */ public function Everything() { $google = $this->Google(); $yahoo = $this->Yahoo(); $bing = $this->Bing(); $seomoz = $this->Seomoz(); $alexa = $this->Alexa(); $facebook = $this->Facebook(); $twitter = $this->Twitter(); $all = array( $google['DATA'], $yahoo['DATA'], $bing['DATA'], $seomoz['DATA'], $alexa['DATA'], $facebook['DATA'], $twitter['DATA'] ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * Custom Arrays * * @access public * @return array Returns multi-array, containing custom data. */ public function Custom() { $all = array( 'SEOMOZ' => array( 'Seomoz_Domainauthority_Array' => $this->Seomoz_Domainauthority_Array() ), 'FACEBOOK' => array( 'Facebook_Mentions_Total' => $this->Facebook_Mentions_Total() ), 'TWITTER' => array( 'Twitter_Mentions_Total' => $this->Twitter_Mentions_Total() ), 'GUID' => array( 'Global_Unique_ID' => $this->Guid() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * Social Arrays * * @access public * @return array Returns multi-array, containing social data. */ public function Social() { $all = array( 'FACEBOOK' => array( 'Facebook_Mentions_Total' => $this->Facebook_Mentions_Total() ), 'TWITTER' => array( 'Twitter_Mentions_Total' => $this->Twitter_Mentions_Total() ), 'GUID' => array( 'Global_Unique_ID' => $this->Guid() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } } ?>components/com_sef/libs/seostats/src/seostats.bing.php000066600000005430150771655450017252 0ustar00 * @copyright 2010-present, Chris Alvares/Stephan Schmitz * @license GNU General Public License (GPL) * * @filename ./seostats.bing.php * @desc Child class of SEOstats, extending the main class * by methods for http://www.bing.com * * @changelog * date author method: change(s) */ defined('_JEXEC') or die('Restricted access'); class SEOstats_Bing extends SEOstats { /** * Returns the total amount of pages for a Domain indexed at Bing * * @access public * @link http://www.bing.com:80/developers/ Get your own application ID here * @return integer Returns the total amount of pages for a Domain indexed at Bing */ public static function bingSiteIndexTotal($uri) { $url = 'http://api.bing.net/json.aspx?&Version=2.2&Market=en-US&Sources=web&Web.Count=1&JsonType=function'; $url .= '&AppId=' . BING_APP_ID; $url .= '&Query=site:' . urlencode($uri); $str = SEOstats::cURL($url); $str = str_ireplace("function BingGetResponse(){return", "", $str); $str = str_ireplace("; /* pageview_candidate */}", "", $str); $data = json_decode($str); return $data->SearchResponse->Web->Total; } /** * Returns array, containing details about the pages indexed at Bing * * @access public * @link http://www.bing.com:80/developers/ Get your own application ID here * @return array Returns array, containing details about the pages indexed at Bing */ public static function bingSiteindexArray($uri) { $url = 'http://api.bing.net/json.aspx?&Version=2.2&Market=en-US&Sources=web&Web.Count=50&JsonType=function'; $url .= '&AppId=' . BING_APP_ID; $url .= '&Query=site:' . urlencode($uri); $str = SEOstats::cURL($url); $str = str_ireplace("function BingGetResponse(){return", "", $str); $str = str_ireplace("; /* pageview_candidate */}", "", $str); $data = json_decode($str); $result = array(); foreach($data->SearchResponse->Web->Results as $entry) { $result[] = array( 'Title' => $entry->Title, 'URL' => $entry->DisplayUrl, 'Click URL' => $entry->Url ); } return $result; } } ?> components/com_sef/libs/seostats/src/index.html000066600000000054150771655450015750 0ustar00components/com_sef/libs/seostats/src/seostats.exception.php000066600000001145150771655450020330 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) * * EXCEPTION */ defined('_JEXEC') or die('Restricted access'); class SEOstatsException extends Exception {} if (!function_exists('curl_init')) { throw new SEOstatsException('SEOstats needs the PHP CURL extension.'); } if (!function_exists('json_decode')) { throw new SEOstatsException('SEOstats needs the PHP JSON extension.'); } ?>components/com_sef/libs/seostats/src/seostats.yahoo.php000066600000006006150771655450017452 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) */ defined('_JEXEC') or die('Restricted access'); class SEOstats_Yahoo extends SEOstats { /** * Returns the total amount of pages for a Domain indexed at Yahoo! * * @access private * @link http://developer.yahoo.com/search/siteexplorer/ Get your own application ID here * @return integer Returns the total amount of pages for a Domain indexed at Yahoo! */ public static function yahooSiteindexTotal($uri) { $url = 'http://search.yahooapis.com/SiteExplorerService/V1/pageData?appid='; $url .= YAHOO_APP_ID; $url .= '&results=1&output=json&query=http://'.urlencode($uri); $str = SEOstats::cURL($url); $data = json_decode($str); return $data->ResultSet->totalResultsAvailable; } /** * Returns array, containing details about the pages indexed at Yahoo! * * @access private * @return array Returns array, containing details about the pages indexed at Yahoo! */ public static function yahooSiteindexArray($uri) { $tsv_url = 'http://siteexplorer.search.yahoo.com/de/export;_ylt=?p='. urlencode($uri).'&bwmf=s&fr=sfp&fr2=seo-rd-se'; $result = array(); foreach ( file($tsv_url) as $line ) { $tmp = explode("\t", $line); if ( isset($tmp[1]) && !empty($tmp[1]) && $tmp[1] != "URL" ) { $result[] = array( 'Title' => utf8_decode($tmp[0]), 'URL' => $tmp[1] ); } } return $result; } /** * Returns the total amount of Backlinks indexed at Yahoo! * * @access private * @link http://developer.yahoo.com/search/siteexplorer/ Get your own application ID here * @return integer Returns the total amount of backlinks indexed at Yahoo! */ public static function yahooBacklinksTotal($uri) { $url = 'http://search.yahooapis.com/SiteExplorerService/V1/inlinkData?appid='; $url .= YAHOO_APP_ID; $url .= '&results=1&output=json&query=http://'.urlencode($uri); $str = SEOstats::cURL($url); $data = json_decode($str); return $data->ResultSet->totalResultsAvailable; } /** * Returns an array containing details about the backlinks indexed at Yahoo! * * @access private * @return array Returns an array containing details about the backlinks indexed at Yahoo! */ public static function yahooBacklinksArray($uri) { $tsv_url = 'http://siteexplorer.search.yahoo.com/de/export;_ylt=?p='. urlencode($uri).'&bwm=i&bwmf=s&fr=sfp&fr2=seo-rd-se'; $result = array(); foreach ( file($tsv_url) as $line ) { $tmp = explode("\t", $line); if ( isset($tmp[1]) && !empty($tmp[1]) && $tmp[1] != "URL" ) { $result[] = array( 'URL' => $tmp[1], 'Anchortext' => utf8_decode($tmp[0]) ); } } return $result; } } ?>components/com_sef/libs/seostats/src/class.seostats.config.php.backup000066600000002065150771655450022151 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) * * @filename ./class.seostats.config.php * @desc Defines some global used class constants. * * @changelog * date author change(s) * 2011/08/04 Stephan Schmitz Defined BING_APP_ID constant. */ define('GOOGLE_TLD', 'com'); define('USE_PAGERANK_CHECKSUM_API', true); /** * Optional changes. */ define('YAHOO_APP_ID', 'oVFwwjnV34GEEZTLB3K_WW1YC9_VysYbCYQ4szoXTAHZscrDvMazUpFR7TR0wchmlA--'); define('BING_APP_ID', 'FCB316D398F094C53B8C7AA8DA24B2D58AB520F8'); define('SEOMOZ_ACCESS_ID', 'member-881a55bcfb'); define('SEOMOZ_SECRET_KEY', '7145d56a1279285be92e6e4875bba8ee'); ?> components/com_sef/libs/seostats/src/seostats.twitter.php000066600000004377150771655450020046 0ustar00 * @copyright 2010-present, Stephan Schmitz, Florent Cima * @license GNU General Public License (GPL) * * @filename ./seostats.twitter.php * @desc Child class of SEOstats, extending the main class * by methods for http://www.twitter.com * * @changelog * date author method: change(s) * 2011/08/08 Florent Cima first commit */ defined('_JEXEC') or die('Restricted access'); class SEOstats_Twitter extends SEOstats { /** * Returns the total amount of twitter mentions for a single page * * @access public * @param url string The URL to check. * @return integer Returns the total of twitter mentions for a single page. */ function getTweetCount($url) { $url = urlencode($url); $twitterEndpoint = "http://urls.api.twitter.com/1/urls/count.json?url=%s"; $fileData = file_get_contents(sprintf($twitterEndpoint, $url)); $json = json_decode($fileData, true); unset($fileData); // free memory return $json['count']; } /** * Returns the total amount of twitter mentions for entire domain * * @access public * @param uri string The URI to check. * @return integer Returns the total of twitter mentions for the entire domain. */ public static function backtweets($uri) { $tmp = SEOstats::cURL( 'http://backtweets.com/search?q='.$uri ); $dom = new DOMDocument(); @$dom->loadHTML($tmp); $xpath = new DOMXPath($dom); $p = $xpath->query('//div/ol/li'); $r = $p->item(2)->textContent; $r = str_replace(',', '', $r); $r = str_replace('Results', '', $r); $r = str_replace('Result', '', $r); $r = trim($r); return ($r != '') ? $r : intval('0'); } } ?> components/com_sef/libs/seostats/src/class.seostats.php.backup000066600000100332150771655450020701 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) * @link http://www.gnu.org/copyleft/gpl.html *======================================================================= * @filename ./class.seostats.php * @description SEOstats main class file that includes the child classes * and the config and contains all public methods. *======================================================================= * @changelog * date author method: change(s) * 2011/09/06 Stephan Schmitz Removed Majesticseo methods. * 2011/08/04 Stephan Schmitz Added method Bing_Siteindex_Total() * Added method Bing_Siteindex_Array() * Added method Bing() * Updated constant * PAGERANK_CHECKSUM_API_URI * Removed pre tags when output of the * print_array() method is json *======================================================================= * Note: The above changelog is related to this file only. Each file of * the package has it's own changelog in the head section. For a general * changelog, please see the CHANGELOG file. *======================================================================= * Copyright (c) 2010-present, Stephan Schmitz * All rights reserved. *======================================================================= * Project Contributors (Alphabetically by first names): * * |Chris Alvares * |-> contributed the BING child class * * |Florent Cima * |-> code fix for SEOstats_Majesticseo::report * * |http://code.google.com/u/@UxJTQFFRABFDXwZ%2F/ * |-> code fix for SEOstats_Google::googleTotal2 *======================================================================= * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Neither the name of the Author nor the name of the Product * may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***********************************************************************/ include_once('class.seostats.config.php'); include_once('modules.php'); class SEOstats { const BUILD_NO = '2.0.8.2'; const PAGERANK_CHECKSUM_API_URI = 'http://pagerank.bexton.net/?url='; /** * Object URL * * @access public * @var string */ public $url; /** * Constructor * * Checks for valid URL syntax and server response. * * @access public * @param string $url String, containing the initialized * object URL. */ public function __construct($url) { $url = str_replace(' ', '+', $url); $this->url = $url; $url_validation = $this->valid_url($this->url); if($url_validation == 'valid') { $valid_response_codes = array('200','301','302'); $curl_result = $this->get_status_code($this->url); if(in_array($curl_result,$valid_response_codes)) { $this->host = parse_url($this->url, PHP_URL_HOST); $this->protocol = parse_url($this->url, PHP_URL_SCHEME); } elseif($curl_result == '0') { $e = 'Invalid URL > '.$this->url.' returned no response for a HTTP HEAD request, at all. It seems like the Domain does not exist.'; $this->errlogtxt($e); throw new SEOstatsException($e); } else { $e = 'Invalid Request > '.$this->url.' returned a '.$curl_result.' status code.'; $this->errlogtxt($e); throw new SEOstatsException($e); } } else { $e = $url_validation; $this->errlogtxt($e); throw new SEOstatsException($e); } } function errlogtxt($errtxt) { $fp = fopen('errlog.txt','a+'); //ouvrir le fichier $newerr = date('Y-m-d\TH:i:sP') .' : ' . $errtxt."\r\n"; //creation du texte de l'erreur fwrite($fp,$newerr); //edition du fichier texte fclose($fp); //fermeture du fichier texte echo $newerr; } /** * HTTP GET request with curl. * * @access private * @param string $url String, containing the URL to curl. * @return string Returns string, containing the curl result. * */ public static function cURL($url) { $ch = curl_init($url); curl_setopt($ch,CURLOPT_USERAGENT,'GoogleHttpClient'); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,5); curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1); curl_setopt($ch,CURLOPT_MAXREDIRS,2); if(strtolower(parse_url($url, PHP_URL_SCHEME)) == 'https') { curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,1); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,1); } $str = curl_exec($ch); curl_close($ch); return $str; } /** * HTTP HEAD request with curl. * * @access private * @param string $url String, containing the * initialized object URL. * @return intval Returns a HTTP status code. */ private function get_status_code($url) { $ch = curl_init($url); curl_setopt($ch,CURLOPT_USERAGENT,'GoogleHttpClient'); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch,CURLOPT_NOBODY,1); curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,5); $str = curl_exec($ch); $int = curl_getinfo($ch,CURLINFO_HTTP_CODE); curl_close($ch); return intval($int); } /** * Validates the initialized object URL syntax. * * @access private * @param string $url String, containing the initialized object URL. * @return string Returns string, containing the validation result. */ private function valid_url($url) { $allowed_schemes = array('http','https'); $host = parse_url($url, PHP_URL_HOST); $scheme = parse_url($url, PHP_URL_SCHEME); if(!isset($url) || empty($url) || $url = '') { $e = 'Invalid Object > Requires an URL.'; } else { if(!in_array(strtolower($scheme),$allowed_schemes)) { $e = 'Invalid URL > SEOstats supports soley RFC compliant URL\'s with HTTP(/S) protocol.'; } elseif(empty($host) || $host == '') { $e = 'Invalid URL > Hostname undefined (or invalid URL syntax).'; } else { /** * Regex pattern found in and copied from the Nutch source * @url {http://nutch.apache.org/} * * Fyi: For the following reason, i decided to stay with preg_match. * * Testing 10k URL's, returned an average execution time (in seconds, per URL) of: * if(!preg_match($pattern,$this->url)) * 0.000104904174805 * if(!filter_var($this->url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED)) * 0.000140905380249 */ $pattern = '([A-Za-z][A-Za-z0-9+.-]{1,120}:[A-Za-z0-9/](([A-Za-z0-9$_.+!*,;/?:@&~=-])'; $pattern .= '|%[A-Fa-f0-9]{2}){1,333}(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*,;/?:@&~=%-]{0,1000}))?)'; if(!preg_match($pattern,$this->url)) { $e = 'Invalid URL > Invalid URL syntax.'; } else { $e = 'valid'; } } } return $e; } /** * Just a 'quicker' way to print an array of a method's result. * * @param string $method String, containing a method name. * @param string $output Optional Parameter. If set to json, * output will be a json encoded array. * @access public * @return string Prints an array within
     tags.
         */
        public function print_array($method,$output='json')
        {
            if($output=='json')
            {
                print_r (json_encode($this->$method()));
            }
            else
            {
                print '
    ';
                print_r ($this->$method());
                print '
    '; } } /** * @access public * @return integer Returns the Google PageRank. */ public function Google_Page_Rank() { return SEOstats_Google::Google_PR($this->host); } /** * @access public * @return integer Returns the total amount of results for a Google 'site:'-search on the object URL. */ public function Google_Siteindex_Total() { $q = urlencode('site:'.$this->host); return SEOstats_Google::googleTotal($q); } /** * @access public * @return integer Returns the total amount of results for a Google 'site:'-search on the object URL. */ public function Google_Siteindex_Total_API() { $q = urlencode('site:'.$this->host); return SEOstats_Google::googleTotal2($q); } /** * Limited to 1000 results, due to Google. * * @access public * @return array Returns array, containing foreach 'site:'-search result the keys 'URL', 'Title' and 'Description'. */ public function Google_Siteindex_Array() { $q = urlencode('site:'.$this->host); return SEOstats_Google::googleArray($q); } /** * @access public * @return integer Returns the total amount of results for a Google 'link:'-search on the object URL. */ public function Google_Backlinks_Total() { $q = urlencode('link:'.$this->host); return SEOstats_Google::googleTotal($q); } /** * @access public * @return integer Returns the total amount of results for a Google 'site:'-search on the object URL. */ public function Google_Backlinks_Total_API() { $q = urlencode('link:'.$this->host); return SEOstats_Google::googleTotal2($q); } /** * Limited to 1000 results, due to Google. * * @access public * @return array Returns array, containing foreach 'link:'-search result the keys 'URL', 'Title' and 'Description'. */ public function Google_Backlinks_Array() { $q = urlencode('link:'.$this->host); return SEOstats_Google::googleArray($q); } /** * @access public * @return integer Returns the total amount of results for an exact match Google search on the object URL. */ public function Google_Mentions_Total() { $q = urlencode('"'.$this->host.'" -site:'.$this->host.''); return SEOstats_Google::googleTotal($q); } /** * Limited to 1000 results, due to Google. * * @access public * @return array Returns array, containing foreach exact match search result the keys 'URL', 'Title' and 'Description'. */ public function Google_Mentions_Array() { $q = urlencode('"'.$this->host.'" -site:'.$this->host.''); return SEOstats_Google::googleArray($q); } /** * Returns Onsite Optimization Tips (for better page performance) by Google. * * @access public * @returun array Returns array, containing the page analysis results. */ public function Google_Performance_Analysis() { return SEOstats_Google::performanceAnalysis($this->host); } /** * Returns the Google Pagespeed Score. * Score is between 0 (worst) and 100 (best). * * @access public * @returun integer Returns a number between 0 - 100. */ public function Google_Pagespeed_Score() { return SEOstats_Google::pagespeedScore($this->host); } /** * @access public * @return integer Returns the total amount of pages for the domain, indexed at Yahoo!. */ public function Yahoo_Siteindex_Total() { return SEOstats_Yahoo::yahooSiteindexTotal($this->host); } /** * Limited to 100 results. * * @access public * @return integer Returns array, containing the keys 'Title', 'URL' and 'Click URL'. */ public function Yahoo_Siteindex_Array() { return SEOstats_Yahoo::yahooSiteindexArray($this->host); } /** * @access public * @return integer Returns the total amount of backlinks to the domain, listed at Yahoo!. */ public function Yahoo_Backlinks_Total() { return SEOstats_Yahoo::yahooBacklinksTotal($this->host); } /** * Limited to 100 results. * * @access public * @return integer Returns array, containing the keys 'URL' and 'Anchortext'. */ public function Yahoo_Backlinks_Array() { return SEOstats_Yahoo::yahooBacklinksArray($this->host); } /** * @access public * @return integer Returns the total amount of pages for the domain, indexed at Yahoo!. */ public function Bing_Siteindex_Total() { return SEOstats_Bing::bingSiteindexTotal($this->host); } /** * Limited to 50 results. * * @access public * @return integer Returns array, containing the keys 'Title', 'URL' and 'Click URL'. */ public function Bing_Siteindex_Array() { return SEOstats_Bing::bingSiteindexArray($this->host); } /** * @access public * @return array Returns array, containing the keys 'URL Authority', 'URL mozRank', 'Domain Authority' and 'Domain mozRank'. */ public function Seomoz_Domainauthority_Array() { return SEOstats_Seomoz::Seomoz_Authority($this->host); } /** * Limited to 25 links per source domain, due to using a free API key. * * @access public * @link http://apiwiki.seomoz.org/w/page/27002419/Glossary Response Format, Term Conventions * @return array Returns multi-array, containing backlink details. */ public function Seomoz_Linkdetails_Array() { return SEOstats_Seomoz::Seomoz_Links($this->host); } /** * @access public * @return integer Returns the Alexa Global Rank. */ public function Alexa_Global_Rank_Array() { return SEOstats_Alexa::extractSingle('div','id','rank','0',$this->host,true); } /** * @access public * @return integer Returns the Alexa Country Rank. */ public function Alexa_Country_Rank() { return SEOstats_Alexa::extractSingle('div','class','data','1',$this->host,false); } /** * @access public * @return array Returns multi-array, containing data from Alexa about the total pageviews. */ public function Alexa_Pageviews() { return SEOstats_Alexa::extractSingle('div','id','pageviews','0',$this->host,true); } /** * @access public * @return array Returns multi-array, containing data from Alexa about pageviews per user. */ public function Alexa_Pageviews_Per_User() { return SEOstats_Alexa::extractSingle('div','id','pageviews_per_user','0',$this->host,true); } /** * @access public * @return array Returns multi-array, containing data from Alexa about the reach. */ public function Alexa_Reach() { return SEOstats_Alexa::extractSingle('div','id','reach','0',$this->host,true); } /** * @access public * @return array Returns multi-array, containing data from Alexa about the bounce rate. */ public function Alexa_Bounce_Rate() { return SEOstats_Alexa::extractSingle('div','id','bounce','0',$this->host,true); } /** * @access public * @return array Returns multi-array, containing data from Alexa about the avg time, users stay on the site. */ public function Alexa_Time_On_Site() { return SEOstats_Alexa::extractSingle('div','id','time_on_site','0',$this->host,true); } /** * @access public * @return array Returns multi-array, containing data from Alexa about visitors from searches. */ public function Alexa_Search_Visits() { return SEOstats_Alexa::extractSingle('div','id','search','0',$this->host,true); } /** * @access public * @return array Returns multi-array, containing the Visits by Country. */ public function Alexa_Visits_By_Country() { return SEOstats_Alexa::Alexa_VBC($this->url); } /** * @access public * @return array Returns multi-array, containing the Alexa Rank, sorted by Country. */ public function Alexa_Rank_By_Country() { return SEOstats_Alexa::Alexa_RBC($this->url); } /** * @access public * @return array Returns multi-array, containing data from Alexa about keywords from search visits. */ public function Alexa_Search_Visits_Keywords() { return SEOstats_Alexa::Alexa_SV_Keywords($this->url); } /** * @access public * @return array Returns multi-array, containing data from Alexa about changes of incoming search terms. */ public function Alexa_Search_Visits_Changes() { return SEOstats_Alexa::Alexa_SV_Changes($this->url); } /** * @access public * @return string Returns string, containing the average load time of the URL from Alexa. */ public function Alexa_Avg_Load_Time() { return SEOstats_Alexa::Alexa_Load_Time($this->url); } /** * @access public * @param integer $type Specifies the graph type. Valid values are 1 to 6. * @param integer $width Specifies the graph width (in px). * @param integer $height Specifies the graph height (in px). * @param integer $period Specifies the displayed time period. Valid values are 1 to 12. * @return string Returns a string, containing the HTML code of an image, showing Alexa Statistics as Graph. */ public function Alexa_Graph($type='1',$width='660',$height='330',$period='1') { switch($type) { case 1: $gtype = 't'; break; case 2: $gtype = 'p'; break; case 3: $gtype = 'u'; break; case 4: $gtype = 's'; break; case 5: $gtype = 'b'; break; case 6: $gtype = 'q'; break; default:break; } $graph = 'Alexa Statistics Graph for '.$this->url.''; return $graph; } /** * @access public * @return integer Returns the total amount of Facebook pages mention the URL. */ public function Facebook_Mentions_Total() { return SEOstats_Facebook::getFacebookShares($this->url); } /** * Limited to 1000 results. * * @access public * @return array Returns array, containing detailed results about Facebook pages mention the URL. */ public function Facebook_Mentions_Array() { $q = urlencode('site:facebook.com "'.$this->host.'"'); return SEOstats_Google::googleArray($q); } /** * Returns the internal ID, the Facebook Graph API registers to - and uses for identifying - a Domain. * * @access public * @link http://developers.facebook.com/docs/reference/api/domain/ * @param host string The URL to get the ID for. * @return integer Returns 0, or the unique Domain-ID. */ public function Facebook_GraphApi_DomainId_ByHostname() { return SEOstats_Facebook::fbGraphApiIdByHost($this->host); } /** * @access public * @return integer Returns the total amount of Twitter pages mention the URL. */ public function Twitter_Mentions_Total() { return SEOstats_Twitter::getTweetCount($this->url); } /** * Limited to 1000 results. * * @access public * @return array Returns array, containing detailed results about Twitter pages mention the URL. */ public function Twitter_Mentions_Array() { $q = urlencode('site:twitter.com "'.$this->host.'"'); return SEOstats_Google::googleArray($q); } /** * @access public * @return array Returns multi-array, containing all Google data. */ public function Google() { $all = array( 'GOOGLE' => array( 'Google_Page_Rank' => $this->Google_Page_Rank(), 'Google_Siteindex_Total' => $this->Google_Siteindex_Total(), 'Google_Siteindex_Total_API' => $this->Google_Siteindex_Total_API(), 'Google_Siteindex_Array' => $this->Google_Siteindex_Array(), 'Google_Backlinks_Total' => $this->Google_Backlinks_Total(), 'Google_Backlinks_Total_API' => $this->Google_Backlinks_Total_API(), 'Google_Backlinks_Array' => $this->Google_Backlinks_Array(), 'Google_Mentions_Total' => $this->Google_Mentions_Total(), 'Google_Mentions_Array' => $this->Google_Mentions_Array() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * @access public * @return array Returns multi-array, containing all Yahoo! data. */ public function Yahoo() { $all = array( 'YAHOO' => array( 'Yahoo_Siteindex_Total' => $this->Yahoo_Siteindex_Total(), 'Yahoo_Siteindex_Array' => $this->Yahoo_Siteindex_Array(), 'Yahoo_Backlinks_Total' => $this->Yahoo_Backlinks_Total(), 'Yahoo_Backlinks_Array' => $this->Yahoo_Backlinks_Array() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * @access public * @return array Returns multi-array, containing all Bing data. */ public function Bing() { $all = array( 'YAHOO' => array( 'Bing_Siteindex_Total' => $this->Bing_Siteindex_Total(), 'Bing_Siteindex_Array' => $this->Bing_Siteindex_Array() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * @access public * @return array Returns multi-array, containing all SEOmoz data. */ public function Seomoz() { $all = array( 'SEOMOZ' => array( 'Seomoz_Domainauthority_Array' => $this->Seomoz_Domainauthority_Array(), 'Seomoz_Linkdetails_Array' => $this->Seomoz_Linkdetails_Array() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * @access public * @return array Returns multi-array, containing all Alexa data. */ public function Alexa() { $all = array( 'ALEXA' => array( 'Alexa_Global_Rank_Array' => $this->Alexa_Global_Rank_Array(), 'Alexa_Country_Rank' => $this->Alexa_Country_Rank(), 'Alexa_Rank_By_Country' => $this->Alexa_Rank_By_Country(), 'Alexa_Visits_By_Country' => $this->Alexa_Visits_By_Country(), 'Alexa_Pageviews' => $this->Alexa_Pageviews(), 'Alexa_Pageviews_Per_User' => $this->Alexa_Pageviews_Per_User(), 'Alexa_Reach' => $this->Alexa_Reach(), 'Alexa_Bounce_Rate' => $this->Alexa_Bounce_Rate(), 'Alexa_Time_On_Site' => $this->Alexa_Time_On_Site(), 'Alexa_Search_Visits' => $this->Alexa_Search_Visits(), 'Alexa_Search_Visits_Keywords' => $this->Alexa_Search_Visits_Keywords(), 'Alexa_Search_Visits_Changes' => $this->Alexa_Search_Visits_Changes(), 'Alexa_Avg_Load_Time' => $this->Alexa_Avg_Load_Time() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * @access public * @return array Returns multi-array, containing all Facebook data. */ public function Facebook() { $all = array( 'FACEBOOK' => array( 'Facebook_Mentions_Total' => $this->Facebook_Mentions_Total(), 'Facebook_Mentions_Array' => $this->Facebook_Mentions_Array() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * @access public * @return array Returns multi-array, containing all Twitter data. */ public function Twitter() { $all = array( 'TWITTER' => array( 'Twitter_Mentions_Total' => $this->Twitter_Mentions_Total(), 'Twitter_Mentions_Array' => $this->Twitter_Mentions_Array() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * @access public * @return integer Returns a global unique ID (useful for database integration) */ public function Guid() { return SEOstats_Guid::CreateGUID($this->varGUID); } /** * Method processing might take a few more seconds! * * @access public * @return array Returns multi-array, containing all data but without Linkdetails. */ public function All_Totals() { $all = array( 'GOOGLE' => array( 'Google_Page_Rank' => $this->Google_Page_Rank(), 'Google_Siteindex_Total' => $this->Google_Siteindex_Total(), 'Google_Siteindex_Total_API' => $this->Google_Siteindex_Total_API(), 'Google_Backlinks_Total' => $this->Google_Backlinks_Total(), 'Google_Backlinks_Total_API' => $this->Google_Backlinks_Total_API(), 'Google_Mentions_Total' => $this->Google_Mentions_Total() ), 'YAHOO' => array( 'Yahoo_Siteindex_Total' => $this->Yahoo_Siteindex_Total(), 'Yahoo_Backlinks_Total' => $this->Yahoo_Backlinks_Total() ), 'BING' => array( 'Bing_Siteindex_Total' => $this->Bing_Siteindex_Total() ), 'SEOMOZ' => array( 'Seomoz_Domainauthority_Array' => $this->Seomoz_Domainauthority_Array() ), 'ALEXA' => array( 'Alexa_Global_Rank_Array' => $this->Alexa_Global_Rank_Array(), 'Alexa_Country_Rank' => $this->Alexa_Country_Rank(), 'Alexa_Rank_By_Country' => $this->Alexa_Rank_By_Country(), 'Alexa_Visits_By_Country' => $this->Alexa_Visits_By_Country(), 'Alexa_Pageviews' => $this->Alexa_Pageviews(), 'Alexa_Pageviews_Per_User' => $this->Alexa_Pageviews_Per_User(), 'Alexa_Reach' => $this->Alexa_Reach(), 'Alexa_Bounce_Rate' => $this->Alexa_Bounce_Rate(), 'Alexa_Time_On_Site' => $this->Alexa_Time_On_Site(), 'Alexa_Search_Visits' => $this->Alexa_Search_Visits(), 'Alexa_Search_Visits_Keywords' => $this->Alexa_Search_Visits_Keywords(), 'Alexa_Search_Visits_Changes' => $this->Alexa_Search_Visits_Changes(), 'Alexa_Avg_Load_Time' => $this->Alexa_Avg_Load_Time() ), 'FACEBOOK' => array( 'Facebook_Mentions_Total' => $this->Facebook_Mentions_Total() ), 'TWITTER' => array( 'Twitter_Mentions_Total' => $this->Twitter_Mentions_Total() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * Method processing might take a few more seconds! * * @access public * @return array Returns multi-array, containing all data. */ public function Everything() { $google = $this->Google(); $yahoo = $this->Yahoo(); $bing = $this->Bing(); $seomoz = $this->Seomoz(); $alexa = $this->Alexa(); $facebook = $this->Facebook(); $twitter = $this->Twitter(); $all = array( $google['DATA'], $yahoo['DATA'], $bing['DATA'], $seomoz['DATA'], $alexa['DATA'], $facebook['DATA'], $twitter['DATA'] ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * Custom Arrays * * @access public * @return array Returns multi-array, containing custom data. */ public function Custom() { $all = array( 'SEOMOZ' => array( 'Seomoz_Domainauthority_Array' => $this->Seomoz_Domainauthority_Array() ), 'FACEBOOK' => array( 'Facebook_Mentions_Total' => $this->Facebook_Mentions_Total() ), 'TWITTER' => array( 'Twitter_Mentions_Total' => $this->Twitter_Mentions_Total() ), 'GUID' => array( 'Global_Unique_ID' => $this->Guid() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } /** * Social Arrays * * @access public * @return array Returns multi-array, containing social data. */ public function Social() { $all = array( 'FACEBOOK' => array( 'Facebook_Mentions_Total' => $this->Facebook_Mentions_Total() ), 'TWITTER' => array( 'Twitter_Mentions_Total' => $this->Twitter_Mentions_Total() ), 'GUID' => array( 'Global_Unique_ID' => $this->Guid() ) ); return array('OBJECT' => $this->url, 'DATA' => $all); } } ?> components/com_sef/libs/seostats/src/modules.php000066600000001236150771655450016137 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) * * GLOBALS */ defined('_JEXEC') or die('Restricted access'); include_once('seostats.google.php'); include_once('seostats.yahoo.php'); include_once('seostats.seomoz.php'); include_once('seostats.alexa.php'); include_once('seostats.exception.php'); include_once('seostats.bing.php'); include_once('seostats.facebook.php'); include_once('seostats.twitter.php'); include_once('seostats.guid.php'); ?>components/com_sef/libs/seostats/src/seostats.facebook.php000066600000004444150771655450020110 0ustar00, * Stephan Schmitz * @copyright 2010-present, Stephan Schmitz, Florent Cima * @license GNU General Public License (GPL) * * @filename ./seostats.facebook.php * @desc Child class of SEOstats, extending the main class * by methods for http://www.facebook.com * * @changelog * date author method: change(s) * 2011/08/08 Florent Cima first commit * 2011/09/15 Stephan Schmitz Updated SEOstats_Facebook::getFacebookShares */ defined('_JEXEC') or die('Restricted access'); class SEOstats_Facebook extends SEOstats { /** * Returns the total amount of Facebook Shares for a single page * * @access public * @link https://graph.facebook.com/ * @param q string The URL to check. * @return integer Returns the total amount of Facebook */ public static function getFacebookShares($q) { $url = 'http://graph.facebook.com/?id='; // Parameters $url .= urlencode($q); //Execution and result of Json in $str $str = SEOstats::cURL($url); //Decode Json object $data = json_decode($str); //Return only number of facebook shares $r = $data->shares; return ($r != NULL) ? $r : intval('0'); } /** * Returns the internal ID, the Facebook Graph API registers to - and uses for identifying - a Domain. * * @access public * @link http://developers.facebook.com/docs/reference/api/domain/ * @param host string The URL to get the ID for. * @return integer Returns 0, or the unique Domain-ID. */ public static function fbGraphApiIdByHost($host) { $url = 'http://graph.facebook.com/?domain=' . $host; $str = SEOstats::cURL($url); $obj = json_decode($str); return (isset($obj->id) && $obj->id != NULL) ? $obj->id : intval('0'); } } ?> components/com_sef/libs/seostats/src/ext/SeoMoz/index.html000066600000000054150771655450017764 0ustar00components/com_sef/libs/seostats/src/ext/SeoMoz/LinksConstants.php000066600000005255150771655450021465 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) */ defined('_JEXEC') or die('Restricted access'); define('LINKS_SCOPE_PAGE_TO_PAGE', 'page_to_page'); define('LINKS_SCOPE_PAGE_TO_SUBDOMAIN', 'page_to_subdomain'); define('LINKS_SCOPE_PAGE_TO_DOMAIN', 'page_to_domain'); define('LINKS_SCOPE_DOMAIN_TO_PAGE', 'domain_to_page'); define('LINKS_SCOPE_DOMAIN_TO_SUBDOMAIN', 'domain_to_subdomain'); define('LINKS_SCOPE_DOMAIN_TO_DOMAIN', 'domain_to_domain'); define('LINKS_SORT_PAGE_AUTHORITY', 'page_authority'); define('LINKS_SORT_DOMAIN_AUTHORITY', 'domain_authority'); define('LINKS_SORT_DOMAINS_LINKING_DOMAIN', 'domains_linking_domain'); define('LINKS_SORT_DOMAINS_LINKING_PAGE', 'domains_linking_page'); define('LINKS_FILTER_INTERNAL', 'internal'); define('LINKS_FILTER_EXTERNAL', 'external'); define('LINKS_FILTER_NOFOLLOW', 'nofollow'); define('LINKS_FILTER_FOLLOW', 'follow'); define('LINKS_FILTER_301', '301'); define('LINKS_COL_ALL', '0'); define('LINKS_COL_TITLE', '1'); define('LINKS_COL_URL', '4'); define('LINKS_COL_SUBDOMAIN', '8'); define('LINKS_COL_ROOT_DOMAIN', '16'); define('LINKS_COL_EXTERNAL_LINKS', '32'); define('LINKS_COL_SUBDMN_EXTERNAL_LINKS', '64'); define('LINKS_COL_ROOTDMN_EXTERNAL_LINKS', '128'); define('LINKS_COL_JUICE_PASSING_LINKS', '256'); define('LINKS_COL_SUBDMN_LINKS', '512'); define('LINKS_COL_ROOTDMN_LINKS', '1024'); define('LINKS_COL_LINKS', '2048'); define('LINKS_COL_SUBDMN_SUBDMN_LINKS', '4096'); define('LINKS_COL_ROOTDMN_ROOTDMN_LINKS', '8192'); define('LINKS_COL_MOZRANK', '16384'); define('LINKS_COL_SUBDMN_MOZRANK', '32768'); define('LINKS_COL_ROOTDMN_MOZRANK', '65536'); define('LINKS_COL_MOZTRUST', '131072'); define('LINKS_COL_SUBDMN_MOZTRUST', '262144'); define('LINKS_COL_ROOTDMN_MOZTRUST', '524288'); define('LINKS_COL_EXTERNAL_MOZRANK', '1048576'); define('LINKS_COL_SUBDMN_EXTERNALDMN_JUICE', '2097152'); define('LINKS_COL_ROOTDMN_EXTERNALDMN_JUICE', '4194304'); define('LINKS_COL_SUBDMN_DOMAIN_JUICE', '8388608'); define('LINKS_COL_ROOTDMN_DOMAIN_JUICE', '16777216'); define('LINKS_COL_CANONICAL_URL', '268435456'); define('LINKS_COL_HTTP_STATUS_CODE', '536870912'); define('LINKS_COL_LINKS_TO_SUBDMN', '4294967296'); define('LINKS_COL_LINKS_TO_ROOTDMN', '8589934592'); define('LINKS_COL_ROOTDMN_LINKS_SUBDMN', '17179869184'); define('LINKS_COL_PAGE_AUTHORITY', '34359738368'); define('LINKS_COL_DOMAIN_AUTHORITY', '68719476736'); ?>components/com_sef/libs/seostats/src/ext/SeoMoz/Authenticator.php000066600000004413150771655450021315 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) */ defined('_JEXEC') or die('Restricted access'); class Authenticator { /** * accessID The user's Access ID */ private $accessID = SEOMOZ_ACCESS_ID; /** * secretKey The user's Secret Key */ private $secretKey = SEOMOZ_SECRET_KEY; /** * expiresInterval The interval after which the authentication string expires * Default 300s */ private $expiresInterval = 300; /** * * This method calculates the authentication String based on the * user's credentials. * * Set the user credentials before calling this method * * @return the authentication string * * @see #setAccessID(String) * @see #setSecretKey(String) */ public function getAuthenticationStr() { $expires = time() + $this->expiresInterval; $stringToSign = $this->accessID."\n".$expires; $binarySignature = hash_hmac('sha1', $stringToSign, $this->secretKey, true); // We need to base64-encode it and then url-encode that. $urlSafeSignature = urlencode(base64_encode($binarySignature)); $authenticationStr = "AccessID=".$this->accessID."&Expires=".$expires."&Signature=".$urlSafeSignature; return $authenticationStr; } /** * @return the $accessID */ public function getAccessID() { return $this->accessID; } /** * @return the $secretKey */ public function getSecretKey() { return $this->secretKey; } /** * @param $accessID the $accessID to set */ public function setAccessID($accessID) { $this->accessID = $accessID; } /** * @param $secretKey the $secretKey to set */ public function setSecretKey($secretKey) { $this->secretKey = $secretKey; } /** * @return the $expiresInterval */ public function getExpiresInterval() { return $this->expiresInterval; } /** * @param $expiresInterval the $expiresInterval to set */ public function setExpiresInterval($expiresInterval) { $this->expiresInterval = $expiresInterval; } } ?>components/com_sef/libs/seostats/src/ext/SeoMoz/URLMetricsConstants.php000066600000003767150771655450022404 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) */ defined('_JEXEC') or die('Restricted access'); define('URLMETRICS_COL_ALL', '0'); define('URLMETRICS_COL_TITLE', '1'); define('URLMETRICS_COL_URL', '4'); define('URLMETRICS_COL_SUBDOMAIN', '8'); define('URLMETRICS_COL_ROOT_DOMAIN', '16'); define('URLMETRICS_COL_EXTERNAL_LINKS', '32'); define('URLMETRICS_COL_SUBDMN_EXTERNAL_LINKS', '64'); define('URLMETRICS_COL_ROOTDMN_EXTERNAL_LINKS', '128'); define('URLMETRICS_COL_JUICE_PASSING_LINKS', '256'); define('URLMETRICS_COL_SUBDMN_LINKS', '512'); define('URLMETRICS_COL_ROOTDMN_LINKS', '1024'); define('URLMETRICS_COL_LINKS', '2048'); define('URLMETRICS_COL_SUBDMN_SUBDMN_LINKS', '4096'); define('URLMETRICS_COL_ROOTDMN_ROOTDMN_LINKS', '8192'); define('URLMETRICS_COL_MOZRANK', '16384'); define('URLMETRICS_COL_SUBDMN_MOZRANK', '32768'); define('URLMETRICS_COL_ROOTDMN_MOZRANK', '65536'); define('URLMETRICS_COL_MOZTRUST', '131072'); define('URLMETRICS_COL_SUBDMN_MOZTRUST', '262144'); define('URLMETRICS_COL_ROOTDMN_MOZTRUST', '524288'); define('URLMETRICS_COL_EXTERNAL_MOZRANK', '1048576'); define('URLMETRICS_COL_SUBDMN_EXTERNALDMN_JUICE', '2097152'); define('URLMETRICS_COL_ROOTDMN_EXTERNALDMN_JUICE', '4194304'); define('URLMETRICS_COL_SUBDMN_DOMAIN_JUICE', '8388608'); define('URLMETRICS_COL_ROOTDMN_DOMAIN_JUICE', '16777216'); define('URLMETRICS_COL_CANONICAL_URL', '268435456'); define('URLMETRICS_COL_HTTP_STATUS_CODE', '536870912'); define('URLMETRICS_COL_LINKS_TO_SUBDMN', '4294967296'); define('URLMETRICS_COL_LINKS_TO_ROOTDMN', '8589934592'); define('URLMETRICS_COL_ROOTDMN_LINKS_SUBDMN', '17179869184'); define('URLMETRICS_COL_PAGE_AUTHORITY', '34359738368'); define('URLMETRICS_COL_DOMAIN_AUTHORITY', '68719476736'); ?>components/com_sef/libs/seostats/src/ext/SeoMoz/LinksService.php000066600000005201150771655450021100 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) */ defined('_JEXEC') or die('Restricted access'); include_once 'Authenticator.php'; include_once 'ConnectionUtil.php'; /** * * Service class to call the various methods to * Links API * * Links api returns a set of links to a page or domain. * * @author Radeep Solutions * */ class LinksService { private $authenticator; public function __construct($authenticator) { $this->authenticator = $authenticator; } /** * This method returns a set of links to a page or domain. * * @param objectURL * @param scope determines the scope of the Target link, as well as the Source results. * @param filters filters the links returned to only include links of the specified type. You may include one or more of the following values separated by '+' * @param sort determines the sorting of the links, in combination with limit and offset, this allows fast access to the top links by several orders: * @param sourceCol specifies data about the source of the link is included * @param offset The start record of the page can be specified using the Offset parameter * @param limit The size of the page can by specified using the Limit parameter. * @return */ public function getLinks($objectURL, $scope = null, $filters = null, $sort = null, $sourceCol = 0, $offset = -1, $limit = -1) { $urlToFetch = "http://lsapi.seomoz.com/linkscape/links/" . urlencode($objectURL) . "?" . $this->authenticator->getAuthenticationStr(); if($scope != null) { $urlToFetch = $urlToFetch . "&Scope=" . $scope; } if($filters != null) { $urlToFetch = $urlToFetch . "&Filter=" . $filters; } if($sort != null) { $urlToFetch = $urlToFetch . "&Sort=" . $sort; } if($sourceCol > 0) { $urlToFetch = $urlToFetch . "&SourceCols=" . $sourceCol; } if($offset >= 0) { $urlToFetch = $urlToFetch . "&Offset=" . $offset; } if($limit >= 0) { $urlToFetch = $urlToFetch . "&Limit=" . $limit; } $response = ConnectionUtil::makeRequest($urlToFetch); return $response; } /** * @return the $authenticator */ public function getAuthenticator() { return $this->authenticator; } /** * @param $authenticator the $authenticator to set */ public function setAuthenticator($authenticator) { $this->authenticator = $authenticator; } } ?>components/com_sef/libs/seostats/src/ext/SeoMoz/ConnectionUtil.php000066600000002043150771655450021435 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) */ defined('_JEXEC') or die('Restricted access'); class ConnectionUtil { const CURL_CONNECTION_TIMEOUT = 120; /** * * Method to make a GET HTTP connecton to * the given url and return the output * * @param urlToFetch url to be connected * @return the http get response */ public static function makeRequest($urlToFetch) { $curl_handle = curl_init(); curl_setopt($curl_handle, CURLOPT_URL, "$urlToFetch"); curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, ConnectionUtil::CURL_CONNECTION_TIMEOUT); curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); $buffer = curl_exec($curl_handle); //var_dump($buffer); curl_close($curl_handle); $arr = json_decode($buffer); return $arr; } } ?>components/com_sef/libs/seostats/src/ext/SeoMoz/ConnectionUtil.php.backup000066600000001761150771655450022707 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) */ class ConnectionUtil { const CURL_CONNECTION_TIMEOUT = 120; /** * * Method to make a GET HTTP connecton to * the given url and return the output * * @param urlToFetch url to be connected * @return the http get response */ public static function makeRequest($urlToFetch) { $curl_handle = curl_init(); curl_setopt($curl_handle, CURLOPT_URL, "$urlToFetch"); curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, ConnectionUtil::CURL_CONNECTION_TIMEOUT); curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); $buffer = curl_exec($curl_handle); //var_dump($buffer); curl_close($curl_handle); $arr = json_decode($buffer); return $arr; } } ?>components/com_sef/libs/seostats/src/ext/SeoMoz/URLMetricsService.php000066600000003236150771655450022017 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) */ defined('_JEXEC') or die('Restricted access'); include_once 'Authenticator.php'; include_once 'ConnectionUtil.php'; /** * * Service class to call the various methods to * URL Metrics * * URL Metrics is a paid API that returns the metrics about a URL or set of URLs. * * @author Radeep Solutions * */ class URLMetricsService { private $authenticator; public function __construct($authenticator) { $this->authenticator = $authenticator; } /** * * This method returns the metrics about a URL or set of URLs. * * @param objectURL * @param col This field filters the data to get only specific columns * col = 0 fetches all the data * @return */ public function getUrlMetrics($objectURL, $col = 0) { $urlToFetch = "http://lsapi.seomoz.com/linkscape/url-metrics/" . urlencode($objectURL) . "?" . Authenticator::getInstance()->getAuthenticationStr(); if($col > 0) { $urlToFetch = $urlToFetch . "&Cols=" . $col; } $response = ConnectionUtil::makeRequest($urlToFetch); return $response; } /** * @return the $authenticator */ public function getAuthenticator() { return $this->authenticator; } /** * @param $authenticator the $authenticator to set */ public function setAuthenticator($authenticator) { $this->authenticator = $authenticator; } } ?>components/com_sef/libs/seostats/src/ext/htmlsql.class.php.backup000066600000044454150771655450021334 0ustar00 0.5 (May 07, 2006): - Renamed the project from webSQL to htmlSQL, because webSQL is already existing... :-( - Added some error checks and error messages - Added the convert_tagname_to_key function and fixed a few issues 0.1 -> 0.4 (April 2006): - Created main parts of the class */ class htmlsql { // configuration: // htmlSQL version: var $version = '0.5'; // referer and user agent: var $referer = ''; var $user_agent = 'Googlebot/2.1'; // Changed from htmlSQL/0.5 to Googlebot/2.1 // these are filled on runtime: // (don't touch them) // holds snoopy object: var $snoopy = NULL; // the results array is stored in here: var $results = array(); // the results objects are stored in here: var $results_objects = NULL; // the error message gets stored in here: var $error = ''; // the downloaded page is stored in here: var $page = ''; /* ** init_snoopy ** ** initializes the snoopy class */ function init_snoopy(){ $this->snoopy = new Snoopy(); $this->snoopy->agent = $this->user_agent; $this->snoopy->referer = $this->referer; } /* ** set_user_agent ** ** set a custom user agent */ function set_user_agent($u){ $this->user_agent = $u; } /* ** set_referer ** ** sets the referer */ function set_referer($r){ $this->referer = $r; } /* ** _get_between ** ** returns the content between $start and $end */ function _get_between($content,$start,$end){ $r = explode($start, $content); if (isset($r[1])){ $r = explode($end, $r[1]); return $r[0]; } return ''; } /* ** connect ** ** connects to a data source (url, file or string) */ function connect($type, $resource){ if ($type == 'url'){ return $this->_fetch_url($resource); } else if ($type == 'file') { if (!file_exists($resource)){ $this->error = 'The given file "'.$resource.' does not exist!'; return false; } $this->page = file_get_contents($resource); return true; } else if ($type == 'string') { $this->page = $resource; return true; } return false; } /* ** _fetch_url ** ** downloads the given URL with snoopy */ function _fetch_url($url){ $parsed_url = parse_url($url); if (!isset($parsed_url['scheme']) or $parsed_url['scheme'] != 'http'){ $this->error = 'Unsupported URL sheme given, please just use "HTTP".'; return false; } if (!isset($parsed_url['host']) or $parsed_url['host'] == ''){ $this->error = 'Invalid URL given!'; return false; } $host = $parsed_url['host']; $host .= (isset($parsed_url['port']) and !empty($parsed_url['port'])) ? ':'.$parsed_url['port'] : ''; $path = (isset($parsed_url['path']) and !empty($parsed_url['path'])) ? $parsed_url['path'] : '/'; $path .= (isset($parsed_url['query']) and !empty($parsed_url['query'])) ? '?'.$parsed_url['query'] : ''; $url = 'http://' . $host . $path; $this->init_snoopy(); if($this->snoopy->fetch($url)){ $this->page = $this->snoopy->results; // empty buffer: $this->snoopy->results = ''; } else { $this->error = 'Could not establish a connection to the given URL!'; return false; } return true; } /* ** _extract_all_tags ** ** */ function _extract_all_tags($html, &$tag_names, &$tag_attributes, &$tag_values, $depth=0){ // stop endless loops: if ($depth > 99999){ return; } preg_match_all('/<([a-z0-9\-]+)(.*?)>((.*?)<\/\1>)?/is', $html, $m); if (count($m[0]) != 0){ for ($t=0; $t < count($m[0]); $t++){ $tag_names[] = trim($m[1][$t]); $tag_attributes[] = trim($m[2][$t]); $tag_values[] = trim($m[4][$t]); // go deeper: if (trim($m[4][$t]) != '' and preg_match('/<[a-z0-9\-]+.*?>/is', $m[4][$t])){ $this->_extract_all_tags($m[4][$t], $tag_names, $tag_attributes, $tag_values, $depth+1); } } } } /* ** isolate_content ** ** isolates the content to a specific part */ function isolate_content($start,$end){ $this->page = $this->_get_between($this->page, $start, $end); } /* ** select ** ** restricts the content of a specific tag */ function select($tagname, $num=0){ $num++; if ($tagname != ''){ preg_match('/<'.$tagname.'.*?>(.*?)<\/'.$tagname.'>/is', $this->page, $m); if (isset($m[$num]) and !empty($m[$num])){ $this->page = $m[$num]; } else { $this->error = 'Could not select tag: "'.$tagname.'('.$num.')"!'; return false; } } return true; } /* ** get_content ** ** returns the content of an request */ function get_content(){ return $this->page; } /* ** _clean_array ** ** */ function _clean_array($arr){ $new = array(); for ($x=0; $x < count($arr); $x++){ $arr[$x] = trim($arr[$x]); if ($arr[$x] != ''){ $new[] = $arr[$x]; } } return $new; } /* ** _test_tag ** ** */ function _test_tag($tag_attributes, $if_term){ preg_match_all('/\$([a-z0-9_\-]+)/i', $if_term, $m); if (isset($m[1])){ for ($x=0; $x < count($m[1]); $x++){ $varname = $m[1][$x]; $$varname = ''; } } $new_list = array(); while (list($k,$v) = each($tag_attributes)){ $k = preg_replace('/[^a-z0-9_\-]/i', '', $k); if ($k != ''){ $new_list[$k] = $v; } } unset($tag_attributes); extract($new_list); $r = false; if (@eval('$r = ('.$if_term.');') === false){ $this->error = 'The WHERE statement is invalid (eval() failed)!'; return false; } return $r; } /* ** _match_tags ** ** */ function _match_tags(&$results, &$return_values, &$where_term, &$tag_attributes, &$tag_values, &$tag_names){ $search_mode = ''; $search_attribute = ''; $search_term = ''; /* ** parse: ** ** href LIKE ".htm" ** class = "foo" */ $where_term = trim($where_term); $search_mode = ($where_term == '') ? 'match_all' : 'eval'; for ($x=0; $x < count($tag_attributes); $x++){ $tag_attributes[$x] = $this->parse_attributes($tag_attributes[$x]); if (is_array($tag_names)){ $tag_attributes[$x]['tagname'] = isset($tag_names[$x]) ? $tag_names[$x] : ''; } else { $tag_attributes[$x]['tagname'] = $tag_names; } // string $tag_attributes[$x]['text'] = isset($tag_values[$x]) ? $tag_values[$x] : ''; if ($search_mode == 'eval'){ if ($this->_test_tag($tag_attributes[$x], $where_term)){ $this->_add_result($results, $return_values, $tag_attributes[$x]); } } else if ($search_mode == 'match_all'){ $this->_add_result($results, $return_values, $tag_attributes[$x]); } } } /* ** query ** ** performs a query */ function query($term){ // query results are stored in here: $results = array(); $this->results = NULL; $this->results_objects = NULL; $term = trim($term); if ($term == ''){ $this->error = 'Empty query given!'; return false; } // match query: preg_match('/^SELECT (.*?) FROM (.*)$/i', $term, $m); // parse returns values // SELECT * FROM ... // SELECT foo,bar FROM ... $return_values = isset($m[1]) ? trim($m[1]) : '*'; if ($return_values != '*'){ $return_values = explode(',', strtolower($return_values)); $return_values = $this->_clean_array($return_values); } // match from and where part: // // ... FROM * WHERE $id=="one" // ... FROM a WHERE $class=="red" // ... FROM a // ... FROM * $last = isset($m[2]) ? trim($m[2]) : ''; $search_term = ''; $where_term = ''; if (preg_match('/^(.*?) WHERE (.*?)$/i', $last, $m)){ $search_term = trim($m[1]); $where_term = trim($m[2]); } else { $search_term = $last; } /* ** find tags: */ if ($search_term == '*'){ // search all $tag_names = array(); $tag_attributes = array(); $tag_values = array(); $html = $this->page; $this->_extract_all_tags($html, $tag_names, $tag_attributes, $tag_values); $this->_match_tags($results, $return_values, $where_term, $tag_attributes, $tag_values, $tag_names); } else { // search term is a tag $tagname = trim($search_term); $tag_attributes = array(); $tag_values = array(); $regexp = '<'.$tagname.'([ \t].*?|)>((.*?)<\/'.$tagname.'>)?'; preg_match_all('/'.$regexp.'/is', $this->page, $m); if (count($m[0]) != 0){ $tag_attributes = $m[1]; $tag_values = $m[3]; } $this->_match_tags($results, $return_values, $where_term, $tag_attributes, $tag_values, $tagname); } $this->results = $results; // was there a error during the search process? if ($this->error != ''){ return false; } return true; } /* ** convert_tagname_to_key ** ** converts the tagname to the array key */ function convert_tagname_to_key(){ $new_array = array(); while(list($key,$val) = each($this->results)){ if (isset($val['tagname'])){ $tag_name = $val['tagname']; unset($val['tagname']); } else { $tag_name = '(empty)'; } $new_array[$tag_name] = $val; } $this->results = $new_array; } /* ** fetch_array ** ** returns the results as an array */ function fetch_array(){ return $this->results; } /* ** _array2object ** ** converts an array to an object */ function _array2object($array) { if (is_array($array)) { $obj = new StdClass(); foreach ($array as $key => $val){ $obj->$key = $val; } } else { $obj = $array; } return $obj; } /* ** fetch_objects ** ** returns the results as objects */ function fetch_objects(){ if ($this->results_objects == NULL){ $results = array(); reset($this->results); while(list($key,$val) = each($this->results)){ $results[$key] = $this->_array2object($val); } $this->results_objects = $results; return $this->results_objects; } else { return $this->results_objects; } } /* ** get_result_count ** ** returns the number of results */ function get_result_count(){ return count($this->results); } /* ** _add_result ** ** */ function _add_result(&$results, $return_values, $tag_attributes){ if ($return_values == '*'){ $results[] = $tag_attributes; } else if (is_array($return_values)){ $new_result = array(); reset($return_values); for ($t=0; $t < count($return_values); $t++){ $_tagname = explode(' as ', $return_values[$t]); $_caption = $return_values[$t]; if (count($_tagname) != 1){ $_caption = trim($_tagname[1]); $_tagname = trim($_tagname[0]); } else { $_tagname = $_caption; } $new_result[$_caption] = isset($tag_attributes[$_tagname]) ? $tag_attributes[$_tagname] : ''; } $results[] = $new_result; } } /* ** parse_attributes ** ** parses HTML attributes and returns an array */ function parse_attributes($attrib){ $attrib .= '>'; $mode = 'search_key'; $tmp = ''; $current_key = ''; $attributes = array(); for ($x=0; $x < strlen($attrib); $x++){ $char = $attrib[$x]; if ($char == '=' and $mode == 'search_key'){ $current_key = trim($tmp); $tmp = ''; $mode = 'value'; } else if ($mode == 'search_key' and preg_match('/[ \t\s\r\n>]/', $char)){ $current_key = strtolower(trim($tmp)); if ($current_key != ''){ $attributes[$current_key] = ''; } $tmp = ''; $current_key = ''; } else if ($mode == 'value' and $char == '"'){ $mode = 'find_value_ending_a'; } else if ($mode == 'value' and $char == '\''){ $mode = 'find_value_ending_b'; } else if ($mode == 'value'){ $tmp .= $char; $mode = 'find_value_ending_c'; } else if ( ($mode == 'find_value_ending_a' and $char == '"') or ($mode == 'find_value_ending_b' and $char == '\'') or ($mode == 'find_value_ending_c' and preg_match('/[ \t\s\r\n>]/', $char)) ){ $mode = 'search_key'; if ($current_key != ''){ $current_key = strtolower($current_key); $attributes[$current_key] = $tmp; } $tmp = ''; } else { $tmp .= $char; } } if ($mode != 'search_key' and $current_key != ''){ $current_key = strtolower($current_key); $attributes[$current_key] = trim(preg_replace('/>+$/', '', $tmp)); } return $attributes; } } ?>components/com_sef/libs/seostats/src/ext/index.html000066600000000054150771655450016550 0ustar00components/com_sef/libs/seostats/src/ext/htmlsql.class.php000066600000044670150771655450020070 0ustar00 0.5 (May 07, 2006): - Renamed the project from webSQL to htmlSQL, because webSQL is already existing... :-( - Added some error checks and error messages - Added the convert_tagname_to_key function and fixed a few issues 0.1 -> 0.4 (April 2006): - Created main parts of the class */ defined('_JEXEC') or die('Restricted access'); class htmlsql { // configuration: // htmlSQL version: var $version = '0.5'; // referer and user agent: var $referer = ''; var $user_agent = 'Googlebot/2.1'; // Changed from htmlSQL/0.5 to Googlebot/2.1 // these are filled on runtime: // (don't touch them) // holds snoopy object: var $snoopy = NULL; // the results array is stored in here: var $results = array(); // the results objects are stored in here: var $results_objects = NULL; // the error message gets stored in here: var $error = ''; // the downloaded page is stored in here: var $page = ''; /* ** init_snoopy ** ** initializes the snoopy class */ function init_snoopy(){ $this->snoopy = new Snoopy(); $this->snoopy->agent = $this->user_agent; $this->snoopy->referer = $this->referer; } /* ** set_user_agent ** ** set a custom user agent */ function set_user_agent($u){ $this->user_agent = $u; } /* ** set_referer ** ** sets the referer */ function set_referer($r){ $this->referer = $r; } /* ** _get_between ** ** returns the content between $start and $end */ function _get_between($content,$start,$end){ $r = explode($start, $content); if (isset($r[1])){ $r = explode($end, $r[1]); return $r[0]; } return ''; } /* ** connect ** ** connects to a data source (url, file or string) */ function connect($type, $resource){ if ($type == 'url'){ return $this->_fetch_url($resource); } else if ($type == 'file') { if (!file_exists($resource)){ $this->error = 'The given file "'.$resource.' does not exist!'; return false; } $this->page = file_get_contents($resource); return true; } else if ($type == 'string') { $this->page = $resource; return true; } return false; } /* ** _fetch_url ** ** downloads the given URL with snoopy */ function _fetch_url($url){ $parsed_url = parse_url($url); if (!isset($parsed_url['scheme']) or $parsed_url['scheme'] != 'http'){ $this->error = 'Unsupported URL sheme given, please just use "HTTP".'; return false; } if (!isset($parsed_url['host']) or $parsed_url['host'] == ''){ $this->error = 'Invalid URL given!'; return false; } $host = $parsed_url['host']; $host .= (isset($parsed_url['port']) and !empty($parsed_url['port'])) ? ':'.$parsed_url['port'] : ''; $path = (isset($parsed_url['path']) and !empty($parsed_url['path'])) ? $parsed_url['path'] : '/'; $path .= (isset($parsed_url['query']) and !empty($parsed_url['query'])) ? '?'.$parsed_url['query'] : ''; $url = 'http://' . $host . $path; $this->init_snoopy(); if($this->snoopy->fetch($url)){ $this->page = $this->snoopy->results; // empty buffer: $this->snoopy->results = ''; } else { $this->error = 'Could not establish a connection to the given URL!'; return false; } return true; } /* ** _extract_all_tags ** ** */ function _extract_all_tags($html, &$tag_names, &$tag_attributes, &$tag_values, $depth=0){ // stop endless loops: if ($depth > 99999){ return; } preg_match_all('/<([a-z0-9\-]+)(.*?)>((.*?)<\/\1>)?/is', $html, $m); if (count($m[0]) != 0){ for ($t=0; $t < count($m[0]); $t++){ $tag_names[] = trim($m[1][$t]); $tag_attributes[] = trim($m[2][$t]); $tag_values[] = trim($m[4][$t]); // go deeper: if (trim($m[4][$t]) != '' and preg_match('/<[a-z0-9\-]+.*?>/is', $m[4][$t])){ $this->_extract_all_tags($m[4][$t], $tag_names, $tag_attributes, $tag_values, $depth+1); } } } } /* ** isolate_content ** ** isolates the content to a specific part */ function isolate_content($start,$end){ $this->page = $this->_get_between($this->page, $start, $end); } /* ** select ** ** restricts the content of a specific tag */ function select($tagname, $num=0){ $num++; if ($tagname != ''){ preg_match('/<'.$tagname.'.*?>(.*?)<\/'.$tagname.'>/is', $this->page, $m); if (isset($m[$num]) and !empty($m[$num])){ $this->page = $m[$num]; } else { $this->error = 'Could not select tag: "'.$tagname.'('.$num.')"!'; return false; } } return true; } /* ** get_content ** ** returns the content of an request */ function get_content(){ return $this->page; } /* ** _clean_array ** ** */ function _clean_array($arr){ $new = array(); for ($x=0; $x < count($arr); $x++){ $arr[$x] = trim($arr[$x]); if ($arr[$x] != ''){ $new[] = $arr[$x]; } } return $new; } /* ** _test_tag ** ** */ function _test_tag($tag_attributes, $if_term){ preg_match_all('/\$([a-z0-9_\-]+)/i', $if_term, $m); if (isset($m[1])){ for ($x=0; $x < count($m[1]); $x++){ $varname = $m[1][$x]; $$varname = ''; } } $new_list = array(); while (list($k,$v) = each($tag_attributes)){ $k = preg_replace('/[^a-z0-9_\-]/i', '', $k); if ($k != ''){ $new_list[$k] = $v; } } unset($tag_attributes); extract($new_list); $r = false; if (@eval('$r = ('.$if_term.');') === false){ $this->error = 'The WHERE statement is invalid (eval() failed)!'; return false; } return $r; } /* ** _match_tags ** ** */ function _match_tags(&$results, &$return_values, &$where_term, &$tag_attributes, &$tag_values, &$tag_names){ $search_mode = ''; $search_attribute = ''; $search_term = ''; /* ** parse: ** ** href LIKE ".htm" ** class = "foo" */ $where_term = trim($where_term); $search_mode = ($where_term == '') ? 'match_all' : 'eval'; for ($x=0; $x < count($tag_attributes); $x++){ $tag_attributes[$x] = $this->parse_attributes($tag_attributes[$x]); if (is_array($tag_names)){ $tag_attributes[$x]['tagname'] = isset($tag_names[$x]) ? $tag_names[$x] : ''; } else { $tag_attributes[$x]['tagname'] = $tag_names; } // string $tag_attributes[$x]['text'] = isset($tag_values[$x]) ? $tag_values[$x] : ''; if ($search_mode == 'eval'){ if ($this->_test_tag($tag_attributes[$x], $where_term)){ $this->_add_result($results, $return_values, $tag_attributes[$x]); } } else if ($search_mode == 'match_all'){ $this->_add_result($results, $return_values, $tag_attributes[$x]); } } } /* ** query ** ** performs a query */ function query($term){ // query results are stored in here: $results = array(); $this->results = NULL; $this->results_objects = NULL; $term = trim($term); if ($term == ''){ $this->error = 'Empty query given!'; return false; } // match query: preg_match('/^SELECT (.*?) FROM (.*)$/i', $term, $m); // parse returns values // SELECT * FROM ... // SELECT foo,bar FROM ... $return_values = isset($m[1]) ? trim($m[1]) : '*'; if ($return_values != '*'){ $return_values = explode(',', strtolower($return_values)); $return_values = $this->_clean_array($return_values); } // match from and where part: // // ... FROM * WHERE $id=="one" // ... FROM a WHERE $class=="red" // ... FROM a // ... FROM * $last = isset($m[2]) ? trim($m[2]) : ''; $search_term = ''; $where_term = ''; if (preg_match('/^(.*?) WHERE (.*?)$/i', $last, $m)){ $search_term = trim($m[1]); $where_term = trim($m[2]); } else { $search_term = $last; } /* ** find tags: */ if ($search_term == '*'){ // search all $tag_names = array(); $tag_attributes = array(); $tag_values = array(); $html = $this->page; $this->_extract_all_tags($html, $tag_names, $tag_attributes, $tag_values); $this->_match_tags($results, $return_values, $where_term, $tag_attributes, $tag_values, $tag_names); } else { // search term is a tag $tagname = trim($search_term); $tag_attributes = array(); $tag_values = array(); $regexp = '<'.$tagname.'([ \t].*?|)>((.*?)<\/'.$tagname.'>)?'; preg_match_all('/'.$regexp.'/is', $this->page, $m); if (count($m[0]) != 0){ $tag_attributes = $m[1]; $tag_values = $m[3]; } $this->_match_tags($results, $return_values, $where_term, $tag_attributes, $tag_values, $tagname); } $this->results = $results; // was there a error during the search process? if ($this->error != ''){ return false; } return true; } /* ** convert_tagname_to_key ** ** converts the tagname to the array key */ function convert_tagname_to_key(){ $new_array = array(); while(list($key,$val) = each($this->results)){ if (isset($val['tagname'])){ $tag_name = $val['tagname']; unset($val['tagname']); } else { $tag_name = '(empty)'; } $new_array[$tag_name] = $val; } $this->results = $new_array; } /* ** fetch_array ** ** returns the results as an array */ function fetch_array(){ return $this->results; } /* ** _array2object ** ** converts an array to an object */ function _array2object($array) { if (is_array($array)) { $obj = new StdClass(); foreach ($array as $key => $val){ $obj->$key = $val; } } else { $obj = $array; } return $obj; } /* ** fetch_objects ** ** returns the results as objects */ function fetch_objects(){ if ($this->results_objects == NULL){ $results = array(); reset($this->results); while(list($key,$val) = each($this->results)){ $results[$key] = $this->_array2object($val); } $this->results_objects = $results; return $this->results_objects; } else { return $this->results_objects; } } /* ** get_result_count ** ** returns the number of results */ function get_result_count(){ return count($this->results); } /* ** _add_result ** ** */ function _add_result(&$results, $return_values, $tag_attributes){ if ($return_values == '*'){ $results[] = $tag_attributes; } else if (is_array($return_values)){ $new_result = array(); reset($return_values); for ($t=0; $t < count($return_values); $t++){ $_tagname = explode(' as ', $return_values[$t]); $_caption = $return_values[$t]; if (count($_tagname) != 1){ $_caption = trim($_tagname[1]); $_tagname = trim($_tagname[0]); } else { $_tagname = $_caption; } $new_result[$_caption] = isset($tag_attributes[$_tagname]) ? $tag_attributes[$_tagname] : ''; } $results[] = $new_result; } } /* ** parse_attributes ** ** parses HTML attributes and returns an array */ function parse_attributes($attrib){ $attrib .= '>'; $mode = 'search_key'; $tmp = ''; $current_key = ''; $attributes = array(); for ($x=0; $x < strlen($attrib); $x++){ $char = $attrib[$x]; if ($char == '=' and $mode == 'search_key'){ $current_key = trim($tmp); $tmp = ''; $mode = 'value'; } else if ($mode == 'search_key' and preg_match('/[ \t\s\r\n>]/', $char)){ $current_key = strtolower(trim($tmp)); if ($current_key != ''){ $attributes[$current_key] = ''; } $tmp = ''; $current_key = ''; } else if ($mode == 'value' and $char == '"'){ $mode = 'find_value_ending_a'; } else if ($mode == 'value' and $char == '\''){ $mode = 'find_value_ending_b'; } else if ($mode == 'value'){ $tmp .= $char; $mode = 'find_value_ending_c'; } else if ( ($mode == 'find_value_ending_a' and $char == '"') or ($mode == 'find_value_ending_b' and $char == '\'') or ($mode == 'find_value_ending_c' and preg_match('/[ \t\s\r\n>]/', $char)) ){ $mode = 'search_key'; if ($current_key != ''){ $current_key = strtolower($current_key); $attributes[$current_key] = $tmp; } $tmp = ''; } else { $tmp .= $char; } } if ($mode != 'search_key' and $current_key != ''){ $current_key = strtolower($current_key); $attributes[$current_key] = trim(preg_replace('/>+$/', '', $tmp)); } return $attributes; } } ?>components/com_sef/libs/seostats/src/seostats.seomoz.php000066600000005223150771655450017647 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) * * @filename ./seostats.seomoz.php * @desc Child class of SEOstats, extending the main class * by methods for http://www.seomoz.com * * @changelog * date author method: change(s) * 2011/09/07 Sylvain Rocheleau added all the results returned by Seomoz to function Seomoz_Authority */ defined('_JEXEC') or die('Restricted access'); class SEOstats_Seomoz extends SEOstats { /** * Gets domain and URL authority from SEOmoz. * * @access private * @link http://www.seomoz.org/api The SEOmoz API * @return array Returns array, containing authority data. */ public static function Seomoz_Authority($uri) { // external helper class include_once ('ext/SeoMoz/Authenticator.php'); $authenticator = new Authenticator(); $url = urlencode($uri); $tmp = SEOstats::cURL('http://lsapi.seomoz.com/linkscape/url-metrics/'.$url.'?'.$authenticator->getAuthenticationStr()); $data = json_decode($tmp); $result = array( 'Title' => $data->ut, 'URL' => $data->uu, 'External Links' => $data->ueid, 'Links' => $data->uid, 'URL Authority' => $data->upa, 'URL mozRank' => $data->umrp, 'Subdomain mozRank' => $data->fmrp, 'HTTP Status Code' => $data->us, 'Page Authority' => $data->upa, 'Domain Authority' => $data->pda ); return $result; } /** * Gets Backlinkdetails from SEOmoz. * Limited to 25 links per source domain, due to using a free API key. * * @access private * @link http://www.seomoz.org/api The SEOmoz API * @return array Returns array, containing linkdetails. */ public static function Seomoz_Links($uri) { // external helper classes include_once('ext/SeoMoz/Authenticator.php'); include_once('ext/SeoMoz/LinksService.php'); include_once('ext/SeoMoz/LinksConstants.php'); $authenticator = new Authenticator(); $linksService = new LinksService($authenticator); $result = $linksService->getLinks($uri, LINKS_SCOPE_PAGE_TO_DOMAIN, null, LINKS_SORT_PAGE_AUTHORITY, LINKS_COL_URL, 0 , 25); return (!empty($result)) ? $result : 'No data available.'; } } ?>components/com_sef/libs/seostats/src/seostats.guid.php000066600000002221150771655450017256 0ustar00 * @copyright 2010-present, Stephan Schmitz, Sylvain Rocheleau * @license GNU General Public License (GPL) * * @filename ./seostats.guid.php * @desc This module will return a unique GUID. It uses the PHP command uniqid to create a 23 character string appended to the IP address of the client without periods. * @changelog * date author change(s) * YYYY/MM/DD Your name first commit **/ defined('_JEXEC') or die('Restricted access'); class SEOstats_Guid extends SEOstats { function CreateGUID() { //Append the IP address w/o periods to the front of the unique ID $varGUID = str_replace('.', '', uniqid($_SERVER['REMOTE_ADDR'], TRUE)); //Return the GUID as the function value return $varGUID; } } ?> components/com_sef/libs/seostats/src/seostats.alexa.php000066600000016733150771655450017435 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) */ defined('_JEXEC') or die('Restricted access'); class SEOstats_Alexa extends SEOstats { /** * Helper. Get the Alexa's free report webpage. * * @access private * @return string String, containing the curl result of the the Alexa webpage. */ private static function _alexa($uri) { $tmp = SEOstats::cURL('http://www.alexa.com/siteinfo/'.$uri); return $tmp; } /** * Extracts a String off of HTML input. * * @access private * * @param string $tag String, containing the html tag to select * @param string $attr String, containing the attribute used on the WHERE condition * @param string $value String, containing the value used on the WHERE condition * @param string $site Input string * @param integer $id Defines the position of the key, to be returned from the preg_match_all array. * * @return string/integer Returns an integer or a string. */ public static function extractSingle($tag,$attr,$value,$id,$uri,$alextract) { // external helper class include_once("ext/htmlsql.class.php"); $wsql = new htmlsql(); $wsql->connect('string', SEOstats_Alexa::_alexa($uri)); $wsql->query('SELECT * FROM '.$tag.' WHERE $'.$attr.' == "'.$value.'"'); $row = $wsql->fetch_array(); if($alextract == true) { return SEOstats_Alexa::alextract($row[$id]['text']); } elseif($alextract == false) { return trim(strip_tags($row[$id]['text'])); } elseif($alextract == 'none') { return $row[$id]['text']; } } /** * Extracts an Array off of HTML input. * * @access private * * @param string $tag String, containing the html tag to select * @param string $attr String, containing the attribute used on the WHERE condition * @param string $value String, containing the value used on the WHERE condition * @param string $site Input string * * @return array Returns an array of results. */ public static function extractMulti($tag,$attr,$value,$uri) { // external helper classs include_once("ext/htmlsql.class.php"); $wsql = new htmlsql(); $wsql->connect('string', SEOstats_Alexa::_alexa($uri)); $wsql->query('SELECT * FROM '.$tag.' WHERE $'.$attr.' == "'.$value.'"'); $results = array (); foreach($wsql->fetch_array() as $row) { $results[] = $row['text']; } return $results; } /** * Gets data off of curled Alexa webpages. * * @access private * @param string $str String, containing the html source code of Alexa's free result webpage. * @return array Returns an array of Alexa results. */ public static function alextract($str) { $tmpArr = explode('',$str); $replace = array("\r", "\r\n", "\n", "7 day", "Yesterday", "1 month", "3 month"); $value1 = trim(str_replace($replace,'',strip_tags($tmpArr[3]))); if ($value1 == '-' || $value1 == '' || empty($value1)) { $value1 = 'No Data available.'; $change1 = ''; } else { $change1 = trim(strip_tags($tmpArr[4])); } $value3 = trim(str_replace($replace,'',strip_tags($tmpArr[6]))); if ($value3 == '-' || $value3 == '' || empty($value3)) { $value3 = 'No Data available.'; $change3 = ''; } else { $change3 = trim(strip_tags($tmpArr[7])); } $month1 = array('value' => $value1, 'change' => $change1); $month3 = array('value' => $value3, 'change' => $change3); $result = array('1 Month' => $month1,'3 Months' => $month3); return $result; } /** * @access public * @return array Returns multi-array, containing the Visits by Country. */ public static function Alexa_VBC($uri) { $str = SEOstats_Alexa::_alexa($uri); preg_match_all('#(.*?)(.*?)
    #',$str,$country); preg_match_all('#

    (.*?)

    #',$str,$percent); $result = array(); $countries = array(); foreach($country[3] as $tmp) { $x = trim(str_replace(' ','',$tmp)); if(!in_array($x,$countries)) { $countries[] = $x; } } for($i=0;$i < sizeof($countries);$i++) { $result[] = array('Country' => trim($countries[$i]), 'Percent of Traffic' => $percent[1][$i]); } return $result; } /** * @access public * @return array Returns multi-array, containing the Alexa Rank, sorted by Country. */ public static function Alexa_RBC($uri) { $str = SEOstats_Alexa::_alexa($uri); preg_match_all('# (.*?)#',$str,$country); preg_match_all('#

    (.*?)

    #',$str,$rank); $result = array(); for($i=0;$i < sizeof($country);$i++) { $result[] = array('Country' => trim($country[1][$i]), 'Rank' => trim($rank[1][$i])); } return $result; } /** * @access public * @return array Returns multi-array, containing data from Alexa about keywords from search visits. */ public static function Alexa_SV_Keywords($uri) { $tmp = SEOstats_Alexa::extractSingle('div','id','top-keywords-from-search','0',$uri,'none'); $tmp = explode('style="color:#253759;">', $tmp); $tmp = explode('', $tmp[2]); $result = array(); for ($i=1;$i',$tmp[$i]); $result[] = array( 'Keyword' => utf8_decode(trim(strip_tags($temp[1]))), 'Percent of Search Traffic' => trim(strip_tags($temp[2]))); } return $result; } /** * @access public * @return array Returns multi-array, containing data from Alexa about changes of incoming search terms. */ public static function Alexa_SV_Changes($uri) { $tmp = SEOstats_Alexa::extractMulti('table','class','dataTable',$uri); $tmp_incr = explode('', $tmp[9]); $tmp_decl = explode('', $tmp[11]); for ($i=1;$i',$tmp_incr[$i]); $result_incr[] = array( 'Keyword' => utf8_decode(trim(strip_tags($temp_incr[1]))), 'Change in Percent' => trim(strip_tags($temp_incr[2]))); } for ($i=1;$i',$tmp_decl[$i]); $result_decl[] = array( 'Keyword' => utf8_decode(trim(strip_tags($temp_decl[1]))), 'Change in Percent' => trim(strip_tags($temp_decl[2]))); } if(empty($result_incr)) { $result_incr = 'No Data available.'; } if(empty($result_decl)) { $result_decl = 'No Data available.'; } $result = array('Increase' => $result_incr, 'Decline' => $result_decl); return $result; } /** * @access public * @return string Returns string, containing the average load time of the URL from Alexa. */ public static function Alexa_Load_Time($uri) { $str = SEOstats_Alexa::_alexa($uri); $html = new DOMDocument(); @$html->loadHtml( $str ); $xpath = new DOMXPath( $html ); $p = $xpath->query( "//div[@class='speedAd']//div//p" ); foreach($p as $match) { if(preg_match('/Seconds/si',$match->textContent)) { return trim(strip_tags($match->textContent)); exit(); } } return 'No data available.'; } } ?>components/com_sef/libs/seostats/src/class.seostats.config.php000066600000002213150771655450020700 0ustar00 * @copyright 2010-present, Stephan Schmitz * @license GNU General Public License (GPL) * * @filename ./class.seostats.config.php * @desc Defines some global used class constants. * * @changelog * date author change(s) * 2011/08/04 Stephan Schmitz Defined BING_APP_ID constant. */ defined('_JEXEC') or die('Restricted access'); define('GOOGLE_TLD', 'com'); define('USE_PAGERANK_CHECKSUM_API', true); /** * Optional changes. */ define('YAHOO_APP_ID', 'oVFwwjnV34GEEZTLB3K_WW1YC9_VysYbCYQ4szoXTAHZscrDvMazUpFR7TR0wchmlA--'); define('BING_APP_ID', 'FCB316D398F094C53B8C7AA8DA24B2D58AB520F8'); define('SEOMOZ_ACCESS_ID', 'member-881a55bcfb'); define('SEOMOZ_SECRET_KEY', '7145d56a1279285be92e6e4875bba8ee'); ?>components/com_sef/libs/seostats/errlog.txt000066600000000000150771655450015206 0ustar00components/com_sef/libs/seostats/README000066600000000503150771655450014043 0ustar00SEOstats is a powerful open source tool to get a lot of SEO relevant data such as detailed backlink analyses, keyword and traffic statistics, website trends, page authority, the Google Pagerank, the Alexa Trafficrank and much more. Therefore SEOstats gathers data from Google, Yahoo, SEOmoz, Alexa, Facebook and Twitter. components/com_sef/libs/seostats/CHANGELOG000066600000011067150771655450014404 0ustar00 ====================================================================== CHANGELOG ---------------------------------------------------------------------- v2.0.8.2 06.09.2011 * removed child class SEOstats_Majesticseo v2.0.8 04.08.2011 * implemented contributed child class: added child class SEOstats_Bing * added method SEOstats::Bing() * implemented contributed fix: added folder support for SEOstats_Majesticseo::report() * implemented contributed fix: fixed return method for SEOstats_Google::googleTotal2() * updated constant PAGERANK_CHECKSUM_API_URI v2.0.7 11.06.2011 * added method Google_Siteindex_Total_API * added method Google_Backlinks_Total_API * fixed Majesticseo methods * fixed method Seomoz_Linkdetails_Array * fixed method Alexa_Avg_Load_Time * improved method googleArray by changing from regular expressions to xpath v2.0.6 18.05.2011 * added method Google_Performance_Analysis * added method Google_Pagespeed_Score * fixed method googleArray * fixed typo in method print_array * split into child classes (by vendor) v2.0.5 29.04.2011 * fixed method googleArray * improved regex pattern for URL validation v2.0.4 13.04.2011 * fixed method Google_Backlinks_Array * improved method googleArray * no more need of external helper classes * added a delay when scraping more than 100 results at once * removed the Google Pagerank API * added a Pagerank Checksum API v2.0.3 13.03.2011 * fixed all Majesticseo methods * added method Majesticseo_Backlinking_CSubnets_Total v2.0.2 18.02.2011 * added method Alexa_Visits_By_Country v2.0.1 18.02.2011 * added method Alexa_Rank_By_Country * added method Alexa_Avg_Load_Time v2.0 17.02.2011 * Major code clean up * improved existing methods * added new Yahoo methods * added new SEOmoz methods * added new Facebook methods * added new Twitter methods * added optional Pagerank API * added optional json output method * removed GUI example v1.2.3 18.12.2010 * fixed method PageRank v1.2.2 17.12.2010 * improved method AlexaGlobalRank * pure numeric result * no more html in output * improved method AlexaCountryRank * pure numeric result * no more html in output * improved Alexa Stats and Trend methods * no more html wrapped output * returns results as array v1.2.1 09.12.2010 * fixed method GoogleLinks v1.2 01.12.2010 * added new Google methods * GoogleIndexDetails * GoogleLinkDetails * GoogleMentions * Introduced global var $google_tld * used in all google methods * if not defined = com * enhanced method GoogleIndex * No longer requires an API Key * enhanced method GoogleLinks * No longer requires an API Key v1.1 29.10.2010 * added Yahoo methods * YahooLinks * YahooLinkDetails v1.0.3 19.10.2010 * fixed method AlexaCountryRank v1.0.2 19.10.2010 * added method PageRank v1.0.1 19.10.2010 * added method cURL ---------------------------------------------------------------------- ====================================================================== components/com_sef/libs/cms/language/multilang.php000066600000004321150771655450016372 0ustar00getQuery(true) ->select('element') ->from('#__extensions') ->where('type = ' . $db->quote('language')) ->where('client_id = 0') ->where('enabled = 1'); $db->setQuery($query); $multilangSiteLangs = $db->loadObjectList('element'); } return $multilangSiteLangs; } /** * Method to return a list of language home page menu items. * * @return array of menu objects. * * @since 3.5 */ public static function getSiteHomePages() { // To avoid doing duplicate database queries. static $multilangSiteHomePages = null; if (!isset($multilangSiteHomePages)) { // Check for Home pages languages. $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('language') ->select('id') ->from($db->quoteName('#__menu')) ->where('home = 1') ->where('published = 1') ->where('client_id = 0'); $db->setQuery($query); $multilangSiteHomePages = $db->loadObjectList('language'); } return $multilangSiteHomePages; } } components/com_sef/libs/cms/language/associations.php000066600000012573150771655450017105 0ustar00quote($extension) : ''); $query = $db->getQuery(true) ->select($db->quoteName('c2.language')) ->from($db->quoteName($tablename, 'c')) ->join('INNER', $db->quoteName('#__associations', 'a') . ' ON a.id = c.' . $db->quoteName($pk) . ' AND a.context=' . $db->quote($context)) ->join('INNER', $db->quoteName('#__associations', 'a2') . ' ON ' . $db->quoteName('a.key') . ' = ' . $db->quoteName('a2.key')) ->join('INNER', $db->quoteName($tablename, 'c2') . ' ON a2.id = c2.' . $db->quoteName($pk) . $categoriesExtraSql); // Use alias field ? if (!empty($aliasField)) { $query->select( $query->concatenate( array( $db->quoteName('c2.' . $pk), $db->quoteName('c2.' . $aliasField), ), ':' ) . ' AS ' . $db->quoteName($pk) ); } else { $query->select($db->quoteName('c2.' . $pk)); } // Use catid field ? if (!empty($catField)) { $query->join( 'INNER', $db->quoteName('#__categories', 'ca') . ' ON ' . $db->quoteName('c2.' . $catField) . ' = ca.id AND ca.extension = ' . $db->quote($extension) ) ->select( $query->concatenate( array('ca.id', 'ca.alias'), ':' ) . ' AS ' . $db->quoteName($catField) ); } $query->where('c.' . $pk . ' = ' . (int) $id); if ($tablename === '#__categories') { $query->where('c.extension = ' . $db->quote($extension)); } // Advanced where clause if (!empty($advClause)) { foreach ($advClause as $clause) { $query->where($clause); } } $db->setQuery($query); try { $items = $db->loadObjectList('language'); } catch (RuntimeException $e) { throw new Exception($e->getMessage(), 500, $e); } if ($items) { foreach ($items as $tag => $item) { // Do not return itself as result if ((int) $item->{$pk} !== $id) { $multilanguageAssociations[$queryKey][$tag] = $item; } } } } return $multilanguageAssociations[$queryKey]; } /** * Method to determine if the language filter Items Associations parameter is enabled. * This works for both site and administrator. * * @return boolean True if the parameter is implemented; false otherwise. * * @since 3.2 */ public static function isEnabled() { // ARTIO JoomSEF - Always return true, associations are enabled in JoomSEF when this file is loaded return true; } } components/com_sef/libs/stats/google.php000066600000015521150771655450014447 0ustar00zerofill($c, 23) | $c << 9; } return '8' . $this->hexencode($c); } private function hexencode($str) { $out = $this->hex8($this->zerofill($str, 24)); $out .= $this->hex8($this->zerofill($str, 16) & 255); $out .= $this->hex8($this->zerofill($str, 8 ) & 255); $out .= $this->hex8($str & 255); return $out; } private function zerofill($a,$b) { $z = hexdec(80000000); if ($z & $a) { $a = ($a>>1); $a &= (~$z); $a |= 0x40000000; $a = ($a>>($b-1)); } else { $a = ($a>>$b); } return $a; } private function hex8 ($str) { $str = dechex($str); (strlen($str) == 1 ? $str = '0' . $str: null); return $str; } function getPageRank($url) { // Page rank can't be obtained currently return 0; $checksum=$this->genhash($url); $googleurl = 'http://toolbarqueries.google.com/tbr?features=Rank&sourceid=navclient-ff&client=navclient-auto-ff'; $googleurl .= '&googleip=O;66.249.81.104;104&ch='.$checksum.'&q=info:'.urlencode($url); $data=SEFTools::PostRequest($googleurl,null,null,'get'); if(!empty($matches[2])) { return $matches[2][0]; } else { return 0; } } function getTotalIndexed($url) { $url = rtrim(JURI::root(), '/').'/'.ltrim($url, '/'); $url = str_replace(array('http://', 'https://'), '', $url); if (substr($url, 0, 4) == 'www.') { $url = substr($url, 4); } $google_url = 'http://www.google.com/search?q=site:'.urlencode($url); $data=SEFTools::PostRequestFollowRedirects($google_url,null,null,'get'); $matches=array(); if (preg_match('#]*id="?resultStats"?>[^0-9]*([0-9,\s]*)<#', html_entity_decode($data->content), $matches)) { return preg_replace('/[^0-9]/', '', $matches[1]); } return 0; } function getPopularity($url) { $url = rtrim(JURI::root(), '/').'/'.ltrim($url, '/'); $url = str_replace(array('http://', 'https://'), '', $url); if (substr($url, 0, 4) == 'www.') { $url = substr($url, 4); } $google_url = 'http://www.google.com/search?q="'.urlencode($url).'"+-site:'.urlencode($url); $data=SEFTools::PostRequestFollowRedirects($google_url,null,null,'get'); $matches=array(); if (preg_match('#]*id="?resultStats"?>[^0-9]*([0-9,\s]*)<#', html_entity_decode($data->content), $matches)) { return preg_replace('/[^0-9]/', '', $matches[1]); } return 0; } /*function getTitlePopularity($url) { $url=str_replace("http://","",$url); $url=str_replace("www.","",$url); $google_url = 'http://www.google.com/search?q="'.urlencode($url).'"+-site:'.urlencode($url); $data=SEFTools::PostRequest($google_url,null,null,'get'); $mathes=array(); preg_match_all('#
    ([A-Za-z]*) ([0-9,]*)#',$data->content,$matches); return $matches[2][0]; }*/ function getFacebookIndexed($url) { $url = rtrim(JURI::root(), '/').'/'.ltrim($url, '/'); $url = str_replace(array('http://', 'https://'), '', $url); if (substr($url, 0, 4) == 'www.') { $url = substr($url, 4); } $google_url = 'http://www.google.com/search?q="'.urlencode($url).'"+site:'.urlencode('facebook.com'); $data=SEFTools::PostRequestFollowRedirects($google_url,null,null,'get'); $matches=array(); if (preg_match('#]*id="?resultStats"?>[^0-9]*([0-9,\s]*)<#', html_entity_decode($data->content), $matches)) { return preg_replace('/[^0-9]/', '', $matches[1]); } return 0; } function getTwitterIndexed($url) { $url = rtrim(JURI::root(), '/').'/'.ltrim($url, '/'); $url = str_replace(array('http://', 'https://'), '', $url); if (substr($url, 0, 4) == 'www.') { $url = substr($url, 4); } $google_url = 'http://www.google.com/search?q="'.urlencode($url).'"+site:'.urlencode('twitter.com'); $data=SEFTools::PostRequestFollowRedirects($google_url,null,null,'get'); $matches=array(); if (preg_match('#]*id="?resultStats"?>[^0-9]*([0-9,\s]*)<#', html_entity_decode($data->content), $matches)) { return preg_replace('/[^0-9]/', '', $matches[1]); } return 0; } function getPageSpeed($url) { require_once JPATH_COMPONENT_ADMINISTRATOR.'/classes/config.php'; $url = rtrim(JURI::root(), '/').'/'.ltrim($url, '/'); $config = SEFConfig::getConfig(); $ndata=new stdClass(); if(strlen($config->google_apikey)==0) { return false; } $google_url='https://www.googleapis.com/pagespeedonline/v1/runPagespeed?url='.urlencode($url).'&key='.$config->google_apikey; // Use CURL if available if (function_exists('curl_init')) { $certFile = realpath(dirname(__FILE__).'/../cacert.pem'); $c=curl_init($google_url); curl_setopt($c,CURLOPT_RETURNTRANSFER,1); curl_setopt($c, CURLOPT_ENCODING, "utf-8" ); curl_setopt($c, CURLOPT_CAINFO, $certFile); $data=curl_exec($c); curl_close($c); } else { // Try to use our own method $data = SEFTools::PostRequest($google_url, null, null, 'get'); if ($data !== false) { $data = $data->content; } } if ($data === false) { // Could not connect return false; } $data=json_decode($data); $ndata=new stdClass(); if(isset($data->error)) { $ndata->message=$data->error->errors[0]->message; return $ndata; } @$ndata->pageStats=$data->pageStats; @$ndata->score=$data->score; $reg=new JRegistry(); $reg->loadObject($ndata); return $reg->toString("ini"); } } ?>components/com_sef/libs/stats/index.html000066600000000054150771655450014452 0ustar00components/com_sef/libs/stats/google.php.backup000066600000015053150771655450015713 0ustar00zerofill($c, 23) | $c << 9; } return '8' . $this->hexencode($c); } private function hexencode($str) { $out = $this->hex8($this->zerofill($str, 24)); $out .= $this->hex8($this->zerofill($str, 16) & 255); $out .= $this->hex8($this->zerofill($str, 8 ) & 255); $out .= $this->hex8($str & 255); return $out; } private function zerofill($a,$b) { $z = hexdec(80000000); if ($z & $a) { $a = ($a>>1); $a &= (~$z); $a |= 0x40000000; $a = ($a>>($b-1)); } else { $a = ($a>>$b); } return $a; } private function hex8 ($str) { $str = dechex($str); (strlen($str) == 1 ? $str = '0' . $str: null); return $str; } function getPageRank($url) { // Page rank can't be obtained currently return 0; $checksum=$this->genhash($url); $googleurl = 'http://toolbarqueries.google.com/tbr?features=Rank&sourceid=navclient-ff&client=navclient-auto-ff'; $googleurl .= '&googleip=O;66.249.81.104;104&ch='.$checksum.'&q=info:'.urlencode($url); $data=SEFTools::PostRequest($googleurl,null,null,'get'); if(!empty($matches[2])) { return $matches[2][0]; } else { return 0; } } function getTotalIndexed($url) { $url = rtrim(JURI::root(), '/').'/'.ltrim($url, '/'); $url = str_replace(array('http://', 'https://'), '', $url); if (substr($url, 0, 4) == 'www.') { $url = substr($url, 4); } $google_url = 'http://www.google.com/search?q=site:'.urlencode($url); $data=SEFTools::PostRequest($google_url,null,null,'get'); $matches=array(); preg_match_all('#
    ([0-9,]*)#',$data->content,$matches); if(!empty($matches[1])) { return $matches[1][0]; } else { return 0; } } function getPopularity($url) { $url = rtrim(JURI::root(), '/').'/'.ltrim($url, '/'); $url = str_replace(array('http://', 'https://'), '', $url); if (substr($url, 0, 4) == 'www.') { $url = substr($url, 4); } $google_url = 'http://www.google.com/search?q="'.urlencode($url).'"+-site:'.urlencode($url); $data=SEFTools::PostRequest($google_url,null,null,'get'); $matches=array(); preg_match_all('#
    ([0-9,]*)#',$data->content,$matches); if(!empty($matches[1])) { return $matches[1][0]; } else { return 0; } } /*function getTitlePopularity($url) { $url=str_replace("http://","",$url); $url=str_replace("www.","",$url); $google_url = 'http://www.google.com/search?q="'.urlencode($url).'"+-site:'.urlencode($url); $data=SEFTools::PostRequest($google_url,null,null,'get'); $mathes=array(); preg_match_all('#
    ([A-Za-z]*) ([0-9,]*)#',$data->content,$matches); return $matches[2][0]; }*/ function getFacebookIndexed($url) { $url = rtrim(JURI::root(), '/').'/'.ltrim($url, '/'); $url = str_replace(array('http://', 'https://'), '', $url); if (substr($url, 0, 4) == 'www.') { $url = substr($url, 4); } $google_url = 'http://www.google.com/search?q="'.urlencode($url).'"+site:'.urlencode('facebook.com'); $data=SEFTools::PostRequest($google_url,null,null,'get'); $matches=array(); preg_match_all('#
    ([0-9,]*)#',$data->content,$matches); if(!empty($matches[1])) { return $matches[1][0]; } else { return 0; } } function getTwitterIndexed($url) { $url = rtrim(JURI::root(), '/').'/'.ltrim($url, '/'); $url = str_replace(array('http://', 'https://'), '', $url); if (substr($url, 0, 4) == 'www.') { $url = substr($url, 4); } $google_url = 'http://www.google.com/search?q="'.urlencode($url).'"+site:'.urlencode('twitter.com'); $data=SEFTools::PostRequest($google_url,null,null,'get'); $matches=array(); preg_match_all('#
    ([0-9,]*)#',$data->content,$matches); if(!empty($matches[1])) { return $matches[1][0]; } else { return 0; } } function getPageSpeed($url) { require_once JPATH_COMPONENT_ADMINISTRATOR.'/classes/config.php'; $url = rtrim(JURI::root(), '/').'/'.ltrim($url, '/'); $config = SEFConfig::getConfig(); $ndata=new stdClass(); if(strlen($config->google_apikey)==0) { return false; } $google_url='https://www.googleapis.com/pagespeedonline/v1/runPagespeed?url='.urlencode($url).'&key='.$config->google_apikey; // Use CURL if available if (function_exists('curl_init')) { $certFile = realpath(dirname(__FILE__).'/../cacert.pem'); $c=curl_init($google_url); curl_setopt($c,CURLOPT_RETURNTRANSFER,1); curl_setopt($c, CURLOPT_ENCODING, "utf-8" ); curl_setopt($c, CURLOPT_CAINFO, $certFile); $data=curl_exec($c); curl_close($c); } else { // Try to use our own method $data = SEFTools::PostRequest($google_url, null, null, 'get'); if ($data !== false) { $data = $data->content; } } if ($data === false) { // Could not connect return false; } $data=json_decode($data); $ndata=new stdClass(); if(isset($data->error)) { $ndata->message=$data->error->errors[0]->message; return $ndata; } @$ndata->pageStats=$data->pageStats; @$ndata->score=$data->score; $reg=new JRegistry(); $reg->loadObject($ndata); return $reg->toString("ini"); } } ?>components/com_sef/adapters/index.html000066600000000054150771655450014166 0ustar00components/com_sef/adapters/sef_ext.php000066600000043407150771655450014350 0ustar00parent =& $parent; JFactory::getLanguage()->load('com_sef'); } function install() { $extDir = JPATH_ROOT.'/components/com_sef/sef_ext'; $db = $this->parent->getDBO(); $this->manifest = $this->parent->getManifest(); $xml = $this->manifest; $name=(string)$xml->name; $name = JFilterInput::getInstance()->clean($name, 'string'); $this->set('name', $name); $description=(string)$xml->description; if (is_a($description, 'JSimpleXMLElement')) { $this->parent->set('message',JText::_($description)); } else { $this->parent->set('message', '' ); } if (count($xml->files->children())) { foreach ($xml->files->children() as $file) { if ((string)$file->attributes()->sef_ext) { $element = (string)$file->attributes()->sef_ext; if(substr($element,0,13)!='ext_joomsef4_') { $element='ext_joomsef4_'.$element; } $this->set('element',$element); break; } } } if(!empty($element)) { $this->parent->setPath('extension_root', $extDir); } else { $this->parent->abort(JText::sprintf('COM_SEF_INSTALLER_ABORT_SEFEXT_INSTALL_NO_FILE', JText::_('JLIB_INSTALLER_'.$this->route))); return false; } $this->route='install'; $query="SELECT extension_id, state, params \n"; $query.="FROM #__extensions \n"; $query.="WHERE type=".$db->quote('sef_ext')." \n"; $query.="AND element=".$db->quote($element); $db->setQuery($query); $ext_o=$db->loadObject(); if (!is_null($ext_o)) { $id=$ext_o->extension_id; } else { $id = null; } if(file_exists($this->parent->getPath('extension_root')) && (!$this->parent->isOverwrite()||$this->parent->isUpgrade())) { if($this->parent->isUpgrade()||($this->parent->manifestClass && method_exists($this->parent->manifestClass,'update')||is_a($xml->update,'SimpleXMLElement'))) { $this->parent->setOverwrite(true); $this->parent->setUpgrade(true); if($id && $ext_o->state!=-2) { $this->route='update'; } } else if(!$this->parent->isOverwrite()) { $this->parent->abort(JText::sprintf('COM_SEF_INSTALLER_ABORT_SEFEXT_INSTALL_DIRECTORY',JText::_('JLIB_INSTALLER_'.$this->route),$this->parent->getPath('extension_root'))); } } if((string)$xml->scriptfile) { $script=(string)$xml->scriptfile; $script_file=$this->parent->getPath('source').'/'.$script; if(is_file($script_file)) { include_once $script_file; $class=$element.'InstallerScript'; if(class_exists($class)) { $this->parent->manifestClass=new $class($this); $this->set('manifest_script',$script); } } } ob_start(); ob_implicit_flush(false); if($this->parent->manifestClass && method_exists($this->parent->manifestClass,'preflight')) { if($this->parent->manifestClass->preflight($this->route,$this)===false) { $this->parent->abort(JText::_('COM_SEF_INSTALLER_ABORT_SEF_INSTALL_CUSTOM_INSTALL_FAILURE')); return false; } } $msg=ob_get_contents(); ob_end_clean(); if(!file_exists($this->parent->getPath('extension_root'))) { if(JFolder::create($this->parent->getPath('extension_root'))) { $this->parent->abort(JText::sprintf('COM_SEF_INSTALLER_ABORT_SEF_INSTALL_CREATE_DIRECTORY',$this->parent->getPath('extension_root'))); return false; } } $this->old_files = null; if($this->route=='update') { $old=null; $tmp=new JInstaller(); $option=str_replace('ext_joomsef4_','com_',$this->get('element')); $tmp_manifest=$tmp->isManifest($this->parent->getPath('extension_root').'/'.$option.'.xml'); if($tmp_manifest) { $this->old_files=$tmp_manifest->files; } } if(!$this->parent->parseFiles($xml->files,-1,$this->old_files)) { $this->parent->abort(); return false; } if($this->get('manifest_script')) { $path['src'] = $this->parent->getPath('source').'/'. $this->get('manifest_script'); $path['dest'] = $this->parent->getPath('extension_root').'/'.$this->get('manifest_script'); if(!file_exists($path['desc'])) { if(!$this->parent->copyFiles(array($path))) { $this->parent->abort(JText::sprintf('COM_SEF_INSTALLER_ABORT_SEF_INSTALL_MANIFEST',JText::_('JLIB_INSTALLER_'.$this->route))); return false; } } } JTable::addIncludePath(JPATH_LIBRARIES.'/joomla/database/table'); $row=JTable::getInstance('extension'); if($id && $ext_o->state!=-2) { $row->load($id); $row->name=$this->get('name'); $row->manifest_cache=$this->parent->generateManifestCache(); $row->store(); } else { if(is_object($ext_o) && ($ext_o->state==-2)) { $row->extension_id=$id; } $row->name=$this->get('name'); $row->type='sef_ext'; $row->element=$element; $row->enabled=1; $row->protected=0; $row->access=1; $row->client_id=0; $row->state=0; if(!is_object($ext_o) || ($ext_o->state!=-2)) { if(isset($this->manifest->install->defaultParams)) { $row->params = SEFTools::getDefaultParams($this->manifest->install->defaultParams); } if(isset($this->manifest->install->defaultFilters)) { $row->custom_data=SEFTools::getDefaultFilters($this->manifest->install->defaultFilters); } } $row->system_data=''; $row->manifest_cache=$this->parent->generateManifestCache(); if(!$row->store()) { $this->parent->abort(Jtext::sprintf('COM_SEF_INSTALLER_ABORT_SEF_INSTALL_ROLLBACK',JText::_('JLIB_INSTALLER_'.$this->route),$db->stderr(true))); return false; } $this->parent->pushStep(array ('type' => 'extension', 'id' => $row->extension_id)); $id = $row->extension_id; } if($this->route=='install') { $utfresult = $this->parent->parseSQLFiles($this->manifest->install->sql); if ($utfresult === false) { // Install failed, rollback changes $this->parent->abort(JText::sprintf('COM_SEF_INSTALLER_ABORT_SEF_INSTALL_SQL_ERROR', JText::_('JLIB_INSTALLER_'.$this->route), $db->stderr(true))); return false; } if($this->manifest->update) { $this->parent->setSchemaVersion($this->manifest->update->schemas, $row->extension_id); } else { $query="SELECT COUNT(*) FROM #__schemas \n"; $query.="WHERE extension_id=".$row->extension_id; $db->setQuery($query); $cnt=$db->loadResult(); if($cnt==0) { $query="INSERT INTO #__schemas \n"; $query.="SET extension_id=".$row->extension_id.", version_id=".$db->quote((string)$xml->version); } else { $query="UPDATE #__schemas \n"; $query.="SET version_id=".$db->quote((string)$xml->version)." \n"; $query.="WHERE extension_id=".$row->extension_id." \n"; } $db->setQuery($query); $db->query(); } } else { if($this->manifest->update) { if(isset($this->manifest->update->schemas)) { $result = $this->parent->parseSchemaUpdates($this->manifest->update->schemas, $row->extension_id); if ($result === false) { $this->parent->abort(JText::sprintf('COM_SEF_INSTALLER_ABORT_SEF_UPDATE_SQL_ERROR', JText::_('JLIB_INSTALLER_'.$this->route), $db->stderr(true))); return false; } } } else { $query="SELECT COUNT(*) FROM #__schemas \n"; $query.="WHERE extension_id=".$row->extension_id; $db->setQuery($query); $cnt=$db->loadResult(); if($cnt==0) { $query="INSERT INTO #__schemas \n"; $query.="SET extension_id=".$row->extension_id.", version_id=".$db->quote((string)$xml->version); } else { $query="UPDATE #__schemas \n"; $query.="SET version_id=".$db->quote((string)$xml->version)." \n"; $query.="WHERE extension_id=".$row->extension_id." \n"; } $db->setQuery($query); $db->query(); } } // Remove any pending updates in Joomla update cache $update = JTable::getInstance('update'); $uid = $update->find(array('element' => $element, 'type' => 'sef_ext', 'client_id' => '', 'folder' => '')); if ($uid) { $update->delete($uid); } ob_start(); ob_implicit_flush(false); if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,$this->route)) { if($this->parent->manifestClass->{$this->route}($this) === false) { $this->parent->abort(JText::_('COM_SEF_INSTALLER_ABORT_SEF_INSTALL_CUSTOM_INSTALL_FAILURE')); return false; } } $msg .= ob_get_contents(); ob_end_clean(); if (!$this->parent->copyManifest(-1)) { $this->parent->abort(JText::sprintf('COM_SEF_INSTALLER_ABORT_SEF_INSTALL_COPY_SETUP', JText::_('JLIB_INSTALLER_'.$this->route))); return false; } ob_start(); ob_implicit_flush(false); if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'postflight')) { $this->parent->manifestClass->postflight($this->route, $this); } $msg .= ob_get_contents(); ob_end_clean(); if ($msg != '') { $this->parent->set('extension_message', $msg); } // Remove already created URLs for this extension from database // 25.4.2012: Only remove automatic URLs that are not locked! $component = str_replace('ext_joomsef4_', 'com_', $element); $query = "DELETE FROM `#__sefurls` WHERE (`origurl` LIKE '%option={$component}&%' OR `origurl` LIKE '%option={$component}') AND `dateadd` = '0000-00-00' AND `locked` = 0"; $db->setQuery($query); if (!$db->query()) { $this->parent->abort( JText::_('COM_SEF_SEF_EXTENSION').' '.JText::_('COM_SEF_INSTALL').': '.JText::_('COM_SEF_ERROR_SQL')." ".$db->stderr(true) ); return false; } return $id; } function update() { $this->parent->setOverwrite(true); $this->parent->setUpgrade(true); $this->route='update'; return $this->install(); } function uninstall($id) { $this->route='uninstall'; $db=JFactory::getDBO(); $row=JTable::getInstance('extension'); if(!$row->load((int)$id)) { JError::raiseWarning(100, JText::_('COM_SEF_INSTALLER_ERROR_SEF_UNINSTALL_ERRORUNKOWNEXTENSION')); return false; } if ($row->protected) { JError::raiseWarning(100, JText::sprintf('COM_SEF_INSTALLER_ERROR_SEF_UNINSTALL_WARNCOREPLUGIN', $row->name)); return false; } $this->parent->setPath('extension_root',JPATH_ROOT.'/components/com_sef/sef_ext'); $manifest_file=$this->parent->getPath('extension_root').'/'.str_replace('ext_joomsef4_','com_',$row->element).'.xml'; if(!file_exists($manifest_file)) { JError::raiseWarning(100, JText::_('COM_SEF_INSTALLER_ERROR_SEF_UNINSTALL_INVALID_NOTFOUND_MANIFEST')); $row->delete($row->extension_id); unset($row); return false; } $xml = simplexml_load_file($manifest_file); $this->manifest = $xml; if (!$xml) { JError::raiseWarning(100, JText::_('COM_SEF_INSTALLER_ERROR_SEF_UNINSTALL_LOAD_MANIFEST')); $row->delete($row->extension_id); unset($row); return false; } if ($xml->getName() != 'install' && $xml->getName() != 'extension') { JError::raiseWarning(100, JText::_('COM_SEF_INSTALLER_ERROR_SEF_UNINSTALL_INVALID_MANIFEST')); return false; } $element=$row->element; $script=(string)$xml->scriptfile; if($script) { $script_file=$this->parent->getPath('source').'/'.$script; if(is_file($script_file)) { include_once($script_file); $class=$element.'InstallerScript'; if(class_exists($class)) { $this->parent->manifestClass=new $class($this); $this->set('manifest_script',$script); } } } ob_start(); ob_implicit_flush(false); if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'preflight')) { if($this->parent->manifestClass->preflight($this->route, $this) === false) { $this->parent->abort(JText::_('COM_SEF_INSTALLER_ABORT_SEF_INSTALL_CUSTOM_INSTALL_FAILURE')); return false; } } $msg = ob_get_contents(); ob_end_clean(); if($this->parent->parseSQLFiles($xml->uninstall->sql)===FALSE) { $this->parent->abort(JText::sprintf('COM_SEF_INSTALLER_ABORT_PLG_UNINSTALL_SQL_ERROR', $db->stderr(true))); return false; } ob_start(); ob_implicit_flush(false); if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'uninstall')) { $this->parent->manifestClass->uninstall($this); } $msg = ob_get_contents(); ob_end_clean(); $this->parent->removeFiles($xml->files, -1); JFile::delete($manifest_file); $query=$db->getQuery(true); $query->delete()->from('#__schemas')->where('extension_id='.$row->extension_id); $db->setQUery($query); $db->query(); $row->delete($row->extension_id); unset($row); if ($msg) { $this->parent->set('extension_message',$msg); } return true; } function discover() { $results=array(); $list=JFolder::files(JPATH_ROOT.'/components/com_sef/sef_ext'); foreach($list as $sef) { if(substr($sef,-4)!='.xml') { continue; } $xml=simplexml_load_file(JPATH_ROOT.'/components/com_sef/sef_ext/'.$sef); if (count($xml->files->children())) { foreach ($xml->files->children() as $file) { if ((string)$file->attributes()->sef_ext) { $element = (string)$file->attributes()->sef_ext; if(substr($element,0,13)!='ext_joomsef4_') { $element='ext_joomsef4_'.$element; } break; } } } $extension=JTable::getInstance('extension'); $extension->set('type','sef_ext'); $extension->set('client_id',0); $extension->set('element',$element); $extension->set('name',(string)$xml->name); $extension->set('state',-1); $extension->set('manifest_cache',json_encode(JApplicationHelper::parseXMLInstallFile(JPATH_ROOT.'/components/com_sef/sef_ext/'.$sef))); $results[]=clone $extension; } return $results; } function discover_install() { $option = str_replace('ext_joomsef4_', 'com_', $this->parent->extension->element); $manifest_path=JPATH_ROOT.'/components/com_sef/sef_ext/'.$option.'.xml'; $this->parent->manifest=$this->parent->isManifest($manifest_path); if (!is_object($this->parent->manifest)) { JError::raiseWarning(101, JText::_('COM_SEF_INSTALLER_ERROR_SEF_DISCOVER_STORE_DETAILS')); return false; } $description=(string)$this->parent->manifest->description; if($description) { $this->parent->set('message',$description); } else { $this->parent->set('message'); } $this->parent->setPath('manifest',$manifest_path); $manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest')); $this->parent->extension->manifest_cache = json_encode($manifest_details); $this->parent->extension->state = 0; $this->parent->extension->name = $manifest_details['name']; $this->parent->extension->enabled = 1; if(isset($this->manifest->install->defaultparams)) { $this->parent->extension->params = SEFTools::getDefaultParams((string)$this->manifest->install->defaultparams); } if(isset($this->manigest->install->defaultfilters)) { $this->parent->extension->custom_data=SEFTools::getDefaultFilters((string)$this->manigest->install->defaultfilters); } if ($this->parent->extension->store()) { return $this->parent->extension->get('extension_id'); } else { JError::raiseWarning(101, JText::_('COM_SEF_INSTALLER_ERROR_SEF_DISCOVER_STORE_DETAILS')); return false; } $utfresult = $this->parent->parseSQLFiles($this->manifest->install->sql); if ($utfresult === false) { JError::raiseWarning(JText::sprintf('COM_SEF_INSTALLER_ABORT_SEF_INSTALL_SQL_ERROR', JText::_('JLIB_INSTALLER_'.$this->route), $db->stderr(true))); return false; } if($this->manifest->update) { $this->parent->setSchemaVersion($this->manifest->update->schemas, $row->extension_id); } } function refreshManifestCache() { $file = str_replace('ext_joomsef4_', 'com_', $this->parent->extension->element); $manifest_path=JPATH_ROOT.'/components/com_sef/sef_ext/'.$file.'.xml'; $this->parent->manifest=$this->parent->isManifest($manifest_path); $this->parent->setPath('manifest',$manifest_path); $manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest')); $this->parent->extension->manifest_cache = json_encode($manifest_details); $this->parent->extension->name = $manifest_details['name']; if (!$this->parent->extension->store()) { JError::raiseWarning(101, JText::_('COM_SEF_INSTALLER_ERROR_SEF_REFRESH_MANIFEST_CACHE')); return false; } return true; } }components/com_sef/adapters/sef_update.php000066600000007676150771655450015042 0ustar00_update_site_id=$data["update_site_id"]; $this->base=array(); $this->update_sites=array(); $this->updates=array(); $ext_data=SEFTools::postRequest($data['location']); $details=$ext_data->content; $db=JFactory::getDBO(); if(!strlen($details)) { $query=$db->getQuery(true); $query->update('#__update_sites')->set('enabled=0')->where('update_site='.$data["update_site_id"]); $db->query(); JError::raiseWarning('101', JText::sprintf('JLIB_UPDATER_ERROR_SEFEXT_OPEN_URL', $data["url"])); return false; } if(preg_match("/^[0-9]{2}/",$details,$status)) { $details=$status[0]; $url=explode("/",$data['location']); $ext=array_pop($url); $ext=str_replace('.xml','',$ext); if(substr_count($ext,"-")) { $ext_name_arr=explode("-",$ext); $ext_name=$ext_name_arr[0]; } else { $ext_name=$ext; } if(substr_count($ext,'com_joomsef4')) { $data["name"]="Artio JoomSEF 4"; } else { $query=$db->getQuery(true); $query->select('name')->from('#__extensions')->where('element='.$db->quote($ext_name))->where('type='.$db->quote('sef_ext')); $db->setQuery($query); $data["name"]=$db->loadResult(); if (is_null($data['name'])) { // Extension not found return true; } $data['name'] .= ' (JoomSEF extension)'; } } switch($details) { case '20': JError::raiseWarning('101', $data["name"].': '.JText::sprintf('COM_SEF_EXPIRED', $data["name"])); break; case '30': JError::raiseWarning('101', $data["name"].': '.JText::sprintf('COM_SEF_NOT_ACTIVATED',$data["name"])); break; case '40': JError::raiseWarning('101', $data["name"].': '.JText::sprintf('COM_SEF_ERR_DOMAIN_NOT_MATCH',$data["name"])); break; case '50': JError::raiseWarning('101', $data["name"].': '.JText::sprintf('COM_SEF_DOWLOAD_ID_INVALID',$data["name"])); break; case '90': // Commercial extension $location_match=array(); if(preg_match("/(-([A-Za-z0-9]*)).xml/",$data["location"],$location_match)) { JError::raiseWarning('101', $data["name"].': '.JText::sprintf('COM_SEF_ERROR_DOWNLOAD_ID_NOT_FOUND',$location_match[2])); // Free extension } else { JError::raiseWarning('101', $data["name"].': '.JText::sprintf('COM_SEF_NOT_FOUND',$data["name"])); } break; default: $xml=simplexml_load_string($details); if(is_object($xml)) { foreach($xml->children() as $update) { $table=JTable::getInstance('update'); $table->update_site_id=$this->_update_site_id; $table->version=(string)$update->version; if ((string)$update->element == 'com_joomsef4') { $sef_version=SEFTools::getSEFVersion(); $table->name=(string)$update->name; $table->element='com_sef'; $table->client_id=1; $table->type='component'; } else { $sefext_version=SEFTools::getExtVersion((string)$update->name); $table->name=(string)$update->name; $table->element=(string)$update->element; $table->client_id=0; $table->type='sef_ext'; } $table->detailsurl=$data["location"]; $this->updates[]=$table; } } } return array('update_sites'=>$this->update_sites,'updates'=>$this->updates); } } ?>components/com_sef/install.sql000066600000007276150771655450012572 0ustar00CREATE TABLE IF NOT EXISTS `#__sefurls` ( `id` int(11) NOT NULL auto_increment, `cpt` int(11) NOT NULL default '0', `sefurl` varchar(255) NOT NULL, `origurl` varchar(255) NOT NULL, `Itemid` varchar(20) default NULL, `metadesc` varchar(1024) default '', `metakey` varchar(255) default '', `metatitle` varchar(255) default '', `metalang` varchar(30) default '', `metarobots` varchar(30) default '', `metagoogle` varchar(30) default '', `metacustom` text, `metaauthor` varchar(30) default '', `canonicallink` varchar(255) default '', `dateadd` date NOT NULL default '0000-00-00', `priority` int(11) NOT NULL DEFAULT '0', `trace` text DEFAULT NULL, `enabled` TINYINT(1) NOT NULL DEFAULT '1', `locked` TINYINT(1) NOT NULL DEFAULT '0', `sef` TINYINT(1) NOT NULL DEFAULT '1', `sm_indexed` TINYINT(1) NOT NULL DEFAULT '0', `sm_date` DATE NOT NULL DEFAULT '0000-00-00', `sm_frequency` VARCHAR(20) NOT NULL DEFAULT 'weekly', `sm_priority` VARCHAR(10) NOT NULL DEFAULT '0.5', `flag` TINYINT(1) NOT NULL DEFAULT '0', `host` varchar(255) NOT NULL DEFAULT '', `showsitename` INTEGER(1) NOT NULL DEFAULT '3', PRIMARY KEY (`id`), KEY `sefurl` (`sefurl`), KEY `origurl` (`origurl`, `Itemid`), KEY `idx_updates` (`locked`, `flag`) ) ENGINE=InnoDB CHARACTER SET 'utf8'; CREATE TABLE IF NOT EXISTS `#__sefexts` ( `id` int(11) NOT NULL auto_increment, `file` varchar(100) NOT NULL, `filters` text, `params` text, `title` varchar(255), PRIMARY KEY (`id`) ) CHARACTER SET 'utf8'; CREATE TABLE IF NOT EXISTS `#__sefmoved` ( `id` int(11) NOT NULL auto_increment, `old` varchar(255) NOT NULL, `new` varchar(255) NOT NULL, `lastHit` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`), KEY `old` (`old`) ) CHARACTER SET 'utf8'; CREATE TABLE IF NOT EXISTS `#__sefexttexts` ( `id` int(11) NOT NULL auto_increment, `extension` varchar(100) NOT NULL, `name` varchar(100) NOT NULL, `value` varchar(100) NOT NULL, `lang_id` int(5) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) CHARACTER SET 'utf8'; CREATE TABLE IF NOT EXISTS `#__sefwords` ( `id` int(11) NOT NULL auto_increment, `word` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) CHARACTER SET 'utf8'; CREATE TABLE IF NOT EXISTS `#__sefurlword_xref` ( `word` int(11) NOT NULL, `url` int(11) NOT NULL, PRIMARY KEY (`word`, `url`) ) CHARACTER SET 'utf8'; CREATE TABLE IF NOT EXISTS `#__sefaliases` ( `id` int(11) NOT NULL auto_increment, `alias` varchar(255) NOT NULL DEFAULT '', `vars` text NOT NULL, `url` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `alias` (`alias`) ) CHARACTER SET 'utf8'; CREATE TABLE IF NOT EXISTS `#__sef_statistics` ( `url_id` int(5) NOT NULL, `page_rank` int(3) NOT NULL, `total_indexed` int(10) NOT NULL, `popularity` int(10) NOT NULL, `facebook_indexed` int(10) NOT NULL, `twitter_indexed` int(10) NOT NULL, `validation_score` varchar(255) NOT NULL, `page_speed_score` mediumtext NOT NULL, PRIMARY KEY (`url_id`) ) CHARACTER SET 'utf8'; CREATE TABLE IF NOT EXISTS `#__seflog` ( `id` INTEGER(11) NOT NULL AUTO_INCREMENT, `time` DATETIME NOT NULL, `message` VARCHAR(255) DEFAULT NULL, `url` VARCHAR(255) NOT NULL DEFAULT '', `component` VARCHAR(255) DEFAULT NULL, `page` VARCHAR(255) DEFAULT NULL, PRIMARY KEY (`id`) ) CHARACTER SET 'utf8'; CREATE TABLE IF NOT EXISTS `#__sef_subdomains` ( `subdomain` varchar(255) NOT NULL DEFAULT '', `Itemid` mediumtext NOT NULL, `Itemid_titlepage` int(10) NOT NULL, `option` varchar(255) NOT NULL, `lang` varchar(10) NOT NULL, PRIMARY KEY (`subdomain`,`lang`) ) CHARACTER SET 'utf8';components/com_finder/tables/map.php000066600000004763150771655450013633 0ustar00_tbl_key; // Sanitize input. JArrayHelper::toInteger($pks); $state = (int) $state; // If there are no primary keys set check to see if the instance key is set. if (empty($pks)) { if ($this->$k) { $pks = array($this->$k); } // Nothing to set publishing state on, return false. else { $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); return false; } } // Build the WHERE clause for the primary keys. $where = $k . '=' . implode(' OR ' . $k . '=', $pks); // Update the publishing state for rows with the given primary keys. $query = $this->_db->getQuery(true) ->update($this->_db->quoteName($this->_tbl)) ->set($this->_db->quoteName('state') . ' = ' . (int) $state) ->where($where); $this->_db->setQuery($query); try { $this->_db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } // If the JTable instance value is in the list of primary keys that were set, set the instance. if (in_array($this->$k, $pks)) { $this->state = $state; } $this->setError(''); return true; } } components/com_finder/tables/index.html000066600000000036150771655450014327 0ustar00components/com_finder/tables/filter.php000066600000014432150771655450014335 0ustar00loadArray($array['params']); $array['params'] = (string) $registry; } return parent::bind($array, $ignore); } /** * Method to perform sanity checks on the JTable instance properties to ensure * they are safe to store in the database. Child classes should override this * method to make sure the data they are storing in the database is safe and * as expected before storage. * * @return boolean True if the instance is sane and able to be stored in the database. * * @since 2.5 */ public function check() { if (trim($this->alias) == '') { $this->alias = $this->title; } $this->alias = JApplication::stringURLSafe($this->alias); if (trim(str_replace('-', '', $this->alias)) == '') { $this->alias = JFactory::getDate()->format('Y-m-d-H-i-s'); } // Check the end date is not earlier than start up. if ($this->d2 > $this->_db->getNullDate() && $this->d2 < $this->d1) { // Swap the dates. $temp = $this->d1; $this->d1 = $this->d2; $this->d2 = $temp; } return true; } /** * Method to set the publishing state for a row or list of rows in the database * table. The method respects checked out rows by other users and will attempt * to checkin rows that it can after adjustments are made. * * @param mixed $pks An array of primary key values to update. If not * set the instance property value is used. [optional] * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published] [optional] * @param integer $userId The user id of the user performing the operation. [optional] * * @return boolean True on success. * * @since 2.5 */ public function publish($pks = null, $state = 1, $userId = 0) { $k = $this->_tbl_key; // Sanitize input. JArrayHelper::toInteger($pks); $userId = (int) $userId; $state = (int) $state; // If there are no primary keys set check to see if the instance key is set. if (empty($pks)) { if ($this->$k) { $pks = array($this->$k); } // Nothing to set publishing state on, return false. else { $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); return false; } } // Build the WHERE clause for the primary keys. $where = $k . '=' . implode(' OR ' . $k . '=', $pks); // Determine if there is checkin support for the table. if (!property_exists($this, 'checked_out') || !property_exists($this, 'checked_out_time')) { $checkin = ''; } else { $checkin = ' AND (checked_out = 0 OR checked_out = ' . (int) $userId . ')'; } // Update the publishing state for rows with the given primary keys. $query = $this->_db->getQuery(true) ->update($this->_db->quoteName($this->_tbl)) ->set($this->_db->quoteName('state') . ' = ' . (int) $state) ->where($where); $this->_db->setQuery($query . $checkin); try { $this->_db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } // If checkin is supported and all rows were adjusted, check them in. if ($checkin && (count($pks) == $this->_db->getAffectedRows())) { // Checkin the rows. foreach ($pks as $pk) { $this->checkin($pk); } } // If the JTable instance value is in the list of primary keys that were set, set the instance. if (in_array($this->$k, $pks)) { $this->state = $state; } $this->setError(''); return true; } /** * Method to store a row in the database from the JTable instance properties. * If a primary key value is set the row with that primary key value will be * updated with the instance property values. If no primary key value is set * a new row will be inserted into the database with the properties from the * JTable instance. * * @param boolean $updateNulls True to update fields even if they are null. [optional] * * @return boolean True on success. * * @since 2.5 */ public function store($updateNulls = false) { $date = JFactory::getDate(); $user = JFactory::getUser(); if ($this->filter_id) { // Existing item $this->modified = $date->toSql(); $this->modified_by = $user->get('id'); } else { // New item. A filter's created field can be set by the user, // so we don't touch it if it is set. if (!(int) $this->created) { $this->created = $date->toSql(); } if (empty($this->created_by)) { $this->created_by = $user->get('id'); } } if (is_array($this->data)) { $this->map_count = count($this->data); $this->data = implode(',', $this->data); } else { $this->map_count = 0; $this->data = implode(',', array()); } // Verify that the alias is unique $table = JTable::getInstance('Filter', 'FinderTable'); if ($table->load(array('alias' => $this->alias)) && ($table->filter_id != $this->filter_id || $this->filter_id == 0)) { $this->setError(JText::_('JLIB_DATABASE_ERROR_ARTICLE_UNIQUE_ALIAS')); return false; } return parent::store($updateNulls); } } components/com_finder/tables/link.php000066600000001241150771655450013777 0ustar00filter = $this->get('Filter'); $this->item = $this->get('Item'); $this->form = $this->get('Form'); $this->state = $this->get('State'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); JHtml::addIncludePath(JPATH_SITE . '/components/com_finder/helpers/html'); // Configure the toolbar. $this->addToolbar(); parent::display($tpl); } /** * Method to configure the toolbar for this view. * * @return void * * @since 2.5 */ protected function addToolbar() { JFactory::getApplication()->input->set('hidemainmenu', true); $user = JFactory::getUser(); $userId = $user->get('id'); $isNew = ($this->item->filter_id == 0); $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); $canDo = JHelperContent::getActions('com_finder'); // Configure the toolbar. JToolbarHelper::title(JText::_('COM_FINDER_FILTER_EDIT_TOOLBAR_TITLE'), 'zoom-in finder'); // Set the actions for new and existing records. if ($isNew) { // For new records, check the create permission. if ($canDo->get('core.create')) { JToolbarHelper::apply('filter.apply'); JToolbarHelper::save('filter.save'); JToolbarHelper::save2new('filter.save2new'); } JToolbarHelper::cancel('filter.cancel'); } else { // Can't save the record if it's checked out. if (!$checkedOut) { // Since it's an existing record, check the edit permission. if ($canDo->get('core.edit')) { JToolbarHelper::apply('filter.apply'); JToolbarHelper::save('filter.save'); // We can save this record, but check the create permission to see if we can return to make a new one. if ($canDo->get('core.create')) { JToolbarHelper::save2new('filter.save2new'); } } } // If an existing item, can save as a copy if ($canDo->get('core.create')) { JToolbarHelper::save2copy('filter.save2copy'); } JToolbarHelper::cancel('filter.cancel', 'JTOOLBAR_CLOSE'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT'); } } components/com_finder/views/filter/tmpl/edit.php000066600000003730150771655450016120 0ustar00
    'details')); ?>
    form->getControlGroup('map_count'); ?>
    $this->filter->data)); ?>
    components/com_finder/views/filter/tmpl/index.html000066600000000037150771655450016454 0ustar00 components/com_finder/views/filter/index.html000066600000000037150771655450015500 0ustar00 components/com_finder/views/indexer/view.html.php000066600000001635150771655450016307 0ustar00


    components/com_finder/views/indexer/tmpl/index.html000066600000000037150771655450016625 0ustar00 components/com_finder/views/indexer/index.html000066600000000037150771655450015651 0ustar00 components/com_finder/views/index.html000066600000000036150771655450014212 0ustar00components/com_finder/views/statistics/view.html.php000066600000001653150771655450017043 0ustar00data = $this->get('Data'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } parent::display($tpl); } } components/com_finder/views/statistics/tmpl/default.php000066600000004144150771655450017524 0ustar00

    data->term_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')), number_format($this->data->link_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')), number_format($this->data->taxonomy_node_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')), number_format($this->data->taxonomy_branch_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR'))); ?>

    data->type_list as $type) :?>
    type_title); $lang_string = JText::_($lang_key); echo ($lang_string == $lang_key) ? $type->type_title : $lang_string; ?> link_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR'));?>
    data->link_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')); ?>
    components/com_finder/views/statistics/tmpl/index.html000066600000000036150771655450017360 0ustar00components/com_finder/views/statistics/index.html000066600000000036150771655450016404 0ustar00components/com_finder/views/filters/view.html.php000066600000005210150771655450016312 0ustar00items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->total = $this->get('Total'); $this->state = $this->get('State'); FinderHelper::addSubmenu('filters'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); // Configure the toolbar. $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Method to configure the toolbar for this view. * * @return void * * @since 2.5 */ protected function addToolbar() { $canDo = JHelperContent::getActions('com_finder'); JToolbarHelper::title(JText::_('COM_FINDER_FILTERS_TOOLBAR_TITLE'), 'zoom-in finder'); $toolbar = JToolbar::getInstance('toolbar'); if ($canDo->get('core.create')) { JToolbarHelper::addNew('filter.add'); JToolbarHelper::editList('filter.edit'); JToolbarHelper::divider(); } if ($canDo->get('core.edit.state')) { JToolbarHelper::publishList('filters.publish'); JToolbarHelper::unpublishList('filters.unpublish'); JToolbarHelper::divider(); } if ($canDo->get('core.delete')) { JToolbarHelper::deleteList('', 'filters.delete'); JToolbarHelper::divider(); } if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_finder'); } JToolbarHelper::divider(); $toolbar->appendButton('Popup', 'stats', 'COM_FINDER_STATISTICS', 'index.php?option=com_finder&view=statistics&tmpl=component', 550, 350); JToolbarHelper::divider(); JToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS'); JHtmlSidebar::setAction('index.php?option=com_finder&view=filters'); JHtmlSidebar::addFilter( JText::_('COM_FINDER_INDEX_FILTER_BY_STATE'), 'filter_state', JHtml::_('select.options', JHtml::_('finder.statelist'), 'value', 'text', $this->state->get('filter.state')) ); } } components/com_finder/views/filters/tmpl/default.php000066600000013503150771655450017001 0ustar00get('id'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); JText::script('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'); ?>
    sidebar)) : ?>
    sidebar; ?>
    items) == 0) : ?> items as $i => $item): $canCreate = $user->authorise('core.create', 'com_finder'); $canEdit = $user->authorise('core.edit', 'com_finder'); $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; $canChange = $user->authorise('core.edit.state', 'com_finder') && $canCheckin; ?>
    total == 0): echo JText::_('COM_FINDER_NO_FILTERS'); ?>
    filter_id); ?> checked_out) { echo JHtml::_('jgrid.checkedout', $i, $item->editor, $item->checked_out_time, 'filters.', $canCheckin); } ?> escape($item->title); ?> escape($item->title); } ?> state, $i, 'filters.', $canChange); ?> created_by_alias ? $item->created_by_alias : $item->user_name; ?> created, JText::_('DATE_FORMAT_LC4')); ?> map_count; ?> filter_id; ?>
    pagination->getListFooter(); ?>
    components/com_finder/views/filters/tmpl/index.html000066600000000037150771655450016637 0ustar00 components/com_finder/views/filters/index.html000066600000000037150771655450015663 0ustar00 components/com_finder/views/index/view.html.php000066600000006160150771655450015756 0ustar00items = $this->get('Items'); $this->total = $this->get('Total'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); $this->pluginState = $this->get('pluginState'); FinderHelper::addSubmenu('index'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); // Configure the toolbar. $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Method to configure the toolbar for this view. * * @return void * * @since 2.5 */ protected function addToolbar() { $canDo = JHelperContent::getActions('com_finder'); JToolbarHelper::title(JText::_('COM_FINDER_INDEX_TOOLBAR_TITLE'), 'zoom-in finder'); $toolbar = JToolbar::getInstance('toolbar'); $toolbar->appendButton( 'Popup', 'archive', 'COM_FINDER_INDEX', 'index.php?option=com_finder&view=indexer&tmpl=component', 500, 210, 0, 0, 'window.parent.location.reload()', 'COM_FINDER_HEADING_INDEXER' ); if ($canDo->get('core.edit.state')) { JToolbarHelper::publishList('index.publish'); JToolbarHelper::unpublishList('index.unpublish'); } if ($canDo->get('core.delete')) { JToolbarHelper::deleteList('', 'index.delete'); } if ($canDo->get('core.edit.state')) { JToolbarHelper::trash('index.purge', 'COM_FINDER_INDEX_TOOLBAR_PURGE', false); } if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_finder'); } $toolbar->appendButton('Popup', 'stats', 'COM_FINDER_STATISTICS', 'index.php?option=com_finder&view=statistics&tmpl=component', 550, 350); JToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT'); JHtmlSidebar::setAction('index.php?option=com_finder&view=index'); JHtmlSidebar::addFilter( JText::_('COM_FINDER_INDEX_FILTER_BY_STATE'), 'filter_state', JHtml::_('select.options', JHtml::_('finder.statelist'), 'value', 'text', $this->state->get('filter.state')) ); JHtmlSidebar::addFilter( JText::_('COM_FINDER_INDEX_TYPE_FILTER'), 'filter_type', JHtml::_('select.options', JHtml::_('finder.typeslist'), 'value', 'text', $this->state->get('filter.type')) ); } } components/com_finder/views/index/tmpl/default.php000066600000014020150771655450016433 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $lang = JFactory::getLanguage(); JText::script('COM_FINDER_INDEX_CONFIRM_PURGE_PROMPT'); JText::script('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'); ?>
    sidebar)) : ?>
    sidebar; ?>
    pagination->getLimitBox(); ?>
    pluginState['plg_content_finder']->enabled) : ?>
    items) == 0) : ?> authorise('core.manage', 'com_finder'); ?> items as $i => $item) : ?>
    total == 0) { echo JText::_('COM_FINDER_INDEX_NO_DATA') . ' ' . JText::_('COM_FINDER_INDEX_TIP'); } else { echo JText::_('COM_FINDER_INDEX_NO_CONTENT'); } ?>
    link_id); ?> published, $i, 'index.', $canChange, 'cb'); ?> escape($item->title); ?> url) > 80) { echo substr($item->url, 0, 70) . '...'; } else { echo $item->url; } ?> publish_start_date) or intval($item->publish_end_date) or intval($item->start_date) or intval($item->end_date)) : ?> t_title); echo $lang->hasKey($key) ? JText::_($key) : $item->t_title; ?> indexdate, JText::_('DATE_FORMAT_LC4')); ?>
    pagination->getListFooter(); ?>
    components/com_finder/views/index/tmpl/index.html000066600000000037150771655450016276 0ustar00 components/com_finder/views/index/index.html000066600000000037150771655450015322 0ustar00 components/com_finder/views/maps/view.html.php000066600000005510150771655450015605 0ustar00items = $this->get('Items'); $this->total = $this->get('Total'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); FinderHelper::addSubmenu('maps'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); // Prepare the view. $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Method to configure the toolbar for this view. * * @return void * * @since 2.5 */ protected function addToolbar() { $canDo = JHelperContent::getActions('com_finder'); JToolbarHelper::title(JText::_('COM_FINDER_MAPS_TOOLBAR_TITLE'), 'zoom-in finder'); $toolbar = JToolbar::getInstance('toolbar'); if ($canDo->get('core.edit.state')) { JToolbarHelper::publishList('maps.publish'); JToolbarHelper::unpublishList('maps.unpublish'); JToolbarHelper::divider(); } if ($canDo->get('core.delete')) { JToolbarHelper::deleteList('', 'maps.delete'); JToolbarHelper::divider(); } if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_finder'); } JToolbarHelper::divider(); $toolbar->appendButton('Popup', 'stats', 'COM_FINDER_STATISTICS', 'index.php?option=com_finder&view=statistics&tmpl=component', 550, 350); JToolbarHelper::divider(); JToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_CONTENT_MAPS'); JHtmlSidebar::setAction('index.php?option=com_finder&view=maps'); JHtmlSidebar::addFilter( '', 'filter_branch', JHtml::_('select.options', JHtml::_('finder.mapslist'), 'value', 'text', $this->state->get('filter.branch')), true ); JHtmlSidebar::addFilter( JText::_('COM_FINDER_INDEX_FILTER_BY_STATE'), 'filter_state', JHtml::_('select.options', JHtml::_('finder.statelist'), 'value', 'text', $this->state->get('filter.state')) ); } } components/com_finder/views/maps/tmpl/default.php000066600000011730150771655450016271 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $lang = JFactory::getLanguage(); JText::script('COM_FINDER_MAPS_CONFIRM_DELETE_PROMPT'); ?>
    sidebar)) : ?>
    sidebar; ?>
    items) == 0) : ?> state->get('filter.branch') != 1) : ?> authorise('core.manage', 'com_finder'); ?> items as $i => $item) : ?>
    id); ?> title); $title = $lang->hasKey($key) ? JText::_($key) : $item->title; ?> state->get('filter.branch') == 1 && $item->num_children) : ?> escape($title); ?> escape(($title == '*') ? JText::_('JALL_LANGUAGE') : $title); ?> num_children > 0) : ?> (num_children; ?>) num_nodes > 0) : ?> (num_nodes; ?>) escape(trim($title, '**')) == 'Language' && JLanguageMultilang::isEnabled()) : ?> state, $i, 'maps.', $canChange, 'cb'); ?>
    pagination->getListFooter(); ?>
    components/com_finder/views/maps/tmpl/index.html000066600000000037150771655450016127 0ustar00 components/com_finder/views/maps/index.html000066600000000037150771655450015153 0ustar00 components/com_finder/sql/uninstall.mysql.sql000066600000002167150771655450015564 0ustar00DROP TABLE IF EXISTS `#__finder_filters`; DROP TABLE IF EXISTS `#__finder_links`; DROP TABLE IF EXISTS `#__finder_links_terms0`; DROP TABLE IF EXISTS `#__finder_links_terms1`; DROP TABLE IF EXISTS `#__finder_links_terms2`; DROP TABLE IF EXISTS `#__finder_links_terms3`; DROP TABLE IF EXISTS `#__finder_links_terms4`; DROP TABLE IF EXISTS `#__finder_links_terms5`; DROP TABLE IF EXISTS `#__finder_links_terms6`; DROP TABLE IF EXISTS `#__finder_links_terms7`; DROP TABLE IF EXISTS `#__finder_links_terms8`; DROP TABLE IF EXISTS `#__finder_links_terms9`; DROP TABLE IF EXISTS `#__finder_links_termsa`; DROP TABLE IF EXISTS `#__finder_links_termsb`; DROP TABLE IF EXISTS `#__finder_links_termsc`; DROP TABLE IF EXISTS `#__finder_links_termsd`; DROP TABLE IF EXISTS `#__finder_links_termse`; DROP TABLE IF EXISTS `#__finder_links_termsf`; DROP TABLE IF EXISTS `#__finder_taxonomy`; DROP TABLE IF EXISTS `#__finder_taxonomy_map`; DROP TABLE IF EXISTS `#__finder_terms`; DROP TABLE IF EXISTS `#__finder_terms_common`; DROP TABLE IF EXISTS `#__finder_tokens`; DROP TABLE IF EXISTS `#__finder_tokens_aggregate`; DROP TABLE IF EXISTS `#__finder_types`; components/com_finder/sql/uninstall.postgresql.sql000066600000002167150771655450016622 0ustar00DROP TABLE IF EXISTS "#__finder_filters"; DROP TABLE IF EXISTS "#__finder_links"; DROP TABLE IF EXISTS "#__finder_links_terms0"; DROP TABLE IF EXISTS "#__finder_links_terms1"; DROP TABLE IF EXISTS "#__finder_links_terms2"; DROP TABLE IF EXISTS "#__finder_links_terms3"; DROP TABLE IF EXISTS "#__finder_links_terms4"; DROP TABLE IF EXISTS "#__finder_links_terms5"; DROP TABLE IF EXISTS "#__finder_links_terms6"; DROP TABLE IF EXISTS "#__finder_links_terms7"; DROP TABLE IF EXISTS "#__finder_links_terms8"; DROP TABLE IF EXISTS "#__finder_links_terms9"; DROP TABLE IF EXISTS "#__finder_links_termsa"; DROP TABLE IF EXISTS "#__finder_links_termsb"; DROP TABLE IF EXISTS "#__finder_links_termsc"; DROP TABLE IF EXISTS "#__finder_links_termsd"; DROP TABLE IF EXISTS "#__finder_links_termse"; DROP TABLE IF EXISTS "#__finder_links_termsf"; DROP TABLE IF EXISTS "#__finder_taxonomy"; DROP TABLE IF EXISTS "#__finder_taxonomy_map"; DROP TABLE IF EXISTS "#__finder_terms"; DROP TABLE IF EXISTS "#__finder_terms_common"; DROP TABLE IF EXISTS "#__finder_tokens"; DROP TABLE IF EXISTS "#__finder_tokens_aggregate"; DROP TABLE IF EXISTS "#__finder_types"; components/com_finder/sql/install.postgresql.sql000066600000123341150771655450016255 0ustar00-- -- Table: #__finder_filters -- CREATE TABLE "#__finder_filters" ( "filter_id" serial NOT NULL, "title" character varying(255) NOT NULL, "alias" character varying(255) NOT NULL, "state" smallint DEFAULT 1 NOT NULL, "created" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "created_by" integer NOT NULL, "created_by_alias" character varying(255) NOT NULL, "modified" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "modified_by" integer DEFAULT 0 NOT NULL, "checked_out" integer DEFAULT 0 NOT NULL, "checked_out_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "map_count" integer DEFAULT 0 NOT NULL, "data" text NOT NULL, "params" text, PRIMARY KEY ("filter_id") ); -- -- Table: #__finder_links -- CREATE TABLE "#__finder_links" ( "link_id" serial NOT NULL, "url" character varying(255) NOT NULL, "route" character varying(255) NOT NULL, "title" character varying(255) DEFAULT NULL, "description" character varying(255) DEFAULT NULL, "indexdate" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "md5sum" character varying(32) DEFAULT NULL, "published" smallint DEFAULT 1 NOT NULL, "state" integer DEFAULT 1, "access" integer DEFAULT 0, "language" character varying(8) NOT NULL, "publish_start_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "publish_end_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "start_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "end_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "list_price" numeric(8,2) DEFAULT 0 NOT NULL, "sale_price" numeric(8,2) DEFAULT 0 NOT NULL, "type_id" bigint NOT NULL, "object" bytea NOT NULL, PRIMARY KEY ("link_id") ); CREATE INDEX "#__finder_links_idx_type" on "#__finder_links" ("type_id"); CREATE INDEX "#__finder_links_idx_title" on "#__finder_links" ("title"); CREATE INDEX "#__finder_links_idx_md5" on "#__finder_links" ("md5sum"); CREATE INDEX "#__finder_links_idx_url" on "#__finder_links" (url(75)); CREATE INDEX "#__finder_links_idx_published_list" on "#__finder_links" ("published", "state", "access", "publish_start_date", "publish_end_date", "list_price"); CREATE INDEX "#__finder_links_idx_published_sale" on "#__finder_links" ("published", "state", "access", "publish_start_date", "publish_end_date", "sale_price"); -- -- Table: #__finder_links_terms0 -- CREATE TABLE "#__finder_links_terms0" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms0_idx_term_weight" on "#__finder_links_terms0" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms0_idx_link_term_weight" on "#__finder_links_terms0" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms1 -- CREATE TABLE "#__finder_links_terms1" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms1_idx_term_weight" on "#__finder_links_terms1" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms1_idx_link_term_weight" on "#__finder_links_terms1" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms2 -- CREATE TABLE "#__finder_links_terms2" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms2_idx_term_weight" on "#__finder_links_terms2" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms2_idx_link_term_weight" on "#__finder_links_terms2" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms3 -- CREATE TABLE "#__finder_links_terms3" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms3_idx_term_weight" on "#__finder_links_terms3" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms3_idx_link_term_weight" on "#__finder_links_terms3" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms4 -- CREATE TABLE "#__finder_links_terms4" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms4_idx_term_weight" on "#__finder_links_terms4" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms4_idx_link_term_weight" on "#__finder_links_terms4" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms5 -- CREATE TABLE "#__finder_links_terms5" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms5_idx_term_weight" on "#__finder_links_terms5" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms5_idx_link_term_weight" on "#__finder_links_terms5" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms6 -- CREATE TABLE "#__finder_links_terms6" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms6_idx_term_weight" on "#__finder_links_terms6" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms6_idx_link_term_weight" on "#__finder_links_terms6" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms7 -- CREATE TABLE "#__finder_links_terms7" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms7_idx_term_weight" on "#__finder_links_terms7" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms7_idx_link_term_weight" on "#__finder_links_terms7" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms8 -- CREATE TABLE "#__finder_links_terms8" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms8_idx_term_weight" on "#__finder_links_terms8" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms8_idx_link_term_weight" on "#__finder_links_terms8" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_terms9 -- CREATE TABLE "#__finder_links_terms9" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_terms9_idx_term_weight" on "#__finder_links_terms9" ("term_id", "weight"); CREATE INDEX "#__finder_links_terms9_idx_link_term_weight" on "#__finder_links_terms9" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_termsa -- CREATE TABLE "#__finder_links_termsa" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_termsa_idx_term_weight" on "#__finder_links_termsa" ("term_id", "weight"); CREATE INDEX "#__finder_links_termsa_idx_link_term_weight" on "#__finder_links_termsa" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_termsb -- CREATE TABLE "#__finder_links_termsb" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_termsb_idx_term_weight" on "#__finder_links_termsb" ("term_id", "weight"); CREATE INDEX "#__finder_links_termsb_idx_link_term_weight" on "#__finder_links_termsb" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_termsc -- CREATE TABLE "#__finder_links_termsc" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_termsc_idx_term_weight" on "#__finder_links_termsc" ("term_id", "weight"); CREATE INDEX "#__finder_links_termsc_idx_link_term_weight" on "#__finder_links_termsc" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_termsd -- CREATE TABLE "#__finder_links_termsd" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_termsd_idx_term_weight" on "#__finder_links_termsd" ("term_id", "weight"); CREATE INDEX "#__finder_links_termsd_idx_link_term_weight" on "#__finder_links_termsd" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_termse -- CREATE TABLE "#__finder_links_termse" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_termse_idx_term_weight" on "#__finder_links_termse" ("term_id", "weight"); CREATE INDEX "#__finder_links_termse_idx_link_term_weight" on "#__finder_links_termse" ("link_id", "term_id", "weight"); -- -- Table: #__finder_links_termsf -- CREATE TABLE "#__finder_links_termsf" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, PRIMARY KEY ("link_id", "term_id") ); CREATE INDEX "#__finder_links_termsf_idx_term_weight" on "#__finder_links_termsf" ("term_id", "weight"); CREATE INDEX "#__finder_links_termsf_idx_link_term_weight" on "#__finder_links_termsf" ("link_id", "term_id", "weight"); -- -- Table: #__finder_taxonomy -- CREATE TABLE "#__finder_taxonomy" ( "id" serial NOT NULL, "parent_id" integer DEFAULT 0 NOT NULL, "title" character varying(255) NOT NULL, "state" smallint DEFAULT 1 NOT NULL, "access" smallint DEFAULT 0 NOT NULL, "ordering" smallint DEFAULT 0 NOT NULL, PRIMARY KEY ("id") ); CREATE INDEX "#__finder_taxonomy_parent_id" on "#__finder_taxonomy" ("parent_id"); CREATE INDEX "#__finder_taxonomy_state" on "#__finder_taxonomy" ("state"); CREATE INDEX "#__finder_taxonomy_ordering" on "#__finder_taxonomy" ("ordering"); CREATE INDEX "#__finder_taxonomy_access" on "#__finder_taxonomy" ("access"); CREATE INDEX "#__finder_taxonomy_idx_parent_published" on "#__finder_taxonomy" ("parent_id", "state", "access"); -- -- Dumping data for table #__finder_taxonomy -- UPDATE "#__finder_taxonomy" SET ("id", "parent_id", "title", "state", "access", "ordering") = (1, 0, 'ROOT', 0, 0, 0) WHERE "id"=1; INSERT INTO "#__finder_taxonomy" ("id", "parent_id", "title", "state", "access", "ordering") SELECT 1, 0, 'ROOT', 0, 0, 0 WHERE 1 NOT IN (SELECT 1 FROM "#__finder_taxonomy" WHERE "id"=1); -- -- Table: #__finder_taxonomy_map -- CREATE TABLE "#__finder_taxonomy_map" ( "link_id" integer NOT NULL, "node_id" integer NOT NULL, PRIMARY KEY ("link_id", "node_id") ); CREATE INDEX "#__finder_taxonomy_map_link_id" on "#__finder_taxonomy_map" ("link_id"); CREATE INDEX "#__finder_taxonomy_map_node_id" on "#__finder_taxonomy_map" ("node_id"); -- -- Table: #__finder_terms -- CREATE TABLE "#__finder_terms" ( "term_id" serial NOT NULL, "term" character varying(75) NOT NULL, "stem" character varying(75) NOT NULL, "common" smallint DEFAULT 0 NOT NULL, "phrase" smallint DEFAULT 0 NOT NULL, "weight" numeric(8,2) DEFAULT 0 NOT NULL, "soundex" character varying(75) NOT NULL, "links" integer DEFAULT 0 NOT NULL, PRIMARY KEY ("term_id"), CONSTRAINT "#__finder_terms_idx_term" UNIQUE ("term") ); CREATE INDEX "#__finder_terms_idx_term_phrase" on "#__finder_terms" ("term", "phrase"); CREATE INDEX "#__finder_terms_idx_stem_phrase" on "#__finder_terms" ("stem", "phrase"); CREATE INDEX "#__finder_terms_idx_soundex_phrase" on "#__finder_terms" ("soundex", "phrase"); -- -- Table: #__finder_terms_common -- CREATE TABLE "#__finder_terms_common" ( "term" character varying(75) NOT NULL, "language" character varying(3) NOT NULL ); CREATE INDEX "#__finder_terms_common_idx_word_lang" on "#__finder_terms_common" ("term", "language"); CREATE INDEX "#__finder_terms_common_idx_lang" on "#__finder_terms_common" ("language"); -- -- Dumping data for table `#__finder_terms_common` -- -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('a', 'en') WHERE "term"='a'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'a', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='a'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('about', 'en') WHERE "term"='about'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'about', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='about'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('after', 'en') WHERE "term"='after'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'after', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='after'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('ago', 'en') WHERE "term"='ago'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'ago', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='ago'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('all', 'en') WHERE "term"='all'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'all', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='all'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('am', 'en') WHERE "term"='am'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'am', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='am'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('an', 'en') WHERE "term"='an'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'an', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='an'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('and', 'en') WHERE "term"='and'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'and', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='and'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('ani', 'en') WHERE "term"='ani'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'ani', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='ani'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('any', 'en') WHERE "term"='any'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'any', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='any'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('are', 'en') WHERE "term"='are'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'are', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='are'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('aren''t', 'en') WHERE "term"='aren''t'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'aren''t', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='aren''t'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('as', 'en') WHERE "term"='as'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'as', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='as'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('at', 'en') WHERE "term"='at'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'at', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='at'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('be', 'en') WHERE "term"='be'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'be', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='be'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('but', 'en') WHERE "term"='but'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'but', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='but'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('by', 'en') WHERE "term"='by'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'by', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='by'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('for', 'en') WHERE "term"='for'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'for', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='for'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('from', 'en') WHERE "term"='from'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'from', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='from'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('get', 'en') WHERE "term"='get'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'get', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='get'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('go', 'en') WHERE "term"='go'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'go', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='go'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('how', 'en') WHERE "term"='how'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'how', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='how'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('if', 'en') WHERE "term"='if'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'if', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='if'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('in', 'en') WHERE "term"='in'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'in', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='in'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('into', 'en') WHERE "term"='into'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'into', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='into'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('is', 'en') WHERE "term"='is'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'is', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='is'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('isn''t', 'en') WHERE "term"='isn''t'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'isn''t', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='isn''t'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('it', 'en') WHERE "term"='it'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'it', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='it'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('its', 'en') WHERE "term"='its'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'its', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='its'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('me', 'en') WHERE "term"='me'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'me', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='me'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('more', 'en') WHERE "term"='more'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'more', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='more'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('most', 'en') WHERE "term"='most'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'most', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='most'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('must', 'en') WHERE "term"='must'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'must', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='must'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('my', 'en') WHERE "term"='my'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'my', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='my'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('new', 'en') WHERE "term"='new'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'new', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='new'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('no', 'en') WHERE "term"='no'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'no', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='no'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('none', 'en') WHERE "term"='none'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'none', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='none'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('not', 'en') WHERE "term"='not'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'not', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='not'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('noth', 'en') WHERE "term"='noth'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'noth', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='noth'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('nothing', 'en') WHERE "term"='nothing'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'nothing', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='nothing'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('of', 'en') WHERE "term"='of'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'of', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='of'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('off', 'en') WHERE "term"='off'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'off', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='off'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('often', 'en') WHERE "term"='often'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'often', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='often'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('old', 'en') WHERE "term"='old'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'old', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='old'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('on', 'en') WHERE "term"='on'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'on', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='on'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('onc', 'en') WHERE "term"='onc'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'onc', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='onc'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('once', 'en') WHERE "term"='once'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'once', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='once'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('onli', 'en') WHERE "term"='onli'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'onli', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='onli'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('only', 'en') WHERE "term"='only'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'only', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='only'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('or', 'en') WHERE "term"='or'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'or', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='or'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('other', 'en') WHERE "term"='other'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'other', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='other'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('our', 'en') WHERE "term"='our'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'our', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='our'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('ours', 'en') WHERE "term"='ours'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'ours', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='ours'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('out', 'en') WHERE "term"='out'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'out', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='out'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('over', 'en') WHERE "term"='over'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'over', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='over'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('page', 'en') WHERE "term"='page'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'page', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='page'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('she', 'en') WHERE "term"='she'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'she', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='she'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('should', 'en') WHERE "term"='should'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'should', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='should'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('small', 'en') WHERE "term"='small'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'small', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='small'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('so', 'en') WHERE "term"='so'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'so', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='so'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('some', 'en') WHERE "term"='some'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'some', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='some'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('than', 'en') WHERE "term"='than'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'than', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='than'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('thank', 'en') WHERE "term"='thank'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'thank', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='thank'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('that', 'en') WHERE "term"='that'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'that', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='that'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('the', 'en') WHERE "term"='the'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'the', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='the'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('their', 'en') WHERE "term"='their'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'their', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='their'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('theirs', 'en') WHERE "term"='theirs'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'theirs', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='theirs'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('them', 'en') WHERE "term"='them'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'them', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='them'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('then', 'en') WHERE "term"='then'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'then', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='then'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('there', 'en') WHERE "term"='there'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'there', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='there'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('these', 'en') WHERE "term"='these'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'these', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='these'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('they', 'en') WHERE "term"='they'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'they', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='they'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('this', 'en') WHERE "term"='this'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'this', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='this'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('those', 'en') WHERE "term"='those'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'those', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='those'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('thus', 'en') WHERE "term"='thus'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'thus', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='thus'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('time', 'en') WHERE "term"='time'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'time', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='time'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('times', 'en') WHERE "term"='times'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'times', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='times'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('to', 'en') WHERE "term"='to'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'to', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='to'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('too', 'en') WHERE "term"='too'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'too', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='too'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('true', 'en') WHERE "term"='true'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'true', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='true'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('under', 'en')WHERE "term"='under'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'under', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='under'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('until', 'en') WHERE "term"='until'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'until', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='until'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('up', 'en') WHERE "term"='up'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'up', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='up'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('upon', 'en') WHERE "term"='upon'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'upon', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='upon'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('use', 'en') WHERE "term"='use'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'use', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='use'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('user', 'en') WHERE "term"='user'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'user', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='user'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('users', 'en') WHERE "term"='users'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'users', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='users'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('veri', 'en') WHERE "term"='veri'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'veri', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='veri'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('version', 'en') WHERE "term"='version'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'version', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='version'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('very', 'en') WHERE "term"='very'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'very', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='very'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('via', 'en') WHERE "term"='via'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'via', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='via'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('want', 'en') WHERE "term"='want'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'want', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='want'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('was', 'en') WHERE "term"='was'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'was', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='was'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('way', 'en') WHERE "term"='way'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'way', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='way'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('were', 'en') WHERE "term"='were'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'were', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='were'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('what', 'en') WHERE "term"='what'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'what', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='what'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('when', 'en') WHERE "term"='when'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'when', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='when'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('where', 'en') WHERE "term"='where'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'where', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='where'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('whi', 'en') WHERE "term"='whi'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'whi', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='whi'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('which', 'en') WHERE "term"='which'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'which', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='which'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('who', 'en') WHERE "term"='who'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'who', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='who'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('whom', 'en') WHERE "term"='whom'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'whom', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='whom'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('whose', 'en') WHERE "term"='whose'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'whose', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='whose'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('why', 'en') WHERE "term"='why'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'why', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='why'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('wide', 'en') WHERE "term"='wide'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'wide', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='wide'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('will', 'en') WHERE "term"='will'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'will', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='will'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('with', 'en') WHERE "term"='with'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'with', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='with'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('within', 'en') WHERE "term"='within'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'within', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='within'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('without', 'en') WHERE "term"='without'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'without', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='without'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('would', 'en') WHERE "term"='would'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'would', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='would'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('yes', 'en') WHERE "term"='yes'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'yes', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='yes'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('yet', 'en') WHERE "term"='yet'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'yet', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='yet'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('you', 'en') WHERE "term"='you'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'you', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='you'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('your', 'en') WHERE "term"='your'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'your', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='your'); -- UPDATE "#__finder_terms_common" SET ("term", "language") = ('yours', 'en') WHERE "term"='yours'; INSERT INTO "#__finder_terms_common" ("term", "language") SELECT 'yours', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHERE "term"='yours'); -- -- Table: #__finder_tokens -- CREATE TABLE "#__finder_tokens" ( "term" character varying(75) NOT NULL, "stem" character varying(75) NOT NULL, "common" smallint DEFAULT 0 NOT NULL, "phrase" smallint DEFAULT 0 NOT NULL, "weight" numeric(8,2) DEFAULT 1 NOT NULL, "context" smallint DEFAULT 2 NOT NULL ); CREATE INDEX "#__finder_tokens_idx_word" on "#__finder_tokens" ("term"); CREATE INDEX "#__finder_tokens_idx_context" on "#__finder_tokens" ("context"); -- -- Table: #__finder_tokens_aggregate -- CREATE TABLE "#__finder_tokens_aggregate" ( "term_id" integer NOT NULL, "map_suffix" character(1) NOT NULL, "term" character varying(75) NOT NULL, "stem" character varying(75) NOT NULL, "common" smallint DEFAULT 0 NOT NULL, "phrase" smallint DEFAULT 0 NOT NULL, "term_weight" numeric(8,2) NOT NULL, "context" smallint DEFAULT 2 NOT NULL, "context_weight" numeric(8,2) NOT NULL, "total_weight" numeric(8,2) NOT NULL ); CREATE INDEX "#__finder_tokens_aggregate_token" on "#__finder_tokens_aggregate" ("term"); CREATE INDEX "_#__finder_tokens_aggregate_keyword_id" on "#__finder_tokens_aggregate" ("term_id"); -- -- Table: #__finder_types -- CREATE TABLE "#__finder_types" ( "id" serial NOT NULL, "title" character varying(100) NOT NULL, "mime" character varying(100) NOT NULL, PRIMARY KEY ("id"), CONSTRAINT "#__finder_types_title" UNIQUE ("title") ); components/com_finder/sql/install.mysql.sql000066600000036027150771655450015223 0ustar00-- -- Table structure for table `#__finder_filters` -- CREATE TABLE IF NOT EXISTS `#__finder_filters` ( `filter_id` int(10) unsigned NOT NULL auto_increment, `title` varchar(255) NOT NULL, `alias` varchar(255) NOT NULL, `state` tinyint(1) NOT NULL default '1', `created` datetime NOT NULL default '0000-00-00 00:00:00', `created_by` int(10) unsigned NOT NULL, `created_by_alias` varchar(255) NOT NULL, `modified` datetime NOT NULL default '0000-00-00 00:00:00', `modified_by` int(10) unsigned NOT NULL default '0', `checked_out` int(10) unsigned NOT NULL default '0', `checked_out_time` datetime NOT NULL default '0000-00-00 00:00:00', `map_count` int(10) unsigned NOT NULL default '0', `data` text NOT NULL, `params` mediumtext, PRIMARY KEY (`filter_id`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links` -- CREATE TABLE IF NOT EXISTS `#__finder_links` ( `link_id` int(10) unsigned NOT NULL auto_increment, `url` varchar(255) NOT NULL, `route` varchar(255) NOT NULL, `title` varchar(255) default NULL, `description` varchar(255) default NULL, `indexdate` datetime NOT NULL default '0000-00-00 00:00:00', `md5sum` varchar(32) default NULL, `published` tinyint(1) NOT NULL default '1', `state` int(5) default '1', `access` int(5) default '0', `language` varchar(8) NOT NULL, `publish_start_date` datetime NOT NULL default '0000-00-00 00:00:00', `publish_end_date` datetime NOT NULL default '0000-00-00 00:00:00', `start_date` datetime NOT NULL default '0000-00-00 00:00:00', `end_date` datetime NOT NULL default '0000-00-00 00:00:00', `list_price` double unsigned NOT NULL default '0', `sale_price` double unsigned NOT NULL default '0', `type_id` int(11) NOT NULL, `object` mediumblob NOT NULL, PRIMARY KEY (`link_id`), KEY `idx_type` (`type_id`), KEY `idx_title` (`title`), KEY `idx_md5` (`md5sum`), KEY `idx_url` (`url`(75)), KEY `idx_published_list` (`published`,`state`,`access`,`publish_start_date`,`publish_end_date`,`list_price`), KEY `idx_published_sale` (`published`,`state`,`access`,`publish_start_date`,`publish_end_date`,`sale_price`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms0` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms0` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms1` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms1` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms2` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms2` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms3` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms3` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms4` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms4` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms5` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms5` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms6` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms6` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms7` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms7` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms8` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms8` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_terms9` -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms9` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_termsa` -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsa` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_termsb` -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsb` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_termsc` -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsc` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_termsd` -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsd` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_termse` -- CREATE TABLE IF NOT EXISTS `#__finder_links_termse` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_links_termsf` -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsf` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_taxonomy` -- CREATE TABLE IF NOT EXISTS `#__finder_taxonomy` ( `id` int(10) unsigned NOT NULL auto_increment, `parent_id` int(10) unsigned NOT NULL default '0', `title` varchar(255) NOT NULL, `state` tinyint(1) unsigned NOT NULL default '1', `access` tinyint(1) unsigned NOT NULL default '0', `ordering` tinyint(1) unsigned NOT NULL default '0', PRIMARY KEY (`id`), KEY `parent_id` (`parent_id`), KEY `state` (`state`), KEY `ordering` (`ordering`), KEY `access` (`access`), KEY `idx_parent_published` (`parent_id`,`state`,`access`) ) DEFAULT CHARSET=utf8; -- -- Dumping data for table `#__finder_taxonomy` -- REPLACE INTO `#__finder_taxonomy` (`id`, `parent_id`, `title`, `state`, `access`, `ordering`) VALUES (1, 0, 'ROOT', 0, 0, 0); -- -------------------------------------------------------- -- -- Table structure for table `#__finder_taxonomy_map` -- CREATE TABLE IF NOT EXISTS `#__finder_taxonomy_map` ( `link_id` int(10) unsigned NOT NULL, `node_id` int(10) unsigned NOT NULL, PRIMARY KEY (`link_id`,`node_id`), KEY `link_id` (`link_id`), KEY `node_id` (`node_id`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_terms` -- CREATE TABLE IF NOT EXISTS `#__finder_terms` ( `term_id` int(10) unsigned NOT NULL auto_increment, `term` varchar(75) NOT NULL, `stem` varchar(75) NOT NULL, `common` tinyint(1) unsigned NOT NULL default '0', `phrase` tinyint(1) unsigned NOT NULL default '0', `weight` float unsigned NOT NULL default '0', `soundex` varchar(75) NOT NULL, `links` int(10) NOT NULL default '0', PRIMARY KEY (`term_id`), UNIQUE KEY `idx_term` (`term`), KEY `idx_term_phrase` (`term`,`phrase`), KEY `idx_stem_phrase` (`stem`,`phrase`), KEY `idx_soundex_phrase` (`soundex`,`phrase`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_terms_common` -- CREATE TABLE IF NOT EXISTS `#__finder_terms_common` ( `term` varchar(75) NOT NULL, `language` varchar(3) NOT NULL, KEY `idx_word_lang` (`term`,`language`), KEY `idx_lang` (`language`) ) DEFAULT CHARSET=utf8; -- -- Dumping data for table `#__finder_terms_common` -- REPLACE INTO `#__finder_terms_common` (`term`, `language`) VALUES ('a', 'en'), ('about', 'en'), ('after', 'en'), ('ago', 'en'), ('all', 'en'), ('am', 'en'), ('an', 'en'), ('and', 'en'), ('ani', 'en'), ('any', 'en'), ('are', 'en'), ('aren''t', 'en'), ('as', 'en'), ('at', 'en'), ('be', 'en'), ('but', 'en'), ('by', 'en'), ('for', 'en'), ('from', 'en'), ('get', 'en'), ('go', 'en'), ('how', 'en'), ('if', 'en'), ('in', 'en'), ('into', 'en'), ('is', 'en'), ('isn''t', 'en'), ('it', 'en'), ('its', 'en'), ('me', 'en'), ('more', 'en'), ('most', 'en'), ('must', 'en'), ('my', 'en'), ('new', 'en'), ('no', 'en'), ('none', 'en'), ('not', 'en'), ('noth', 'en'), ('nothing', 'en'), ('of', 'en'), ('off', 'en'), ('often', 'en'), ('old', 'en'), ('on', 'en'), ('onc', 'en'), ('once', 'en'), ('onli', 'en'), ('only', 'en'), ('or', 'en'), ('other', 'en'), ('our', 'en'), ('ours', 'en'), ('out', 'en'), ('over', 'en'), ('page', 'en'), ('she', 'en'), ('should', 'en'), ('small', 'en'), ('so', 'en'), ('some', 'en'), ('than', 'en'), ('thank', 'en'), ('that', 'en'), ('the', 'en'), ('their', 'en'), ('theirs', 'en'), ('them', 'en'), ('then', 'en'), ('there', 'en'), ('these', 'en'), ('they', 'en'), ('this', 'en'), ('those', 'en'), ('thus', 'en'), ('time', 'en'), ('times', 'en'), ('to', 'en'), ('too', 'en'), ('true', 'en'), ('under', 'en'), ('until', 'en'), ('up', 'en'), ('upon', 'en'), ('use', 'en'), ('user', 'en'), ('users', 'en'), ('veri', 'en'), ('version', 'en'), ('very', 'en'), ('via', 'en'), ('want', 'en'), ('was', 'en'), ('way', 'en'), ('were', 'en'), ('what', 'en'), ('when', 'en'), ('where', 'en'), ('whi', 'en'), ('which', 'en'), ('who', 'en'), ('whom', 'en'), ('whose', 'en'), ('why', 'en'), ('wide', 'en'), ('will', 'en'), ('with', 'en'), ('within', 'en'), ('without', 'en'), ('would', 'en'), ('yes', 'en'), ('yet', 'en'), ('you', 'en'), ('your', 'en'), ('yours', 'en'); -- -------------------------------------------------------- -- -- Table structure for table `#__finder_tokens` -- CREATE TABLE IF NOT EXISTS `#__finder_tokens` ( `term` varchar(75) NOT NULL, `stem` varchar(75) NOT NULL, `common` tinyint(1) unsigned NOT NULL default '0', `phrase` tinyint(1) unsigned NOT NULL default '0', `weight` float unsigned NOT NULL default '1', `context` tinyint(1) unsigned NOT NULL default '2', KEY `idx_word` (`term`), KEY `idx_context` (`context`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_tokens_aggregate` -- CREATE TABLE IF NOT EXISTS `#__finder_tokens_aggregate` ( `term_id` int(10) unsigned NOT NULL, `map_suffix` char(1) NOT NULL, `term` varchar(75) NOT NULL, `stem` varchar(75) NOT NULL, `common` tinyint(1) unsigned NOT NULL default '0', `phrase` tinyint(1) unsigned NOT NULL default '0', `term_weight` float unsigned NOT NULL, `context` tinyint(1) unsigned NOT NULL default '2', `context_weight` float unsigned NOT NULL, `total_weight` float unsigned NOT NULL, KEY `token` (`term`), KEY `keyword_id` (`term_id`) ) DEFAULT CHARSET=utf8; -- -------------------------------------------------------- -- -- Table structure for table `#__finder_types` -- CREATE TABLE IF NOT EXISTS `#__finder_types` ( `id` int(10) unsigned NOT NULL auto_increment, `title` varchar(100) NOT NULL, `mime` varchar(100) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `title` (`title`) ) DEFAULT CHARSET=utf8; components/com_finder/sql/index.html000066600000000036150771655450013654 0ustar00components/com_finder/index.html000066600000000036150771655450013055 0ustar00components/com_finder/config.xml000066600000020436150771655450013055 0ustar00
    components/com_finder/finder.php000066600000001064150771655450013042 0ustar00authorise('core.manage', 'com_finder')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } $controller = JControllerLegacy::getInstance('Finder'); $controller->execute(JFactory::getApplication()->input->get('task')); $controller->redirect(); components/com_finder/controller.php000066600000003232150771655450013755 0ustar00input->get('view', 'index', 'word'); $layout = $this->input->get('layout', 'index', 'word'); $f_id = $this->input->get('filter_id', null, 'int'); // Check for edit form. if ($view == 'filter' && $layout == 'edit' && !$this->checkEditId('com_finder.edit.filter', $f_id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $f_id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_finder&view=filters', false)); return false; } parent::display(); return $this; } } components/com_finder/controllers/index.php000066600000003273150771655450015254 0ustar00 true)) { $model = parent::getModel($name, $prefix, $config); return $model; } /** * Method to purge all indexed links from the database. * * @return boolean True on success. * * @since 2.5 */ public function purge() { JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Remove the script time limit. @set_time_limit(0); $model = $this->getModel('Index', 'FinderModel'); // Attempt to purge the index. $return = $model->purge(); if (!$return) { $message = JText::_('COM_FINDER_INDEX_PURGE_FAILED', $model->getError()); $this->setRedirect('index.php?option=com_finder&view=index', $message); return false; } else { $message = JText::_('COM_FINDER_INDEX_PURGE_SUCCESS'); $this->setRedirect('index.php?option=com_finder&view=index', $message); return true; } } } components/com_finder/controllers/index.html000066600000000036150771655450015423 0ustar00components/com_finder/controllers/maps.php000066600000001702150771655450015100 0ustar00 true)) { $model = parent::getModel($name, $prefix, $config); return $model; } } components/com_finder/controllers/filter.php000066600000016517150771655450015437 0ustar00input; $lang = JFactory::getLanguage(); $model = $this->getModel(); $table = $model->getTable(); $data = $input->post->get('jform', array(), 'array'); $checkin = property_exists($table, 'checked_out'); $context = "$this->option.edit.$this->context"; $task = $this->getTask(); // Determine the name of the primary key for the data. if (empty($key)) { $key = $table->getKeyName(); } // To avoid data collisions the urlVar may be different from the primary key. if (empty($urlVar)) { $urlVar = $key; } $recordId = $input->get($urlVar, '', 'int'); if (!$this->checkEditId($context, $recordId)) { // Somehow the person just went to the form and tried to save it. We don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $recordId)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); return false; } // Populate the row id from the session. $data[$key] = $recordId; // The save2copy task needs to be handled slightly differently. if ($task == 'save2copy') { // Check-in the original row. if ($checkin && $model->checkin($data[$key]) === false) { // Check-in failed. Go back to the item and display a notice. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError())); $this->setMessage($this->getError(), 'error'); $this->setRedirect('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $urlVar)); return false; } // Reset the ID and then treat the request as for Apply. $data[$key] = 0; $task = 'apply'; } // Access check. if (!$this->allowSave($data, $key)) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); return false; } // Validate the posted data. // Sometimes the form needs some posted data, such as for plugins and modules. $form = $model->getForm($data, false); if (!$form) { $app->enqueueMessage($model->getError(), 'error'); return false; } // Test whether the data is valid. $validData = $model->validate($form, $data); // Check for validation errors. if ($validData === false) { // Get the validation messages. $errors = $model->getErrors(); // Push up to three validation messages out to the user. for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) { if (($errors[$i]) instanceof Exception) { $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); } else { $app->enqueueMessage($errors[$i], 'warning'); } } // Save the data in the session. $app->setUserState($context . '.data', $data); // Redirect back to the edit screen. $this->setRedirect( JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key), false) ); return false; } // Get and sanitize the filter data. $validData['data'] = $input->post->get('t', array(), 'array'); $validData['data'] = array_unique($validData['data']); JArrayHelper::toInteger($validData['data']); // Remove any values of zero. if (array_search(0, $validData['data'], true)) { unset($validData['data'][array_search(0, $validData['data'], true)]); } // Attempt to save the data. if (!$model->save($validData)) { // Save the data in the session. $app->setUserState($context . '.data', $validData); // Redirect back to the edit screen. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError())); $this->setMessage($this->getError(), 'error'); $this->setRedirect( JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key), false) ); return false; } // Save succeeded, so check-in the record. if ($checkin && $model->checkin($validData[$key]) === false) { // Save the data in the session. $app->setUserState($context . '.data', $validData); // Check-in failed, so go back to the record and display a notice. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError())); $this->setMessage($this->getError(), 'error'); $this->setRedirect('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key)); return false; } $this->setMessage( JText::_( ($lang->hasKey($this->text_prefix . ($recordId == 0 && $app->isSite() ? '_SUBMIT' : '') . '_SAVE_SUCCESS') ? $this->text_prefix : 'JLIB_APPLICATION') . ($recordId == 0 && $app->isSite() ? '_SUBMIT' : '') . '_SAVE_SUCCESS' ) ); // Redirect the user and adjust session state based on the chosen task. switch ($task) { case 'apply': // Set the record data in the session. $recordId = $model->getState($this->context . '.id'); $this->holdEditId($context, $recordId); $app->setUserState($context . '.data', null); $model->checkout($recordId); // Redirect back to the edit screen. $this->setRedirect( JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key), false) ); break; case 'save2new': // Clear the record id and data from the session. $this->releaseEditId($context, $recordId); $app->setUserState($context . '.data', null); // Redirect back to the edit screen. $this->setRedirect( JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend(null, $key), false) ); break; default: // Clear the record id and data from the session. $this->releaseEditId($context, $recordId); $app->setUserState($context . '.data', null); // Redirect to the list screen. $this->setRedirect( JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false) ); break; } // Invoke the postSave method to allow for the child class to access the model. $this->postSaveHook($model, $validData); return true; } } components/com_finder/controllers/indexer.json.php000066600000022215150771655450016550 0ustar00get('enable_logging', '0')) { if ($log == null) { $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'indexer.php'; $log = JLog::addLogger($options); } } // Log the start JLog::add('Starting the indexer', JLog::INFO); // We don't want this form to be cached. header('Pragma: no-cache'); header('Cache-Control: no-cache'); header('Expires: -1'); // Check for a valid token. If invalid, send a 403 with the error message. JSession::checkToken('request') or $this->sendResponse(new Exception(JText::_('JINVALID_TOKEN'), 403)); // Put in a buffer to silence noise. ob_start(); // Reset the indexer state. FinderIndexer::resetState(); // Import the finder plugins. JPluginHelper::importPlugin('finder'); // Add the indexer language to JS JText::script('COM_FINDER_AN_ERROR_HAS_OCCURRED'); JText::script('COM_FINDER_NO_ERROR_RETURNED'); // Start the indexer. try { // Trigger the onStartIndex event. JEventDispatcher::getInstance()->trigger('onStartIndex'); // Get the indexer state. $state = FinderIndexer::getState(); $state->start = 1; // Send the response. $this->sendResponse($state); } // Catch an exception and return the response. catch (Exception $e) { $this->sendResponse($e); } } /** * Method to run the next batch of content through the indexer. * * @return void * * @since 2.5 */ public function batch() { static $log; $params = JComponentHelper::getParams('com_finder'); if ($params->get('enable_logging', '0')) { if ($log == null) { $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'indexer.php'; $log = JLog::addLogger($options); } } // Log the start JLog::add('Starting the indexer batch process', JLog::INFO); // We don't want this form to be cached. header('Pragma: no-cache'); header('Cache-Control: no-cache'); header('Expires: -1'); // Check for a valid token. If invalid, send a 403 with the error message. JSession::checkToken('request') or $this->sendResponse(new Exception(JText::_('JINVALID_TOKEN'), 403)); // Put in a buffer to silence noise. ob_start(); // Remove the script time limit. @set_time_limit(0); // Get the indexer state. $state = FinderIndexer::getState(); // Reset the batch offset. $state->batchOffset = 0; // Update the indexer state. FinderIndexer::setState($state); // Import the finder plugins. JPluginHelper::importPlugin('finder'); /* * We are going to swap out the raw document object with an HTML document * in order to work around some plugins that don't do proper environment * checks before trying to use HTML document functions. */ $raw = clone(JFactory::getDocument()); $lang = JFactory::getLanguage(); // Get the document properties. $attributes = array ( 'charset' => 'utf-8', 'lineend' => 'unix', 'tab' => ' ', 'language' => $lang->getTag(), 'direction' => $lang->isRTL() ? 'rtl' : 'ltr' ); // Get the HTML document. $html = JDocument::getInstance('html', $attributes); $doc = JFactory::getDocument(); // Swap the documents. $doc = $html; // Get the admin application. $admin = clone(JFactory::getApplication()); // Get the site app. $site = JApplication::getInstance('site'); // Swap the app. $app = JFactory::getApplication(); $app = $site; // Start the indexer. try { // Trigger the onBeforeIndex event. JEventDispatcher::getInstance()->trigger('onBeforeIndex'); // Trigger the onBuildIndex event. JEventDispatcher::getInstance()->trigger('onBuildIndex'); // Get the indexer state. $state = FinderIndexer::getState(); $state->start = 0; $state->complete = 0; // Swap the documents back. $doc = $raw; // Swap the applications back. $app = $admin; // Send the response. $this->sendResponse($state); } // Catch an exception and return the response. catch (Exception $e) { // Swap the documents back. $doc = $raw; // Send the response. $this->sendResponse($e); } } /** * Method to optimize the index and perform any necessary cleanup. * * @return void * * @since 2.5 */ public function optimize() { // We don't want this form to be cached. header('Pragma: no-cache'); header('Cache-Control: no-cache'); header('Expires: -1'); // Check for a valid token. If invalid, send a 403 with the error message. JSession::checkToken('request') or $this->sendResponse(new Exception(JText::_('JINVALID_TOKEN'), 403)); // Put in a buffer to silence noise. ob_start(); // Import the finder plugins. JPluginHelper::importPlugin('finder'); try { // Optimize the index FinderIndexer::getInstance()->optimize(); // Get the indexer state. $state = FinderIndexer::getState(); $state->start = 0; $state->complete = 1; // Send the response. $this->sendResponse($state); } // Catch an exception and return the response. catch (Exception $e) { $this->sendResponse($e); } } /** * Method to handle a send a JSON response. The body parameter * can be a Exception object for when an error has occurred or * a JObject for a good response. * * @param mixed $data JObject on success, Exception on error. [optional] * * @return void * * @since 2.5 */ public static function sendResponse($data = null) { static $log; $params = JComponentHelper::getParams('com_finder'); if ($params->get('enable_logging', '0')) { if ($log == null) { $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'indexer.php'; $log = JLog::addLogger($options); } } // Send the assigned error code if we are catching an exception. if ($data instanceof Exception) { $app = JFactory::getApplication(); JLog::add($data->getMessage(), JLog::ERROR); $app->setHeader('status', $data->getCode()); $app->sendHeaders(); } // Create the response object. $response = new FinderIndexerResponse($data); // Add the buffer. $response->buffer = JDEBUG ? ob_get_contents() : ob_end_clean(); // Send the JSON response. echo json_encode($response); // Close the application. JFactory::getApplication()->close(); } } /** * Finder Indexer JSON Response Class * * @package Joomla.Administrator * @subpackage com_finder * @since 2.5 */ class FinderIndexerResponse { /** * Class Constructor * * @param mixed $state The processing state for the indexer * * @since 2.5 */ public function __construct($state) { static $log; $params = JComponentHelper::getParams('com_finder'); if ($params->get('enable_logging', '0')) { if ($log == null) { $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'indexer.php'; $log = JLog::addLogger($options); } } // The old token is invalid so send a new one. $this->token = JFactory::getSession()->getFormToken(); // Check if we are dealing with an error. if ($state instanceof Exception) { // Log the error JLog::add($state->getMessage(), JLog::ERROR); // Prepare the error response. $this->error = true; $this->header = JText::_('COM_FINDER_INDEXER_HEADER_ERROR'); $this->message = $state->getMessage(); } else { // Prepare the response data. $this->batchSize = (int) $state->batchSize; $this->batchOffset = (int) $state->batchOffset; $this->totalItems = (int) $state->totalItems; $this->startTime = $state->startTime; $this->endTime = JFactory::getDate()->toSQL(); $this->start = !empty($state->start) ? (int) $state->start : 0; $this->complete = !empty($state->complete) ? (int) $state->complete : 0; // Set the appropriate messages. if ($this->totalItems <= 0 && $this->complete) { $this->header = JText::_('COM_FINDER_INDEXER_HEADER_COMPLETE'); $this->message = JText::_('COM_FINDER_INDEXER_MESSAGE_COMPLETE'); } elseif ($this->totalItems <= 0) { $this->header = JText::_('COM_FINDER_INDEXER_HEADER_OPTIMIZE'); $this->message = JText::_('COM_FINDER_INDEXER_MESSAGE_OPTIMIZE'); } else { $this->header = JText::_('COM_FINDER_INDEXER_HEADER_RUNNING'); $this->message = JText::_('COM_FINDER_INDEXER_MESSAGE_RUNNING'); } } } } // Register the error handler. JError::setErrorHandling(E_ALL, 'callback', array('FinderControllerIndexer', 'sendResponse')); components/com_finder/controllers/filters.php000066600000001712150771655450015611 0ustar00 true)) { $model = parent::getModel($name, $prefix, $config); return $model; } } components/com_finder/access.xml000066600000001315150771655450013044 0ustar00
    components/com_finder/helpers/language.php000066600000004633150771655450015025 0ustar00load('com_finder', JPATH_SITE); } /** * Method to load Smart Search plug-in language files. * * @return void * * @since 2.5 */ public static function loadPluginLanguage() { static $loaded = false; // If already loaded, don't load again. if ($loaded) { return; } $loaded = true; // Get array of all the enabled Smart Search plug-in names. $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('name') ->from($db->quoteName('#__extensions')) ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) ->where($db->quoteName('folder') . ' = ' . $db->quote('finder')) ->where($db->quoteName('enabled') . ' = 1'); $db->setQuery($query); $plugins = $db->loadObjectList(); if (empty($plugins)) { return; } // Load generic language strings. $lang = JFactory::getLanguage(); $lang->load('plg_content_finder', JPATH_ADMINISTRATOR); // Load language file for each plug-in. foreach ($plugins as $plugin) { $lang->load($plugin->name, JPATH_ADMINISTRATOR); } } } components/com_finder/helpers/html/index.html000066600000000036150771655450015463 0ustar00components/com_finder/helpers/html/finder.php000066600000006042150771655450015451 0ustar00getQuery(true) ->select('DISTINCT t.title AS text, t.id AS value') ->from($db->quoteName('#__finder_types') . ' AS t') ->join('LEFT', $db->quoteName('#__finder_links') . ' AS l ON l.type_id = t.id') ->order('t.title ASC'); $db->setQuery($query); try { $rows = $db->loadObjectList(); } catch (RuntimeException $e) { return; } // Compile the options. $options = array(); foreach ($rows as $row) { $key = $lang->hasKey(FinderHelperLanguage::branchPlural($row->text)) ? FinderHelperLanguage::branchPlural($row->text) : $row->text; $string = JText::sprintf('COM_FINDER_ITEM_X_ONLY', JText::_($key)); $options[] = JHtml::_('select.option', $row->value, $string); } return $options; } /** * Creates a list of maps. * * @return array An array containing the maps that can be selected. * * @since 2.5 */ public static function mapslist() { $lang = JFactory::getLanguage(); // Load the finder types. $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('title AS text, id AS value') ->from($db->quoteName('#__finder_taxonomy')) ->where($db->quoteName('parent_id') . ' = 1') ->order('ordering, title ASC'); $db->setQuery($query); try { $rows = $db->loadObjectList(); } catch (RuntimeException $e) { return; } // Compile the options. $options = array(); $options[] = JHtml::_('select.option', '1', JText::_('COM_FINDER_MAPS_BRANCHES')); foreach ($rows as $row) { $key = $lang->hasKey(FinderHelperLanguage::branchPlural($row->text)) ? FinderHelperLanguage::branchPlural($row->text) : $row->text; $string = JText::sprintf('COM_FINDER_ITEM_X_ONLY', JText::_($key)); $options[] = JHtml::_('select.option', $row->value, $string); } return $options; } /** * Creates a list of published states. * * @return array An array containing the states that can be selected. * * @since 2.5 */ public static function statelist() { $options = array(); $options[] = JHtml::_('select.option', '1', JText::sprintf('COM_FINDER_ITEM_X_ONLY', JText::_('JPUBLISHED'))); $options[] = JHtml::_('select.option', '0', JText::sprintf('COM_FINDER_ITEM_X_ONLY', JText::_('JUNPUBLISHED'))); return $options; } } components/com_finder/helpers/indexer/parser.php000066600000006115150771655450016171 0ustar00clean($format, 'cmd'); $path = __DIR__ . '/parser/' . $format . '.php'; $class = 'FinderIndexerParser' . ucfirst($format); // Check if a parser exists for the format. if (file_exists($path)) { // Instantiate the parser. include_once $path; $instances[$format] = new $class; } else { // Throw invalid format exception. throw new Exception(JText::sprintf('COM_FINDER_INDEXER_INVALID_PARSER', $format)); } return $instances[$format]; } /** * Method to parse input and extract the plain text. Because this method is * called from both inside and outside the indexer, it needs to be able to * batch out its parsing functionality to deal with the inefficiencies of * regular expressions. We will parse recursively in 2KB chunks. * * @param string $input The input to parse. * * @return string The plain text input. * * @since 2.5 */ public function parse($input) { $return = null; // Parse the input in batches if bigger than 2KB. if (strlen($input) > 2048) { $start = 0; $end = strlen($input); $chunk = 2048; while ($start < $end) { // Setup the string. $string = substr($input, $start, $chunk); // Find the last space character if we aren't at the end. $ls = (($start + $chunk) < $end ? strrpos($string, ' ') : false); // Truncate to the last space character. if ($ls !== false) { $string = substr($string, 0, $ls); } // Adjust the start position for the next iteration. $start += ($ls !== false ? ($ls + 1 - $chunk) + $chunk : $chunk); // Parse the chunk. $return .= $this->process($string); } } // The input is less than 2KB so we can parse it efficiently. else { // Parse the chunk. $return .= $this->process($input); } return $return; } /** * Method to process input and extract the plain text. * * @param string $input The input to process. * * @return string The plain text input. * * @since 2.5 */ abstract protected function process($input); } components/com_finder/helpers/indexer/token.php000066600000007221150771655450016014 0ustar00language = $lang; // Tokens can be a single word or an array of words representing a phrase. if (is_array($term)) { // Populate the token instance. $this->term = implode($spacer, $term); $this->stem = implode($spacer, array_map(array('FinderIndexerHelper', 'stem'), $term, array($lang))); $this->numeric = false; $this->common = false; $this->phrase = true; $this->length = JString::strlen($this->term); /* * Calculate the weight of the token. * * 1. Length of the token up to 30 and divide by 30, add 1. * 2. Round weight to 4 decimal points. */ $this->weight = (($this->length >= 30 ? 30 : $this->length) / 30) + 1; $this->weight = round($this->weight, 4); } else { // Populate the token instance. $this->term = $term; $this->stem = FinderIndexerHelper::stem($this->term, $lang); $this->numeric = (is_numeric($this->term) || (bool) preg_match('#^[0-9,.\-\+]+$#', $this->term)); $this->common = $this->numeric ? false : FinderIndexerHelper::isCommon($this->term, $lang); $this->phrase = false; $this->length = JString::strlen($this->term); /* * Calculate the weight of the token. * * 1. Length of the token up to 15 and divide by 15. * 2. If common term, divide weight by 8. * 3. If numeric, multiply weight by 1.5. * 4. Round weight to 4 decimal points. */ $this->weight = (($this->length >= 15 ? 15 : $this->length) / 15); $this->weight = ($this->common == true ? $this->weight / 8 : $this->weight); $this->weight = ($this->numeric == true ? $this->weight * 1.5 : $this->weight); $this->weight = round($this->weight, 4); } } } components/com_finder/helpers/indexer/index.html000066600000000036150771655450016155 0ustar00components/com_finder/helpers/indexer/taxonomy.php000066600000023077150771655450016561 0ustar00id; } // Check to see if the branch is in the table. $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__finder_taxonomy')) ->where($db->quoteName('parent_id') . ' = 1') ->where($db->quoteName('title') . ' = ' . $db->quote($title)); $db->setQuery($query); // Get the result. $result = $db->loadObject(); // Check if the database matches the input data. if (!empty($result) && $result->state == $state && $result->access == $access) { // The data matches, add the item to the cache. self::$branches[$title] = $result; return self::$branches[$title]->id; } /* * The database did not match the input. This could be because the * state has changed or because the branch does not exist. Let's figure * out which case is true and deal with it. */ $branch = new JObject; if (empty($result)) { // Prepare the branch object. $branch->parent_id = 1; $branch->title = $title; $branch->state = (int) $state; $branch->access = (int) $access; } else { // Prepare the branch object. $branch->id = (int) $result->id; $branch->parent_id = (int) $result->parent_id; $branch->title = $result->title; $branch->state = (int) $result->title; $branch->access = (int) $result->access; $branch->ordering = (int) $result->ordering; } // Store the branch. self::storeNode($branch); // Add the branch to the cache. self::$branches[$title] = $branch; return self::$branches[$title]->id; } /** * Method to add a node to the taxonomy tree. * * @param string $branch The title of the branch to store the node in. * @param string $title The title of the node. * @param integer $state The published state of the node. [optional] * @param integer $access The access state of the node. [optional] * * @return integer The id of the node. * * @since 2.5 * @throws Exception on database error. */ public static function addNode($branch, $title, $state = 1, $access = 1) { // Check to see if the node is in the cache. if (isset(self::$nodes[$branch][$title])) { return self::$nodes[$branch][$title]->id; } // Get the branch id, insert it if it does not exist. $branchId = self::addBranch($branch); // Check to see if the node is in the table. $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__finder_taxonomy')) ->where($db->quoteName('parent_id') . ' = ' . $db->quote($branchId)) ->where($db->quoteName('title') . ' = ' . $db->quote($title)); $db->setQuery($query); // Get the result. $result = $db->loadObject(); // Check if the database matches the input data. if (!empty($result) && $result->state == $state && $result->access == $access) { // The data matches, add the item to the cache. self::$nodes[$branch][$title] = $result; return self::$nodes[$branch][$title]->id; } /* * The database did not match the input. This could be because the * state has changed or because the node does not exist. Let's figure * out which case is true and deal with it. */ $node = new JObject; if (empty($result)) { // Prepare the node object. $node->parent_id = (int) $branchId; $node->title = $title; $node->state = (int) $state; $node->access = (int) $access; } else { // Prepare the node object. $node->id = (int) $result->id; $node->parent_id = (int) $result->parent_id; $node->title = $result->title; $node->state = (int) $result->title; $node->access = (int) $result->access; $node->ordering = (int) $result->ordering; } // Store the node. self::storeNode($node); // Add the node to the cache. self::$nodes[$branch][$title] = $node; return self::$nodes[$branch][$title]->id; } /** * Method to add a map entry between a link and a taxonomy node. * * @param integer $linkId The link to map to. * @param integer $nodeId The node to map to. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ public static function addMap($linkId, $nodeId) { // Insert the map. $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('link_id')) ->from($db->quoteName('#__finder_taxonomy_map')) ->where($db->quoteName('link_id') . ' = ' . (int) $linkId) ->where($db->quoteName('node_id') . ' = ' . (int) $nodeId); $db->setQuery($query); $db->execute(); $id = (int) $db->loadResult(); $map = new JObject; $map->link_id = (int) $linkId; $map->node_id = (int) $nodeId; if ($id) { $db->updateObject('#__finder_taxonomy_map', $map, array('link_id', 'node_id')); } else { $db->insertObject('#__finder_taxonomy_map', $map); } return true; } /** * Method to get the title of all taxonomy branches. * * @return array An array of branch titles. * * @since 2.5 * @throws Exception on database error. */ public static function getBranchTitles() { $db = JFactory::getDbo(); // Set user variables $user = JFactory::getUser(); $groups = implode(',', $user->getAuthorisedViewLevels()); // Create a query to get the taxonomy branch titles. $query = $db->getQuery(true) ->select($db->quoteName('title')) ->from($db->quoteName('#__finder_taxonomy')) ->where($db->quoteName('parent_id') . ' = 1') ->where($db->quoteName('state') . ' = 1') ->where($db->quoteName('access') . ' IN (' . $groups . ')'); // Get the branch titles. $db->setQuery($query); $results = $db->loadColumn(); return $results; } /** * Method to find a taxonomy node in a branch. * * @param string $branch The branch to search. * @param string $title The title of the node. * * @return mixed Integer id on success, null on no match. * * @since 2.5 * @throws Exception on database error. */ public static function getNodeByTitle($branch, $title) { $db = JFactory::getDbo(); // Set user variables $user = JFactory::getUser(); $groups = implode(',', $user->getAuthorisedViewLevels()); // Create a query to get the node. $query = $db->getQuery(true) ->select('t1.*') ->from($db->quoteName('#__finder_taxonomy') . ' AS t1') ->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id') ->where('t1.access IN (' . $groups . ')') ->where('t1.state = 1') ->where('t1.title LIKE ' . $db->quote($db->escape($title) . '%')) ->where('t2.access IN (' . $groups . ')') ->where('t2.state = 1') ->where('t2.title = ' . $db->quote($branch)); // Get the node. $db->setQuery($query, 0, 1); $result = $db->loadObject(); return $result; } /** * Method to remove map entries for a link. * * @param integer $linkId The link to remove. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ public static function removeMaps($linkId) { // Delete the maps. $db = JFactory::getDbo(); $query = $db->getQuery(true) ->delete($db->quoteName('#__finder_taxonomy_map')) ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); $db->setQuery($query); $db->execute(); return true; } /** * Method to remove orphaned taxonomy nodes and branches. * * @return integer The number of deleted rows. * * @since 2.5 * @throws Exception on database error. */ public static function removeOrphanNodes() { // Delete all orphaned nodes. $db = JFactory::getDbo(); $query = 'DELETE t' . ' FROM ' . $db->quoteName('#__finder_taxonomy') . ' AS t' . ' LEFT JOIN ' . $db->quoteName('#__finder_taxonomy_map') . ' AS m ON m.node_id = t.id' . ' WHERE t.parent_id > 1' . ' AND m.link_id IS NULL'; $db->setQuery($query); $db->execute(); return $db->getAffectedRows(); } /** * Method to store a node to the database. This method will accept either a branch or a node. * * @param object $item The item to store. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ protected static function storeNode($item) { $db = JFactory::getDbo(); // Check if we are updating or inserting the item. if (empty($item->id)) { // Insert the item. $db->insertObject('#__finder_taxonomy', $item, 'id'); } else { // Update the item. $db->updateObject('#__finder_taxonomy', $item, 'id'); } return true; } } components/com_finder/helpers/indexer/stemmer.php000066600000003706150771655450016354 0ustar00clean($adapter, 'cmd'); $path = __DIR__ . '/stemmer/' . $adapter . '.php'; $class = 'FinderIndexerStemmer' . ucfirst($adapter); // Check if a stemmer exists for the adapter. if (file_exists($path)) { // Instantiate the stemmer. include_once $path; $instances[$adapter] = new $class; } else { // Throw invalid adapter exception. throw new Exception(JText::sprintf('COM_FINDER_INDEXER_INVALID_STEMMER', $adapter)); } return $instances[$adapter]; } /** * Method to stem a token and return the root. * * @param string $token The token to stem. * @param string $lang The language of the token. * * @return string The root token. * * @since 2.5 */ abstract public function stem($token, $lang); } components/com_finder/helpers/indexer/parser/rtf.php000066600000002162150771655450016762 0ustar00components/com_finder/helpers/indexer/parser/html.php000066600000002603150771655450017133 0ustar00]*>.*?#si', ' ', $input); // Deal with spacing issues in the input. $input = str_replace('>', '> ', $input); $input = str_replace(array(' ', ' '), ' ', $input); $input = trim(preg_replace('#\s+#u', ' ', $input)); // Strip the tags from the input and decode entities. $input = strip_tags($input); $input = html_entity_decode($input, ENT_QUOTES, 'UTF-8'); $input = trim(preg_replace('#\s+#u', ' ', $input)); return $input; } } components/com_finder/helpers/indexer/parser/txt.php000066600000001454150771655450017011 0ustar00parse($input); } /** * Method to tokenize a text string. * * @param string $input The input to tokenize. * @param string $lang The language of the input. * @param boolean $phrase Flag to indicate whether input could be a phrase. [optional] * * @return array An array of FinderIndexerToken objects. * * @since 2.5 */ public static function tokenize($input, $lang, $phrase = false) { static $cache; $store = JString::strlen($input) < 128 ? md5($input . '::' . $lang . '::' . $phrase) : null; // Check if the string has been tokenized already. if ($store && isset($cache[$store])) { return $cache[$store]; } $tokens = array(); $quotes = html_entity_decode('‘’'', ENT_QUOTES, 'UTF-8'); // Get the simple language key. $lang = self::getPrimaryLanguage($lang); /* * Parsing the string input into terms is a multi-step process. * * Regexes: * 1. Remove everything except letters, numbers, quotes, apostrophe, plus, dash, period, and comma. * 2. Remove plus, dash, period, and comma characters located before letter characters. * 3. Remove plus, dash, period, and comma characters located after other characters. * 4. Remove plus, period, and comma characters enclosed in alphabetical characters. Ungreedy. * 5. Remove orphaned apostrophe, plus, dash, period, and comma characters. * 6. Remove orphaned quote characters. * 7. Replace the assorted single quotation marks with the ASCII standard single quotation. * 8. Remove multiple space characters and replaces with a single space. */ $input = JString::strtolower($input); $input = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,]+#mui', ' ', $input); $input = preg_replace('#(^|\s)[+-.,]+([\pL\pM]+)#mui', ' $1', $input); $input = preg_replace('#([\pL\pM\pN]+)[+-.,]+(\s|$)#mui', '$1 ', $input); $input = preg_replace('#([\pL\pM]+)[+.,]+([\pL\pM]+)#muiU', '$1 $2', $input); $input = preg_replace('#(^|\s)[\'+-.,]+(\s|$)#mui', ' ', $input); $input = preg_replace('#(^|\s)[\p{Pi}\p{Pf}]+(\s|$)#mui', ' ', $input); $input = preg_replace('#[' . $quotes . ']+#mui', '\'', $input); $input = preg_replace('#\s+#mui', ' ', $input); $input = JString::trim($input); // Explode the normalized string to get the terms. $terms = explode(' ', $input); /* * If we have Unicode support and are dealing with Chinese text, Chinese * has to be handled specially because there are not necessarily any spaces * between the "words". So, we have to test if the words belong to the Chinese * character set and if so, explode them into single glyphs or "words". */ if ($lang === 'zh') { // Iterate through the terms and test if they contain Chinese. for ($i = 0, $n = count($terms); $i < $n; $i++) { $charMatches = array(); $charCount = preg_match_all('#[\p{Han}]#mui', $terms[$i], $charMatches); // Split apart any groups of Chinese characters. for ($j = 0; $j < $charCount; $j++) { $tSplit = JString::str_ireplace($charMatches[0][$j], '', $terms[$i], false); if (!empty($tSplit)) { $terms[$i] = $tSplit; } else { unset($terms[$i]); } $terms[] = $charMatches[0][$j]; } } // Reset array keys. $terms = array_values($terms); } /* * If we have to handle the input as a phrase, that means we don't * tokenize the individual terms and we do not create the two and three * term combinations. The phrase must contain more than one word! */ if ($phrase === true && count($terms) > 1) { // Create tokens from the phrase. $tokens[] = new FinderIndexerToken($terms, $lang); } else { // Create tokens from the terms. for ($i = 0, $n = count($terms); $i < $n; $i++) { $tokens[] = new FinderIndexerToken($terms[$i], $lang); } // Create two and three word phrase tokens from the individual words. for ($i = 0, $n = count($tokens); $i < $n; $i++) { // Setup the phrase positions. $i2 = $i + 1; $i3 = $i + 2; // Create the two word phrase. if ($i2 < $n && isset($tokens[$i2])) { // Tokenize the two word phrase. $token = new FinderIndexerToken(array($tokens[$i]->term, $tokens[$i2]->term), $lang, $lang === 'zh' ? '' : ' '); $token->derived = true; // Add the token to the stack. $tokens[] = $token; } // Create the three word phrase. if ($i3 < $n && isset($tokens[$i3])) { // Tokenize the three word phrase. $token = new FinderIndexerToken(array($tokens[$i]->term, $tokens[$i2]->term, $tokens[$i3]->term), $lang, $lang === 'zh' ? '' : ' '); $token->derived = true; // Add the token to the stack. $tokens[] = $token; } } } if ($store) { $cache[$store] = count($tokens) > 1 ? $tokens : array_shift($tokens); return $cache[$store]; } else { return count($tokens) > 1 ? $tokens : array_shift($tokens); } } /** * Method to get the base word of a token. This method uses the public * {@link FinderIndexerHelper::$stemmer} object if it is set. If no stemmer is set, * the original token is returned. * * @param string $token The token to stem. * @param string $lang The language of the token. * * @return string The root token. * * @since 2.5 */ public static function stem($token, $lang) { // Trim apostrophes at either end of the token. $token = JString::trim($token, '\''); // Trim everything after any apostrophe in the token. if (($pos = JString::strpos($token, '\'')) !== false) { $token = JString::substr($token, 0, $pos); } // Stem the token if we have a valid stemmer to use. if (self::$stemmer instanceof FinderIndexerStemmer) { return self::$stemmer->stem($token, $lang); } else { return $token; } } /** * Method to add a content type to the database. * * @param string $title The type of content. For example: PDF * @param string $mime The mime type of the content. For example: PDF [optional] * * @return integer The id of the content type. * * @since 2.5 * @throws Exception on database error. */ public static function addContentType($title, $mime = null) { static $types; $db = JFactory::getDbo(); $query = $db->getQuery(true); // Check if the types are loaded. if (empty($types)) { // Build the query to get the types. $query->select('*') ->from($db->quoteName('#__finder_types')); // Get the types. $db->setQuery($query); $types = $db->loadObjectList('title'); } // Check if the type already exists. if (isset($types[$title])) { return (int) $types[$title]->id; } // Add the type. $query->clear() ->insert($db->quoteName('#__finder_types')) ->columns(array($db->quoteName('title'), $db->quoteName('mime'))) ->values($db->quote($title) . ', ' . $db->quote($mime)); $db->setQuery($query); $db->execute(); // Return the new id. return (int) $db->insertid(); } /** * Method to check if a token is common in a language. * * @param string $token The token to test. * @param string $lang The language to reference. * * @return boolean True if common, false otherwise. * * @since 2.5 */ public static function isCommon($token, $lang) { static $data; // Load the common tokens for the language if necessary. if (!isset($data[$lang])) { $data[$lang] = self::getCommonWords($lang); } // Check if the token is in the common array. if (in_array($token, $data[$lang])) { return true; } else { return false; } } /** * Method to get an array of common terms for a language. * * @param string $lang The language to use. * * @return array Array of common terms. * * @since 2.5 * @throws Exception on database error. */ public static function getCommonWords($lang) { $db = JFactory::getDbo(); // Create the query to load all the common terms for the language. $query = $db->getQuery(true) ->select($db->quoteName('term')) ->from($db->quoteName('#__finder_terms_common')) ->where($db->quoteName('language') . ' = ' . $db->quote($lang)); // Load all of the common terms for the language. $db->setQuery($query); $results = $db->loadColumn(); return $results; } /** * Method to get the default language for the site. * * @return string The default language string. * * @since 2.5 */ public static function getDefaultLanguage() { static $lang; // We need to go to com_languages to get the site default language, it's the best we can guess. if (empty($lang)) { $lang = JComponentHelper::getParams('com_languages')->get('site', 'en-GB'); } return $lang; } /** * Method to parse a language/locale key and return a simple language string. * * @param string $lang The language/locale key. For example: en-GB * * @return string The simple language string. For example: en * * @since 2.5 */ public static function getPrimaryLanguage($lang) { static $data; // Only parse the identifier if necessary. if (!isset($data[$lang])) { if (is_callable(array('Locale', 'getPrimaryLanguage'))) { // Get the language key using the Locale package. $data[$lang] = Locale::getPrimaryLanguage($lang); } else { // Get the language key using string position. $data[$lang] = JString::substr($lang, 0, JString::strpos($lang, '-')); } } return $data[$lang]; } /** * Method to get the path (SEF route) for a content item. * * @param string $url The non-SEF route to the content item. * * @return string The path for the content item. * * @since 2.5 */ public static function getContentPath($url) { static $router; // Only get the router once. if (!($router instanceof JRouter)) { // Get and configure the site router. $config = JFactory::getConfig(); $router = JRouter::getInstance('site'); $router->setMode($config->get('sef', 1)); } // Build the relative route. $uri = $router->build($url); $route = $uri->toString(array('path', 'query', 'fragment')); $route = str_replace(JUri::base(true) . '/', '', $route); return $route; } /** * Method to get extra data for a content before being indexed. This is how * we add Comments, Tags, Labels, etc. that should be available to Finder. * * @param FinderIndexerResult &$item The item to index as an FinderIndexerResult object. * * @return boolean True on success, false on failure. * * @since 2.5 * @throws Exception on database error. */ public static function getContentExtras(FinderIndexerResult &$item) { // Get the event dispatcher. $dispatcher = JEventDispatcher::getInstance(); // Load the finder plugin group. JPluginHelper::importPlugin('finder'); try { // Trigger the event. $results = $dispatcher->trigger('onPrepareFinderContent', array(&$item)); // Check the returned results. This is for plugins that don't throw // exceptions when they encounter serious errors. if (in_array(false, $results)) { throw new Exception($dispatcher->getError(), 500); } } catch (Exception $e) { // Handle a caught exception. throw $e; } return true; } /** * Method to process content text using the onContentPrepare event trigger. * * @param string $text The content to process. * @param JRegistry $params The parameters object. [optional] * * @return string The processed content. * * @since 2.5 */ public static function prepareContent($text, $params = null) { static $loaded; // Get the dispatcher. $dispatcher = JEventDispatcher::getInstance(); // Load the content plugins if necessary. if (empty($loaded)) { JPluginHelper::importPlugin('content'); $loaded = true; } // Instantiate the parameter object if necessary. if (!($params instanceof JRegistry)) { $registry = new JRegistry; $registry->loadString($params); $params = $registry; } // Create a mock content object. $content = JTable::getInstance('Content'); $content->text = $text; // Fire the onContentPrepare event. $dispatcher->trigger('onContentPrepare', array('com_finder.indexer', &$content, &$params, 0)); return $content->text; } } components/com_finder/helpers/indexer/indexer.php000066600000027737150771655450016350 0ustar00name; if ($format == 'mysqli') { $format = 'mysql'; } elseif ($format == 'sqlazure') { $format = 'sqlsrv'; } $path = __DIR__ . '/driver/' . $format . '.php'; $class = 'FinderIndexerDriver' . ucfirst($format); // Check if a parser exists for the format. if (file_exists($path)) { // Instantiate the parser. include_once $path; return new $class; } else { // Throw invalid format exception. throw new RuntimeException(JText::sprintf('COM_FINDER_INDEXER_INVALID_DRIVER', $format)); } } /** * Method to get the indexer state. * * @return object The indexer state object. * * @since 2.5 */ public static function getState() { // First, try to load from the internal state. if (!empty(self::$state)) { return self::$state; } // If we couldn't load from the internal state, try the session. $session = JFactory::getSession(); $data = $session->get('_finder.state', null); // If the state is empty, load the values for the first time. if (empty($data)) { $data = new JObject; // Load the default configuration options. $data->options = JComponentHelper::getParams('com_finder'); // Setup the weight lookup information. $data->weights = array( self::TITLE_CONTEXT => round($data->options->get('title_multiplier', 1.7), 2), self::TEXT_CONTEXT => round($data->options->get('text_multiplier', 0.7), 2), self::META_CONTEXT => round($data->options->get('meta_multiplier', 1.2), 2), self::PATH_CONTEXT => round($data->options->get('path_multiplier', 2.0), 2), self::MISC_CONTEXT => round($data->options->get('misc_multiplier', 0.3), 2) ); // Set the current time as the start time. $data->startTime = JFactory::getDate()->toSQL(); // Set the remaining default values. $data->batchSize = (int) $data->options->get('batch_size', 50); $data->batchOffset = 0; $data->totalItems = 0; $data->pluginState = array(); } // Setup the profiler if debugging is enabled. if (JFactory::getApplication()->getCfg('debug')) { self::$profiler = JProfiler::getInstance('FinderIndexer'); } // Setup the stemmer. if ($data->options->get('stem', 1) && $data->options->get('stemmer', 'porter_en')) { FinderIndexerHelper::$stemmer = FinderIndexerStemmer::getInstance($data->options->get('stemmer', 'porter_en')); } // Set the state. self::$state = $data; return self::$state; } /** * Method to set the indexer state. * * @param object $data A new indexer state object. * * @return boolean True on success, false on failure. * * @since 2.5 */ public static function setState($data) { // Check the state object. if (empty($data) || !$data instanceof JObject) { return false; } // Set the new internal state. self::$state = $data; // Set the new session state. $session = JFactory::getSession(); $session->set('_finder.state', $data); return true; } /** * Method to reset the indexer state. * * @return void * * @since 2.5 */ public static function resetState() { // Reset the internal state to null. self::$state = null; // Reset the session state to null. $session = JFactory::getSession(); $session->set('_finder.state', null); } /** * Method to index a content item. * * @param FinderIndexerResult $item The content item to index. * @param string $format The format of the content. [optional] * * @return integer The ID of the record in the links table. * * @since 2.5 * @throws Exception on database error. */ abstract public function index($item, $format = 'html'); /** * Method to remove a link from the index. * * @param integer $linkId The id of the link. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ abstract public function remove($linkId); /** * Method to optimize the index. We use this method to remove unused terms * and any other optimizations that might be necessary. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ abstract public function optimize(); /** * Method to get a content item's signature. * * @param object $item The content item to index. * * @return string The content item's signature. * * @since 2.5 */ protected static function getSignature($item) { // Get the indexer state. $state = self::getState(); // Get the relevant configuration variables. $config = array(); $config[] = $state->weights; $config[] = $state->options->get('stem', 1); $config[] = $state->options->get('stemmer', 'porter_en'); return md5(serialize(array($item, $config))); } /** * Method to parse input, tokenize it, and then add it to the database. * * @param mixed $input String or resource to use as input. A resource * input will automatically be chunked to conserve * memory. Strings will be chunked if longer than * 2K in size. * @param integer $context The context of the input. See context constants. * @param string $lang The language of the input. * @param string $format The format of the input. * * @return integer The number of tokens extracted from the input. * * @since 2.5 */ protected function tokenizeToDB($input, $context, $lang, $format) { $count = 0; $buffer = null; if (!empty($input)) { // If the input is a resource, batch the process out. if (is_resource($input)) { // Batch the process out to avoid memory limits. while (!feof($input)) { // Read into the buffer. $buffer .= fread($input, 2048); /* * If we haven't reached the end of the file, seek to the last * space character and drop whatever is after that to make sure * we didn't truncate a term while reading the input. */ if (!feof($input)) { // Find the last space character. $ls = strrpos($buffer, ' '); // Adjust string based on the last space character. if ($ls) { // Truncate the string to the last space character. $string = substr($buffer, 0, $ls); // Adjust the buffer based on the last space for the next iteration and trim. $buffer = JString::trim(substr($buffer, $ls)); } // No space character was found. else { $string = $buffer; } } // We've reached the end of the file, so parse whatever remains. else { $string = $buffer; } // Parse the input. $string = FinderIndexerHelper::parse($string, $format); // Check the input. if (empty($string)) { continue; } // Tokenize the input. $tokens = FinderIndexerHelper::tokenize($string, $lang); // Add the tokens to the database. $count += $this->addTokensToDB($tokens, $context); // Check if we're approaching the memory limit of the token table. if ($count > self::$state->options->get('memory_table_limit', 30000)) { $this->toggleTables(false); } unset($string); unset($tokens); } } // If the input is greater than 2K in size, it is more efficient to // batch out the operation into smaller chunks of work. elseif (strlen($input) > 2048) { $start = 0; $end = strlen($input); $chunk = 2048; /* * As it turns out, the complex regular expressions we use for * sanitizing input are not very efficient when given large * strings. It is much faster to process lots of short strings. */ while ($start < $end) { // Setup the string. $string = substr($input, $start, $chunk); // Find the last space character if we aren't at the end. $ls = (($start + $chunk) < $end ? strrpos($string, ' ') : false); // Truncate to the last space character. if ($ls !== false) { $string = substr($string, 0, $ls); } // Adjust the start position for the next iteration. $start += ($ls !== false ? ($ls + 1 - $chunk) + $chunk : $chunk); // Parse the input. $string = FinderIndexerHelper::parse($string, $format); // Check the input. if (empty($string)) { continue; } // Tokenize the input. $tokens = FinderIndexerHelper::tokenize($string, $lang); // Add the tokens to the database. $count += $this->addTokensToDB($tokens, $context); // Check if we're approaching the memory limit of the token table. if ($count > self::$state->options->get('memory_table_limit', 30000)) { $this->toggleTables(false); } } } else { // Parse the input. $input = FinderIndexerHelper::parse($input, $format); // Check the input. if (empty($input)) { return $count; } // Tokenize the input. $tokens = FinderIndexerHelper::tokenize($input, $lang); // Add the tokens to the database. $count = $this->addTokensToDB($tokens, $context); } } return $count; } /** * Method to add a set of tokens to the database. * * @param mixed $tokens An array or single FinderIndexerToken object. * @param mixed $context The context of the tokens. See context constants. [optional] * * @return integer The number of tokens inserted into the database. * * @since 2.5 * @throws Exception on database error. */ abstract protected function addTokensToDB($tokens, $context = ''); /** * Method to switch the token tables from Memory tables to MyISAM tables * when they are close to running out of memory. * * @param boolean $memory Flag to control how they should be toggled. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ abstract protected function toggleTables($memory); } components/com_finder/helpers/indexer/query.php000066600000106141150771655450016042 0ustar00input = isset($options['input']) ? $options['input'] : null; // Get the empty query setting. $this->empty = isset($options['empty']) ? (bool) $options['empty'] : false; // Get the input language. $this->language = !empty($options['language']) ? $options['language'] : FinderIndexerHelper::getDefaultLanguage(); $this->language = FinderIndexerHelper::getPrimaryLanguage($this->language); // Get the matching mode. $this->mode = 'AND'; // Initialize the temporary date storage. $this->dates = new JRegistry; // Populate the temporary date storage. if (isset($options['date1']) && !empty($options['date1'])) { $this->dates->set('date1', $options['date1']); } if (isset($options['date2']) && !empty($options['date1'])) { $this->dates->set('date2', $options['date2']); } if (isset($options['when1']) && !empty($options['date1'])) { $this->dates->set('when1', $options['when1']); } if (isset($options['when2']) && !empty($options['date1'])) { $this->dates->set('when2', $options['when2']); } // Process the static taxonomy filters. if (isset($options['filter']) && !empty($options['filter'])) { $this->processStaticTaxonomy($options['filter']); } // Process the dynamic taxonomy filters. if (isset($options['filters']) && !empty($options['filters'])) { $this->processDynamicTaxonomy($options['filters']); } // Get the date filters. $d1 = $this->dates->get('date1'); $d2 = $this->dates->get('date2'); $w1 = $this->dates->get('when1'); $w2 = $this->dates->get('when2'); // Process the date filters. if (!empty($d1) || !empty($d2)) { $this->processDates($d1, $d2, $w1, $w2); } // Process the input string. $this->processString($this->input, $this->language, $this->mode); // Get the number of matching terms. foreach ($this->included as $token) { $this->terms += count($token->matches); } // Remove the temporary date storage. unset($this->dates); /* * Lastly, determine whether this query can return a result set. */ // Check if we have a query string. if (!empty($this->input)) { $this->search = true; } // Check if we can search without a query string. elseif ($this->empty && (!empty($this->filter) || !empty($this->filters) || !empty($this->date1) || !empty($this->date2))) { $this->search = true; } // We do not have a valid search query. else { $this->search = false; } } /** * Method to convert the query object into a URI string. * * @param string $base The base URI. [optional] * * @return string The complete query URI. * * @since 2.5 */ public function toURI($base = null) { // Set the base if not specified. if (empty($base)) { $base = 'index.php?option=com_finder&view=search'; } // Get the base URI. $uri = JUri::getInstance($base); // Add the static taxonomy filter if present. if (!empty($this->filter)) { $uri->setVar('f', $this->filter); } // Get the filters in the request. $input = JFactory::getApplication()->input; $t = $input->request->get('t', array(), 'array'); // Add the dynamic taxonomy filters if present. if (!empty($this->filters)) { foreach ($this->filters as $nodes) { foreach ($nodes as $node) { if (!in_array($node, $t)) { continue; } $uri->setVar('t[]', $node); } } } // Add the input string if present. if (!empty($this->input)) { $uri->setVar('q', $this->input); } // Add the start date if present. if (!empty($this->date1)) { $uri->setVar('d1', $this->date1); } // Add the end date if present. if (!empty($this->date2)) { $uri->setVar('d2', $this->date2); } // Add the start date modifier if present. if (!empty($this->when1)) { $uri->setVar('w1', $this->when1); } // Add the end date modifier if present. if (!empty($this->when2)) { $uri->setVar('w2', $this->when2); } // Add a menu item id if one is not present. if (!$uri->getVar('Itemid')) { // Get the menu item id. $query = array( 'view' => $uri->getVar('view'), 'f' => $uri->getVar('f'), 'q' => $uri->getVar('q') ); $item = FinderHelperRoute::getItemid($query); // Add the menu item id if present. if ($item !== null) { $uri->setVar('Itemid', $item); } } return $uri->toString(array('path', 'query')); } /** * Method to get a list of excluded search term ids. * * @return array An array of excluded term ids. * * @since 2.5 */ public function getExcludedTermIds() { $results = array(); // Iterate through the excluded tokens and compile the matching terms. for ($i = 0, $c = count($this->excluded); $i < $c; $i++) { $results = array_merge($results, $this->excluded[$i]->matches); } // Sanitize the terms. $results = array_unique($results); JArrayHelper::toInteger($results); return $results; } /** * Method to get a list of included search term ids. * * @return array An array of included term ids. * * @since 2.5 */ public function getIncludedTermIds() { $results = array(); // Iterate through the included tokens and compile the matching terms. for ($i = 0, $c = count($this->included); $i < $c; $i++) { // Check if we have any terms. if (empty($this->included[$i]->matches)) { continue; } // Get the term. $term = $this->included[$i]->term; // Prepare the container for the term if necessary. if (!array_key_exists($term, $results)) { $results[$term] = array(); } // Add the matches to the stack. $results[$term] = array_merge($results[$term], $this->included[$i]->matches); } // Sanitize the terms. foreach ($results as $key => $value) { $results[$key] = array_unique($results[$key]); JArrayHelper::toInteger($results[$key]); } return $results; } /** * Method to get a list of required search term ids. * * @return array An array of required term ids. * * @since 2.5 */ public function getRequiredTermIds() { $results = array(); // Iterate through the included tokens and compile the matching terms. for ($i = 0, $c = count($this->included); $i < $c; $i++) { // Check if the token is required. if ($this->included[$i]->required) { // Get the term. $term = $this->included[$i]->term; // Prepare the container for the term if necessary. if (!array_key_exists($term, $results)) { $results[$term] = array(); } // Add the matches to the stack. $results[$term] = array_merge($results[$term], $this->included[$i]->matches); } } // Sanitize the terms. foreach ($results as $key => $value) { $results[$key] = array_unique($results[$key]); JArrayHelper::toInteger($results[$key]); } return $results; } /** * Method to process the static taxonomy input. The static taxonomy input * comes in the form of a pre-defined search filter that is assigned to the * search form. * * @param integer $filterId The id of static filter. * * @return boolean True on success, false on failure. * * @since 2.5 * @throws Exception on database error. */ protected function processStaticTaxonomy($filterId) { // Get the database object. $db = JFactory::getDbo(); // Initialize user variables $user = JFactory::getUser(); $groups = implode(',', $user->getAuthorisedViewLevels()); // Load the predefined filter. $query = $db->getQuery(true) ->select('f.data, f.params') ->from($db->quoteName('#__finder_filters') . ' AS f') ->where('f.filter_id = ' . (int) $filterId); $db->setQuery($query); $return = $db->loadObject(); // Check the returned filter. if (empty($return)) { return false; } // Set the filter. $this->filter = (int) $filterId; // Get a parameter object for the filter date options. $registry = new JRegistry; $registry->loadString($return->params); $params = $registry; // Set the dates if not already set. $this->dates->def('d1', $params->get('d1')); $this->dates->def('d2', $params->get('d2')); $this->dates->def('w1', $params->get('w1')); $this->dates->def('w2', $params->get('w2')); // Remove duplicates and sanitize. $filters = explode(',', $return->data); $filters = array_unique($filters); JArrayHelper::toInteger($filters); // Remove any values of zero. if (array_search(0, $filters, true) !== false) { unset($filters[array_search(0, $filters, true)]); } // Check if we have any real input. if (empty($filters)) { return true; } /* * Create the query to get filters from the database. We do this for * two reasons: one, it allows us to ensure that the filters being used * are real; two, we need to sort the filters by taxonomy branch. */ $query->clear() ->select('t1.id, t1.title, t2.title AS branch') ->from($db->quoteName('#__finder_taxonomy') . ' AS t1') ->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id') ->where('t1.state = 1') ->where('t1.access IN (' . $groups . ')') ->where('t1.id IN (' . implode(',', $filters) . ')') ->where('t2.state = 1') ->where('t2.access IN (' . $groups . ')'); // Load the filters. $db->setQuery($query); $results = $db->loadObjectList(); // Sort the filter ids by branch. foreach ($results as $result) { $this->filters[$result->branch][$result->title] = (int) $result->id; } return true; } /** * Method to process the dynamic taxonomy input. The dynamic taxonomy input * comes in the form of select fields that the user chooses from. The * dynamic taxonomy input is processed AFTER the static taxonomy input * because the dynamic options can be used to further narrow a static * taxonomy filter. * * @param array $filters An array of taxonomy node ids. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ protected function processDynamicTaxonomy($filters) { // Initialize user variables $user = JFactory::getUser(); $groups = implode(',', $user->getAuthorisedViewLevels()); // Remove duplicates and sanitize. $filters = array_unique($filters); JArrayHelper::toInteger($filters); // Remove any values of zero. if (array_search(0, $filters, true) !== false) { unset($filters[array_search(0, $filters, true)]); } // Check if we have any real input. if (empty($filters)) { return true; } // Get the database object. $db = JFactory::getDbo(); $query = $db->getQuery(true); /* * Create the query to get filters from the database. We do this for * two reasons: one, it allows us to ensure that the filters being used * are real; two, we need to sort the filters by taxonomy branch. */ $query->select('t1.id, t1.title, t2.title AS branch') ->from($db->quoteName('#__finder_taxonomy') . ' AS t1') ->join('INNER', $db->quoteName('#__finder_taxonomy') . ' AS t2 ON t2.id = t1.parent_id') ->where('t1.state = 1') ->where('t1.access IN (' . $groups . ')') ->where('t1.id IN (' . implode(',', $filters) . ')') ->where('t2.state = 1') ->where('t2.access IN (' . $groups . ')'); // Load the filters. $db->setQuery($query); $results = $db->loadObjectList(); // Cleared filter branches. $cleared = array(); /* * Sort the filter ids by branch. Because these filters are designed to * override and further narrow the items selected in the static filter, * we will clear the values from the static filter on a branch by * branch basis before adding the dynamic filters. So, if the static * filter defines a type filter of "articles" and three "category" * filters but the user only limits the category further, the category * filters will be flushed but the type filters will not. */ foreach ($results as $result) { // Check if the branch has been cleared. if (!in_array($result->branch, $cleared)) { // Clear the branch. $this->filters[$result->branch] = array(); // Add the branch to the cleared list. $cleared[] = $result->branch; } // Add the filter to the list. $this->filters[$result->branch][$result->title] = (int) $result->id; } return true; } /** * Method to process the query date filters to determine start and end * date limitations. * * @param string $date1 The first date filter. * @param string $date2 The second date filter. * @param string $when1 The first date modifier. * @param string $when2 The second date modifier. * * @return boolean True on success. * * @since 2.5 */ protected function processDates($date1, $date2, $when1, $when2) { // Clean up the inputs. $date1 = JString::trim(JString::strtolower($date1)); $date2 = JString::trim(JString::strtolower($date2)); $when1 = JString::trim(JString::strtolower($when1)); $when2 = JString::trim(JString::strtolower($when2)); // Get the time offset. $offset = JFactory::getApplication()->getCfg('offset'); // Array of allowed when values. $whens = array('before', 'after', 'exact'); // The value of 'today' is a special case that we need to handle. if ($date1 === JString::strtolower(JText::_('COM_FINDER_QUERY_FILTER_TODAY'))) { $today = JFactory::getDate('now', $offset); $date1 = $today->format('%Y-%m-%d'); } // Try to parse the date string. $date = JFactory::getDate($date1, $offset); // Check if the date was parsed successfully. if ($date->toUnix() !== null) { // Set the date filter. $this->date1 = $date->toSQL(); $this->when1 = in_array($when1, $whens) ? $when1 : 'before'; } // The value of 'today' is a special case that we need to handle. if ($date2 === JString::strtolower(JText::_('COM_FINDER_QUERY_FILTER_TODAY'))) { $today = JFactory::getDate('now', $offset); $date2 = $today->format('%Y-%m-%d'); } // Try to parse the date string. $date = JFactory::getDate($date2, $offset); // Check if the date was parsed successfully. if ($date->toUnix() !== null) { // Set the date filter. $this->date2 = $date->toSQL(); $this->when2 = in_array($when2, $whens) ? $when2 : 'before'; } return true; } /** * Method to process the query input string and extract required, optional, * and excluded tokens; taxonomy filters; and date filters. * * @param string $input The query input string. * @param string $lang The query input language. * @param string $mode The query matching mode. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ protected function processString($input, $lang, $mode) { // Clean up the input string. $input = html_entity_decode($input, ENT_QUOTES, 'UTF-8'); $input = JString::strtolower($input); $input = preg_replace('#\s+#mi', ' ', $input); $input = JString::trim($input); $debug = JFactory::getConfig()->get('debug_lang'); /* * First, we need to handle string based modifiers. String based * modifiers could potentially include things like "category:blah" or * "before:2009-10-21" or "type:article", etc. */ $patterns = array( 'before' => JText::_('COM_FINDER_FILTER_WHEN_BEFORE'), 'after' => JText::_('COM_FINDER_FILTER_WHEN_AFTER') ); // Add the taxonomy branch titles to the possible patterns. foreach (FinderIndexerTaxonomy::getBranchTitles() as $branch) { // Add the pattern. $patterns[$branch] = JString::strtolower(JText::_(FinderHelperLanguage::branchSingular($branch))); } // Container for search terms and phrases. $terms = array(); $phrases = array(); // Cleared filter branches. $cleared = array(); /* * Compile the suffix pattern. This is used to match the values of the * filter input string. Single words can be input directly, multi-word * values have to be wrapped in double quotes. */ $quotes = html_entity_decode('‘’'', ENT_QUOTES, 'UTF-8'); $suffix = '(([\w\d' . $quotes . '-]+)|\"([\w\d\s' . $quotes . '-]+)\")'; /* * Iterate through the possible filter patterns and search for matches. * We need to match the key, colon, and a value pattern for the match * to be valid. */ foreach ($patterns as $modifier => $pattern) { $matches = array(); if ($debug) { $pattern = substr($pattern, 2, -2); } // Check if the filter pattern is in the input string. if (preg_match('#' . $pattern . '\s*:\s*' . $suffix . '#mi', $input, $matches)) { // Get the value given to the modifier. $value = isset($matches[3]) ? $matches[3] : $matches[1]; // Now we have to handle the filter string. switch ($modifier) { // Handle a before and after date filters. case 'before': case 'after': { // Get the time offset. $offset = JFactory::getApplication()->getCfg('offset'); // Array of allowed when values. $whens = array('before', 'after', 'exact'); // The value of 'today' is a special case that we need to handle. if ($value === JString::strtolower(JText::_('COM_FINDER_QUERY_FILTER_TODAY'))) { $today = JFactory::getDate('now', $offset); $value = $today->format('%Y-%m-%d'); } // Try to parse the date string. $date = JFactory::getDate($value, $offset); // Check if the date was parsed successfully. if ($date->toUnix() !== null) { // Set the date filter. $this->date1 = $date->toSQL(); $this->when1 = in_array($modifier, $whens) ? $modifier : 'before'; } break; } // Handle a taxonomy branch filter. default: { // Try to find the node id. $return = FinderIndexerTaxonomy::getNodeByTitle($modifier, $value); // Check if the node id was found. if ($return) { // Check if the branch has been cleared. if (!in_array($modifier, $cleared)) { // Clear the branch. $this->filters[$modifier] = array(); // Add the branch to the cleared list. $cleared[] = $modifier; } // Add the filter to the list. $this->filters[$modifier][$return->title] = (int) $return->id; } break; } } // Clean up the input string again. $input = str_replace($matches[0], '', $input); $input = preg_replace('#\s+#mi', ' ', $input); $input = JString::trim($input); } } /* * Extract the tokens enclosed in double quotes so that we can handle * them as phrases. */ if (JString::strpos($input, '"') !== false) { $matches = array(); // Extract the tokens enclosed in double quotes. if (preg_match_all('#\"([^"]+)\"#mi', $input, $matches)) { /* * One or more phrases were found so we need to iterate through * them, tokenize them as phrases, and remove them from the raw * input string before we move on to the next processing step. */ foreach ($matches[1] as $key => $match) { // Find the complete phrase in the input string. $pos = JString::strpos($input, $matches[0][$key]); $len = JString::strlen($matches[0][$key]); // Add any terms that are before this phrase to the stack. if (JString::trim(JString::substr($input, 0, $pos))) { $terms = array_merge($terms, explode(' ', JString::trim(JString::substr($input, 0, $pos)))); } // Strip out everything up to and including the phrase. $input = JString::substr($input, $pos + $len); // Clean up the input string again. $input = preg_replace('#\s+#mi', ' ', $input); $input = JString::trim($input); // Get the number of words in the phrase. $parts = explode(' ', $match); // Check if the phrase is longer than three words. if (count($parts) > 3) { /* * If the phrase is longer than three words, we need to * break it down into smaller chunks of phrases that * are less than or equal to three words. We overlap * the chunks so that we can ensure that a match is * found for the complete phrase and not just portions * of it. */ for ($i = 0, $c = count($parts); $i < $c; $i += 2) { // Set up the chunk. $chunk = array(); // The chunk has to be assembled based on how many // pieces are available to use. switch ($c - $i) { /* * If only one word is left, we can break from * the switch and loop because the last word * was already used at the end of the last * chunk. */ case 1: break 2; // If there words are left, we use them both as // the last chunk of the phrase and we're done. case 2: $chunk[] = $parts[$i]; $chunk[] = $parts[$i + 1]; break; // If there are three or more words left, we // build a three word chunk and continue on. default: $chunk[] = $parts[$i]; $chunk[] = $parts[$i + 1]; $chunk[] = $parts[$i + 2]; break; } // If the chunk is not empty, add it as a phrase. if (count($chunk)) { $phrases[] = implode(' ', $chunk); $terms[] = implode(' ', $chunk); } } } else { // The phrase is <= 3 words so we can use it as is. $phrases[] = $match; $terms[] = $match; } } } } // Add the remaining terms if present. if (!empty($input)) { $terms = array_merge($terms, explode(' ', $input)); } // An array of our boolean operators. $operator => $translation $operators = array( 'AND' => JString::strtolower(JText::_('COM_FINDER_QUERY_OPERATOR_AND')), 'OR' => JString::strtolower(JText::_('COM_FINDER_QUERY_OPERATOR_OR')), 'NOT' => JString::strtolower(JText::_('COM_FINDER_QUERY_OPERATOR_NOT')) ); // If language debugging is enabled you need to ignore the debug strings in matching. if (JDEBUG) { $debugStrings = array('**', '??'); $operators = str_replace($debugStrings, '', $operators); } /* * Iterate through the terms and perform any sorting that needs to be * done based on boolean search operators. Terms that are before an * and/or/not modifier have to be handled in relation to their operator. */ for ($i = 0, $c = count($terms); $i < $c; $i++) { // Check if the term is followed by an operator that we understand. if (isset($terms[$i + 1]) && in_array($terms[$i + 1], $operators)) { // Get the operator mode. $op = array_search($terms[$i + 1], $operators); // Handle the AND operator. if ($op === 'AND' && isset($terms[$i + 2])) { // Tokenize the current term. $token = FinderIndexerHelper::tokenize($terms[$i], $lang, true); $token = $this->getTokenData($token); // Set the required flag. $token->required = true; // Add the current token to the stack. $this->included[] = $token; $this->highlight = array_merge($this->highlight, array_keys($token->matches)); // Skip the next token (the mode operator). $this->operators[] = $terms[$i + 1]; // Tokenize the term after the next term (current plus two). $other = FinderIndexerHelper::tokenize($terms[$i + 2], $lang, true); $other = $this->getTokenData($other); // Set the required flag. $other->required = true; // Add the token after the next token to the stack. $this->included[] = $other; $this->highlight = array_merge($this->highlight, array_keys($other->matches)); // Remove the processed phrases if possible. if (($pk = array_search($terms[$i], $phrases)) !== false) { unset($phrases[$pk]); } if (($pk = array_search($terms[$i + 2], $phrases)) !== false) { unset($phrases[$pk]); } // Remove the processed terms. unset($terms[$i]); unset($terms[$i + 1]); unset($terms[$i + 2]); // Adjust the loop. $i += 2; continue; } // Handle the OR operator. elseif ($op === 'OR' && isset($terms[$i + 2])) { // Tokenize the current term. $token = FinderIndexerHelper::tokenize($terms[$i], $lang, true); $token = $this->getTokenData($token); // Set the required flag. $token->required = false; // Add the current token to the stack. if (count($token->matches)) { $this->included[] = $token; $this->highlight = array_merge($this->highlight, array_keys($token->matches)); } else { $this->ignored[] = $token; } // Skip the next token (the mode operator). $this->operators[] = $terms[$i + 1]; // Tokenize the term after the next term (current plus two). $other = FinderIndexerHelper::tokenize($terms[$i + 2], $lang, true); $other = $this->getTokenData($other); // Set the required flag. $other->required = false; // Add the token after the next token to the stack. if (count($other->matches)) { $this->included[] = $other; $this->highlight = array_merge($this->highlight, array_keys($other->matches)); } else { $this->ignored[] = $other; } // Remove the processed phrases if possible. if (($pk = array_search($terms[$i], $phrases)) !== false) { unset($phrases[$pk]); } if (($pk = array_search($terms[$i + 2], $phrases)) !== false) { unset($phrases[$pk]); } // Remove the processed terms. unset($terms[$i]); unset($terms[$i + 1]); unset($terms[$i + 2]); // Adjust the loop. $i += 2; continue; } } // Handle an orphaned OR operator. elseif (isset($terms[$i + 1]) && array_search($terms[$i], $operators) === 'OR') { // Skip the next token (the mode operator). $this->operators[] = $terms[$i]; // Tokenize the next term (current plus one). $other = FinderIndexerHelper::tokenize($terms[$i + 1], $lang, true); $other = $this->getTokenData($other); // Set the required flag. $other->required = false; // Add the token after the next token to the stack. if (count($other->matches)) { $this->included[] = $other; $this->highlight = array_merge($this->highlight, array_keys($other->matches)); } else { $this->ignored[] = $other; } // Remove the processed phrase if possible. if (($pk = array_search($terms[$i + 1], $phrases)) !== false) { unset($phrases[$pk]); } // Remove the processed terms. unset($terms[$i]); unset($terms[$i + 1]); // Adjust the loop. $i += 1; continue; } // Handle the NOT operator. elseif (isset($terms[$i + 1]) && array_search($terms[$i], $operators) === 'NOT') { // Skip the next token (the mode operator). $this->operators[] = $terms[$i]; // Tokenize the next term (current plus one). $other = FinderIndexerHelper::tokenize($terms[$i + 1], $lang, true); $other = $this->getTokenData($other); // Set the required flag. $other->required = false; // Add the next token to the stack. if (count($other->matches)) { $this->excluded[] = $other; } else { $this->ignored[] = $other; } // Remove the processed phrase if possible. if (($pk = array_search($terms[$i + 1], $phrases)) !== false) { unset($phrases[$pk]); } // Remove the processed terms. unset($terms[$i]); unset($terms[$i + 1]); // Adjust the loop. $i += 1; continue; } } /* * Iterate through any search phrases and tokenize them. We handle * phrases as autonomous units and do not break them down into two and * three word combinations. */ for ($i = 0, $c = count($phrases); $i < $c; $i++) { // Tokenize the phrase. $token = FinderIndexerHelper::tokenize($phrases[$i], $lang, true); $token = $this->getTokenData($token); // Set the required flag. $token->required = true; // Add the current token to the stack. $this->included[] = $token; $this->highlight = array_merge($this->highlight, array_keys($token->matches)); // Remove the processed term if possible. if (($pk = array_search($phrases[$i], $terms)) !== false) { unset($terms[$pk]); } // Remove the processed phrase. unset($phrases[$i]); } /* * Handle any remaining tokens using the standard processing mechanism. */ if (!empty($terms)) { // Tokenize the terms. $terms = implode(' ', $terms); $tokens = FinderIndexerHelper::tokenize($terms, $lang, false); // Make sure we are working with an array. $tokens = is_array($tokens) ? $tokens : array($tokens); // Get the token data and required state for all the tokens. foreach ($tokens as $token) { // Get the token data. $token = $this->getTokenData($token); // Set the required flag for the token. $token->required = $mode === 'AND' ? ($token->phrase ? false : true) : false; // Add the token to the appropriate stack. if (count($token->matches) || $token->required) { $this->included[] = $token; $this->highlight = array_merge($this->highlight, array_keys($token->matches)); } else { $this->ignored[] = $token; } } } return true; } /** * Method to get the base and similar term ids and, if necessary, suggested * term data from the database. The terms ids are identified based on a * 'like' match in MySQL and/or a common stem. If no term ids could be * found, then we know that we will not be able to return any results for * that term and we should try to find a similar term to use that we can * match so that we can suggest the alternative search query to the user. * * @param FinderIndexerToken $token A FinderIndexerToken object. * * @return FinderIndexerToken A FinderIndexerToken object. * * @since 2.5 * @throws Exception on database error. */ protected function getTokenData($token) { // Get the database object. $db = JFactory::getDbo(); // Create a database query to build match the token. $query = $db->getQuery(true) ->select('t.term, t.term_id') ->from('#__finder_terms AS t'); /* * If the token is a phrase, the lookup process is fairly simple. If * the token is a word, it is a little more complicated. We have to * create two queries to lookup the term and the stem respectively, * then union the result sets together. This is MUCH faster than using * an or condition in the database query. */ if ($token->phrase) { // Add the phrase to the query. $query->where('t.term = ' . $db->quote($token->term)) ->where('t.phrase = 1'); } else { // Add the term to the query. $query->where('t.term = ' . $db->quote($token->term)) ->where('t.phrase = 0'); // Clone the query, replace the WHERE clause. $sub = clone($query); $sub->clear('where'); $sub->where('t.stem = ' . $db->quote($token->stem)); $sub->where('t.phrase = 0'); // Union the two queries. $query->union($sub); } // Get the terms. $db->setQuery($query); $matches = $db->loadObjectList(); // Setup the container. $token->matches = array(); // Check the matching terms. if (!empty($matches)) { // Add the matches to the token. for ($i = 0, $c = count($matches); $i < $c; $i++) { $token->matches[$matches[$i]->term] = (int) $matches[$i]->term_id; } } // If no matches were found, try to find a similar but better token. if (empty($token->matches)) { // Create a database query to get the similar terms. // TODO: PostgreSQL doesn't support SOUNDEX out of the box $query->clear() ->select('DISTINCT t.term_id AS id, t.term AS term') ->from('#__finder_terms AS t') // ->where('t.soundex = ' . soundex($db->quote($token->term))) ->where('t.soundex = SOUNDEX(' . $db->quote($token->term) . ')') ->where('t.phrase = ' . (int) $token->phrase); // Get the terms. $db->setQuery($query); $results = $db->loadObjectList(); // Check if any similar terms were found. if (empty($results)) { return $token; } // Stack for sorting the similar terms. $suggestions = array(); // Get the levnshtein distance for all suggested terms. foreach ($results as $sk => $st) { // Get the levenshtein distance between terms. $distance = levenshtein($st->term, $token->term); // Make sure the levenshtein distance isn't over 50. if ($distance < 50) { $suggestions[$sk] = $distance; } } // Sort the suggestions. asort($suggestions, SORT_NUMERIC); // Get the closest match. $keys = array_keys($suggestions); $key = $keys[0]; // Add the suggested term. $token->suggestion = $results[$key]->term; } return $token; } } components/com_finder/helpers/indexer/stemmer/index.html000066600000000036150771655450017631 0ustar00components/com_finder/helpers/indexer/stemmer/fr.php000066600000024606150771655450016765 0ustar00cache[$lang][$token])) { // Stem the token. $result = static::_getStem($token); // Add the token to the cache. $this->cache[$lang][$token] = $result; } return $this->cache[$lang][$token]; } /** * French stemmer rules variables. * * @return array The rules * * @since 3.0 */ protected static function getStemRules() { if (static::$_stemRules) { return static::$_stemRules; } $vars = array(); // French accented letters in ISO-8859-1 encoding $vars['accents'] = chr(224) . chr(226) . chr(232) . chr(233) . chr(234) . chr(235) . chr(238) . chr(239) . chr(244) . chr(251) . chr(249) . chr(231); // The rule patterns include all accented words for french language $vars['rule_pattern'] = "/^([a-z" . $vars['accents'] . "]*)(\*){0,1}(\d)([a-z" . $vars['accents'] . "]*)([.|>])/"; // French vowels (including y) in ISO-8859-1 encoding $vars['vowels'] = chr(97) . chr(224) . chr(226) . chr(101) . chr(232) . chr(233) . chr(234) . chr(235) . chr(105) . chr(238) . chr(239) . chr(111) . chr(244) . chr(117) . chr(251) . chr(249) . chr(121); // The French rules in ISO-8859-1 encoding $vars['rules'] = array( 'esre1>', 'esio1>', 'siol1.', 'siof0.', 'sioe0.', 'sio3>', 'st1>', 'sf1>', 'sle1>', 'slo1>', 's' . chr(233) . '1>', chr(233) . 'tuae5.', chr(233) . 'tuae2.', 'tnia0.', 'tniv1.', 'tni3>', 'suor1.', 'suo0.', 'sdrail5.', 'sdrai4.', 'er' . chr(232) . 'i1>', 'sesue3x>', 'esuey5i.', 'esue2x>', 'se1>', 'er' . chr(232) . 'g3.', 'eca1>', 'esiah0.', 'esi1>', 'siss2.', 'sir2>', 'sit2>', 'egan' . chr(233) . '1.', 'egalli6>', 'egass1.', 'egas0.', 'egat3.', 'ega3>', 'ette4>', 'ett2>', 'etio1.', 'tio' . chr(231) . '4c.', 'tio0.', 'et1>', 'eb1>', 'snia1>', 'eniatnau8>', 'eniatn4.', 'enia1>', 'niatnio3.', 'niatg3.', 'e' . chr(233) . '1>', chr(233) . 'hcat1.', chr(233) . 'hca4.', chr(233) . 'tila5>', chr(233) . 'tici5.', chr(233) . 'tir1.', chr(233) . 'ti3>', chr(233) . 'gan1.', chr(233) . 'ga3>', chr(233) . 'tehc1.', chr(233) . 'te3>', chr(233) . 'it0.', chr(233) . '1>', 'eire4.', 'eirue5.', 'eio1.', 'eia1.', 'ei1>', 'eng1.', 'xuaessi7.', 'xuae1>', 'uaes0.', 'uae3.', 'xuave2l.', 'xuav2li>', 'xua3la>', 'ela1>', 'lart2.', 'lani2>', 'la' . chr(233) . '2>', 'siay4i.', 'siassia7.', 'siarv1*.', 'sia1>', 'tneiayo6i.', 'tneiay6i.', 'tneiassia9.', 'tneiareio7.', 'tneia5>', 'tneia4>', 'tiario4.', 'tiarim3.', 'tiaria3.', 'tiaris3.', 'tiari5.', 'tiarve6>', 'tiare5>', 'iare4>', 'are3>', 'tiay4i.', 'tia3>', 'tnay4i.', 'em' . chr(232) . 'iu5>', 'em' . chr(232) . 'i4>', 'tnaun3.', 'tnauqo3.', 'tnau4>', 'tnaf0.', 'tnat' . chr(233) . '2>', 'tna3>', 'tno3>', 'zeiy4i.', 'zey3i.', 'zeire5>', 'zeird4.', 'zeirio4.', 'ze2>', 'ssiab0.', 'ssia4.', 'ssi3.', 'tnemma6>', 'tnemesuey9i.', 'tnemesue8>', 'tnemevi7.', 'tnemessia5.', 'tnemessi8.', 'tneme5>', 'tnemia4.', 'tnem' . chr(233) . '5>', 'el2l>', 'lle3le>', 'let' . chr(244) . '0.', 'lepp0.', 'le2>', 'srei1>', 'reit3.', 'reila2.', 'rei3>', 'ert' . chr(226) . 'e5.', 'ert' . chr(226) . chr(233) . '1.', 'ert' . chr(226) . '4.', 'drai4.', 'erdro0.', 'erute5.', 'ruta0.', 'eruta1.', 'erutiov1.', 'erub3.', 'eruh3.', 'erul3.', 'er2r>', 'nn1>', 'r' . chr(232) . 'i3.', 'srev0.', 'sr1>', 'rid2>', 're2>', 'xuei4.', 'esuei5.', 'lbati3.', 'lba3>', 'rueis0.', 'ruehcn4.', 'ecirta6.', 'ruetai6.', 'rueta5.', 'rueir0.', 'rue3>', 'esseti6.', 'essere6>', 'esserd1.', 'esse4>', 'essiab1.', 'essia5.', 'essio1.', 'essi4.', 'essal4.', 'essa1>', 'ssab1.', 'essurp1.', 'essu4.', 'essi1.', 'ssor1.', 'essor2.', 'esso1>', 'ess2>', 'tio3.', 'r' . chr(232) . 's2re.', 'r' . chr(232) . '0e.', 'esn1.', 'eu1>', 'sua0.', 'su1>', 'utt1>', 'tu' . chr(231) . '3c.', 'u' . chr(231) . '2c.', 'ur1.', 'ehcn2>', 'ehcu1>', 'snorr3.', 'snoru3.', 'snorua3.', 'snorv3.', 'snorio4.', 'snori5.', 'snore5>', 'snortt4>', 'snort' . chr(238) . 'a7.', 'snort3.', 'snor4.', 'snossi6.', 'snoire6.', 'snoird5.', 'snoitai7.', 'snoita6.', 'snoits1>', 'noits0.', 'snoi4>', 'noitaci7>', 'noitai6.', 'noita5.', 'noitu4.', 'noi3>', 'snoya0.', 'snoy4i.', 'sno' . chr(231) . 'a1.', 'sno' . chr(231) . 'r1.', 'snoe4.', 'snosiar1>', 'snola1.', 'sno3>', 'sno1>', 'noll2.', 'tnennei4.', 'ennei2>', 'snei1>', 'sne' . chr(233) . '1>', 'enne' . chr(233) . '5e.', 'ne' . chr(233) . '3e.', 'neic0.', 'neiv0.', 'nei3.', 'sc1.', 'sd1.', 'sg1.', 'sni1.', 'tiu0.', 'ti2.', 'sp1>', 'sna1>', 'sue1.', 'enn2>', 'nong2.', 'noss2.', 'rioe4.', 'riot0.', 'riorc1.', 'riovec5.', 'rio3.', 'ric2.', 'ril2.', 'tnerim3.', 'tneris3>', 'tneri5.', 't' . chr(238) . 'a3.', 'riss2.', 't' . chr(238) . '2.', 't' . chr(226) . '2>', 'ario2.', 'arim1.', 'ara1.', 'aris1.', 'ari3.', 'art1>', 'ardn2.', 'arr1.', 'arua1.', 'aro1.', 'arv1.', 'aru1.', 'ar2.', 'rd1.', 'ud1.', 'ul1.', 'ini1.', 'rin2.', 'tnessiab3.', 'tnessia7.', 'tnessi6.', 'tnessni4.', 'sini2.', 'sl1.', 'iard3.', 'iario3.', 'ia2>', 'io0.', 'iule2.', 'i1>', 'sid2.', 'sic2.', 'esoi4.', 'ed1.', 'ai2>', 'a1>', 'adr1.', 'tner' . chr(232) . '5>', 'evir1.', 'evio4>', 'evi3.', 'fita4.', 'fi2>', 'enie1.', 'sare4>', 'sari4>', 'sard3.', 'sart2>', 'sa2.', 'tnessa6>', 'tnessu6>', 'tnegna3.', 'tnegi3.', 'tneg0.', 'tneru5>', 'tnemg0.', 'tnerni4.', 'tneiv1.', 'tne3>', 'une1.', 'en1>', 'nitn2.', 'ecnay5i.', 'ecnal1.', 'ecna4.', 'ec1>', 'nn1.', 'rit2>', 'rut2>', 'rud2.', 'ugn1>', 'eg1>', 'tuo0.', 'tul2>', 't' . chr(251) . '2>', 'ev1>', 'v' . chr(232) . '2ve>', 'rtt1>', 'emissi6.', 'em1.', 'ehc1.', 'c' . chr(233) . 'i2c' . chr(232) . '.', 'libi2l.', 'llie1.', 'liei4i.', 'xuev1.', 'xuey4i.', 'xueni5>', 'xuell4.', 'xuere5.', 'xue3>', 'rb' . chr(233) . '3rb' . chr(232) . '.', 'tur2.', 'rir' . chr(233) . '4re.', 'rir2.', 'c' . chr(226) . '2ca.', 'snu1.', 'rt' . chr(238) . 'a4.', 'long2.', 'vec2.', chr(231) . '1c>', 'ssilp3.', 'silp2.', 't' . chr(232) . 'hc2te.', 'n' . chr(232) . 'm2ne.', 'llepp1.', 'tan2.', 'rv' . chr(232) . '3rve.', 'rv' . chr(233) . '3rve.', 'r' . chr(232) . '2re.', 'r' . chr(233) . '2re.', 't' . chr(232) . '2te.', 't' . chr(233) . '2te.', 'epp1.', 'eya2i.', 'ya1i.', 'yo1i.', 'esu1.', 'ugi1.', 'tt1.', 'end0.' ); static::$_stemRules = $vars; return static::$_stemRules; } /** * Returns the number of the first rule from the rule number * that can be applied to the given reversed input. * returns -1 if no rule can be applied, ie the stem has been found * * @param string $reversed_input The input to check in reversed order * @param integer $rule_number The rule number to check * * @return integer Number of the first rule * * @since 3.0 */ private static function _getFirstRule($reversed_input, $rule_number) { $vars = static::getStemRules(); $nb_rules = count($vars['rules']); for ($i = $rule_number; $i < $nb_rules; $i++) { // Gets the letters from the current rule $rule = $vars['rules'][$i]; $rule = preg_replace($vars['rule_pattern'], "\\1", $rule); if (strncasecmp(utf8_decode($rule), $reversed_input, strlen(utf8_decode($rule))) == 0) { return $i; } } return -1; } /** * Check the acceptability of a stem for French language * * @param string $reversed_stem The stem to check in reverse form * * @return boolean True if stem is acceptable * * @since 3.0 */ private static function _check($reversed_stem) { $vars = static::getStemRules(); if (preg_match('/[' . $vars['vowels'] . ']$/', utf8_encode($reversed_stem))) { // If the form starts with a vowel then at least two letters must remain after stemming (e.g.: "etaient" --> "et") return (strlen($reversed_stem) > 2); } else { // If the reversed stem starts with a consonant then at least two letters must remain after stemming if (strlen($reversed_stem) <= 2) { return false; } // And at least one of these must be a vowel or "y" return (preg_match('/[' . $vars['vowels'] . ']/', utf8_encode($reversed_stem))); } } /** * Paice/Husk stemmer which returns a stem for the given $input * * @param string $input The word for which we want the stem in UTF-8 * * @return string The stem * * @since 3.0 */ private static function _getStem($input) { $vars = static::getStemRules(); $intact = true; $reversed_input = strrev(utf8_decode($input)); $rule_number = 0; // This loop goes through the rules' array until it finds an ending one (ending by '.') or the last one ('end0.') while (true) { $rule_number = static::_getFirstRule($reversed_input, $rule_number); if ($rule_number == -1) { // No other rule can be applied => the stem has been found break; } $rule = $vars['rules'][$rule_number]; preg_match($vars['rule_pattern'], $rule, $matches); if (($matches[2] != '*') || ($intact)) { $reversed_stem = utf8_decode($matches[4]) . substr($reversed_input, $matches[3], strlen($reversed_input) - $matches[3]); if (self::_check($reversed_stem)) { $reversed_input = $reversed_stem; if ($matches[5] == '.') { break; } } else { // Go to another rule $rule_number++; } } else { // Go to another rule $rule_number++; } } return utf8_encode(strrev($reversed_input)); } } components/com_finder/helpers/indexer/stemmer/porter_en.php000066600000023604150771655450020350 0ustar00cache[$lang][$token])) { // Stem the token. $result = $token; $result = self::_step1ab($result); $result = self::_step1c($result); $result = self::_step2($result); $result = self::_step3($result); $result = self::_step4($result); $result = self::_step5($result); // Add the token to the cache. $this->cache[$lang][$token] = $result; } return $this->cache[$lang][$token]; } /** * Step 1 * * @param string $word The token to stem. * * @return string * * @since 2.5 */ private static function _step1ab($word) { // Part a if (substr($word, -1) == 's') { self::_replace($word, 'sses', 'ss') or self::_replace($word, 'ies', 'i') or self::_replace($word, 'ss', 'ss') or self::_replace($word, 's', ''); } // Part b if (substr($word, -2, 1) != 'e' or !self::_replace($word, 'eed', 'ee', 0)) { // First rule $v = self::$_regex_vowel; // Words ending with ing and ed // Note use of && and OR, for precedence reasons if (preg_match("#$v+#", substr($word, 0, -3)) && self::_replace($word, 'ing', '') or preg_match("#$v+#", substr($word, 0, -2)) && self::_replace($word, 'ed', '')) { // If one of above two test successful if (!self::_replace($word, 'at', 'ate') and !self::_replace($word, 'bl', 'ble') and !self::_replace($word, 'iz', 'ize')) { // Double consonant ending if (self::_doubleConsonant($word) and substr($word, -2) != 'll' and substr($word, -2) != 'ss' and substr($word, -2) != 'zz') { $word = substr($word, 0, -1); } elseif (self::_m($word) == 1 and self::_cvc($word)) { $word .= 'e'; } } } } return $word; } /** * Step 1c * * @param string $word The token to stem. * * @return string * * @since 2.5 */ private static function _step1c($word) { $v = self::$_regex_vowel; if (substr($word, -1) == 'y' && preg_match("#$v+#", substr($word, 0, -1))) { self::_replace($word, 'y', 'i'); } return $word; } /** * Step 2 * * @param string $word The token to stem. * * @return string * * @since 2.5 */ private static function _step2($word) { switch (substr($word, -2, 1)) { case 'a': self::_replace($word, 'ational', 'ate', 0) or self::_replace($word, 'tional', 'tion', 0); break; case 'c': self::_replace($word, 'enci', 'ence', 0) or self::_replace($word, 'anci', 'ance', 0); break; case 'e': self::_replace($word, 'izer', 'ize', 0); break; case 'g': self::_replace($word, 'logi', 'log', 0); break; case 'l': self::_replace($word, 'entli', 'ent', 0) or self::_replace($word, 'ousli', 'ous', 0) or self::_replace($word, 'alli', 'al', 0) or self::_replace($word, 'bli', 'ble', 0) or self::_replace($word, 'eli', 'e', 0); break; case 'o': self::_replace($word, 'ization', 'ize', 0) or self::_replace($word, 'ation', 'ate', 0) or self::_replace($word, 'ator', 'ate', 0); break; case 's': self::_replace($word, 'iveness', 'ive', 0) or self::_replace($word, 'fulness', 'ful', 0) or self::_replace($word, 'ousness', 'ous', 0) or self::_replace($word, 'alism', 'al', 0); break; case 't': self::_replace($word, 'biliti', 'ble', 0) or self::_replace($word, 'aliti', 'al', 0) or self::_replace($word, 'iviti', 'ive', 0); break; } return $word; } /** * Step 3 * * @param string $word The token to stem. * * @return string * * @since 2.5 */ private static function _step3($word) { switch (substr($word, -2, 1)) { case 'a': self::_replace($word, 'ical', 'ic', 0); break; case 's': self::_replace($word, 'ness', '', 0); break; case 't': self::_replace($word, 'icate', 'ic', 0) or self::_replace($word, 'iciti', 'ic', 0); break; case 'u': self::_replace($word, 'ful', '', 0); break; case 'v': self::_replace($word, 'ative', '', 0); break; case 'z': self::_replace($word, 'alize', 'al', 0); break; } return $word; } /** * Step 4 * * @param string $word The token to stem. * * @return string * * @since 2.5 */ private static function _step4($word) { switch (substr($word, -2, 1)) { case 'a': self::_replace($word, 'al', '', 1); break; case 'c': self::_replace($word, 'ance', '', 1) or self::_replace($word, 'ence', '', 1); break; case 'e': self::_replace($word, 'er', '', 1); break; case 'i': self::_replace($word, 'ic', '', 1); break; case 'l': self::_replace($word, 'able', '', 1) or self::_replace($word, 'ible', '', 1); break; case 'n': self::_replace($word, 'ant', '', 1) or self::_replace($word, 'ement', '', 1) or self::_replace($word, 'ment', '', 1) or self::_replace($word, 'ent', '', 1); break; case 'o': if (substr($word, -4) == 'tion' or substr($word, -4) == 'sion') { self::_replace($word, 'ion', '', 1); } else { self::_replace($word, 'ou', '', 1); } break; case 's': self::_replace($word, 'ism', '', 1); break; case 't': self::_replace($word, 'ate', '', 1) or self::_replace($word, 'iti', '', 1); break; case 'u': self::_replace($word, 'ous', '', 1); break; case 'v': self::_replace($word, 'ive', '', 1); break; case 'z': self::_replace($word, 'ize', '', 1); break; } return $word; } /** * Step 5 * * @param string $word The token to stem. * * @return string * * @since 2.5 */ private static function _step5($word) { // Part a if (substr($word, -1) == 'e') { if (self::_m(substr($word, 0, -1)) > 1) { self::_replace($word, 'e', ''); } elseif (self::_m(substr($word, 0, -1)) == 1) { if (!self::_cvc(substr($word, 0, -1))) { self::_replace($word, 'e', ''); } } } // Part b if (self::_m($word) > 1 and self::_doubleConsonant($word) and substr($word, -1) == 'l') { $word = substr($word, 0, -1); } return $word; } /** * Replaces the first string with the second, at the end of the string. If third * arg is given, then the preceding string must match that m count at least. * * @param string &$str String to check * @param string $check Ending to check for * @param string $repl Replacement string * @param integer $m Optional minimum number of m() to meet * * @return boolean Whether the $check string was at the end * of the $str string. True does not necessarily mean * that it was replaced. * * @since 2.5 */ private static function _replace(&$str, $check, $repl, $m = null) { $len = 0 - strlen($check); if (substr($str, $len) == $check) { $substr = substr($str, 0, $len); if (is_null($m) or self::_m($substr) > $m) { $str = $substr . $repl; } return true; } return false; } /** * m() measures the number of consonant sequences in $str. if c is * a consonant sequence and v a vowel sequence, and <..> indicates arbitrary * presence, * * gives 0 * vc gives 1 * vcvc gives 2 * vcvcvc gives 3 * * @param string $str The string to return the m count for * * @return integer The m count * * @since 2.5 */ private static function _m($str) { $c = self::$_regex_consonant; $v = self::$_regex_vowel; $str = preg_replace("#^$c+#", '', $str); $str = preg_replace("#$v+$#", '', $str); preg_match_all("#($v+$c+)#", $str, $matches); return count($matches[1]); } /** * Returns true/false as to whether the given string contains two * of the same consonant next to each other at the end of the string. * * @param string $str String to check * * @return boolean Result * * @since 2.5 */ private static function _doubleConsonant($str) { $c = self::$_regex_consonant; return preg_match("#$c{2}$#", $str, $matches) and $matches[0]{0} == $matches[0]{1}; } /** * Checks for ending CVC sequence where second C is not W, X or Y * * @param string $str String to check * * @return boolean Result * * @since 2.5 */ private static function _cvc($str) { $c = self::$_regex_consonant; $v = self::$_regex_vowel; return preg_match("#($c$v$c)$#", $str, $matches) and strlen($matches[1]) == 3 and $matches[1]{2} != 'w' and $matches[1]{2} != 'x' and $matches[1]{2} != 'y'; } } components/com_finder/helpers/indexer/stemmer/snowball.php000066600000005434150771655450020175 0ustar00sef) ? $languages[0]->sef : '*'; $lang = $defaultLang; } // Stem the token if it is not in the cache. if (!isset($this->cache[$lang][$token])) { // Get the stem function from the language string. switch ($lang) { // Danish stemmer. case 'da': $function = 'stem_danish'; break; // German stemmer. case 'de': $function = 'stem_german'; break; // English stemmer. default: case 'en': $function = 'stem_english'; break; // Spanish stemmer. case 'es': $function = 'stem_spanish'; break; // Finnish stemmer. case 'fi': $function = 'stem_finnish'; break; // French stemmer. case 'fr': $function = 'stem_french'; break; // Hungarian stemmer. case 'hu': $function = 'stem_hungarian'; break; // Italian stemmer. case 'it': $function = 'stem_italian'; break; // Norwegian stemmer. case 'nb': $function = 'stem_norwegian'; break; // Dutch stemmer. case 'nl': $function = 'stem_dutch'; break; // Portuguese stemmer. case 'pt': $function = 'stem_portuguese'; break; // Romanian stemmer. case 'ro': $function = 'stem_romanian'; break; // Russian stemmer. case 'ru': $function = 'stem_russian_unicode'; break; // Swedish stemmer. case 'sv': $function = 'stem_swedish'; break; // Turkish stemmer. case 'tr': $function = 'stem_turkish_unicode'; break; } // Stem the word if the stemmer method exists. $this->cache[$lang][$token] = function_exists($function) ? $function($token) : $token; } return $this->cache[$lang][$token]; } } components/com_finder/helpers/indexer/adapter.php000066600000053116150771655450016320 0ustar00db = JFactory::getDbo(); // Call the parent constructor. parent::__construct($subject, $config); // Get the type id. $this->type_id = $this->getTypeId(); // Add the content type if it doesn't exist and is set. if (empty($this->type_id) && !empty($this->type_title)) { $this->type_id = FinderIndexerHelper::addContentType($this->type_title, $this->mime); } // Check for a layout override. if ($this->params->get('layout')) { $this->layout = $this->params->get('layout'); } // Get the indexer object $this->indexer = FinderIndexer::getInstance(); } /** * Method to get the adapter state and push it into the indexer. * * @return boolean True on success. * * @since 2.5 * @throws Exception on error. */ public function onStartIndex() { // Get the indexer state. $iState = FinderIndexer::getState(); // Get the number of content items. $total = (int) $this->getContentCount(); // Add the content count to the total number of items. $iState->totalItems += $total; // Populate the indexer state information for the adapter. $iState->pluginState[$this->context]['total'] = $total; $iState->pluginState[$this->context]['offset'] = 0; // Set the indexer state. FinderIndexer::setState($iState); } /** * Method to prepare for the indexer to be run. This method will often * be used to include dependencies and things of that nature. * * @return boolean True on success. * * @since 2.5 * @throws Exception on error. */ public function onBeforeIndex() { // Get the indexer and adapter state. $iState = FinderIndexer::getState(); $aState = $iState->pluginState[$this->context]; // Check the progress of the indexer and the adapter. if ($iState->batchOffset == $iState->batchSize || $aState['offset'] == $aState['total']) { return true; } // Run the setup method. return $this->setup(); } /** * Method to index a batch of content items. This method can be called by * the indexer many times throughout the indexing process depending on how * much content is available for indexing. It is important to track the * progress correctly so we can display it to the user. * * @return boolean True on success. * * @since 2.5 * @throws Exception on error. */ public function onBuildIndex() { // Get the indexer and adapter state. $iState = FinderIndexer::getState(); $aState = $iState->pluginState[$this->context]; // Check the progress of the indexer and the adapter. if ($iState->batchOffset == $iState->batchSize || $aState['offset'] == $aState['total']) { return true; } // Get the batch offset and size. $offset = (int) $aState['offset']; $limit = (int) ($iState->batchSize - $iState->batchOffset); // Get the content items to index. $items = $this->getItems($offset, $limit); // Iterate through the items and index them. for ($i = 0, $n = count($items); $i < $n; $i++) { // Index the item. $this->index($items[$i]); // Adjust the offsets. $offset++; $iState->batchOffset++; $iState->totalItems--; } // Update the indexer state. $aState['offset'] = $offset; $iState->pluginState[$this->context] = $aState; FinderIndexer::setState($iState); return true; } /** * Method to change the value of a content item's property in the links * table. This is used to synchronize published and access states that * are changed when not editing an item directly. * * @param string $id The ID of the item to change. * @param string $property The property that is being changed. * @param integer $value The new value of that property. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ protected function change($id, $property, $value) { // Check for a property we know how to handle. if ($property !== 'state' && $property !== 'access') { return true; } // Get the url for the content id. $item = $this->db->quote($this->getUrl($id, $this->extension, $this->layout)); // Update the content items. $query = $this->db->getQuery(true) ->update($this->db->quoteName('#__finder_links')) ->set($this->db->quoteName($property) . ' = ' . (int) $value) ->where($this->db->quoteName('url') . ' = ' . $item); $this->db->setQuery($query); $this->db->execute(); return true; } /** * Method to index an item. * * @param FinderIndexerResult $item The item to index as a FinderIndexerResult object. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ abstract protected function index(FinderIndexerResult $item); /** * Method to reindex an item. * * @param integer $id The ID of the item to reindex. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ protected function reindex($id) { // Run the setup method. $this->setup(); // Remove the old item. $this->remove($id); // Get the item. $item = $this->getItem($id); // Index the item. $this->index($item); } /** * Method to remove an item from the index. * * @param string $id The ID of the item to remove. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ protected function remove($id) { // Get the item's URL $url = $this->db->quote($this->getUrl($id, $this->extension, $this->layout)); // Get the link ids for the content items. $query = $this->db->getQuery(true) ->select($this->db->quoteName('link_id')) ->from($this->db->quoteName('#__finder_links')) ->where($this->db->quoteName('url') . ' = ' . $url); $this->db->setQuery($query); $items = $this->db->loadColumn(); // Check the items. if (empty($items)) { return true; } // Remove the items. foreach ($items as $item) { $this->indexer->remove($item); } return true; } /** * Method to setup the adapter before indexing. * * @return boolean True on success, false on failure. * * @since 2.5 * @throws Exception on database error. */ abstract protected function setup(); /** * Method to update index data on category access level changes * * @param JTable $row A JTable object * * @return void * * @since 2.5 */ protected function categoryAccessChange($row) { $query = clone($this->getStateQuery()); $query->where('c.id = ' . (int) $row->id); // Get the access level. $this->db->setQuery($query); $items = $this->db->loadObjectList(); // Adjust the access level for each item within the category. foreach ($items as $item) { // Set the access level. $temp = max($item->access, $row->access); // Update the item. $this->change((int) $item->id, 'access', $temp); // Reindex the item $this->reindex($row->id); } } /** * Method to update index data on category access level changes * * @param array $pks A list of primary key ids of the content that has changed state. * @param integer $value The value of the state that the content has been changed to. * * @return void * * @since 2.5 */ protected function categoryStateChange($pks, $value) { /* * The item's published state is tied to the category * published state so we need to look up all published states * before we change anything. */ foreach ($pks as $pk) { $query = clone($this->getStateQuery()); $query->where('c.id = ' . (int) $pk); // Get the published states. $this->db->setQuery($query); $items = $this->db->loadObjectList(); // Adjust the state for each item within the category. foreach ($items as $item) { // Translate the state. $temp = $this->translateState($item->state, $value); // Update the item. $this->change($item->id, 'state', $temp); // Reindex the item $this->reindex($item->id); } } } /** * Method to check the existing access level for categories * * @param JTable $row A JTable object * * @return void * * @since 2.5 */ protected function checkCategoryAccess($row) { $query = $this->db->getQuery(true) ->select($this->db->quoteName('access')) ->from($this->db->quoteName('#__categories')) ->where($this->db->quoteName('id') . ' = ' . (int) $row->id); $this->db->setQuery($query); // Store the access level to determine if it changes $this->old_cataccess = $this->db->loadResult(); } /** * Method to check the existing access level for items * * @param JTable $row A JTable object * * @return void * * @since 2.5 */ protected function checkItemAccess($row) { $query = $this->db->getQuery(true) ->select($this->db->quoteName('access')) ->from($this->db->quoteName($this->table)) ->where($this->db->quoteName('id') . ' = ' . (int) $row->id); $this->db->setQuery($query); // Store the access level to determine if it changes $this->old_access = $this->db->loadResult(); } /** * Method to get the number of content items available to index. * * @return integer The number of content items available to index. * * @since 2.5 * @throws Exception on database error. */ protected function getContentCount() { $return = 0; // Get the list query. $query = $this->getListQuery(); // Check if the query is valid. if (empty($query)) { return $return; } // Tweak the SQL query to make the total lookup faster. if ($query instanceof JDatabaseQuery) { $query = clone($query); $query->clear('select') ->select('COUNT(*)') ->clear('order'); } // Get the total number of content items to index. $this->db->setQuery($query); $return = (int) $this->db->loadResult(); return $return; } /** * Method to get a content item to index. * * @param integer $id The id of the content item. * * @return FinderIndexerResult A FinderIndexerResult object. * * @since 2.5 * @throws Exception on database error. */ protected function getItem($id) { // Get the list query and add the extra WHERE clause. $query = $this->getListQuery(); $query->where('a.id = ' . (int) $id); // Get the item to index. $this->db->setQuery($query); $row = $this->db->loadAssoc(); // Convert the item to a result object. $item = JArrayHelper::toObject($row, 'FinderIndexerResult'); // Set the item type. $item->type_id = $this->type_id; // Set the item layout. $item->layout = $this->layout; return $item; } /** * Method to get a list of content items to index. * * @param integer $offset The list offset. * @param integer $limit The list limit. * @param JDatabaseQuery $query A JDatabaseQuery object. [optional] * * @return array An array of FinderIndexerResult objects. * * @since 2.5 * @throws Exception on database error. */ protected function getItems($offset, $limit, $query = null) { $items = array(); // Get the content items to index. $this->db->setQuery($this->getListQuery($query), $offset, $limit); $rows = $this->db->loadAssocList(); // Convert the items to result objects. foreach ($rows as $row) { // Convert the item to a result object. $item = JArrayHelper::toObject($row, 'FinderIndexerResult'); // Set the item type. $item->type_id = $this->type_id; // Set the mime type. $item->mime = $this->mime; // Set the item layout. $item->layout = $this->layout; // Set the extension if present if (isset($row->extension)) { $item->extension = $row->extension; } // Add the item to the stack. $items[] = $item; } return $items; } /** * Method to get the SQL query used to retrieve the list of content items. * * @param mixed $query A JDatabaseQuery object. [optional] * * @return JDatabaseQuery A database object. * * @since 2.5 */ protected function getListQuery($query = null) { // Check if we can use the supplied SQL query. $query = $query instanceof JDatabaseQuery ? $query : $this->db->getQuery(true); return $query; } /** * Method to get the plugin type * * @param integer $id The plugin ID * * @return string The plugin type * * @since 2.5 */ protected function getPluginType($id) { // Prepare the query $query = $this->db->getQuery(true) ->select($this->db->quoteName('element')) ->from($this->db->quoteName('#__extensions')) ->where($this->db->quoteName('extension_id') . ' = ' . (int) $id); $this->db->setQuery($query); $type = $this->db->loadResult(); return $type; } /** * Method to get a SQL query to load the published and access states for * an article and category. * * @return JDatabaseQuery A database object. * * @since 2.5 */ protected function getStateQuery() { $query = $this->db->getQuery(true); // Item ID $query->select('a.id'); // Item and category published state $query->select('a.' . $this->state_field . ' AS state, c.published AS cat_state'); // Item and category access levels $query->select('a.access, c.access AS cat_access') ->from($this->table . ' AS a') ->join('LEFT', '#__categories AS c ON c.id = a.catid'); return $query; } /** * Method to get the query clause for getting items to update by time. * * @param string $time The modified timestamp. * * @return JDatabaseQuery A database object. * * @since 2.5 */ protected function getUpdateQueryByTime($time) { // Build an SQL query based on the modified time. $query = $this->db->getQuery(true) ->where('a.modified >= ' . $this->db->quote($time)); return $query; } /** * Method to get the query clause for getting items to update by id. * * @param array $ids The ids to load. * * @return JDatabaseQuery A database object. * * @since 2.5 */ protected function getUpdateQueryByIds($ids) { // Build an SQL query based on the item ids. $query = $this->db->getQuery(true) ->where('a.id IN(' . implode(',', $ids) . ')'); return $query; } /** * Method to get the type id for the adapter content. * * @return integer The numeric type id for the content. * * @since 2.5 * @throws Exception on database error. */ protected function getTypeId() { // Get the type id from the database. $query = $this->db->getQuery(true) ->select($this->db->quoteName('id')) ->from($this->db->quoteName('#__finder_types')) ->where($this->db->quoteName('title') . ' = ' . $this->db->quote($this->type_title)); $this->db->setQuery($query); $result = (int) $this->db->loadResult(); return $result; } /** * Method to get the URL for the item. The URL is how we look up the link * in the Finder index. * * @param integer $id The id of the item. * @param string $extension The extension the category is in. * @param string $view The view for the URL. * * @return string The URL of the item. * * @since 2.5 */ protected function getURL($id, $extension, $view) { return 'index.php?option=' . $extension . '&view=' . $view . '&id=' . $id; } /** * Method to get the page title of any menu item that is linked to the * content item, if it exists and is set. * * @param string $url The url of the item. * * @return mixed The title on success, null if not found. * * @since 2.5 * @throws Exception on database error. */ protected function getItemMenuTitle($url) { $return = null; // Set variables $user = JFactory::getUser(); $groups = implode(',', $user->getAuthorisedViewLevels()); // Build a query to get the menu params. $query = $this->db->getQuery(true) ->select($this->db->quoteName('params')) ->from($this->db->quoteName('#__menu')) ->where($this->db->quoteName('link') . ' = ' . $this->db->quote($url)) ->where($this->db->quoteName('published') . ' = 1') ->where($this->db->quoteName('access') . ' IN (' . $groups . ')'); // Get the menu params from the database. $this->db->setQuery($query); $params = $this->db->loadResult(); // Check the results. if (empty($params)) { return $return; } // Instantiate the params. $params = json_decode($params); // Get the page title if it is set. if ($params->page_title) { $return = $params->page_title; } return $return; } /** * Method to update index data on access level changes * * @param JTable $row A JTable object * * @return void * * @since 2.5 */ protected function itemAccessChange($row) { $query = clone($this->getStateQuery()); $query->where('a.id = ' . (int) $row->id); // Get the access level. $this->db->setQuery($query); $item = $this->db->loadObject(); // Set the access level. $temp = max($row->access, $item->cat_access); // Update the item. $this->change((int) $row->id, 'access', $temp); } /** * Method to update index data on published state changes * * @param array $pks A list of primary key ids of the content that has changed state. * @param integer $value The value of the state that the content has been changed to. * * @return void * * @since 2.5 */ protected function itemStateChange($pks, $value) { /* * The item's published state is tied to the category * published state so we need to look up all published states * before we change anything. */ foreach ($pks as $pk) { $query = clone($this->getStateQuery()); $query->where('a.id = ' . (int) $pk); // Get the published states. $this->db->setQuery($query); $item = $this->db->loadObject(); // Translate the state. $temp = $this->translateState($value, $item->cat_state); // Update the item. $this->change($pk, 'state', $temp); // Reindex the item $this->reindex($pk); } } /** * Method to update index data when a plugin is disabled * * @param array $pks A list of primary key ids of the content that has changed state. * * @return void * * @since 2.5 */ protected function pluginDisable($pks) { // Since multiple plugins may be disabled at a time, we need to check first // that we're handling the appropriate one for the context foreach ($pks as $pk) { if ($this->getPluginType($pk) == strtolower($this->context)) { // Get all of the items to unindex them $query = clone($this->getStateQuery()); $this->db->setQuery($query); $items = $this->db->loadColumn(); // Remove each item foreach ($items as $item) { $this->remove($item); } } } } /** * Method to translate the native content states into states that the * indexer can use. * * @param integer $item The item state. * @param integer $category The category state. [optional] * * @return integer The translated indexer state. * * @since 2.5 */ protected function translateState($item, $category = null) { // If category is present, factor in its states as well if ($category !== null) { if ($category == 0) { $item = 0; } } // Translate the state switch ($item) { // Published and archived items only should return a published state case 1; case 2: return 1; // All other states should return a unpublished state default: case 0: return 0; } } } components/com_finder/helpers/indexer/result.php000066600000021146150771655450016214 0ustar00 array('title', 'subtitle', 'id'), FinderIndexer::TEXT_CONTEXT => array('summary', 'body'), FinderIndexer::META_CONTEXT => array('meta', 'list_price', 'sale_price'), FinderIndexer::PATH_CONTEXT => array('path', 'alias'), FinderIndexer::MISC_CONTEXT => array('comments') ); /** * The indexer will use this data to create taxonomy mapping entries for * the item so that it can be filtered by type, label, category, * or whatever. * * @var array * @since 2.5 */ protected $taxonomy = array(); /** * The content URL. * * @var string * @since 2.5 */ public $url; /** * The content route. * * @var string * @since 2.5 */ public $route; /** * The content title. * * @var string * @since 2.5 */ public $title; /** * The content description. * * @var string * @since 2.5 */ public $description; /** * The published state of the result. * * @var integer * @since 2.5 */ public $published; /** * The content published state. * * @var integer * @since 2.5 */ public $state; /** * The content access level. * * @var integer * @since 2.5 */ public $access; /** * The content language. * * @var string * @since 2.5 */ public $language = '*'; /** * The publishing start date. * * @var string * @since 2.5 */ public $publish_start_date; /** * The publishing end date. * * @var string * @since 2.5 */ public $publish_end_date; /** * The generic start date. * * @var string * @since 2.5 */ public $start_date; /** * The generic end date. * * @var string * @since 2.5 */ public $end_date; /** * The item list price. * * @var mixed * @since 2.5 */ public $list_price; /** * The item sale price. * * @var mixed * @since 2.5 */ public $sale_price; /** * The content type id. This is set by the adapter. * * @var integer * @since 2.5 */ public $type_id; /** * The default language for content. * * @var string * @since 3.0.2 */ public $defaultLanguage; /** * Constructor * * @since 3.0.3 */ public function __construct() { $this->defaultLanguage = JComponentHelper::getParams('com_languages')->get('site', 'en-GB'); } /** * The magic set method is used to push additional values into the elements * array in order to preserve the cleanliness of the object. * * @param string $name The name of the element. * @param mixed $value The value of the element. * * @return void * * @since 2.5 */ public function __set($name, $value) { $this->elements[$name] = $value; } /** * The magic get method is used to retrieve additional element values * from the elements array. * * @param string $name The name of the element. * * @return mixed The value of the element if set, null otherwise. * * @since 2.5 */ public function __get($name) { // Get the element value if set. if (array_key_exists($name, $this->elements)) { return $this->elements[$name]; } else { return null; } } /** * The magic isset method is used to check the state of additional element * values in the elements array. * * @param string $name The name of the element. * * @return boolean True if set, false otherwise. * * @since 2.5 */ public function __isset($name) { return isset($this->elements[$name]); } /** * The magic unset method is used to unset additional element values in the * elements array. * * @param string $name The name of the element. * * @return void * * @since 2.5 */ public function __unset($name) { unset($this->elements[$name]); } /** * Method to retrieve additional element values from the elements array. * * @param string $name The name of the element. * * @return mixed The value of the element if set, null otherwise. * * @since 2.5 */ public function getElement($name) { // Get the element value if set. if (array_key_exists($name, $this->elements)) { return $this->elements[$name]; } else { return null; } } /** * Method to set additional element values in the elements array. * * @param string $name The name of the element. * @param mixed $value The value of the element. * * @return void * * @since 2.5 */ public function setElement($name, $value) { $this->elements[$name] = $value; } /** * Method to get all processing instructions. * * @return array An array of processing instructions. * * @since 2.5 */ public function getInstructions() { return $this->instructions; } /** * Method to add a processing instruction for an item property. * * @param string $group The group to associate the property with. * @param string $property The property to process. * * @return void * * @since 2.5 */ public function addInstruction($group, $property) { // Check if the group exists. We can't add instructions for unknown groups. if (array_key_exists($group, $this->instructions)) { // Check if the property exists in the group. if (!in_array($property, $this->instructions[$group])) { // Add the property to the group. $this->instructions[$group][] = $property; } } } /** * Method to remove a processing instruction for an item property. * * @param string $group The group to associate the property with. * @param string $property The property to process. * * @return void * * @since 2.5 */ public function removeInstruction($group, $property) { // Check if the group exists. We can't remove instructions for unknown groups. if (array_key_exists($group, $this->instructions)) { // Search for the property in the group. $key = array_search($property, $this->instructions[$group]); // If the property was found, remove it. if ($key !== false) { unset($this->instructions[$group][$key]); } } } /** * Method to get the taxonomy maps for an item. * * @param string $branch The taxonomy branch to get. [optional] * * @return array An array of taxonomy maps. * * @since 2.5 */ public function getTaxonomy($branch = null) { // Get the taxonomy branch if available. if ($branch !== null && isset($this->taxonomy[$branch])) { // Filter the input. $branch = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,]+#mui', ' ', $branch); return $this->taxonomy[$branch]; } return $this->taxonomy; } /** * Method to add a taxonomy map for an item. * * @param string $branch The title of the taxonomy branch to add the node to. * @param string $title The title of the taxonomy node. * @param integer $state The published state of the taxonomy node. [optional] * @param integer $access The access level of the taxonomy node. [optional] * * @return void * * @since 2.5 */ public function addTaxonomy($branch, $title, $state = 1, $access = 1) { // Filter the input. $branch = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,]+#mui', ' ', $branch); // Create the taxonomy node. $node = new JObject; $node->title = $title; $node->state = (int) $state; $node->access = (int) $access; // Add the node to the taxonomy branch. $this->taxonomy[$branch][$node->title] = $node; } /** * Method to set the item language * * @return void * * @since 3.0 */ public function setLanguage() { if ($this->language == '*' || $this->language == '') { $this->language = $this->defaultLanguage; } } } components/com_finder/helpers/indexer/driver/sqlsrv.php000066600000050724150771655450017527 0ustar00mark('beforeIndexing') : null; $db = JFactory::getDbo(); $nd = $db->getNullDate(); // Check if the item is in the database. $query = $db->getQuery(true) ->select($db->quoteName('link_id') . ', ' . $db->quoteName('md5sum')) ->from($db->quoteName('#__finder_links')) ->where($db->quoteName('url') . ' = ' . $db->quote($item->url)); // Load the item from the database. $db->setQuery($query); $link = $db->loadObject(); // Get the indexer state. $state = static::getState(); // Get the signatures of the item. $curSig = static::getSignature($item); $oldSig = isset($link->md5sum) ? $link->md5sum : null; // Get the other item information. $linkId = empty($link->link_id) ? null : $link->link_id; $isNew = empty($link->link_id) ? true : false; // Check the signatures. If they match, the item is up to date. if (!$isNew && $curSig == $oldSig) { return $linkId; } /* * If the link already exists, flush all the term maps for the item. * Maps are stored in 16 tables so we need to iterate through and flush * each table one at a time. */ if (!$isNew) { for ($i = 0; $i <= 15; $i++) { // Flush the maps for the link. $query->clear() ->delete($db->quoteName('#__finder_links_terms' . dechex($i))) ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); $db->setQuery($query); $db->execute(); } // Remove the taxonomy maps. FinderIndexerTaxonomy::removeMaps($linkId); } // Mark afterUnmapping in the profiler. static::$profiler ? static::$profiler->mark('afterUnmapping') : null; // Perform cleanup on the item data. $item->publish_start_date = (int) $item->publish_start_date != 0 ? $item->publish_start_date : $nd; $item->publish_end_date = (int) $item->publish_end_date != 0 ? $item->publish_end_date : $nd; $item->start_date = (int) $item->start_date != 0 ? $item->start_date : $nd; $item->end_date = (int) $item->end_date != 0 ? $item->end_date : $nd; // Prepare the item description. $item->description = FinderIndexerHelper::parse($item->summary); /* * Now, we need to enter the item into the links table. If the item * already exists in the database, we need to use an UPDATE query. * Otherwise, we need to use an INSERT to get the link id back. */ if ($isNew) { $columnsArray = array( $db->quoteName('url'), $db->quoteName('route'), $db->quoteName('title'), $db->quoteName('description'), $db->quoteName('indexdate'), $db->quoteName('published'), $db->quoteName('state'), $db->quoteName('access'), $db->quoteName('language'), $db->quoteName('type_id'), $db->quoteName('object'), $db->quoteName('publish_start_date'), $db->quoteName('publish_end_date'), $db->quoteName('start_date'), $db->quoteName('end_date'), $db->quoteName('list_price'), $db->quoteName('sale_price') ); // Insert the link. $query->clear() ->insert($db->quoteName('#__finder_links')) ->columns($columnsArray) ->values( $db->quote($item->url) . ', ' . $db->quote($item->route) . ', ' . $db->quote($item->title) . ', ' . $db->quote($item->description) . ', ' . $query->currentTimestamp() . ', ' . '1, ' . (int) $item->state . ', ' . (int) $item->access . ', ' . $db->quote($item->language) . ', ' . (int) $item->type_id . ', ' . $db->quote(serialize($item)) . ', ' . $db->quote($item->publish_start_date) . ', ' . $db->quote($item->publish_end_date) . ', ' . $db->quote($item->start_date) . ', ' . $db->quote($item->end_date) . ', ' . (double) ($item->list_price ? $item->list_price : 0) . ', ' . (double) ($item->sale_price ? $item->sale_price : 0) ); $db->setQuery($query); $db->execute(); // Get the link id. $linkId = (int) $db->insertid(); } else { // Update the link. $query->clear() ->update($db->quoteName('#__finder_links')) ->set($db->quoteName('route') . ' = ' . $db->quote($item->route)) ->set($db->quoteName('title') . ' = ' . $db->quote($item->title)) ->set($db->quoteName('description') . ' = ' . $db->quote($item->description)) ->set($db->quoteName('indexdate') . ' = ' . $query->currentTimestamp()) ->set($db->quoteName('state') . ' = ' . (int) $item->state) ->set($db->quoteName('access') . ' = ' . (int) $item->access) ->set($db->quoteName('language') . ' = ' . $db->quote($item->language)) ->set($db->quoteName('type_id') . ' = ' . (int) $item->type_id) ->set($db->quoteName('object') . ' = ' . $db->quote(serialize($item))) ->set($db->quoteName('publish_start_date') . ' = ' . $db->quote($item->publish_start_date)) ->set($db->quoteName('publish_end_date') . ' = ' . $db->quote($item->publish_end_date)) ->set($db->quoteName('start_date') . ' = ' . $db->quote($item->start_date)) ->set($db->quoteName('end_date') . ' = ' . $db->quote($item->end_date)) ->set($db->quoteName('list_price') . ' = ' . (double) ($item->list_price ? $item->list_price : 0)) ->set($db->quoteName('sale_price') . ' = ' . (double) ($item->sale_price ? $item->sale_price : 0)) ->where('link_id = ' . (int) $linkId); $db->setQuery($query); $db->execute(); } // Set up the variables we will need during processing. $count = 0; // Mark afterLinking in the profiler. static::$profiler ? static::$profiler->mark('afterLinking') : null; // Truncate the tokens tables. $db->truncateTable('#__finder_tokens'); // Truncate the tokens aggregate table. $db->truncateTable('#__finder_tokens_aggregate'); /* * Process the item's content. The items can customize their * processing instructions to define extra properties to process * or rearrange how properties are weighted. */ foreach ($item->getInstructions() as $group => $properties) { // Iterate through the properties of the group. foreach ($properties as $property) { // Check if the property exists in the item. if (empty($item->$property)) { continue; } // Tokenize the property. if (is_array($item->$property)) { // Tokenize an array of content and add it to the database. foreach ($item->$property as $ip) { /* * If the group is path, we need to a few extra processing * steps to strip the extension and convert slashes and dashes * to spaces. */ if ($group === static::PATH_CONTEXT) { $ip = JFile::stripExt($ip); $ip = str_replace('/', ' ', $ip); $ip = str_replace('-', ' ', $ip); } // Tokenize a string of content and add it to the database. $count += $this->tokenizeToDB($ip, $group, $item->language, $format); // Check if we're approaching the memory limit of the token table. if ($count > static::$state->options->get('memory_table_limit', 30000)) { $this->toggleTables(false); } } } else { /* * If the group is path, we need to a few extra processing * steps to strip the extension and convert slashes and dashes * to spaces. */ if ($group === static::PATH_CONTEXT) { $item->$property = JFile::stripExt($item->$property); $item->$property = str_replace('/', ' ', $item->$property); $item->$property = str_replace('-', ' ', $item->$property); } // Tokenize a string of content and add it to the database. $count += $this->tokenizeToDB($item->$property, $group, $item->language, $format); // Check if we're approaching the memory limit of the token table. if ($count > static::$state->options->get('memory_table_limit', 30000)) { $this->toggleTables(false); } } } } /* * Process the item's taxonomy. The items can customize their * taxonomy mappings to define extra properties to map. */ foreach ($item->getTaxonomy() as $branch => $nodes) { // Iterate through the nodes and map them to the branch. foreach ($nodes as $node) { // Add the node to the tree. $nodeId = FinderIndexerTaxonomy::addNode($branch, $node->title, $node->state, $node->access); // Add the link => node map. FinderIndexerTaxonomy::addMap($linkId, $nodeId); // Tokenize the node title and add them to the database. $count += $this->tokenizeToDB($node->title, static::META_CONTEXT, $item->language, $format); } } // Mark afterProcessing in the profiler. static::$profiler ? static::$profiler->mark('afterProcessing') : null; /* * At this point, all of the item's content has been parsed, tokenized * and inserted into the #__finder_tokens table. Now, we need to * aggregate all the data into that table into a more usable form. The * aggregated data will be inserted into #__finder_tokens_aggregate * table. */ $query = 'INSERT INTO ' . $db->quoteName('#__finder_tokens_aggregate') . ' (' . $db->quoteName('term_id') . ', ' . $db->quoteName('term') . ', ' . $db->quoteName('stem') . ', ' . $db->quoteName('common') . ', ' . $db->quoteName('phrase') . ', ' . $db->quoteName('term_weight') . ', ' . $db->quoteName('context') . ', ' . $db->quoteName('context_weight') . ', ' . $db->quoteName('language') . ')' . ' SELECT' . ' t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context,' . ' ROUND( t1.weight * COUNT( t2.term ) * %F, 8 ) AS context_weight, t1.language' . ' FROM (' . ' SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' . ' FROM ' . $db->quoteName('#__finder_tokens') . ' AS t1' . ' WHERE t1.context = %d' . ' ) AS t1' . ' JOIN ' . $db->quoteName('#__finder_tokens') . ' AS t2 ON t2.term = t1.term' . ' LEFT JOIN ' . $db->quoteName('#__finder_terms') . ' AS t ON t.term = t1.term' . ' WHERE t2.context = %d' . ' GROUP BY t1.term, t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' . ' ORDER BY t1.term DESC'; // Iterate through the contexts and aggregate the tokens per context. foreach ($state->weights as $context => $multiplier) { // Run the query to aggregate the tokens for this context.. $db->setQuery(sprintf($query, $multiplier, $context, $context)); $db->execute(); } // Mark afterAggregating in the profiler. static::$profiler ? static::$profiler->mark('afterAggregating') : null; /* * When we pulled down all of the aggregate data, we did a LEFT JOIN * over the terms table to try to find all the term ids that * already exist for our tokens. If any of the rows in the aggregate * table have a term of 0, then no term record exists for that * term so we need to add it to the terms table. */ $db->setQuery( 'INSERT INTO ' . $db->quoteName('#__finder_terms') . ' (' . $db->quoteName('term') . ', ' . $db->quoteName('stem') . ', ' . $db->quoteName('common') . ', ' . $db->quoteName('phrase') . ', ' . $db->quoteName('weight') . ', ' . $db->quoteName('soundex') . ')' . ' SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term)' . ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' AS ta' . ' WHERE ta.term_id IS NULL' . ' GROUP BY ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight' ); $db->execute(); /* * Now, we just inserted a bunch of new records into the terms table * so we need to go back and update the aggregate table with all the * new term ids. */ $query = $db->getQuery(true) ->update('ta') ->set('ta.term_id = t.term_id from #__finder_tokens_aggregate AS ta INNER JOIN #__finder_terms AS t ON t.term = ta.term') ->where('ta.term_id IS NULL'); $db->setQuery($query); $db->execute(); // Mark afterTerms in the profiler. static::$profiler ? static::$profiler->mark('afterTerms') : null; /* * After we've made sure that all of the terms are in the terms table * and the aggregate table has the correct term ids, we need to update * the links counter for each term by one. */ $query->clear() ->update('t') ->set('t.links = t.links + 1 FROM #__finder_terms AS t INNER JOIN #__finder_tokens_aggregate AS ta ON ta.term_id = t.term_id'); $db->setQuery($query); $db->execute(); // Mark afterTerms in the profiler. static::$profiler ? static::$profiler->mark('afterTerms') : null; /* * Before we can insert all of the mapping rows, we have to figure out * which mapping table the rows need to be inserted into. The mapping * table for each term is based on the first character of the md5 of * the first character of the term. In php, it would be expressed as * substr(md5(substr($token, 0, 1)), 0, 1) */ $query->clear() ->update($db->quoteName('#__finder_tokens_aggregate')) ->set($db->quoteName('map_suffix') . " = SUBSTRING(HASHBYTES('MD5', SUBSTRING(" . $db->quoteName('term') . ', 1, 1)), 1, 1)'); $db->setQuery($query); $db->execute(); /* * At this point, the aggregate table contains a record for each * term in each context. So, we're going to pull down all of that * data while grouping the records by term and add all of the * sub-totals together to arrive at the final total for each token for * this link. Then, we insert all of that data into the appropriate * mapping table. */ for ($i = 0; $i <= 15; $i++) { // Get the mapping table suffix. $suffix = dechex($i); /* * We have to run this query 16 times, one for each link => term * mapping table. */ $db->setQuery( 'INSERT INTO ' . $db->quoteName('#__finder_links_terms' . $suffix) . ' (' . $db->quoteName('link_id') . ', ' . $db->quoteName('term_id') . ', ' . $db->quoteName('weight') . ')' . ' SELECT ' . (int) $linkId . ', ' . $db->quoteName('term_id') . ',' . ' ROUND(SUM(' . $db->quoteName('context_weight') . '), 8)' . ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' WHERE ' . $db->quoteName('map_suffix') . ' = ' . $db->quote($suffix) . ' GROUP BY term, term_id' . ' ORDER BY ' . $db->quoteName('term') . ' DESC' ); $db->execute(); } // Mark afterMapping in the profiler. static::$profiler ? static::$profiler->mark('afterMapping') : null; // Update the signature. $query->clear() ->update($db->quoteName('#__finder_links')) ->set($db->quoteName('md5sum') . ' = ' . $db->quote($curSig)) ->where($db->quoteName('link_id') . ' = ' . $db->quote($linkId)); $db->setQuery($query); $db->execute(); // Mark afterSigning in the profiler. static::$profiler ? static::$profiler->mark('afterSigning') : null; // Truncate the tokens tables. $db->truncateTable('#__finder_tokens'); // Truncate the tokens aggregate table. $db->truncateTable('#__finder_tokens_aggregate'); // Toggle the token tables back to memory tables. $this->toggleTables(true); // Mark afterTruncating in the profiler. static::$profiler ? static::$profiler->mark('afterTruncating') : null; return $linkId; } /** * Method to remove a link from the index. * * @param integer $linkId The id of the link. * * @return boolean True on success. * * @since 3.1 * @throws Exception on database error. */ public function remove($linkId) { $db = JFactory::getDbo(); $query = $db->getQuery(true); // Update the link counts and remove the mapping records. for ($i = 0; $i <= 15; $i++) { // Update the link counts for the terms. $query->update('t') ->set('t.links = t.links - 1 from #__finder_terms AS t INNER JOIN #__finder_links_terms' . dechex($i) . ' AS AS m ON m.term_id = t.term_id') ->where('m.link_id = ' . $db->quote((int) $linkId)); $db->setQuery($query); $db->execute(); // Remove all records from the mapping tables. $query->clear() ->delete($db->quoteName('#__finder_links_terms' . dechex($i))) ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); $db->setQuery($query); $db->execute(); } // Delete all orphaned terms. $query->clear() ->delete($db->quoteName('#__finder_terms')) ->where($db->quoteName('links') . ' <= 0'); $db->setQuery($query); $db->execute(); // Delete the link from the index. $query->clear() ->delete($db->quoteName('#__finder_links')) ->where($db->quoteName('link_id') . ' = ' . $db->quote((int) $linkId)); $db->setQuery($query); $db->execute(); // Remove the taxonomy maps. FinderIndexerTaxonomy::removeMaps($linkId); // Remove the orphaned taxonomy nodes. FinderIndexerTaxonomy::removeOrphanNodes(); return true; } /** * Method to optimize the index. We use this method to remove unused terms * and any other optimizations that might be necessary. * * @return boolean True on success. * * @since 3.1 * @throws Exception on database error. */ public function optimize() { // Get the database object. $db = JFactory::getDbo(); $query = $db->getQuery(true); // Delete all orphaned terms. $query->delete($db->quoteName('#__finder_terms')) ->where($db->quoteName('links') . ' <= 0'); $db->setQuery($query); $db->execute(); // Remove the orphaned taxonomy nodes. FinderIndexerTaxonomy::removeOrphanNodes(); return true; } /** * Method to add a set of tokens to the database. * * @param mixed $tokens An array or single FinderIndexerToken object. * @param mixed $context The context of the tokens. See context constants. [optional] * * @return integer The number of tokens inserted into the database. * * @since 3.1 * @throws Exception on database error. */ protected function addTokensToDB($tokens, $context = '') { // Get the database object. $db = JFactory::getDbo(); $query = $db->getQuery(true); // Force tokens to an array. $tokens = is_array($tokens) ? $tokens : array($tokens); // Count the number of token values. $values = 0; // Set some variables to count the iterations $totalTokens = count($tokens); $remaining = $totalTokens; $iterations = 0; $loop = true; do { // Shift the token off the array $token = array_shift($tokens); $query->values( $db->quote($token->term) . ', ' . $db->quote($token->stem) . ', ' . (int) $token->common . ', ' . (int) $token->phrase . ', ' . (float) $token->weight . ', ' . (int) $context . ', ' . $db->quote($token->language) ); $values++; $iterations++; $remaining--; // Run the query if we've reached 1000 iterations or there are no tokens remaining if ($iterations == 1000 || $remaining == 0) { // Insert the tokens into the database. $query->insert($db->quoteName('#__finder_tokens')) ->columns( array( $db->quoteName('term'), $db->quoteName('stem'), $db->quoteName('common'), $db->quoteName('phrase'), $db->quoteName('weight'), $db->quoteName('context'), $db->quoteName('language') ) ); $db->setQuery($query); $db->execute(); // Reset the query $query->clear(); } // If there's nothing remaining, we're done looping if ($remaining == 0) { $loop = false; } } while ($loop == true); return $values; } /** * Method to switch the token tables from Memory tables to MyISAM tables * when they are close to running out of memory. * * @param boolean $memory Flag to control how they should be toggled. * * @return boolean True on success. * * @since 3.1 * @throws Exception on database error. */ protected function toggleTables($memory) { return true; } } components/com_finder/helpers/indexer/driver/mysql.php000066600000053166150771655450017345 0ustar00mark('beforeIndexing') : null; $db = JFactory::getDbo(); $nd = $db->getNullDate(); // Check if the item is in the database. $query = $db->getQuery(true) ->select($db->quoteName('link_id') . ', ' . $db->quoteName('md5sum')) ->from($db->quoteName('#__finder_links')) ->where($db->quoteName('url') . ' = ' . $db->quote($item->url)); // Load the item from the database. $db->setQuery($query); $link = $db->loadObject(); // Get the indexer state. $state = static::getState(); // Get the signatures of the item. $curSig = static::getSignature($item); $oldSig = isset($link->md5sum) ? $link->md5sum : null; // Get the other item information. $linkId = empty($link->link_id) ? null : $link->link_id; $isNew = empty($link->link_id) ? true : false; // Check the signatures. If they match, the item is up to date. if (!$isNew && $curSig == $oldSig) { return $linkId; } /* * If the link already exists, flush all the term maps for the item. * Maps are stored in 16 tables so we need to iterate through and flush * each table one at a time. */ if (!$isNew) { for ($i = 0; $i <= 15; $i++) { // Flush the maps for the link. $query->clear() ->delete($db->quoteName('#__finder_links_terms' . dechex($i))) ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); $db->setQuery($query); $db->execute(); } // Remove the taxonomy maps. FinderIndexerTaxonomy::removeMaps($linkId); } // Mark afterUnmapping in the profiler. static::$profiler ? static::$profiler->mark('afterUnmapping') : null; // Perform cleanup on the item data. $item->publish_start_date = (int) $item->publish_start_date != 0 ? $item->publish_start_date : $nd; $item->publish_end_date = (int) $item->publish_end_date != 0 ? $item->publish_end_date : $nd; $item->start_date = (int) $item->start_date != 0 ? $item->start_date : $nd; $item->end_date = (int) $item->end_date != 0 ? $item->end_date : $nd; // Prepare the item description. $item->description = FinderIndexerHelper::parse($item->summary); /* * Now, we need to enter the item into the links table. If the item * already exists in the database, we need to use an UPDATE query. * Otherwise, we need to use an INSERT to get the link id back. */ if ($isNew) { $columnsArray = array( $db->quoteName('url'), $db->quoteName('route'), $db->quoteName('title'), $db->quoteName('description'), $db->quoteName('indexdate'), $db->quoteName('published'), $db->quoteName('state'), $db->quoteName('access'), $db->quoteName('language'), $db->quoteName('type_id'), $db->quoteName('object'), $db->quoteName('publish_start_date'), $db->quoteName('publish_end_date'), $db->quoteName('start_date'), $db->quoteName('end_date'), $db->quoteName('list_price'), $db->quoteName('sale_price') ); // Insert the link. $query->clear() ->insert($db->quoteName('#__finder_links')) ->columns($columnsArray) ->values( $db->quote($item->url) . ', ' . $db->quote($item->route) . ', ' . $db->quote($item->title) . ', ' . $db->quote($item->description) . ', ' . $query->currentTimestamp() . ', ' . '1, ' . (int) $item->state . ', ' . (int) $item->access . ', ' . $db->quote($item->language) . ', ' . (int) $item->type_id . ', ' . $db->quote(serialize($item)) . ', ' . $db->quote($item->publish_start_date) . ', ' . $db->quote($item->publish_end_date) . ', ' . $db->quote($item->start_date) . ', ' . $db->quote($item->end_date) . ', ' . (double) ($item->list_price ? $item->list_price : 0) . ', ' . (double) ($item->sale_price ? $item->sale_price : 0) ); $db->setQuery($query); $db->execute(); // Get the link id. $linkId = (int) $db->insertid(); } else { // Update the link. $query->clear() ->update($db->quoteName('#__finder_links')) ->set($db->quoteName('route') . ' = ' . $db->quote($item->route)) ->set($db->quoteName('title') . ' = ' . $db->quote($item->title)) ->set($db->quoteName('description') . ' = ' . $db->quote($item->description)) ->set($db->quoteName('indexdate') . ' = ' . $query->currentTimestamp()) ->set($db->quoteName('state') . ' = ' . (int) $item->state) ->set($db->quoteName('access') . ' = ' . (int) $item->access) ->set($db->quoteName('language') . ' = ' . $db->quote($item->language)) ->set($db->quoteName('type_id') . ' = ' . (int) $item->type_id) ->set($db->quoteName('object') . ' = ' . $db->quote(serialize($item))) ->set($db->quoteName('publish_start_date') . ' = ' . $db->quote($item->publish_start_date)) ->set($db->quoteName('publish_end_date') . ' = ' . $db->quote($item->publish_end_date)) ->set($db->quoteName('start_date') . ' = ' . $db->quote($item->start_date)) ->set($db->quoteName('end_date') . ' = ' . $db->quote($item->end_date)) ->set($db->quoteName('list_price') . ' = ' . (double) ($item->list_price ? $item->list_price : 0)) ->set($db->quoteName('sale_price') . ' = ' . (double) ($item->sale_price ? $item->sale_price : 0)) ->where('link_id = ' . (int) $linkId); $db->setQuery($query); $db->execute(); } // Set up the variables we will need during processing. $count = 0; // Mark afterLinking in the profiler. static::$profiler ? static::$profiler->mark('afterLinking') : null; // Truncate the tokens tables. $db->truncateTable('#__finder_tokens'); // Truncate the tokens aggregate table. $db->truncateTable('#__finder_tokens_aggregate'); /* * Process the item's content. The items can customize their * processing instructions to define extra properties to process * or rearrange how properties are weighted. */ foreach ($item->getInstructions() as $group => $properties) { // Iterate through the properties of the group. foreach ($properties as $property) { // Check if the property exists in the item. if (empty($item->$property)) { continue; } // Tokenize the property. if (is_array($item->$property)) { // Tokenize an array of content and add it to the database. foreach ($item->$property as $ip) { /* * If the group is path, we need to a few extra processing * steps to strip the extension and convert slashes and dashes * to spaces. */ if ($group === static::PATH_CONTEXT) { $ip = JFile::stripExt($ip); $ip = str_replace('/', ' ', $ip); $ip = str_replace('-', ' ', $ip); } // Tokenize a string of content and add it to the database. $count += $this->tokenizeToDB($ip, $group, $item->language, $format); // Check if we're approaching the memory limit of the token table. if ($count > static::$state->options->get('memory_table_limit', 30000)) { $this->toggleTables(false); } } } else { /* * If the group is path, we need to a few extra processing * steps to strip the extension and convert slashes and dashes * to spaces. */ if ($group === static::PATH_CONTEXT) { $item->$property = JFile::stripExt($item->$property); $item->$property = str_replace('/', ' ', $item->$property); $item->$property = str_replace('-', ' ', $item->$property); } // Tokenize a string of content and add it to the database. $count += $this->tokenizeToDB($item->$property, $group, $item->language, $format); // Check if we're approaching the memory limit of the token table. if ($count > static::$state->options->get('memory_table_limit', 30000)) { $this->toggleTables(false); } } } } /* * Process the item's taxonomy. The items can customize their * taxonomy mappings to define extra properties to map. */ foreach ($item->getTaxonomy() as $branch => $nodes) { // Iterate through the nodes and map them to the branch. foreach ($nodes as $node) { // Add the node to the tree. $nodeId = FinderIndexerTaxonomy::addNode($branch, $node->title, $node->state, $node->access); // Add the link => node map. FinderIndexerTaxonomy::addMap($linkId, $nodeId); // Tokenize the node title and add them to the database. $count += $this->tokenizeToDB($node->title, static::META_CONTEXT, $item->language, $format); } } // Mark afterProcessing in the profiler. static::$profiler ? static::$profiler->mark('afterProcessing') : null; /* * At this point, all of the item's content has been parsed, tokenized * and inserted into the #__finder_tokens table. Now, we need to * aggregate all the data into that table into a more usable form. The * aggregated data will be inserted into #__finder_tokens_aggregate * table. */ $query = 'INSERT INTO ' . $db->quoteName('#__finder_tokens_aggregate') . ' (' . $db->quoteName('term_id') . ', ' . $db->quoteName('term') . ', ' . $db->quoteName('stem') . ', ' . $db->quoteName('common') . ', ' . $db->quoteName('phrase') . ', ' . $db->quoteName('term_weight') . ', ' . $db->quoteName('context') . ', ' . $db->quoteName('context_weight') . ', ' . $db->quoteName('language') . ')' . ' SELECT' . ' t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, ' . ' ROUND( t1.weight * COUNT( t2.term ) * %F, 8 ) AS context_weight, t1.language' . ' FROM (' . ' SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' . ' FROM ' . $db->quoteName('#__finder_tokens') . ' AS t1' . ' WHERE t1.context = %d' . ' ) AS t1' . ' JOIN ' . $db->quoteName('#__finder_tokens') . ' AS t2 ON t2.term = t1.term' . ' LEFT JOIN ' . $db->quoteName('#__finder_terms') . ' AS t ON t.term = t1.term' . ' WHERE t2.context = %d' . ' GROUP BY t1.term' . ' ORDER BY t1.term DESC'; // Iterate through the contexts and aggregate the tokens per context. foreach ($state->weights as $context => $multiplier) { // Run the query to aggregate the tokens for this context.. $db->setQuery(sprintf($query, $multiplier, $context, $context)); $db->execute(); } // Mark afterAggregating in the profiler. static::$profiler ? static::$profiler->mark('afterAggregating') : null; /* * When we pulled down all of the aggregate data, we did a LEFT JOIN * over the terms table to try to find all the term ids that * already exist for our tokens. If any of the rows in the aggregate * table have a term of 0, then no term record exists for that * term so we need to add it to the terms table. */ $db->setQuery( 'INSERT IGNORE INTO ' . $db->quoteName('#__finder_terms') . ' (' . $db->quoteName('term') . ', ' . $db->quoteName('stem') . ', ' . $db->quoteName('common') . ', ' . $db->quoteName('phrase') . ', ' . $db->quoteName('weight') . ', ' . $db->quoteName('soundex') . ', ' . $db->quoteName('language') . ')' . ' SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term), ta.language' . ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' AS ta' . ' WHERE ta.term_id = 0' . ' GROUP BY ta.term' ); $db->execute(); /* * Now, we just inserted a bunch of new records into the terms table * so we need to go back and update the aggregate table with all the * new term ids. */ $query = $db->getQuery(true) ->update($db->quoteName('#__finder_tokens_aggregate') . ' AS ta') ->join('INNER', $db->quoteName('#__finder_terms') . ' AS t ON t.term = ta.term') ->set('ta.term_id = t.term_id') ->where('ta.term_id = 0'); $db->setQuery($query); $db->execute(); // Mark afterTerms in the profiler. static::$profiler ? static::$profiler->mark('afterTerms') : null; /* * After we've made sure that all of the terms are in the terms table * and the aggregate table has the correct term ids, we need to update * the links counter for each term by one. */ $query->clear() ->update($db->quoteName('#__finder_terms') . ' AS t') ->join('INNER', $db->quoteName('#__finder_tokens_aggregate') . ' AS ta ON ta.term_id = t.term_id') ->set('t.' . $db->quoteName('links') . ' = t.links + 1'); $db->setQuery($query); $db->execute(); // Mark afterTerms in the profiler. static::$profiler ? static::$profiler->mark('afterTerms') : null; /* * Before we can insert all of the mapping rows, we have to figure out * which mapping table the rows need to be inserted into. The mapping * table for each term is based on the first character of the md5 of * the first character of the term. In php, it would be expressed as * substr(md5(substr($token, 0, 1)), 0, 1) */ $query->clear() ->update($db->quoteName('#__finder_tokens_aggregate')) ->set($db->quoteName('map_suffix') . ' = SUBSTR(MD5(SUBSTR(' . $db->quoteName('term') . ', 1, 1)), 1, 1)'); $db->setQuery($query); $db->execute(); /* * At this point, the aggregate table contains a record for each * term in each context. So, we're going to pull down all of that * data while grouping the records by term and add all of the * sub-totals together to arrive at the final total for each token for * this link. Then, we insert all of that data into the appropriate * mapping table. */ for ($i = 0; $i <= 15; $i++) { // Get the mapping table suffix. $suffix = dechex($i); /* * We have to run this query 16 times, one for each link => term * mapping table. */ $db->setQuery( 'INSERT INTO ' . $db->quoteName('#__finder_links_terms' . $suffix) . ' (' . $db->quoteName('link_id') . ', ' . $db->quoteName('term_id') . ', ' . $db->quoteName('weight') . ')' . ' SELECT ' . (int) $linkId . ', ' . $db->quoteName('term_id') . ',' . ' ROUND(SUM(' . $db->quoteName('context_weight') . '), 8)' . ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' WHERE ' . $db->quoteName('map_suffix') . ' = ' . $db->quote($suffix) . ' GROUP BY ' . $db->quoteName('term') . ' ORDER BY ' . $db->quoteName('term') . ' DESC' ); $db->execute(); } // Mark afterMapping in the profiler. static::$profiler ? static::$profiler->mark('afterMapping') : null; // Update the signature. $query->clear() ->update($db->quoteName('#__finder_links')) ->set($db->quoteName('md5sum') . ' = ' . $db->quote($curSig)) ->where($db->quoteName('link_id') . ' = ' . $db->quote($linkId)); $db->setQuery($query); $db->execute(); // Mark afterSigning in the profiler. static::$profiler ? static::$profiler->mark('afterSigning') : null; // Truncate the tokens tables. $db->truncateTable('#__finder_tokens'); // Truncate the tokens aggregate table. $db->truncateTable('#__finder_tokens_aggregate'); // Toggle the token tables back to memory tables. $this->toggleTables(true); // Mark afterTruncating in the profiler. static::$profiler ? static::$profiler->mark('afterTruncating') : null; return $linkId; } /** * Method to remove a link from the index. * * @param integer $linkId The id of the link. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ public function remove($linkId) { $db = JFactory::getDbo(); $query = $db->getQuery(true); // Update the link counts and remove the mapping records. for ($i = 0; $i <= 15; $i++) { // Update the link counts for the terms. $query->update($db->quoteName('#__finder_terms') . ' AS t') ->join('INNER', $db->quoteName('#__finder_links_terms' . dechex($i)) . ' AS m ON m.term_id = t.term_id') ->set('t.links = t.links - 1') ->where('m.link_id = ' . $db->quote((int) $linkId)); $db->setQuery($query); $db->execute(); // Remove all records from the mapping tables. $query->clear() ->delete($db->quoteName('#__finder_links_terms' . dechex($i))) ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); $db->setQuery($query); $db->execute(); } // Delete all orphaned terms. $query->clear() ->delete($db->quoteName('#__finder_terms')) ->where($db->quoteName('links') . ' <= 0'); $db->setQuery($query); $db->execute(); // Delete the link from the index. $query->clear() ->delete($db->quoteName('#__finder_links')) ->where($db->quoteName('link_id') . ' = ' . $db->quote((int) $linkId)); $db->setQuery($query); $db->execute(); // Remove the taxonomy maps. FinderIndexerTaxonomy::removeMaps($linkId); // Remove the orphaned taxonomy nodes. FinderIndexerTaxonomy::removeOrphanNodes(); return true; } /** * Method to optimize the index. We use this method to remove unused terms * and any other optimizations that might be necessary. * * @return boolean True on success. * * @since 3.0 * @throws Exception on database error. */ public function optimize() { // Get the database object. $db = JFactory::getDbo(); $query = $db->getQuery(true); // Delete all orphaned terms. $query->delete($db->quoteName('#__finder_terms')) ->where($db->quoteName('links') . ' <= 0'); $db->setQuery($query); $db->execute(); // Optimize the links table. $db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_links')); $db->execute(); for ($i = 0; $i <= 15; $i++) { // Optimize the terms mapping table. $db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_links_terms' . dechex($i))); $db->execute(); } // Optimize the terms mapping table. $db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_links_terms')); $db->execute(); // Remove the orphaned taxonomy nodes. FinderIndexerTaxonomy::removeOrphanNodes(); // Optimize the taxonomy mapping table. $db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_taxonomy_map')); $db->execute(); return true; } /** * Method to add a set of tokens to the database. * * @param mixed $tokens An array or single FinderIndexerToken object. * @param mixed $context The context of the tokens. See context constants. [optional] * * @return integer The number of tokens inserted into the database. * * @since 3.0 * @throws Exception on database error. */ protected function addTokensToDB($tokens, $context = '') { // Get the database object. $db = JFactory::getDbo(); $query = $db->getQuery(true); // Force tokens to an array. $tokens = is_array($tokens) ? $tokens : array($tokens); // Count the number of token values. $values = 0; // Insert the tokens into the database. $query->insert($db->quoteName('#__finder_tokens')) ->columns( array( $db->quoteName('term'), $db->quoteName('stem'), $db->quoteName('common'), $db->quoteName('phrase'), $db->quoteName('weight'), $db->quoteName('context'), $db->quoteName('language') ) ); // Iterate through the tokens to create SQL value sets. foreach ($tokens as $token) { $query->values( $db->quote($token->term) . ', ' . $db->quote($token->stem) . ', ' . (int) $token->common . ', ' . (int) $token->phrase . ', ' . (float) $token->weight . ', ' . (int) $context . ', ' . $db->quote($token->language) ); $values++; } $db->setQuery($query); $db->execute(); return $values; } /** * Method to switch the token tables from Memory tables to MyISAM tables * when they are close to running out of memory. * * @param boolean $memory Flag to control how they should be toggled. * * @return boolean True on success. * * @since 3.0 * @throws Exception on database error. */ protected function toggleTables($memory) { static $state; // Get the database adapter. $db = JFactory::getDbo(); // Check if we are setting the tables to the Memory engine. if ($memory === true && $state !== true) { // Set the tokens table to Memory. $db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens') . ' ENGINE = MEMORY'); $db->execute(); // Set the tokens aggregate table to Memory. $db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens_aggregate') . ' ENGINE = MEMORY'); $db->execute(); // Set the internal state. $state = $memory; } // We must be setting the tables to the MyISAM engine. elseif ($memory === false && $state !== false) { // Set the tokens table to MyISAM. $db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens') . ' ENGINE = MYISAM'); $db->execute(); // Set the tokens aggregate table to MyISAM. $db->setQuery('ALTER TABLE ' . $db->quoteName('#__finder_tokens_aggregate') . ' ENGINE = MYISAM'); $db->execute(); // Set the internal state. $state = $memory; } return true; } } components/com_finder/helpers/indexer/driver/index.html000066600000000036150771655450017450 0ustar00components/com_finder/helpers/indexer/driver/postgresql.php000066600000051512150771655450020374 0ustar00mark('beforeIndexing') : null; $db = JFactory::getDbo(); $nd = $db->getNullDate(); // Check if the item is in the database. $query = $db->getQuery(true) ->select($db->quoteName('link_id') . ', ' . $db->quoteName('md5sum')) ->from($db->quoteName('#__finder_links')) ->where($db->quoteName('url') . ' = ' . $db->quote($item->url)); // Load the item from the database. $db->setQuery($query); $link = $db->loadObject(); // Get the indexer state. $state = static::getState(); // Get the signatures of the item. $curSig = static::getSignature($item); $oldSig = isset($link->md5sum) ? $link->md5sum : null; // Get the other item information. $linkId = empty($link->link_id) ? null : $link->link_id; $isNew = empty($link->link_id) ? true : false; // Check the signatures. If they match, the item is up to date. if (!$isNew && $curSig == $oldSig) { return $linkId; } /* * If the link already exists, flush all the term maps for the item. * Maps are stored in 16 tables so we need to iterate through and flush * each table one at a time. */ if (!$isNew) { for ($i = 0; $i <= 15; $i++) { // Flush the maps for the link. $query->clear() ->delete($db->quoteName('#__finder_links_terms' . dechex($i))) ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); $db->setQuery($query); $db->execute(); } // Remove the taxonomy maps. FinderIndexerTaxonomy::removeMaps($linkId); } // Mark afterUnmapping in the profiler. static::$profiler ? static::$profiler->mark('afterUnmapping') : null; // Perform cleanup on the item data. $item->publish_start_date = (int) $item->publish_start_date != 0 ? $item->publish_start_date : $nd; $item->publish_end_date = (int) $item->publish_end_date != 0 ? $item->publish_end_date : $nd; $item->start_date = (int) $item->start_date != 0 ? $item->start_date : $nd; $item->end_date = (int) $item->end_date != 0 ? $item->end_date : $nd; // Prepare the item description. $item->description = FinderIndexerHelper::parse($item->summary); /* * Now, we need to enter the item into the links table. If the item * already exists in the database, we need to use an UPDATE query. * Otherwise, we need to use an INSERT to get the link id back. */ if ($isNew) { $columnsArray = array( $db->quoteName('url'), $db->quoteName('route'), $db->quoteName('title'), $db->quoteName('description'), $db->quoteName('indexdate'), $db->quoteName('published'), $db->quoteName('state'), $db->quoteName('access'), $db->quoteName('language'), $db->quoteName('type_id'), $db->quoteName('object'), $db->quoteName('publish_start_date'), $db->quoteName('publish_end_date'), $db->quoteName('start_date'), $db->quoteName('end_date'), $db->quoteName('list_price'), $db->quoteName('sale_price') ); // Insert the link. $query->clear() ->insert($db->quoteName('#__finder_links')) ->columns($columnsArray) ->values( $db->quote($item->url) . ', ' . $db->quote($item->route) . ', ' . $db->quote($item->title) . ', ' . $db->quote($item->description) . ', ' . $query->currentTimestamp() . ', ' . '1, ' . (int) $item->state . ', ' . (int) $item->access . ', ' . $db->quote($item->language) . ', ' . (int) $item->type_id . ', ' . $db->quote(serialize($item)) . ', ' . $db->quote($item->publish_start_date) . ', ' . $db->quote($item->publish_end_date) . ', ' . $db->quote($item->start_date) . ', ' . $db->quote($item->end_date) . ', ' . (double) ($item->list_price ? $item->list_price : 0) . ', ' . (double) ($item->sale_price ? $item->sale_price : 0) ); $db->setQuery($query); $db->execute(); // Get the link id. $linkId = (int) $db->insertid(); } else { // Update the link. $query->clear() ->update($db->quoteName('#__finder_links')) ->set($db->quoteName('route') . ' = ' . $db->quote($item->route)) ->set($db->quoteName('title') . ' = ' . $db->quote($item->title)) ->set($db->quoteName('description') . ' = ' . $db->quote($item->description)) ->set($db->quoteName('indexdate') . ' = ' . $query->currentTimestamp()) ->set($db->quoteName('state') . ' = ' . (int) $item->state) ->set($db->quoteName('access') . ' = ' . (int) $item->access) ->set($db->quoteName('language') . ' = ' . $db->quote($item->language)) ->set($db->quoteName('type_id') . ' = ' . (int) $item->type_id) ->set($db->quoteName('object') . ' = ' . $db->quote(serialize($item))) ->set($db->quoteName('publish_start_date') . ' = ' . $db->quote($item->publish_start_date)) ->set($db->quoteName('publish_end_date') . ' = ' . $db->quote($item->publish_end_date)) ->set($db->quoteName('start_date') . ' = ' . $db->quote($item->start_date)) ->set($db->quoteName('end_date') . ' = ' . $db->quote($item->end_date)) ->set($db->quoteName('list_price') . ' = ' . (double) ($item->list_price ? $item->list_price : 0)) ->set($db->quoteName('sale_price') . ' = ' . (double) ($item->sale_price ? $item->sale_price : 0)) ->where('link_id = ' . (int) $linkId); $db->setQuery($query); $db->execute(); } // Set up the variables we will need during processing. $count = 0; // Mark afterLinking in the profiler. static::$profiler ? static::$profiler->mark('afterLinking') : null; // Truncate the tokens tables. $db->truncateTable('#__finder_tokens'); // Truncate the tokens aggregate table. $db->truncateTable('#__finder_tokens_aggregate'); /* * Process the item's content. The items can customize their * processing instructions to define extra properties to process * or rearrange how properties are weighted. */ foreach ($item->getInstructions() as $group => $properties) { // Iterate through the properties of the group. foreach ($properties as $property) { // Check if the property exists in the item. if (empty($item->$property)) { continue; } // Tokenize the property. if (is_array($item->$property)) { // Tokenize an array of content and add it to the database. foreach ($item->$property as $ip) { /* * If the group is path, we need to a few extra processing * steps to strip the extension and convert slashes and dashes * to spaces. */ if ($group === static::PATH_CONTEXT) { $ip = JFile::stripExt($ip); $ip = str_replace('/', ' ', $ip); $ip = str_replace('-', ' ', $ip); } // Tokenize a string of content and add it to the database. $count += $this->tokenizeToDB($ip, $group, $item->language, $format); // Check if we're approaching the memory limit of the token table. if ($count > static::$state->options->get('memory_table_limit', 30000)) { $this->toggleTables(false); } } } else { /* * If the group is path, we need to a few extra processing * steps to strip the extension and convert slashes and dashes * to spaces. */ if ($group === static::PATH_CONTEXT) { $item->$property = JFile::stripExt($item->$property); $item->$property = str_replace('/', ' ', $item->$property); $item->$property = str_replace('-', ' ', $item->$property); } // Tokenize a string of content and add it to the database. $count += $this->tokenizeToDB($item->$property, $group, $item->language, $format); // Check if we're approaching the memory limit of the token table. if ($count > static::$state->options->get('memory_table_limit', 30000)) { $this->toggleTables(false); } } } } /* * Process the item's taxonomy. The items can customize their * taxonomy mappings to define extra properties to map. */ foreach ($item->getTaxonomy() as $branch => $nodes) { // Iterate through the nodes and map them to the branch. foreach ($nodes as $node) { // Add the node to the tree. $nodeId = FinderIndexerTaxonomy::addNode($branch, $node->title, $node->state, $node->access); // Add the link => node map. FinderIndexerTaxonomy::addMap($linkId, $nodeId); // Tokenize the node title and add them to the database. $count += $this->tokenizeToDB($node->title, static::META_CONTEXT, $item->language, $format); } } // Mark afterProcessing in the profiler. static::$profiler ? static::$profiler->mark('afterProcessing') : null; /* * At this point, all of the item's content has been parsed, tokenized * and inserted into the #__finder_tokens table. Now, we need to * aggregate all the data into that table into a more usable form. The * aggregated data will be inserted into #__finder_tokens_aggregate * table. */ $query = 'INSERT INTO ' . $db->quoteName('#__finder_tokens_aggregate') . ' (' . $db->quoteName('term_id') . ', ' . $db->quoteName('term') . ', ' . $db->quoteName('stem') . ', ' . $db->quoteName('common') . ', ' . $db->quoteName('phrase') . ', ' . $db->quoteName('term_weight') . ', ' . $db->quoteName('context') . ', ' . $db->quoteName('context_weight') . ', ' . $db->quoteName('language') . ')' . ' SELECT' . ' t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context,' . ' ROUND( t1.weight * COUNT( t2.term ) * %F, 8 ) AS context_weight, t1.language' . ' FROM (' . ' SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' . ' FROM ' . $db->quoteName('#__finder_tokens') . ' AS t1' . ' WHERE t1.context = %d' . ' ) AS t1' . ' JOIN ' . $db->quoteName('#__finder_tokens') . ' AS t2 ON t2.term = t1.term' . ' LEFT JOIN ' . $db->quoteName('#__finder_terms') . ' AS t ON t.term = t1.term' . ' WHERE t2.context = %d' . ' GROUP BY t1.term, t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' . ' ORDER BY t1.term DESC'; // Iterate through the contexts and aggregate the tokens per context. foreach ($state->weights as $context => $multiplier) { // Run the query to aggregate the tokens for this context.. $db->setQuery(sprintf($query, $multiplier, $context, $context)); $db->execute(); } // Mark afterAggregating in the profiler. static::$profiler ? static::$profiler->mark('afterAggregating') : null; /* * When we pulled down all of the aggregate data, we did a LEFT JOIN * over the terms table to try to find all the term ids that * already exist for our tokens. If any of the rows in the aggregate * table have a term of 0, then no term record exists for that * term so we need to add it to the terms table. */ /* Emulation of IGNORE INTO behaviour */ $db->setQuery( ' SELECT ta.term' . ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' AS ta' . ' WHERE ta.term_id = 0' ); if ($db->loadRow() == null) { $db->setQuery( 'INSERT INTO ' . $db->quoteName('#__finder_terms') . ' (' . $db->quoteName('term') . ', ' . $db->quoteName('stem') . ', ' . $db->quoteName('common') . ', ' . $db->quoteName('phrase') . ', ' . $db->quoteName('weight') . ', ' . $db->quoteName('soundex') . ', ' . $db->quoteName('language') . ')' . ' SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term), ta.language' . ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' AS ta' . ' WHERE ta.term_id = 0' . ' GROUP BY ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term), ta.language' ); $db->execute(); } /* * Now, we just inserted a bunch of new records into the terms table * so we need to go back and update the aggregate table with all the * new term ids. */ $query = $db->getQuery(true) ->update($db->quoteName('#__finder_tokens_aggregate') . ' AS ta') ->join('INNER', $db->quoteName('#__finder_terms') . ' AS t ON t.term = ta.term') ->set('ta.term_id = t.term_id') ->where('ta.term_id = 0'); $db->setQuery($query); $db->execute(); // Mark afterTerms in the profiler. static::$profiler ? static::$profiler->mark('afterTerms') : null; /* * After we've made sure that all of the terms are in the terms table * and the aggregate table has the correct term ids, we need to update * the links counter for each term by one. */ $query->clear() ->update($db->quoteName('#__finder_terms') . ' AS t') ->join('INNER', $db->quoteName('#__finder_tokens_aggregate') . ' AS ta ON ta.term_id = t.term_id') ->set('t.' . $db->quoteName('links') . ' = t.links + 1'); $db->setQuery($query); $db->execute(); // Mark afterTerms in the profiler. static::$profiler ? static::$profiler->mark('afterTerms') : null; /* * Before we can insert all of the mapping rows, we have to figure out * which mapping table the rows need to be inserted into. The mapping * table for each term is based on the first character of the md5 of * the first character of the term. In php, it would be expressed as * substr(md5(substr($token, 0, 1)), 0, 1) */ $query->clear() ->update($db->quoteName('#__finder_tokens_aggregate')) ->set($db->quoteName('map_suffix') . ' = SUBSTR(MD5(SUBSTR(' . $db->quoteName('term') . ', 1, 1)), 1, 1)'); $db->setQuery($query); $db->execute(); /* * At this point, the aggregate table contains a record for each * term in each context. So, we're going to pull down all of that * data while grouping the records by term and add all of the * sub-totals together to arrive at the final total for each token for * this link. Then, we insert all of that data into the appropriate * mapping table. */ for ($i = 0; $i <= 15; $i++) { // Get the mapping table suffix. $suffix = dechex($i); /* * We have to run this query 16 times, one for each link => term * mapping table. */ $db->setQuery( 'INSERT INTO ' . $db->quoteName('#__finder_links_terms' . $suffix) . ' (' . $db->quoteName('link_id') . ', ' . $db->quoteName('term_id') . ', ' . $db->quoteName('weight') . ')' . ' SELECT ' . (int) $linkId . ', ' . $db->quoteName('term_id') . ',' . ' ROUND(SUM(' . $db->quoteName('context_weight') . '), 8)' . ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' WHERE ' . $db->quoteName('map_suffix') . ' = ' . $db->quote($suffix) . ' GROUP BY ' . $db->quoteName('term') . ' ORDER BY ' . $db->quoteName('term') . ' DESC' ); $db->execute(); } // Mark afterMapping in the profiler. static::$profiler ? static::$profiler->mark('afterMapping') : null; // Update the signature. $query->clear() ->update($db->quoteName('#__finder_links')) ->set($db->quoteName('md5sum') . ' = ' . $db->quote($curSig)) ->where($db->quoteName('link_id') . ' = ' . $db->quote($linkId)); $db->setQuery($query); $db->execute(); // Mark afterSigning in the profiler. static::$profiler ? static::$profiler->mark('afterSigning') : null; // Truncate the tokens tables. $db->truncateTable('#__finder_tokens'); // Truncate the tokens aggregate table. $db->truncateTable('#__finder_tokens_aggregate'); // Toggle the token tables back to memory tables. $this->toggleTables(true); // Mark afterTruncating in the profiler. static::$profiler ? static::$profiler->mark('afterTruncating') : null; return $linkId; } /** * Method to remove a link from the index. * * @param integer $linkId The id of the link. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ public function remove($linkId) { $db = JFactory::getDbo(); $query = $db->getQuery(true); // Update the link counts and remove the mapping records. for ($i = 0; $i <= 15; $i++) { // Update the link counts for the terms. $query->update($db->quoteName('#__finder_terms') . ' AS t') ->join('INNER', $db->quoteName('#__finder_links_terms' . dechex($i)) . ' AS m ON m.term_id = t.term_id') ->set('t.links = t.links - 1') ->where('m.link_id = ' . $db->quote((int) $linkId)); $db->setQuery($query); $db->execute(); // Remove all records from the mapping tables. $query->clear() ->delete($db->quoteName('#__finder_links_terms' . dechex($i))) ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); $db->setQuery($query); $db->execute(); } // Delete all orphaned terms. $query->clear() ->delete($db->quoteName('#__finder_terms')) ->where($db->quoteName('links') . ' <= 0'); $db->setQuery($query); $db->execute(); // Delete the link from the index. $query->clear() ->delete($db->quoteName('#__finder_links')) ->where($db->quoteName('link_id') . ' = ' . $db->quote((int) $linkId)); $db->setQuery($query); $db->execute(); // Remove the taxonomy maps. FinderIndexerTaxonomy::removeMaps($linkId); // Remove the orphaned taxonomy nodes. FinderIndexerTaxonomy::removeOrphanNodes(); return true; } /** * Method to optimize the index. We use this method to remove unused terms * and any other optimizations that might be necessary. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ public function optimize() { // Get the database object. $db = JFactory::getDbo(); $query = $db->getQuery(true); // Delete all orphaned terms. $query->delete($db->quoteName('#__finder_terms')) ->where($db->quoteName('links') . ' <= 0'); $db->setQuery($query); $db->execute(); // Optimize the links table. $db->setQuery('VACUUM ' . $db->quoteName('#__finder_links')); $db->execute(); $db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_links')); $db->execute(); for ($i = 0; $i <= 15; $i++) { // Optimize the terms mapping table. $db->setQuery('VACUUM ' . $db->quoteName('#__finder_links_terms' . dechex($i))); $db->execute(); $db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_links_terms' . dechex($i))); $db->execute(); } // Optimize the terms mapping table. $db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_links_terms')); $db->execute(); // Remove the orphaned taxonomy nodes. FinderIndexerTaxonomy::removeOrphanNodes(); // Optimize the taxonomy mapping table. $db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_taxonomy_map')); $db->execute(); return true; } /** * Method to add a set of tokens to the database. * * @param mixed $tokens An array or single FinderIndexerToken object. * @param mixed $context The context of the tokens. See context constants. [optional] * * @return integer The number of tokens inserted into the database. * * @since 2.5 * @throws Exception on database error. */ protected function addTokensToDB($tokens, $context = '') { // Get the database object. $db = JFactory::getDbo(); $query = $db->getQuery(true); // Force tokens to an array. $tokens = is_array($tokens) ? $tokens : array($tokens); // Count the number of token values. $values = 0; // Insert the tokens into the database. $query->insert($db->quoteName('#__finder_tokens')) ->columns( array( $db->quoteName('term'), $db->quoteName('stem'), $db->quoteName('common'), $db->quoteName('phrase'), $db->quoteName('weight'), $db->quoteName('context'), $db->quoteName('language') ) ); // Iterate through the tokens to create SQL value sets. foreach ($tokens as $token) { $query->values( $db->quote($token->term) . ', ' . $db->quote($token->stem) . ', ' . (int) $token->common . ', ' . (int) $token->phrase . ', ' . (float) $token->weight . ', ' . (int) $context . ', ' . $db->quote($token->language) ); $values++; } $db->setQuery($query); $db->execute(); return $values; } /** * Method to switch the token tables from Memory tables to MyISAM tables * when they are close to running out of memory. * * @param boolean $memory Flag to control how they should be toggled. * * @return boolean True on success. * * @since 2.5 * @throws Exception on database error. */ protected function toggleTables($memory) { return true; } } components/com_finder/helpers/index.html000066600000000036150771655450014517 0ustar00components/com_finder/helpers/finder.php000066600000003210150771655450014477 0ustar00 com_finder Joomla! Project (C) 2005 - 2014 Open Source Matters. All rights reserved. August 2011 GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_FINDER_XML_DESCRIPTION COM_FINDER controller.php index.html finder.php router.php controllers helpers models views js images css index.html sql/install.mysql.sql sql/install.postgresql.sql sql/uninstall.mysql.sql sql/uninstall.postgresql.sql language/en-GB.com_finder.ini access.xml config.xml controller.php finder.php index.html controllers helpers models sql tables views language/en-GB.com_finder.ini language/en-GB.com_finder.sys.ini COM_FINDER components/com_finder/models/index.php000066600000024171150771655450014171 0ustar00authorise('core.delete', $this->option); } /** * Method to test whether a record can be deleted. * * @param object $record A record object. * * @return boolean True if allowed to change the state of the record. Defaults to the permission for the component. * * @since 2.5 */ protected function canEditState($record) { $user = JFactory::getUser(); return $user->authorise('core.edit.state', $this->option); } /** * Method to delete one or more records. * * @param array &$pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * * @since 2.5 */ public function delete(&$pks) { $dispatcher = JEventDispatcher::getInstance(); $pks = (array) $pks; $table = $this->getTable(); // Include the content plugins for the on delete events. JPluginHelper::importPlugin('content'); // Iterate the items to delete each one. foreach ($pks as $i => $pk) { if ($table->load($pk)) { if ($this->canDelete($table)) { $context = $this->option . '.' . $this->name; // Trigger the onContentBeforeDelete event. $result = $dispatcher->trigger($this->event_before_delete, array($context, $table)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } if (!$table->delete($pk)) { $this->setError($table->getError()); return false; } // Trigger the onContentAfterDelete event. $dispatcher->trigger($this->event_after_delete, array($context, $table)); } else { // Prune items that you can't change. unset($pks[$i]); $error = $this->getError(); if ($error) { $this->setError($error); } else { $this->setError(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); } } } else { $this->setError($table->getError()); return false; } } // Clear the component's cache $this->cleanCache(); return true; } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery A JDatabaseQuery object * * @since 2.5 */ protected function getListQuery() { $db = $this->getDbo(); $query = $db->getQuery(true) ->select('l.*') ->select('t.title AS t_title') ->from($db->quoteName('#__finder_links') . ' AS l') ->join('INNER', $db->quoteName('#__finder_types') . ' AS t ON t.id = l.type_id'); // Check the type filter. if ($this->getState('filter.type')) { $query->where('l.type_id = ' . (int) $this->getState('filter.type')); } // Check for state filter. if (is_numeric($this->getState('filter.state'))) { $query->where('l.published = ' . (int) $this->getState('filter.state')); } // Check the search phrase. if ($this->getState('filter.search') != '') { $search = $db->escape($this->getState('filter.search')); $query->where( 'l.title LIKE ' . $db->quote('%' . $db->escape($search) . '%') . ' OR l.url LIKE ' . $db->quote('%' . $db->escape($search) . '%') . ' OR l.indexdate LIKE ' . $db->quote('%' . $db->escape($search) . '%') ); } // Handle the list ordering. $ordering = $this->getState('list.ordering'); $direction = $this->getState('list.direction'); if (!empty($ordering)) { $query->order($db->escape($ordering) . ' ' . $db->escape($direction)); } return $query; } /** * Method to get the state of the Smart Search plug-ins. * * @return array Array of relevant plug-ins and whether they are enabled or not. * * @since 2.5 */ public function getPluginState() { $db = $this->getDbo(); $query = $db->getQuery(true) ->select('name, enabled') ->from($db->quoteName('#__extensions')) ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) ->where($db->quoteName('folder') . ' IN(' . $db->quote('system') . ',' . $db->quote('content') . ')') ->where($db->quoteName('element') . ' = ' . $db->quote('finder')); $db->setQuery($query); $db->execute(); $plugins = $db->loadObjectList('name'); return $plugins; } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. [optional] * * @return string A store id. * * @since 2.5 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.state'); $id .= ':' . $this->getState('filter.type'); return parent::getStoreId($id); } /** * Returns a JTable object, always creating it. * * @param string $type The table type to instantiate. [optional] * @param string $prefix A prefix for the table class name. [optional] * @param array $config Configuration array for model. [optional] * * @return JTable A database object * * @since 2.5 */ public function getTable($type = 'Link', $prefix = 'FinderTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Method to purge the index, deleting all links. * * @return boolean True on success, false on failure. * * @since 2.5 * @throws Exception on database error */ public function purge() { $db = $this->getDbo(); // Truncate the links table. $db->truncateTable('#__finder_links'); // Truncate the links terms tables. for ($i = 0; $i <= 15; $i++) { // Get the mapping table suffix. $suffix = dechex($i); $db->truncateTable('#__finder_links_terms' . $suffix); } // Truncate the terms table. $db->truncateTable('#__finder_terms'); // Truncate the taxonomy map table. $db->truncateTable('#__finder_taxonomy_map'); // Delete all the taxonomy nodes except the root. $query = $db->getQuery(true) ->delete($db->quoteName('#__finder_taxonomy')) ->where($db->quoteName('id') . ' > 1'); $db->setQuery($query); $db->execute(); // Truncate the tokens tables. $db->truncateTable('#__finder_tokens'); // Truncate the tokens aggregate table. $db->truncateTable('#__finder_tokens_aggregate'); return true; } /** * Method to auto-populate the model state. Calling getState in this method will result in recursion. * * @param string $ordering An optional ordering field. [optional] * @param string $direction An optional direction. [optional] * * @return void * * @since 2.5 */ protected function populateState($ordering = null, $direction = null) { // Load the filter state. $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string'); $this->setState('filter.state', $state); $type = $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string'); $this->setState('filter.type', $type); // Load the parameters. $params = JComponentHelper::getParams('com_finder'); $this->setState('params', $params); // List state information. parent::populateState('l.title', 'asc'); } /** * Method to change the published state of one or more records. * * @param array &$pks A list of the primary keys to change. * @param integer $value The value of the published state. [optional] * * @return boolean True on success. * * @since 2.5 */ public function publish(&$pks, $value = 1) { $dispatcher = JEventDispatcher::getInstance(); $user = JFactory::getUser(); $table = $this->getTable(); $pks = (array) $pks; // Include the content plugins for the change of state event. JPluginHelper::importPlugin('content'); // Access checks. foreach ($pks as $i => $pk) { $table->reset(); if ($table->load($pk)) { if (!$this->canEditState($table)) { // Prune items that you can't change. unset($pks[$i]); $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); return false; } } } // Attempt to change the state of the records. if (!$table->publish($pks, $value, $user->get('id'))) { $this->setError($table->getError()); return false; } $context = $this->option . '.' . $this->name; // Trigger the onContentChangeState event. $result = $dispatcher->trigger('onContentChangeState', array($context, $pks, $value)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } // Clear the component's cache $this->cleanCache(); return true; } } components/com_finder/models/index.html000066600000000036150771655450014340 0ustar00components/com_finder/models/fields/index.html000066600000000036150771655450015606 0ustar00components/com_finder/models/fields/searchfilter.php000066600000002311150771655450016773 0ustar00getQuery(true) ->select('f.title AS text, f.filter_id AS value') ->from($db->quoteName('#__finder_filters') . ' AS f') ->where('f.state = 1') ->order('f.title ASC'); $db->setQuery($query); $options = $db->loadObjectList(); array_unshift($options, JHtml::_('select.option', '', JText::_('COM_FINDER_SELECT_SEARCH_FILTER'), 'value', 'text')); return $options; } } components/com_finder/models/fields/directories.php000066600000004223150771655450016640 0ustar00getCfg('log_path'), JFactory::getApplication()->getCfg('tmp_path') ); // Get the base directories. jimport('joomla.filesystem.folder'); $dirs = JFolder::folders(JPATH_SITE, '.', false, true); // Iterate through the base directories and find the subdirectories. foreach ($dirs as $dir) { // Check if the directory should be excluded. if (in_array($dir, $exclude)) { continue; } // Get the child directories. $return = JFolder::folders($dir, '.', true, true); // Merge the directories. if (is_array($return)) { $values[] = $dir; $values = array_merge($values, $return); } } // Convert the values to options. foreach ($values as $value) { $options[] = JHtml::_('select.option', str_replace(JPATH_SITE . '/', '', $value), str_replace(JPATH_SITE . '/', '', $values)); } // Add a null option. array_unshift($options, JHtml::_('select.option', '', '- ' . JText::_('JNONE') . ' -')); return $options; } } components/com_finder/models/forms/index.html000066600000000036150771655450015466 0ustar00components/com_finder/models/forms/filter.xml000066600000006500150771655450015502 0ustar00
    components/com_finder/models/maps.php000066600000021370150771655450014020 0ustar00authorise('core.delete', $this->option); } /** * Method to test whether a record can be deleted. * * @param object $record A record object. * * @return boolean True if allowed to change the state of the record. Defaults to the permission for the component. * * @since 2.5 */ protected function canEditState($record) { $user = JFactory::getUser(); return $user->authorise('core.edit.state', $this->option); } /** * Method to delete one or more records. * * @param array &$pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * * @since 2.5 */ public function delete(&$pks) { $dispatcher = JEventDispatcher::getInstance(); $pks = (array) $pks; $table = $this->getTable(); // Include the content plugins for the on delete events. JPluginHelper::importPlugin('content'); // Iterate the items to delete each one. foreach ($pks as $i => $pk) { if ($table->load($pk)) { if ($this->canDelete($table)) { $context = $this->option . '.' . $this->name; // Trigger the onContentBeforeDelete event. $result = $dispatcher->trigger('onContentBeforeDelete', array($context, $table)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } if (!$table->delete($pk)) { $this->setError($table->getError()); return false; } // Trigger the onContentAfterDelete event. $dispatcher->trigger('onContentAfterDelete', array($context, $table)); } else { // Prune items that you can't change. unset($pks[$i]); $error = $this->getError(); if ($error) { $this->setError($error); } else { $this->setError(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); } } } else { $this->setError($table->getError()); return false; } } // Clear the component's cache $this->cleanCache(); return true; } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery A JDatabaseQuery object * * @since 2.5 */ protected function getListQuery() { $db = $this->getDbo(); $query = $db->getQuery(true); // Select all fields from the table. $query->select('a.*') ->from($db->quoteName('#__finder_taxonomy') . ' AS a'); // Self-join to get children. $query->select('COUNT(b.id) AS num_children') ->join('LEFT', $db->quoteName('#__finder_taxonomy') . ' AS b ON b.parent_id=a.id'); // Join to get the map links $query->select('COUNT(c.node_id) AS num_nodes') ->join('LEFT', $db->quoteName('#__finder_taxonomy_map') . ' AS c ON c.node_id=a.id') ->group('a.id, a.parent_id, a.title, a.state, a.access, a.ordering'); // If the model is set to check item state, add to the query. if (is_numeric($this->getState('filter.state'))) { $query->where('a.state = ' . (int) $this->getState('filter.state')); } // Filter the maps over the branch if set. $branch_id = $this->getState('filter.branch'); if (!empty($branch_id)) { $query->where('a.parent_id = ' . (int) $branch_id); } // Filter the maps over the search string if set. $search = $this->getState('filter.search'); if (!empty($search)) { $query->where('a.title LIKE ' . $db->quote('%' . $search . '%')); } // Handle the list ordering. $ordering = $this->getState('list.ordering'); $direction = $this->getState('list.direction'); if (!empty($ordering)) { $query->order($db->escape($ordering) . ' ' . $db->escape($direction)); } return $query; } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. [optional] * * @return string A store id. * * @since 2.5 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.state'); $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.branch'); return parent::getStoreId($id); } /** * Returns a JTable object, always creating it. * * @param string $type The table type to instantiate. [optional] * @param string $prefix A prefix for the table class name. [optional] * @param array $config Configuration array for model. [optional] * * @return JTable A database object * * @since 2.5 */ public function getTable($type = 'Map', $prefix = 'FinderTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Method to auto-populate the model state. Calling getState in this method will result in recursion. * * @param string $ordering An optional ordering field. [optional] * @param string $direction An optional direction. [optional] * * @return void * * @since 2.5 */ protected function populateState($ordering = null, $direction = null) { // Load the filter state. $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string'); $this->setState('filter.state', $state); $branch = $this->getUserStateFromRequest($this->context . '.filter.branch', 'filter_branch', '1', 'string'); $this->setState('filter.branch', $branch); // Load the parameters. $params = JComponentHelper::getParams('com_finder'); $this->setState('params', $params); // List state information. parent::populateState('a.title', 'asc'); } /** * Method to change the published state of one or more records. * * @param array &$pks A list of the primary keys to change. * @param integer $value The value of the published state. [optional] * * @return boolean True on success. * * @since 2.5 */ public function publish(&$pks, $value = 1) { $dispatcher = JEventDispatcher::getInstance(); $user = JFactory::getUser(); $table = $this->getTable(); $pks = (array) $pks; // Include the content plugins for the change of state event. JPluginHelper::importPlugin('content'); // Access checks. foreach ($pks as $i => $pk) { $table->reset(); if ($table->load($pk)) { if (!$this->canEditState($table)) { // Prune items that you can't change. unset($pks[$i]); $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); return false; } } } // Attempt to change the state of the records. if (!$table->publish($pks, $value, $user->get('id'))) { $this->setError($table->getError()); return false; } $context = $this->option . '.' . $this->name; // Trigger the onContentChangeState event. $result = $dispatcher->trigger('onContentChangeState', array($context, $pks, $value)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } // Clear the component's cache $this->cleanCache(); return true; } /** * Method to purge all maps from the taxonomy. * * @return boolean Returns true on success, false on failure. * * @since 2.5 */ public function purge() { $db = $this->getDbo(); $query = $db->getQuery(true) ->delete($db->quoteName('#__finder_taxonomy')) ->where($db->quoteName('parent_id') . ' > 1'); $db->setQuery($query); $db->execute(); $query->clear() ->delete($db->quoteName('#__finder_taxonomy_map')) ->where('1'); $db->setQuery($query); $db->execute(); return true; } } components/com_finder/models/indexer.php000066600000000705150771655450014515 0ustar00getState('filter.id'); // Get a FinderTableFilter instance. $filter = $this->getTable(); // Attempt to load the row. $return = $filter->load($filter_id); // Check for a database error. if ($return === false && $filter->getError()) { $this->setError($filter->getError()); return false; } // Process the filter data. if (!empty($filter->data)) { $filter->data = explode(',', $filter->data); } elseif (empty($filter->data)) { $filter->data = array(); } // Check for a database error. if ($this->_db->getErrorNum()) { $this->setError($this->_db->getErrorMsg()); return false; } return $filter; } /** * Method to get the record form. * * @param array $data Data for the form. [optional] * @param boolean $loadData True if the form is to load its own data (default case), false if not. [optional] * * @return mixed A JForm object on success, false on failure * * @since 2.5 */ public function getForm($data = array(), $loadData = true) { // Get the form. $form = $this->loadForm('com_finder.filter', 'filter', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } return $form; } /** * Returns a JTable object, always creating it. * * @param string $type The table type to instantiate. [optional] * @param string $prefix A prefix for the table class name. [optional] * @param array $config Configuration array for model. [optional] * * @return JTable A database object * * @since 2.5 */ public function getTable($type = 'Filter', $prefix = 'FinderTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * * @since 2.5 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_finder.edit.filter.data', array()); if (empty($data)) { $data = $this->getItem(); } $this->preprocessData('com_finder.filter', $data); return $data; } } components/com_finder/models/filters.php000066600000007152150771655450014532 0ustar00getDbo(); $query = $db->getQuery(true); // Select all fields from the table. $query->select('a.*') ->from($db->quoteName('#__finder_filters') . ' AS a'); // Join over the users for the checked out user. $query->select('uc.name AS editor') ->join('LEFT', $db->quoteName('#__users') . ' AS uc ON uc.id=a.checked_out'); // Join over the users for the author. $query->select('ua.name AS user_name') ->join('LEFT', $db->quoteName('#__users') . ' AS ua ON ua.id = a.created_by'); // Check for a search filter. if ($this->getState('filter.search')) { $query->where('( a.title LIKE \'%' . $db->escape($this->getState('filter.search')) . '%\' )'); } // If the model is set to check item state, add to the query. if (is_numeric($this->getState('filter.state'))) { $query->where('a.state = ' . (int) $this->getState('filter.state')); } // Add the list ordering clause. $query->order($db->escape($this->getState('list.ordering') . ' ' . $db->escape($this->getState('list.direction')))); return $query; } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. [optional] * * @return string A store id. * * @since 2.5 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.state'); return parent::getStoreId($id); } /** * Method to auto-populate the model state. Calling getState in this method will result in recursion. * * @param string $ordering An optional ordering field. [optional] * @param string $direction An optional direction. [optional] * * @return void * * @since 2.5 */ protected function populateState($ordering = null, $direction = null) { // Load the filter state. $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string'); $this->setState('filter.state', $state); // Load the parameters. $params = JComponentHelper::getParams('com_finder'); $this->setState('params', $params); // List state information. parent::populateState('a.title', 'asc'); } } components/com_finder/models/statistics.php000066600000004224150771655450015251 0ustar00getDbo(); $query = $db->getQuery(true); $data = new JObject; $query->select('COUNT(term_id)') ->from($db->quoteName('#__finder_terms')); $db->setQuery($query); $data->term_count = $db->loadResult(); $query->clear() ->select('COUNT(link_id)') ->from($db->quoteName('#__finder_links')); $db->setQuery($query); $data->link_count = $db->loadResult(); $query->clear() ->select('COUNT(id)') ->from($db->quoteName('#__finder_taxonomy')) ->where($db->quoteName('parent_id') . ' = 1'); $db->setQuery($query); $data->taxonomy_branch_count = $db->loadResult(); $query->clear() ->select('COUNT(id)') ->from($db->quoteName('#__finder_taxonomy')) ->where($db->quoteName('parent_id') . ' > 1'); $db->setQuery($query); $data->taxonomy_node_count = $db->loadResult(); $query->clear() ->select('t.title AS type_title, COUNT(a.link_id) AS link_count') ->from($db->quoteName('#__finder_links') . ' AS a') ->join('INNER', $db->quoteName('#__finder_types') . ' AS t ON t.id = a.type_id') ->group('a.type_id, t.title') ->order($db->quoteName('type_title'), 'ASC'); $db->setQuery($query); $data->type_list = $db->loadObjectList(); $lang = JFactory::getLanguage(); $plugins = JPluginHelper::getPlugin('finder'); foreach ($plugins as $plugin) { $lang->load('plg_finder_' . $plugin->name . '.sys', JPATH_ADMINISTRATOR, null, false, true) || $lang->load('plg_finder_' . $plugin->name . '.sys', JPATH_PLUGINS . '/finder/' . $plugin->name, null, false, true); } return $data; } } components/com_joomlaupdate/views/index.html000066600000000037150771655450015430 0ustar00 components/com_joomlaupdate/views/default/view.html.php000066600000003432150771655450017507 0ustar00state = $this->get('State'); // Load useful classes $model = $this->getModel(); $this->loadHelper('select'); // Assign view variables $ftp = $model->getFTPOptions(); $this->assign('updateInfo', $model->getUpdateInformation()); $this->assign('methodSelect', JoomlaupdateHelperSelect::getMethods($ftp['enabled'])); // Set the toolbar information JToolbarHelper::title(JText::_('COM_JOOMLAUPDATE_OVERVIEW'), 'arrow-up-2 install'); JToolbarHelper::custom('update.purge', 'purge', 'purge', 'JTOOLBAR_PURGE_CACHE', false, false); // Add toolbar buttons if (JFactory::getUser()->authorise('core.admin', 'com_joomlaupdate')) { JToolbarHelper::preferences('com_joomlaupdate'); } JToolBarHelper::divider(); JToolBarHelper::help('JHELP_COMPONENTS_JOOMLA_UPDATE'); // Load mooTools JHtml::_('behavior.framework', true); // Include jQuery JHtml::_('jquery.framework'); // Load our Javascript $document = JFactory::getDocument(); $document->addScript('../media/com_joomlaupdate/default.js'); JHtml::_('stylesheet', 'media/mediamanager.css', array(), true); // Render the view parent::display($tpl); } } components/com_joomlaupdate/views/default/tmpl/default.php000066600000007074150771655450020200 0ustar00ftp['enabled'] ? '' : 'style = "display: none"'; ?>
    updateInfo['object'])) : ?>

    > > > > >
    updateInfo['installed'] ?>
    updateInfo['latest'] ?>
    updateInfo['object']->downloadurl->_data ?>
    methodSelect ?>
     
    components/com_joomlaupdate/views/default/tmpl/complete.php000066600000000754150771655450020362 0ustar00

    components/com_joomlaupdate/views/default/tmpl/index.html000066600000000037150771655450020030 0ustar00 components/com_joomlaupdate/views/default/index.html000066600000000037150771655450017054 0ustar00 components/com_joomlaupdate/views/update/view.html.php000066600000004125150771655450017345 0ustar00getUserState('com_joomlaupdate.password', null); $filesize = JFactory::getApplication()->getUserState('com_joomlaupdate.filesize', null); $ajaxUrl = JUri::base().'components/com_joomlaupdate/restore.php'; $returnUrl = 'index.php?option=com_joomlaupdate&task=update.finalise'; // Set the toolbar information JToolbarHelper::title(JText::_('COM_JOOMLAUPDATE_OVERVIEW'), 'arrow-up-2 install'); JToolBarHelper::divider(); JToolBarHelper::help('JHELP_COMPONENTS_JOOMLA_UPDATE'); // Add toolbar buttons if (JFactory::getUser()->authorise('core.admin', 'com_joomlaupdate')) { JToolbarHelper::preferences('com_joomlaupdate'); } // Load mooTools JHtml::_('behavior.framework', true); // Include jQuery JHtml::_('jquery.framework'); $updateScript = <<addScript('../media/com_joomlaupdate/json2.js'); $document->addScript('../media/com_joomlaupdate/encryption.js'); $document->addScript('../media/com_joomlaupdate/update.js'); JHtml::_('jquery.framework'); JHtml::_('script', 'system/progressbar.js', true, true); JHtml::_('stylesheet', 'media/mediamanager.css', array(), true); $document->addScriptDeclaration($updateScript); // Render the view parent::display($tpl); } } components/com_joomlaupdate/views/update/tmpl/default.php000066600000002637150771655450020036 0ustar00

    'progress', 'id' => 'progress'), true ); ?>
    components/com_joomlaupdate/views/update/tmpl/index.html000066600000000037150771655450017666 0ustar00 components/com_joomlaupdate/views/update/index.html000066600000000037150771655450016712 0ustar00 components/com_joomlaupdate/index.html000066600000000037150771655450014273 0ustar00 components/com_joomlaupdate/config.xml000066600000002374150771655450014273 0ustar00
    components/com_joomlaupdate/restore.php000066600000523674150771655450014513 0ustar00|'), array('*' => '.*', '?' => '.?')) . '$/i', $string ); } } // Unicode-safe binary data length function if(function_exists('mb_strlen')) { function akstringlen($string) { return mb_strlen($string,'8bit'); } } else { function akstringlen($string) { return strlen($string); } } /** * Gets a query parameter from GET or POST data * @param $key * @param $default */ function getQueryParam( $key, $default = null ) { $value = null; if(array_key_exists($key, $_REQUEST)) { $value = $_REQUEST[$key]; } elseif(array_key_exists($key, $_POST)) { $value = $_POST[$key]; } elseif(array_key_exists($key, $_GET)) { $value = $_GET[$key]; } else { return $default; } if(get_magic_quotes_gpc() && !is_null($value)) $value=stripslashes($value); return $value; } /** * Akeeba Backup's JSON compatibility layer * * On systems where json_encode and json_decode are not available, Akeeba * Backup will attempt to use PEAR's Services_JSON library to emulate them. * A copy of this library is included in this file and will be used if and * only if it isn't already loaded, e.g. due to PEAR's auto-loading, or a * 3PD extension loading it for its own purposes. */ /** * Converts to and from JSON format. * * JSON (JavaScript Object Notation) is a lightweight data-interchange * format. It is easy for humans to read and write. It is easy for machines * to parse and generate. It is based on a subset of the JavaScript * Programming Language, Standard ECMA-262 3rd Edition - December 1999. * This feature can also be found in Python. JSON is a text format that is * completely language independent but uses conventions that are familiar * to programmers of the C-family of languages, including C, C++, C#, Java, * JavaScript, Perl, TCL, and many others. These properties make JSON an * ideal data-interchange language. * * This package provides a simple encoder and decoder for JSON notation. It * is intended for use with client-side Javascript applications that make * use of HTTPRequest to perform server communication functions - data can * be encoded into JSON notation for use in a client-side javascript, or * decoded from incoming Javascript requests. JSON format is native to * Javascript, and can be directly eval()'ed with no further parsing * overhead * * All strings should be in ASCII or UTF-8 format! * * LICENSE: Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: Redistributions of source code must retain the * above copyright notice, this list of conditions and the following * disclaimer. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * @category * @package Services_JSON * @author Michal Migurski * @author Matt Knapp * @author Brett Stimmerman * @copyright 2005 Michal Migurski * @version CVS: $Id: restore.php 612 2011-05-19 08:26:26Z nikosdion $ * @license http://www.opensource.org/licenses/bsd-license.php * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 */ if(!defined('JSON_FORCE_OBJECT')) { define('JSON_FORCE_OBJECT', 1); } if(!defined('SERVICES_JSON_SLICE')) { /** * Marker constant for Services_JSON::decode(), used to flag stack state */ define('SERVICES_JSON_SLICE', 1); /** * Marker constant for Services_JSON::decode(), used to flag stack state */ define('SERVICES_JSON_IN_STR', 2); /** * Marker constant for Services_JSON::decode(), used to flag stack state */ define('SERVICES_JSON_IN_ARR', 3); /** * Marker constant for Services_JSON::decode(), used to flag stack state */ define('SERVICES_JSON_IN_OBJ', 4); /** * Marker constant for Services_JSON::decode(), used to flag stack state */ define('SERVICES_JSON_IN_CMT', 5); /** * Behavior switch for Services_JSON::decode() */ define('SERVICES_JSON_LOOSE_TYPE', 16); /** * Behavior switch for Services_JSON::decode() */ define('SERVICES_JSON_SUPPRESS_ERRORS', 32); } /** * Converts to and from JSON format. * * Brief example of use: * * * // create a new instance of Services_JSON * $json = new Services_JSON(); * * // convert a complexe value to JSON notation, and send it to the browser * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); * $output = $json->encode($value); * * print($output); * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] * * // accept incoming POST data, assumed to be in JSON notation * $input = file_get_contents('php://input', 1000000); * $value = $json->decode($input); * */ if(!class_exists('Akeeba_Services_JSON')) { class Akeeba_Services_JSON { /** * constructs a new JSON instance * * @param int $use object behavior flags; combine with boolean-OR * * possible values: * - SERVICES_JSON_LOOSE_TYPE: loose typing. * "{...}" syntax creates associative arrays * instead of objects in decode(). * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. * Values which can't be encoded (e.g. resources) * appear as NULL instead of throwing errors. * By default, a deeply-nested resource will * bubble up with an error, so all return values * from encode() should be checked with isError() */ function Akeeba_Services_JSON($use = 0) { $this->use = $use; } /** * convert a string from one UTF-16 char to one UTF-8 char * * Normally should be handled by mb_convert_encoding, but * provides a slower PHP-only method for installations * that lack the multibye string extension. * * @param string $utf16 UTF-16 character * @return string UTF-8 character * @access private */ function utf162utf8($utf16) { // oh please oh please oh please oh please oh please if(function_exists('mb_convert_encoding')) { return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); } $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); switch(true) { case ((0x7F & $bytes) == $bytes): // this case should never be reached, because we are in ASCII range // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr(0x7F & $bytes); case (0x07FF & $bytes) == $bytes: // return a 2-byte UTF-8 character // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr(0xC0 | (($bytes >> 6) & 0x1F)) . chr(0x80 | ($bytes & 0x3F)); case (0xFFFF & $bytes) == $bytes: // return a 3-byte UTF-8 character // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr(0xE0 | (($bytes >> 12) & 0x0F)) . chr(0x80 | (($bytes >> 6) & 0x3F)) . chr(0x80 | ($bytes & 0x3F)); } // ignoring UTF-32 for now, sorry return ''; } /** * convert a string from one UTF-8 char to one UTF-16 char * * Normally should be handled by mb_convert_encoding, but * provides a slower PHP-only method for installations * that lack the multibye string extension. * * @param string $utf8 UTF-8 character * @return string UTF-16 character * @access private */ function utf82utf16($utf8) { // oh please oh please oh please oh please oh please if(function_exists('mb_convert_encoding')) { return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); } switch(strlen($utf8)) { case 1: // this case should never be reached, because we are in ASCII range // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return $utf8; case 2: // return a UTF-16 character from a 2-byte UTF-8 char // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr(0x07 & (ord($utf8{0}) >> 2)) . chr((0xC0 & (ord($utf8{0}) << 6)) | (0x3F & ord($utf8{1}))); case 3: // return a UTF-16 character from a 3-byte UTF-8 char // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr((0xF0 & (ord($utf8{0}) << 4)) | (0x0F & (ord($utf8{1}) >> 2))) . chr((0xC0 & (ord($utf8{1}) << 6)) | (0x7F & ord($utf8{2}))); } // ignoring UTF-32 for now, sorry return ''; } /** * encodes an arbitrary variable into JSON format * * @param mixed $var any number, boolean, string, array, or object to be encoded. * see argument 1 to Services_JSON() above for array-parsing behavior. * if var is a strng, note that encode() always expects it * to be in ASCII or UTF-8 format! * * @return mixed JSON string representation of input var or an error if a problem occurs * @access public */ function encode($var) { switch (gettype($var)) { case 'boolean': return $var ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $var; case 'double': case 'float': return (float) $var; case 'string': // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT $ascii = ''; $strlen_var = strlen($var); /* * Iterate over every character in the string, * escaping with a slash or encoding to UTF-8 where necessary */ for ($c = 0; $c < $strlen_var; ++$c) { $ord_var_c = ord($var{$c}); switch (true) { case $ord_var_c == 0x08: $ascii .= '\b'; break; case $ord_var_c == 0x09: $ascii .= '\t'; break; case $ord_var_c == 0x0A: $ascii .= '\n'; break; case $ord_var_c == 0x0C: $ascii .= '\f'; break; case $ord_var_c == 0x0D: $ascii .= '\r'; break; case $ord_var_c == 0x22: case $ord_var_c == 0x2F: case $ord_var_c == 0x5C: // double quote, slash, slosh $ascii .= '\\'.$var{$c}; break; case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): // characters U-00000000 - U-0000007F (same as ASCII) $ascii .= $var{$c}; break; case (($ord_var_c & 0xE0) == 0xC0): // characters U-00000080 - U-000007FF, mask 110XXXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1})); $c += 1; $utf16 = $this->utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xF0) == 0xE0): // characters U-00000800 - U-0000FFFF, mask 1110XXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2})); $c += 2; $utf16 = $this->utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xF8) == 0xF0): // characters U-00010000 - U-001FFFFF, mask 11110XXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2}), ord($var{$c + 3})); $c += 3; $utf16 = $this->utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xFC) == 0xF8): // characters U-00200000 - U-03FFFFFF, mask 111110XX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2}), ord($var{$c + 3}), ord($var{$c + 4})); $c += 4; $utf16 = $this->utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xFE) == 0xFC): // characters U-04000000 - U-7FFFFFFF, mask 1111110X // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2}), ord($var{$c + 3}), ord($var{$c + 4}), ord($var{$c + 5})); $c += 5; $utf16 = $this->utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; } } return '"'.$ascii.'"'; case 'array': /* * As per JSON spec if any array key is not an integer * we must treat the the whole array as an object. We * also try to catch a sparsely populated associative * array with numeric keys here because some JS engines * will create an array with empty indexes up to * max_index which can cause memory issues and because * the keys, which may be relevant, will be remapped * otherwise. * * As per the ECMA and JSON specification an object may * have any string as a property. Unfortunately due to * a hole in the ECMA specification if the key is a * ECMA reserved word or starts with a digit the * parameter is only accessible using ECMAScript's * bracket notation. */ // treat as a JSON object if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { $properties = array_map(array($this, 'name_value'), array_keys($var), array_values($var)); foreach($properties as $property) { if(Akeeba_Services_JSON::isError($property)) { return $property; } } return '{' . join(',', $properties) . '}'; } // treat it like a regular array $elements = array_map(array($this, 'encode'), $var); foreach($elements as $element) { if(Akeeba_Services_JSON::isError($element)) { return $element; } } return '[' . join(',', $elements) . ']'; case 'object': $vars = get_object_vars($var); $properties = array_map(array($this, 'name_value'), array_keys($vars), array_values($vars)); foreach($properties as $property) { if(Akeeba_Services_JSON::isError($property)) { return $property; } } return '{' . join(',', $properties) . '}'; default: return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) ? 'null' : new Akeeba_Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); } } /** * array-walking function for use in generating JSON-formatted name-value pairs * * @param string $name name of key to use * @param mixed $value reference to an array element to be encoded * * @return string JSON-formatted name-value pair, like '"name":value' * @access private */ function name_value($name, $value) { $encoded_value = $this->encode($value); if(Akeeba_Services_JSON::isError($encoded_value)) { return $encoded_value; } return $this->encode(strval($name)) . ':' . $encoded_value; } /** * reduce a string by removing leading and trailing comments and whitespace * * @param $str string string value to strip of comments and whitespace * * @return string string value stripped of comments and whitespace * @access private */ function reduce_string($str) { $str = preg_replace(array( // eliminate single line comments in '// ...' form '#^\s*//(.+)$#m', // eliminate multi-line comments in '/* ... */' form, at start of string '#^\s*/\*(.+)\*/#Us', // eliminate multi-line comments in '/* ... */' form, at end of string '#/\*(.+)\*/\s*$#Us' ), '', $str); // eliminate extraneous space return trim($str); } /** * decodes a JSON string into appropriate variable * * @param string $str JSON-formatted string * * @return mixed number, boolean, string, array, or object * corresponding to given JSON input string. * See argument 1 to Akeeba_Services_JSON() above for object-output behavior. * Note that decode() always returns strings * in ASCII or UTF-8 format! * @access public */ function decode($str) { $str = $this->reduce_string($str); switch (strtolower($str)) { case 'true': return true; case 'false': return false; case 'null': return null; default: $m = array(); if (is_numeric($str)) { // Lookie-loo, it's a number // This would work on its own, but I'm trying to be // good about returning integers where appropriate: // return (float)$str; // Return float or int, as appropriate return ((float)$str == (integer)$str) ? (integer)$str : (float)$str; } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { // STRINGS RETURNED IN UTF-8 FORMAT $delim = substr($str, 0, 1); $chrs = substr($str, 1, -1); $utf8 = ''; $strlen_chrs = strlen($chrs); for ($c = 0; $c < $strlen_chrs; ++$c) { $substr_chrs_c_2 = substr($chrs, $c, 2); $ord_chrs_c = ord($chrs{$c}); switch (true) { case $substr_chrs_c_2 == '\b': $utf8 .= chr(0x08); ++$c; break; case $substr_chrs_c_2 == '\t': $utf8 .= chr(0x09); ++$c; break; case $substr_chrs_c_2 == '\n': $utf8 .= chr(0x0A); ++$c; break; case $substr_chrs_c_2 == '\f': $utf8 .= chr(0x0C); ++$c; break; case $substr_chrs_c_2 == '\r': $utf8 .= chr(0x0D); ++$c; break; case $substr_chrs_c_2 == '\\"': case $substr_chrs_c_2 == '\\\'': case $substr_chrs_c_2 == '\\\\': case $substr_chrs_c_2 == '\\/': if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || ($delim == "'" && $substr_chrs_c_2 != '\\"')) { $utf8 .= $chrs{++$c}; } break; case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): // single, escaped unicode character $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) . chr(hexdec(substr($chrs, ($c + 4), 2))); $utf8 .= $this->utf162utf8($utf16); $c += 5; break; case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): $utf8 .= $chrs{$c}; break; case ($ord_chrs_c & 0xE0) == 0xC0: // characters U-00000080 - U-000007FF, mask 110XXXXX //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $c, 2); ++$c; break; case ($ord_chrs_c & 0xF0) == 0xE0: // characters U-00000800 - U-0000FFFF, mask 1110XXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $c, 3); $c += 2; break; case ($ord_chrs_c & 0xF8) == 0xF0: // characters U-00010000 - U-001FFFFF, mask 11110XXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $c, 4); $c += 3; break; case ($ord_chrs_c & 0xFC) == 0xF8: // characters U-00200000 - U-03FFFFFF, mask 111110XX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $c, 5); $c += 4; break; case ($ord_chrs_c & 0xFE) == 0xFC: // characters U-04000000 - U-7FFFFFFF, mask 1111110X // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $c, 6); $c += 5; break; } } return $utf8; } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { // array, or object notation if ($str{0} == '[') { $stk = array(SERVICES_JSON_IN_ARR); $arr = array(); } else { if ($this->use & SERVICES_JSON_LOOSE_TYPE) { $stk = array(SERVICES_JSON_IN_OBJ); $obj = array(); } else { $stk = array(SERVICES_JSON_IN_OBJ); $obj = new stdClass(); } } array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => 0, 'delim' => false)); $chrs = substr($str, 1, -1); $chrs = $this->reduce_string($chrs); if ($chrs == '') { if (reset($stk) == SERVICES_JSON_IN_ARR) { return $arr; } else { return $obj; } } //print("\nparsing {$chrs}\n"); $strlen_chrs = strlen($chrs); for ($c = 0; $c <= $strlen_chrs; ++$c) { $top = end($stk); $substr_chrs_c_2 = substr($chrs, $c, 2); if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { // found a comma that is not inside a string, array, etc., // OR we've reached the end of the character list $slice = substr($chrs, $top['where'], ($c - $top['where'])); array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); if (reset($stk) == SERVICES_JSON_IN_ARR) { // we are in an array, so just push an element onto the stack array_push($arr, $this->decode($slice)); } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { // we are in an object, so figure // out the property name and set an // element in an associative array, // for now $parts = array(); if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { // "name":value pair $key = $this->decode($parts[1]); $val = $this->decode($parts[2]); if ($this->use & SERVICES_JSON_LOOSE_TYPE) { $obj[$key] = $val; } else { $obj->$key = $val; } } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { // name:value pair, where name is unquoted $key = $parts[1]; $val = $this->decode($parts[2]); if ($this->use & SERVICES_JSON_LOOSE_TYPE) { $obj[$key] = $val; } else { $obj->$key = $val; } } } } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { // found a quote, and we are not inside a string array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); //print("Found start of string at {$c}\n"); } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == SERVICES_JSON_IN_STR) && ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { // found a quote, we're in a string, and it's not escaped // we know that it's not escaped becase there is _not_ an // odd number of backslashes at the end of the string so far array_pop($stk); //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); } elseif (($chrs{$c} == '[') && in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { // found a left-bracket, and we are in an array, object, or slice array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); //print("Found start of array at {$c}\n"); } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { // found a right-bracket, and we're in an array array_pop($stk); //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); } elseif (($chrs{$c} == '{') && in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { // found a left-brace, and we are in an array, object, or slice array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); //print("Found start of object at {$c}\n"); } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { // found a right-brace, and we're in an object array_pop($stk); //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { // found a comment start, and we are in an array, object, or slice array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); $c++; //print("Found start of comment at {$c}\n"); } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { // found a comment end, and we're in one now array_pop($stk); $c++; for ($i = $top['where']; $i <= $c; ++$i) $chrs = substr_replace($chrs, ' ', $i, 1); //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); } } if (reset($stk) == SERVICES_JSON_IN_ARR) { return $arr; } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { return $obj; } } } } function isError($data, $code = null) { if (class_exists('pear')) { return PEAR::isError($data, $code); } elseif (is_object($data) && (get_class($data) == 'services_json_error' || is_subclass_of($data, 'services_json_error'))) { return true; } return false; } } class Akeeba_Services_JSON_Error { function Akeeba_Services_JSON_Error($message = 'unknown error', $code = null, $mode = null, $options = null, $userinfo = null) { } } } if(!function_exists('json_encode')) { function json_encode($value, $options = 0) { $flags = SERVICES_JSON_LOOSE_TYPE; if( $options & JSON_FORCE_OBJECT ) $flags = 0; $encoder = new Akeeba_Services_JSON($flags); return $encoder->encode($value); } } if(!function_exists('json_decode')) { function json_decode($value, $assoc = false) { $flags = 0; if($assoc) $flags = SERVICES_JSON_LOOSE_TYPE; $decoder = new Akeeba_Services_JSON($flags); return $decoder->decode($value); } } /** * The base class of Akeeba Engine objects. Allows for error and warnings logging * and propagation. Largely based on the Joomla! 1.5 JObject class. */ abstract class AKAbstractObject { /** @var array An array of errors */ private $_errors = array(); /** @var array The queue size of the $_errors array. Set to 0 for infinite size. */ protected $_errors_queue_size = 0; /** @var array An array of warnings */ private $_warnings = array(); /** @var array The queue size of the $_warnings array. Set to 0 for infinite size. */ protected $_warnings_queue_size = 0; /** * Public constructor, makes sure we are instanciated only by the factory class */ public function __construct() { /* // Assisted Singleton pattern if(function_exists('debug_backtrace')) { $caller=debug_backtrace(); if( ($caller[1]['class'] != 'AKFactory') && ($caller[2]['class'] != 'AKFactory') && ($caller[3]['class'] != 'AKFactory') && ($caller[4]['class'] != 'AKFactory') ) { var_dump(debug_backtrace()); trigger_error("You can't create direct descendants of ".__CLASS__, E_USER_ERROR); } } */ } /** * Get the most recent error message * @param integer $i Optional error index * @return string Error message */ public function getError($i = null) { return $this->getItemFromArray($this->_errors, $i); } /** * Return all errors, if any * @return array Array of error messages */ public function getErrors() { return $this->_errors; } /** * Add an error message * @param string $error Error message */ public function setError($error) { if($this->_errors_queue_size > 0) { if(count($this->_errors) >= $this->_errors_queue_size) { array_shift($this->_errors); } } array_push($this->_errors, $error); } /** * Resets all error messages */ public function resetErrors() { $this->_errors = array(); } /** * Get the most recent warning message * @param integer $i Optional warning index * @return string Error message */ public function getWarning($i = null) { return $this->getItemFromArray($this->_warnings, $i); } /** * Return all warnings, if any * @return array Array of error messages */ public function getWarnings() { return $this->_warnings; } /** * Add an error message * @param string $error Error message */ public function setWarning($warning) { if($this->_warnings_queue_size > 0) { if(count($this->_warnings) >= $this->_warnings_queue_size) { array_shift($this->_warnings); } } array_push($this->_warnings, $warning); } /** * Resets all warning messages */ public function resetWarnings() { $this->_warnings = array(); } /** * Propagates errors and warnings to a foreign object. The foreign object SHOULD * implement the setError() and/or setWarning() methods but DOESN'T HAVE TO be of * AKAbstractObject type. For example, this can even be used to propagate to a * JObject instance in Joomla!. Propagated items will be removed from ourself. * @param object $object The object to propagate errors and warnings to. */ public function propagateToObject(&$object) { // Skip non-objects if(!is_object($object)) return; if( method_exists($object,'setError') ) { if(!empty($this->_errors)) { foreach($this->_errors as $error) { $object->setError($error); } $this->_errors = array(); } } if( method_exists($object,'setWarning') ) { if(!empty($this->_warnings)) { foreach($this->_warnings as $warning) { $object->setWarning($warning); } $this->_warnings = array(); } } } /** * Propagates errors and warnings from a foreign object. Each propagated list is * then cleared on the foreign object, as long as it implements resetErrors() and/or * resetWarnings() methods. * @param object $object The object to propagate errors and warnings from */ public function propagateFromObject(&$object) { if( method_exists($object,'getErrors') ) { $errors = $object->getErrors(); if(!empty($errors)) { foreach($errors as $error) { $this->setError($error); } } if(method_exists($object,'resetErrors')) { $object->resetErrors(); } } if( method_exists($object,'getWarnings') ) { $warnings = $object->getWarnings(); if(!empty($warnings)) { foreach($warnings as $warning) { $this->setWarning($warning); } } if(method_exists($object,'resetWarnings')) { $object->resetWarnings(); } } } /** * Sets the size of the error queue (acts like a LIFO buffer) * @param int $newSize The new queue size. Set to 0 for infinite length. */ protected function setErrorsQueueSize($newSize = 0) { $this->_errors_queue_size = (int)$newSize; } /** * Sets the size of the warnings queue (acts like a LIFO buffer) * @param int $newSize The new queue size. Set to 0 for infinite length. */ protected function setWarningsQueueSize($newSize = 0) { $this->_warnings_queue_size = (int)$newSize; } /** * Returns the last item of a LIFO string message queue, or a specific item * if so specified. * @param array $array An array of strings, holding messages * @param int $i Optional message index * @return mixed The message string, or false if the key doesn't exist */ private function getItemFromArray($array, $i = null) { // Find the item if ( $i === null) { // Default, return the last item $item = end($array); } else if ( ! array_key_exists($i, $array) ) { // If $i has been specified but does not exist, return false return false; } else { $item = $array[$i]; } return $item; } } /** * File post processor engines base class */ abstract class AKAbstractPostproc extends AKAbstractObject { /** @var string The current (real) file path we'll have to process */ protected $filename = null; /** @var int The requested permissions */ protected $perms = 0755; /** @var string The temporary file path we gave to the unarchiver engine */ protected $tempFilename = null; /** @var int The UNIX timestamp of the file's desired modification date */ public $timestamp = 0; /** * Processes the current file, e.g. moves it from temp to final location by FTP */ abstract public function process(); /** * The unarchiver tells us the path to the filename it wants to extract and we give it * a different path instead. * @param string $filename The path to the real file * @param int $perms The permissions we need the file to have * @return string The path to the temporary file */ abstract public function processFilename($filename, $perms = 0755); /** * Recursively creates a directory if it doesn't exist * @param string $dirName The directory to create * @param int $perms The permissions to give to that directory */ abstract public function createDirRecursive( $dirName, $perms ); abstract public function chmod( $file, $perms ); abstract public function unlink( $file ); abstract public function rmdir( $directory ); abstract public function rename( $from, $to ); } /** * The base class of unarchiver classes */ abstract class AKAbstractUnarchiver extends AKAbstractPart { /** @var string Archive filename */ protected $filename = null; /** @var array List of the names of all archive parts */ public $archiveList = array(); /** @var int The total size of all archive parts */ public $totalSize = array(); /** @var integer Current archive part number */ protected $currentPartNumber = -1; /** @var integer The offset inside the current part */ protected $currentPartOffset = 0; /** @var bool Should I restore permissions? */ protected $flagRestorePermissions = false; /** @var AKAbstractPostproc Post processing class */ protected $postProcEngine = null; /** @var string Absolute path to prepend to extracted files */ protected $addPath = ''; /** @var array Which files to rename */ public $renameFiles = array(); /** @var array Which directories to rename */ public $renameDirs = array(); /** @var array Which files to skip */ public $skipFiles = array(); /** @var integer Chunk size for processing */ protected $chunkSize = 524288; /** @var resource File pointer to the current archive part file */ protected $fp = null; /** @var int Run state when processing the current archive file */ protected $runState = null; /** @var stdClass File header data, as read by the readFileHeader() method */ protected $fileHeader = null; /** @var int How much of the uncompressed data we've read so far */ protected $dataReadLength = 0; /** * Public constructor */ public function __construct() { parent::__construct(); } /** * Wakeup function, called whenever the class is unserialized */ public function __wakeup() { if($this->currentPartNumber >= 0) { $this->fp = @fopen($this->archiveList[$this->currentPartNumber], 'rb'); if( (is_resource($this->fp)) && ($this->currentPartOffset > 0) ) { @fseek($this->fp, $this->currentPartOffset); } } } /** * Sleep function, called whenever the class is serialized */ public function shutdown() { if(is_resource($this->fp)) { $this->currentPartOffset = @ftell($this->fp); @fclose($this->fp); } } /** * Implements the abstract _prepare() method */ final protected function _prepare() { parent::__construct(); if( count($this->_parametersArray) > 0 ) { foreach($this->_parametersArray as $key => $value) { switch($key) { case 'filename': // Archive's absolute filename $this->filename = $value; break; case 'restore_permissions': // Should I restore permissions? $this->flagRestorePermissions = $value; break; case 'post_proc': // Should I use FTP? $this->postProcEngine = AKFactory::getpostProc($value); break; case 'add_path': // Path to prepend $this->addPath = $value; $this->addPath = str_replace('\\','/',$this->addPath); $this->addPath = rtrim($this->addPath,'/'); if(!empty($this->addPath)) $this->addPath .= '/'; break; case 'rename_files': // Which files to rename (hash array) $this->renameFiles = $value; break; case 'rename_dirs': // Which files to rename (hash array) $this->renameDirs = $value; break; case 'skip_files': // Which files to skip (indexed array) $this->skipFiles = $value; break; } } } $this->scanArchives(); $this->readArchiveHeader(); $errMessage = $this->getError(); if(!empty($errMessage)) { $this->setState('error', $errMessage); } else { $this->runState = AK_STATE_NOFILE; $this->setState('prepared'); } } protected function _run() { if($this->getState() == 'postrun') return; $this->setState('running'); $timer = AKFactory::getTimer(); $status = true; while( $status && ($timer->getTimeLeft() > 0) ) { switch( $this->runState ) { case AK_STATE_NOFILE: $status = $this->readFileHeader(); if($status) { // Send start of file notification $message = new stdClass; $message->type = 'startfile'; $message->content = new stdClass; if( array_key_exists('realfile', get_object_vars($this->fileHeader)) ) { $message->content->realfile = $this->fileHeader->realFile; } else { $message->content->realfile = $this->fileHeader->file; } $message->content->file = $this->fileHeader->file; if( array_key_exists('compressed', get_object_vars($this->fileHeader)) ) { $message->content->compressed = $this->fileHeader->compressed; } else { $message->content->compressed = 0; } $message->content->uncompressed = $this->fileHeader->uncompressed; $this->notify($message); } break; case AK_STATE_HEADER: case AK_STATE_DATA: $status = $this->processFileData(); break; case AK_STATE_DATAREAD: case AK_STATE_POSTPROC: $this->postProcEngine->timestamp = $this->fileHeader->timestamp; $status = $this->postProcEngine->process(); $this->propagateFromObject( $this->postProcEngine ); $this->runState = AK_STATE_DONE; break; case AK_STATE_DONE: default: if($status) { // Send end of file notification $message = new stdClass; $message->type = 'endfile'; $message->content = new stdClass; if( array_key_exists('realfile', get_object_vars($this->fileHeader)) ) { $message->content->realfile = $this->fileHeader->realFile; } else { $message->content->realfile = $this->fileHeader->file; } $message->content->file = $this->fileHeader->file; if( array_key_exists('compressed', get_object_vars($this->fileHeader)) ) { $message->content->compressed = $this->fileHeader->compressed; } else { $message->content->compressed = 0; } $message->content->uncompressed = $this->fileHeader->uncompressed; $this->notify($message); } $this->runState = AK_STATE_NOFILE; continue; } } $error = $this->getError(); if( !$status && ($this->runState == AK_STATE_NOFILE) && empty( $error ) ) { // We just finished $this->setState('postrun'); } elseif( !empty($error) ) { $this->setState( 'error', $error ); } } protected function _finalize() { // Nothing to do $this->setState('finished'); } /** * Returns the base extension of the file, e.g. '.jpa' * @return string */ private function getBaseExtension() { static $baseextension; if(empty($baseextension)) { $basename = basename($this->filename); $lastdot = strrpos($basename,'.'); $baseextension = substr($basename, $lastdot); } return $baseextension; } /** * Scans for archive parts */ private function scanArchives() { $privateArchiveList = array(); // Get the components of the archive filename $dirname = dirname($this->filename); $base_extension = $this->getBaseExtension(); $basename = basename($this->filename, $base_extension); $this->totalSize = 0; // Scan for multiple parts until we don't find any more of them $count = 0; $found = true; $this->archiveList = array(); while($found) { ++$count; $extension = substr($base_extension, 0, 2).sprintf('%02d', $count); $filename = $dirname.DIRECTORY_SEPARATOR.$basename.$extension; $found = file_exists($filename); if($found) { // Add yet another part, with a numeric-appended filename $this->archiveList[] = $filename; $filesize = @filesize($filename); $this->totalSize += $filesize; $privateArchiveList[] = array($filename, $filesize); } else { // Add the last part, with the regular extension $this->archiveList[] = $this->filename; $filename = $this->filename; $filesize = @filesize($filename); $this->totalSize += $filesize; $privateArchiveList[] = array($filename, $filesize); } } $this->currentPartNumber = -1; $this->currentPartOffset = 0; $this->runState = AK_STATE_NOFILE; // Send start of file notification $message = new stdClass; $message->type = 'totalsize'; $message->content = new stdClass; $message->content->totalsize = $this->totalSize; $message->content->filelist = $privateArchiveList; $this->notify($message); } /** * Opens the next part file for reading */ protected function nextFile() { ++$this->currentPartNumber; if( $this->currentPartNumber > (count($this->archiveList) - 1) ) { $this->setState('postrun'); return false; } else { if( is_resource($this->fp) ) @fclose($this->fp); $this->fp = @fopen( $this->archiveList[$this->currentPartNumber], 'rb' ); fseek($this->fp, 0); $this->currentPartOffset = 0; return true; } } /** * Returns true if we have reached the end of file * @param $local bool True to return EOF of the local file, false (default) to return if we have reached the end of the archive set * @return bool True if we have reached End Of File */ protected function isEOF($local = false) { $eof = @feof($this->fp); if(!$eof) { // Border case: right at the part's end (eeeek!!!). For the life of me, I don't understand why // feof() doesn't report true. It expects the fp to be positioned *beyond* the EOF to report // true. Incredible! :( $position = @ftell($this->fp); $filesize = @filesize( $this->archiveList[$this->currentPartNumber] ); if( $position >= $filesize ) $eof = true; } if($local) { return $eof; } else { return $eof && ($this->currentPartNumber >= (count($this->archiveList)-1) ); } } /** * Tries to make a directory user-writable so that we can write a file to it * @param $path string A path to a file */ protected function setCorrectPermissions($path) { static $rootDir = null; if(is_null($rootDir)) { $rootDir = rtrim(AKFactory::get('kickstart.setup.destdir',''),'/\\'); } $directory = rtrim(dirname($path),'/\\'); if($directory != $rootDir) { // Is this an unwritable directory? if(!is_writeable($directory)) { $this->postProcEngine->chmod( $directory, 0755 ); } } $this->postProcEngine->chmod( $path, 0644 ); } /** * Concrete classes are supposed to use this method in order to read the archive's header and * prepare themselves to the point of being ready to extract the first file. */ protected abstract function readArchiveHeader(); /** * Concrete classes must use this method to read the file header * @return bool True if reading the file was successful, false if an error occured or we reached end of archive */ protected abstract function readFileHeader(); /** * Concrete classes must use this method to process file data. It must set $runState to AK_STATE_DATAREAD when * it's finished processing the file data. * @return bool True if processing the file data was successful, false if an error occured */ protected abstract function processFileData(); /** * Reads data from the archive and notifies the observer with the 'reading' message * @param $fp * @param $length */ protected function fread($fp, $length = null) { if(is_numeric($length)) { if($length > 0) { $data = fread($fp, $length); } else { $data = fread($fp); } } else { $data = fread($fp); } if($data === false) $data = ''; // Send start of file notification $message = new stdClass; $message->type = 'reading'; $message->content = new stdClass; $message->content->length = strlen($data); $this->notify($message); return $data; } } /** * The superclass of all Akeeba Kickstart parts. The "parts" are intelligent stateful * classes which perform a single procedure and have preparation, running and * finalization phases. The transition between phases is handled automatically by * this superclass' tick() final public method, which should be the ONLY public API * exposed to the rest of the Akeeba Engine. */ abstract class AKAbstractPart extends AKAbstractObject { /** * Indicates whether this part has finished its initialisation cycle * @var boolean */ protected $isPrepared = false; /** * Indicates whether this part has more work to do (it's in running state) * @var boolean */ protected $isRunning = false; /** * Indicates whether this part has finished its finalization cycle * @var boolean */ protected $isFinished = false; /** * Indicates whether this part has finished its run cycle * @var boolean */ protected $hasRan = false; /** * The name of the engine part (a.k.a. Domain), used in return table * generation. * @var string */ protected $active_domain = ""; /** * The step this engine part is in. Used verbatim in return table and * should be set by the code in the _run() method. * @var string */ protected $active_step = ""; /** * A more detailed description of the step this engine part is in. Used * verbatim in return table and should be set by the code in the _run() * method. * @var string */ protected $active_substep = ""; /** * Any configuration variables, in the form of an array. * @var array */ protected $_parametersArray = array(); /** @var string The database root key */ protected $databaseRoot = array(); /** @var int Last reported warnings's position in array */ private $warnings_pointer = -1; /** @var array An array of observers */ protected $observers = array(); /** * Runs the preparation for this part. Should set _isPrepared * to true */ abstract protected function _prepare(); /** * Runs the finalisation process for this part. Should set * _isFinished to true. */ abstract protected function _finalize(); /** * Runs the main functionality loop for this part. Upon calling, * should set the _isRunning to true. When it finished, should set * the _hasRan to true. If an error is encountered, setError should * be used. */ abstract protected function _run(); /** * Sets the BREAKFLAG, which instructs this engine part that the current step must break immediately, * in fear of timing out. */ protected function setBreakFlag() { AKFactory::set('volatile.breakflag', true); } /** * Sets the engine part's internal state, in an easy to use manner * * @param string $state One of init, prepared, running, postrun, finished, error * @param string $errorMessage The reported error message, should the state be set to error */ protected function setState($state = 'init', $errorMessage='Invalid setState argument') { switch($state) { case 'init': $this->isPrepared = false; $this->isRunning = false; $this->isFinished = false; $this->hasRun = false; break; case 'prepared': $this->isPrepared = true; $this->isRunning = false; $this->isFinished = false; $this->hasRun = false; break; case 'running': $this->isPrepared = true; $this->isRunning = true; $this->isFinished = false; $this->hasRun = false; break; case 'postrun': $this->isPrepared = true; $this->isRunning = false; $this->isFinished = false; $this->hasRun = true; break; case 'finished': $this->isPrepared = true; $this->isRunning = false; $this->isFinished = true; $this->hasRun = false; break; case 'error': default: $this->setError($errorMessage); break; } } /** * The public interface to an engine part. This method takes care for * calling the correct method in order to perform the initialisation - * run - finalisation cycle of operation and return a proper reponse array. * @return array A Reponse Array */ final public function tick() { // Call the right action method, depending on engine part state switch( $this->getState() ) { case "init": $this->_prepare(); break; case "prepared": $this->_run(); break; case "running": $this->_run(); break; case "postrun": $this->_finalize(); break; } // Send a Return Table back to the caller $out = $this->_makeReturnTable(); return $out; } /** * Returns a copy of the class's status array * @return array */ public function getStatusArray() { return $this->_makeReturnTable(); } /** * Sends any kind of setup information to the engine part. Using this, * we avoid passing parameters to the constructor of the class. These * parameters should be passed as an indexed array and should be taken * into account during the preparation process only. This function will * set the error flag if it's called after the engine part is prepared. * * @param array $parametersArray The parameters to be passed to the * engine part. */ final public function setup( $parametersArray ) { if( $this->isPrepared ) { $this->setState('error', "Can't modify configuration after the preparation of " . $this->active_domain); } else { $this->_parametersArray = $parametersArray; if(array_key_exists('root', $parametersArray)) { $this->databaseRoot = $parametersArray['root']; } } } /** * Returns the state of this engine part. * * @return string The state of this engine part. It can be one of * error, init, prepared, running, postrun, finished. */ final public function getState() { if( $this->getError() ) { return "error"; } if( !($this->isPrepared) ) { return "init"; } if( !($this->isFinished) && !($this->isRunning) && !( $this->hasRun ) && ($this->isPrepared) ) { return "prepared"; } if ( !($this->isFinished) && $this->isRunning && !( $this->hasRun ) ) { return "running"; } if ( !($this->isFinished) && !($this->isRunning) && $this->hasRun ) { return "postrun"; } if ( $this->isFinished ) { return "finished"; } } /** * Constructs a Response Array based on the engine part's state. * @return array The Response Array for the current state */ final protected function _makeReturnTable() { // Get a list of warnings $warnings = $this->getWarnings(); // Report only new warnings if there is no warnings queue size if( $this->_warnings_queue_size == 0 ) { if( ($this->warnings_pointer > 0) && ($this->warnings_pointer < (count($warnings)) ) ) { $warnings = array_slice($warnings, $this->warnings_pointer + 1); $this->warnings_pointer += count($warnings); } else { $this->warnings_pointer = count($warnings); } } $out = array( 'HasRun' => (!($this->isFinished)), 'Domain' => $this->active_domain, 'Step' => $this->active_step, 'Substep' => $this->active_substep, 'Error' => $this->getError(), 'Warnings' => $warnings ); return $out; } final protected function setDomain($new_domain) { $this->active_domain = $new_domain; } final public function getDomain() { return $this->active_domain; } final protected function setStep($new_step) { $this->active_step = $new_step; } final public function getStep() { return $this->active_step; } final protected function setSubstep($new_substep) { $this->active_substep = $new_substep; } final public function getSubstep() { return $this->active_substep; } /** * Attaches an observer object * @param AKAbstractPartObserver $obs */ function attach(AKAbstractPartObserver $obs) { $this->observers["$obs"] = $obs; } /** * Dettaches an observer object * @param AKAbstractPartObserver $obs */ function detach(AKAbstractPartObserver $obs) { delete($this->observers["$obs"]); } /** * Notifies observers each time something interesting happened to the part * @param mixed $message The event object */ protected function notify($message) { foreach ($this->observers as $obs) { $obs->update($this, $message); } } } /** * Descendants of this class can be used in the unarchiver's observer methods (attach, detach and notify) * @author Nicholas * */ abstract class AKAbstractPartObserver { abstract public function update($object, $message); } /** * Direct file writer */ class AKPostprocDirect extends AKAbstractPostproc { public function process() { $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); if($restorePerms) { @chmod($this->filename, $this->perms); } else { if(@is_file($this->filename)) { @chmod($this->filename, 0644); } else { @chmod($this->filename, 0755); } } if($this->timestamp > 0) { @touch($this->filename, $this->timestamp); } return true; } public function processFilename($filename, $perms = 0755) { $this->perms = $perms; $this->filename = $filename; return $filename; } public function createDirRecursive( $dirName, $perms ) { if( AKFactory::get('kickstart.setup.dryrun','0') ) return true; if (@mkdir($dirName, 0755, true)) { @chmod($dirName, 0755); return true; } $root = AKFactory::get('kickstart.setup.destdir'); $root = rtrim(str_replace('\\','/',$root),'/'); $dir = rtrim(str_replace('\\','/',$dirName),'/'); if(strpos($dir, $root) === 0) { $dir = ltrim(substr($dir, strlen($root)), '/'); $root .= '/'; } else { $root = ''; } if(empty($dir)) return true; $dirArray = explode('/', $dir); $path = ''; foreach( $dirArray as $dir ) { $path .= $dir . '/'; $ret = is_dir($root.$path) ? true : @mkdir($root.$path); if( !$ret ) { // Is this a file instead of a directory? if(is_file($root.$path) ) { @unlink($root.$path); $ret = @mkdir($root.$path); } if( !$ret ) { $this->setError( AKText::sprintf('COULDNT_CREATE_DIR',$path) ); return false; } } // Try to set new directory permissions to 0755 @chmod($root.$path, $perms); } return true; } public function chmod( $file, $perms ) { if( AKFactory::get('kickstart.setup.dryrun','0') ) return true; return @chmod( $file, $perms ); } public function unlink( $file ) { return @unlink( $file ); } public function rmdir( $directory ) { return @rmdir( $directory ); } public function rename( $from, $to ) { return @rename($from, $to); } } /** * FTP file writer */ class AKPostprocFTP extends AKAbstractPostproc { /** @var bool Should I use FTP over implicit SSL? */ public $useSSL = false; /** @var bool use Passive mode? */ public $passive = true; /** @var string FTP host name */ public $host = ''; /** @var int FTP port */ public $port = 21; /** @var string FTP user name */ public $user = ''; /** @var string FTP password */ public $pass = ''; /** @var string FTP initial directory */ public $dir = ''; /** @var resource The FTP handle */ private $handle = null; /** @var string The temporary directory where the data will be stored */ private $tempDir = ''; public function __construct() { parent::__construct(); $this->useSSL = AKFactory::get('kickstart.ftp.ssl', false); $this->passive = AKFactory::get('kickstart.ftp.passive', true); $this->host = AKFactory::get('kickstart.ftp.host', ''); $this->port = AKFactory::get('kickstart.ftp.port', 21); if(trim($this->port) == '') $this->port = 21; $this->user = AKFactory::get('kickstart.ftp.user', ''); $this->pass = AKFactory::get('kickstart.ftp.pass', ''); $this->dir = AKFactory::get('kickstart.ftp.dir', ''); $this->tempDir = AKFactory::get('kickstart.ftp.tempdir', ''); $connected = $this->connect(); if($connected) { if(!empty($this->tempDir)) { $tempDir = rtrim($this->tempDir, '/\\').'/'; $writable = $this->isDirWritable($tempDir); } else { $tempDir = ''; $writable = false; } if(!$writable) { // Default temporary directory is the current root $tempDir = function_exists('getcwd') ? getcwd() : dirname(__FILE__); if(empty($tempDir)) { // Oh, we have no directory reported! $tempDir = '.'; } $absoluteDirToHere = $tempDir; $tempDir = rtrim(str_replace('\\','/',$tempDir),'/'); if(!empty($tempDir)) $tempDir .= '/'; $this->tempDir = $tempDir; // Is this directory writable? $writable = $this->isDirWritable($tempDir); } if(!$writable) { // Nope. Let's try creating a temporary directory in the site's root. $tempDir = $absoluteDirToHere.'/kicktemp'; $this->createDirRecursive($tempDir, 0777); // Try making it writable... $this->fixPermissions($tempDir); $writable = $this->isDirWritable($tempDir); } // Was the new directory writable? if(!$writable) { // Let's see if the user has specified one $userdir = AKFactory::get('kickstart.ftp.tempdir', ''); if(!empty($userdir)) { // Is it an absolute or a relative directory? $absolute = false; $absolute = $absolute || ( substr($userdir,0,1) == '/' ); $absolute = $absolute || ( substr($userdir,1,1) == ':' ); $absolute = $absolute || ( substr($userdir,2,1) == ':' ); if(!$absolute) { // Make absolute $tempDir = $absoluteDirToHere.$userdir; } else { // it's already absolute $tempDir = $userdir; } // Does the directory exist? if( is_dir($tempDir) ) { // Yeah. Is it writable? $writable = $this->isDirWritable($tempDir); } } } $this->tempDir = $tempDir; if(!$writable) { // No writable directory found!!! $this->setError(AKText::_('FTP_TEMPDIR_NOT_WRITABLE')); } else { AKFactory::set('kickstart.ftp.tempdir', $tempDir); $this->tempDir = $tempDir; } } } function __wakeup() { $this->connect(); } public function connect() { // Connect to server, using SSL if so required if($this->useSSL) { $this->handle = @ftp_ssl_connect($this->host, $this->port); } else { $this->handle = @ftp_connect($this->host, $this->port); } if($this->handle === false) { $this->setError(AKText::_('WRONG_FTP_HOST')); return false; } // Login if(! @ftp_login($this->handle, $this->user, $this->pass)) { $this->setError(AKText::_('WRONG_FTP_USER')); @ftp_close($this->handle); return false; } // Change to initial directory if(! @ftp_chdir($this->handle, $this->dir)) { $this->setError(AKText::_('WRONG_FTP_PATH1')); @ftp_close($this->handle); return false; } // Enable passive mode if the user requested it if( $this->passive ) { @ftp_pasv($this->handle, true); } else { @ftp_pasv($this->handle, false); } return true; } public function process() { if( is_null($this->tempFilename) ) { // If an empty filename is passed, it means that we shouldn't do any post processing, i.e. // the entity was a directory or symlink return true; } $remotePath = dirname($this->filename); $removePath = AKFactory::get('kickstart.setup.destdir',''); if(!empty($removePath)) { $removePath = ltrim($removePath, "/"); $remotePath = ltrim($remotePath, "/"); $left = substr($remotePath, 0, strlen($removePath)); if($left == $removePath) { $remotePath = substr($remotePath, strlen($removePath)); } } $absoluteFSPath = dirname($this->filename); $relativeFTPPath = trim($remotePath, '/'); $absoluteFTPPath = '/'.trim( $this->dir, '/' ).'/'.trim($remotePath, '/'); $onlyFilename = basename($this->filename); $remoteName = $absoluteFTPPath.'/'.$onlyFilename; $ret = @ftp_chdir($this->handle, $absoluteFTPPath); if($ret === false) { $ret = $this->createDirRecursive( $absoluteFSPath, 0755); if($ret === false) { $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); return false; } $ret = @ftp_chdir($this->handle, $absoluteFTPPath); if($ret === false) { $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); return false; } } $ret = @ftp_put($this->handle, $remoteName, $this->tempFilename, FTP_BINARY); if($ret === false) { // If we couldn't create the file, attempt to fix the permissions in the PHP level and retry! $this->fixPermissions($this->filename); $this->unlink($this->filename); $fp = @fopen($this->tempFilename); if($fp !== false) { $ret = @ftp_fput($this->handle, $remoteName, $fp, FTP_BINARY); @fclose($fp); } else { $ret = false; } } @unlink($this->tempFilename); if($ret === false) { $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); return false; } $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); if($restorePerms) { @ftp_chmod($this->_handle, $perms, $remoteName); } else { @ftp_chmod($this->_handle, 0644, $remoteName); } return true; } public function processFilename($filename, $perms = 0755) { // Catch some error conditions... if($this->getError()) { return false; } // If a null filename is passed, it means that we shouldn't do any post processing, i.e. // the entity was a directory or symlink if(is_null($filename)) { $this->filename = null; $this->tempFilename = null; return null; } // Strip absolute filesystem path to website's root $removePath = AKFactory::get('kickstart.setup.destdir',''); if(!empty($removePath)) { $left = substr($filename, 0, strlen($removePath)); if($left == $removePath) { $filename = substr($filename, strlen($removePath)); } } // Trim slash on the left $filename = ltrim($filename, '/'); $this->filename = $filename; $this->tempFilename = tempnam($this->tempDir, 'kickstart-'); $this->perms = $perms; if( empty($this->tempFilename) ) { // Oops! Let's try something different $this->tempFilename = $this->tempDir.'/kickstart-'.time().'.dat'; } return $this->tempFilename; } private function isDirWritable($dir) { $fp = @fopen($dir.'/kickstart.dat', 'wb'); if($fp === false) { return false; } else { @fclose($fp); unlink($dir.'/kickstart.dat'); return true; } } public function createDirRecursive( $dirName, $perms ) { // Strip absolute filesystem path to website's root $removePath = AKFactory::get('kickstart.setup.destdir',''); if(!empty($removePath)) { // UNIXize the paths $removePath = str_replace('\\','/',$removePath); $dirName = str_replace('\\','/',$dirName); // Make sure they both end in a slash $removePath = rtrim($removePath,'/\\').'/'; $dirName = rtrim($dirName,'/\\').'/'; // Process the path removal $left = substr($dirName, 0, strlen($removePath)); if($left == $removePath) { $dirName = substr($dirName, strlen($removePath)); } } if(empty($dirName)) $dirName = ''; // 'cause the substr() above may return FALSE. $check = '/'.trim($this->dir,'/').'/'.trim($dirName, '/'); if($this->is_dir($check)) return true; $alldirs = explode('/', $dirName); $previousDir = '/'.trim($this->dir); foreach($alldirs as $curdir) { $check = $previousDir.'/'.$curdir; if(!$this->is_dir($check)) { // Proactively try to delete a file by the same name @ftp_delete($this->handle, $check); if(@ftp_mkdir($this->handle, $check) === false) { // If we couldn't create the directory, attempt to fix the permissions in the PHP level and retry! $this->fixPermissions($removePath.$check); if(@ftp_mkdir($this->handle, $check) === false) { // Can we fall back to pure PHP mode, sire? if(!@mkdir($check)) { $this->setError(AKText::sprintf('FTP_CANT_CREATE_DIR',$dir)); return false; } else { // Since the directory was built by PHP, change its permissions @chmod($check, "0777"); return true; } } } @ftp_chmod($this->handle, $perms, $check); } $previousDir = $check; } return true; } public function close() { @ftp_close($this->handle); } /* * Tries to fix directory/file permissions in the PHP level, so that * the FTP operation doesn't fail. * @param $path string The full path to a directory or file */ private function fixPermissions( $path ) { // Turn off error reporting if(!defined('KSDEBUG')) { $oldErrorReporting = @error_reporting(E_NONE); } // Get UNIX style paths $relPath = str_replace('\\','/',$path); $basePath = rtrim(str_replace('\\','/',dirname(__FILE__)),'/'); $basePath = rtrim($basePath,'/'); if(!empty($basePath)) $basePath .= '/'; // Remove the leading relative root if( substr($relPath,0,strlen($basePath)) == $basePath ) $relPath = substr($relPath,strlen($basePath)); $dirArray = explode('/', $relPath); $pathBuilt = rtrim($basePath,'/'); foreach( $dirArray as $dir ) { if(empty($dir)) continue; $oldPath = $pathBuilt; $pathBuilt .= '/'.$dir; if(is_dir($oldPath.$dir)) { @chmod($oldPath.$dir, 0777); } else { if(@chmod($oldPath.$dir, 0777) === false) { @unlink($oldPath.$dir); } } } // Restore error reporting if(!defined('KSDEBUG')) { @error_reporting($oldErrorReporting); } } public function chmod( $file, $perms ) { return @ftp_chmod($this->handle, $perms, $path); } private function is_dir( $dir ) { return @ftp_chdir( $this->handle, $dir ); } public function unlink( $file ) { $removePath = AKFactory::get('kickstart.setup.destdir',''); if(!empty($removePath)) { $left = substr($file, 0, strlen($removePath)); if($left == $removePath) { $file = substr($file, strlen($removePath)); } } $check = '/'.trim($this->dir,'/').'/'.trim($file, '/'); return @ftp_delete( $this->handle, $check ); } public function rmdir( $directory ) { $removePath = AKFactory::get('kickstart.setup.destdir',''); if(!empty($removePath)) { $left = substr($directory, 0, strlen($removePath)); if($left == $removePath) { $directory = substr($directory, strlen($removePath)); } } $check = '/'.trim($this->dir,'/').'/'.trim($directory, '/'); return @ftp_rmdir( $this->handle, $check ); } public function rename( $from, $to ) { $originalFrom = $from; $originalTo = $to; $removePath = AKFactory::get('kickstart.setup.destdir',''); if(!empty($removePath)) { $left = substr($from, 0, strlen($removePath)); if($left == $removePath) { $from = substr($from, strlen($removePath)); } } $from = '/'.trim($this->dir,'/').'/'.trim($from, '/'); if(!empty($removePath)) { $left = substr($to, 0, strlen($removePath)); if($left == $removePath) { $to = substr($to, strlen($removePath)); } } $to = '/'.trim($this->dir,'/').'/'.trim($to, '/'); $result = @ftp_rename( $this->handle, $from, $to ); if($result !== true) { return @rename($from, $to); } else { return true; } } } /** * JPA archive extraction class */ class AKUnarchiverJPA extends AKAbstractUnarchiver { private $archiveHeaderData = array(); protected function readArchiveHeader() { // Initialize header data array $this->archiveHeaderData = new stdClass(); // Open the first part $this->nextFile(); // Fail for unreadable files if( $this->fp === false ) return false; // Read the signature $sig = fread( $this->fp, 3 ); if ($sig != 'JPA') { // Not a JPA file $this->setError( AKText::_('ERR_NOT_A_JPA_FILE') ); return false; } // Read and parse header length $header_length_array = unpack( 'v', fread( $this->fp, 2 ) ); $header_length = $header_length_array[1]; // Read and parse the known portion of header data (14 bytes) $bin_data = fread($this->fp, 14); $header_data = unpack('Cmajor/Cminor/Vcount/Vuncsize/Vcsize', $bin_data); // Load any remaining header data (forward compatibility) $rest_length = $header_length - 19; if( $rest_length > 0 ) $junk = fread($this->fp, $rest_length); else $junk = ''; // Temporary array with all the data we read $temp = array( 'signature' => $sig, 'length' => $header_length, 'major' => $header_data['major'], 'minor' => $header_data['minor'], 'filecount' => $header_data['count'], 'uncompressedsize' => $header_data['uncsize'], 'compressedsize' => $header_data['csize'], 'unknowndata' => $junk ); // Array-to-object conversion foreach($temp as $key => $value) { $this->archiveHeaderData->{$key} = $value; } $this->currentPartOffset = @ftell($this->fp); $this->dataReadLength = 0; return true; } /** * Concrete classes must use this method to read the file header * @return bool True if reading the file was successful, false if an error occured or we reached end of archive */ protected function readFileHeader() { // If the current part is over, proceed to the next part please if( $this->isEOF(true) ) { $this->nextFile(); } // Get and decode Entity Description Block $signature = fread($this->fp, 3); $this->fileHeader = new stdClass(); $this->fileHeader->timestamp = 0; // Check signature if( $signature != 'JPF' ) { if($this->isEOF(true)) { // This file is finished; make sure it's the last one $this->nextFile(); if(!$this->isEOF(false)) { $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); return false; } // We're just finished return false; } else { // This is not a file block! The archive is corrupt. $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); return false; } } // This a JPA Entity Block. Process the header. $isBannedFile = false; // Read length of EDB and of the Entity Path Data $length_array = unpack('vblocksize/vpathsize', fread($this->fp, 4)); // Read the path data if($length_array['pathsize'] > 0) { $file = fread( $this->fp, $length_array['pathsize'] ); } else { $file = ''; } // Handle file renaming $isRenamed = false; if(is_array($this->renameFiles) && (count($this->renameFiles) > 0) ) { if(array_key_exists($file, $this->renameFiles)) { $file = $this->renameFiles[$file]; $isRenamed = true; } } // Handle directory renaming $isDirRenamed = false; if(is_array($this->renameDirs) && (count($this->renameDirs) > 0)) { if(array_key_exists(dirname($file), $this->renameDirs)) { $file = rtrim($this->renameDirs[dirname($file)],'/').'/'.basename($file); $isRenamed = true; $isDirRenamed = true; } } // Read and parse the known data portion $bin_data = fread( $this->fp, 14 ); $header_data = unpack('Ctype/Ccompression/Vcompsize/Vuncompsize/Vperms', $bin_data); // Read any unknown data $restBytes = $length_array['blocksize'] - (21 + $length_array['pathsize']); if( $restBytes > 0 ) { // Start reading the extra fields while($restBytes >= 4) { $extra_header_data = fread($this->fp, 4); $extra_header = unpack('vsignature/vlength', $extra_header_data); $restBytes -= 4; $extra_header['length'] -= 4; switch($extra_header['signature']) { case 256: // File modified timestamp if($extra_header['length'] > 0) { $bindata = fread($this->fp, $extra_header['length']); $restBytes -= $extra_header['length']; $timestamps = unpack('Vmodified', substr($bindata,0,4)); $filectime = $timestamps['modified']; $this->fileHeader->timestamp = $filectime; } break; default: // Unknown field if($extra_header['length']>0) { $junk = fread($this->fp, $extra_header['length']); $restBytes -= $extra_header['length']; } break; } } if($restBytes > 0) $junk = fread($this->fp, $restBytes); } $compressionType = $header_data['compression']; // Populate the return array $this->fileHeader->file = $file; $this->fileHeader->compressed = $header_data['compsize']; $this->fileHeader->uncompressed = $header_data['uncompsize']; switch($header_data['type']) { case 0: $this->fileHeader->type = 'dir'; break; case 1: $this->fileHeader->type = 'file'; break; case 2: $this->fileHeader->type = 'link'; break; } switch( $compressionType ) { case 0: $this->fileHeader->compression = 'none'; break; case 1: $this->fileHeader->compression = 'gzip'; break; case 2: $this->fileHeader->compression = 'bzip2'; break; } $this->fileHeader->permissions = $header_data['perms']; // Find hard-coded banned files if( (basename($this->fileHeader->file) == ".") || (basename($this->fileHeader->file) == "..") ) { $isBannedFile = true; } // Also try to find banned files passed in class configuration if((count($this->skipFiles) > 0) && (!$isRenamed) ) { if(in_array($this->fileHeader->file, $this->skipFiles)) { $isBannedFile = true; } } // If we have a banned file, let's skip it if($isBannedFile) { // Advance the file pointer, skipping exactly the size of the compressed data $seekleft = $this->fileHeader->compressed; while($seekleft > 0) { // Ensure that we can seek past archive part boundaries $curSize = @filesize($this->archiveList[$this->currentPartNumber]); $curPos = @ftell($this->fp); $canSeek = $curSize - $curPos; if($canSeek > $seekleft) $canSeek = $seekleft; @fseek( $this->fp, $canSeek, SEEK_CUR ); $seekleft -= $canSeek; if($seekleft) $this->nextFile(); } $this->currentPartOffset = @ftell($this->fp); $this->runState = AK_STATE_DONE; return true; } // Last chance to prepend a path to the filename if(!empty($this->addPath) && !$isDirRenamed) { $this->fileHeader->file = $this->addPath.$this->fileHeader->file; } // Get the translated path name $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); if($this->fileHeader->type == 'file') { // Regular file; ask the postproc engine to process its filename if($restorePerms) { $this->fileHeader->realFile = $this->postProcEngine->processFilename( $this->fileHeader->file, $this->fileHeader->permissions ); } else { $this->fileHeader->realFile = $this->postProcEngine->processFilename( $this->fileHeader->file ); } } elseif($this->fileHeader->type == 'dir') { $dir = $this->fileHeader->file; // Directory; just create it if($restorePerms) { $this->postProcEngine->createDirRecursive( $this->fileHeader->file, $this->fileHeader->permissions ); } else { $this->postProcEngine->createDirRecursive( $this->fileHeader->file, 0755 ); } $this->postProcEngine->processFilename(null); } else { // Symlink; do not post-process $this->postProcEngine->processFilename(null); } $this->createDirectory(); // Header is read $this->runState = AK_STATE_HEADER; $this->dataReadLength = 0; return true; } /** * Concrete classes must use this method to process file data. It must set $runState to AK_STATE_DATAREAD when * it's finished processing the file data. * @return bool True if processing the file data was successful, false if an error occured */ protected function processFileData() { switch( $this->fileHeader->type ) { case 'dir': return $this->processTypeDir(); break; case 'link': return $this->processTypeLink(); break; case 'file': switch($this->fileHeader->compression) { case 'none': return $this->processTypeFileUncompressed(); break; case 'gzip': case 'bzip2': return $this->processTypeFileCompressedSimple(); break; } break; } } private function processTypeFileUncompressed() { // Uncompressed files are being processed in small chunks, to avoid timeouts if( ($this->dataReadLength == 0) && !AKFactory::get('kickstart.setup.dryrun','0') ) { // Before processing file data, ensure permissions are adequate $this->setCorrectPermissions( $this->fileHeader->file ); } // Open the output file if( !AKFactory::get('kickstart.setup.dryrun','0') ) { $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false); if ($this->dataReadLength == 0) { $outfp = @fopen( $this->fileHeader->realFile, 'wb' ); } else { $outfp = @fopen( $this->fileHeader->realFile, 'ab' ); } // Can we write to the file? if( ($outfp === false) && (!$ignore) ) { // An error occured $this->setError( AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile) ); return false; } } // Does the file have any data, at all? if( $this->fileHeader->compressed == 0 ) { // No file data! if( !AKFactory::get('kickstart.setup.dryrun','0') && is_resource($outfp) ) @fclose($outfp); $this->runState = AK_STATE_DATAREAD; return true; } // Reference to the global timer $timer = AKFactory::getTimer(); $toReadBytes = 0; $leftBytes = $this->fileHeader->compressed - $this->dataReadLength; // Loop while there's data to read and enough time to do it while( ($leftBytes > 0) && ($timer->getTimeLeft() > 0) ) { $toReadBytes = ($leftBytes > $this->chunkSize) ? $this->chunkSize : $leftBytes; $data = $this->fread( $this->fp, $toReadBytes ); $reallyReadBytes = akstringlen($data); $leftBytes -= $reallyReadBytes; $this->dataReadLength += $reallyReadBytes; if($reallyReadBytes < $toReadBytes) { // We read less than requested! Why? Did we hit local EOF? if( $this->isEOF(true) && !$this->isEOF(false) ) { // Yeap. Let's go to the next file $this->nextFile(); } else { // Nope. The archive is corrupt $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } if( !AKFactory::get('kickstart.setup.dryrun','0') ) if(is_resource($outfp)) @fwrite( $outfp, $data ); } // Close the file pointer if( !AKFactory::get('kickstart.setup.dryrun','0') ) if(is_resource($outfp)) @fclose($outfp); // Was this a pre-timeout bail out? if( $leftBytes > 0 ) { $this->runState = AK_STATE_DATA; } else { // Oh! We just finished! $this->runState = AK_STATE_DATAREAD; $this->dataReadLength = 0; } return true; } private function processTypeFileCompressedSimple() { if( !AKFactory::get('kickstart.setup.dryrun','0') ) { // Before processing file data, ensure permissions are adequate $this->setCorrectPermissions( $this->fileHeader->file ); // Open the output file $outfp = @fopen( $this->fileHeader->realFile, 'wb' ); // Can we write to the file? $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false); if( ($outfp === false) && (!$ignore) ) { // An error occured $this->setError( AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile) ); return false; } } // Does the file have any data, at all? if( $this->fileHeader->compressed == 0 ) { // No file data! if( !AKFactory::get('kickstart.setup.dryrun','0') ) if(is_resource($outfp)) @fclose($outfp); $this->runState = AK_STATE_DATAREAD; return true; } // Simple compressed files are processed as a whole; we can't do chunk processing $zipData = $this->fread( $this->fp, $this->fileHeader->compressed ); while( akstringlen($zipData) < $this->fileHeader->compressed ) { // End of local file before reading all data, but have more archive parts? if($this->isEOF(true) && !$this->isEOF(false)) { // Yeap. Read from the next file $this->nextFile(); $bytes_left = $this->fileHeader->compressed - akstringlen($zipData); $zipData .= $this->fread( $this->fp, $bytes_left ); } else { $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } if($this->fileHeader->compression == 'gzip') { $unzipData = gzinflate( $zipData ); } elseif($this->fileHeader->compression == 'bzip2') { $unzipData = bzdecompress( $zipData ); } unset($zipData); // Write to the file. if( !AKFactory::get('kickstart.setup.dryrun','0') && is_resource($outfp) ) { @fwrite( $outfp, $unzipData, $this->fileHeader->uncompressed ); @fclose( $outfp ); } unset($unzipData); $this->runState = AK_STATE_DATAREAD; return true; } /** * Process the file data of a link entry * @return bool */ private function processTypeLink() { $readBytes = 0; $toReadBytes = 0; $leftBytes = $this->fileHeader->compressed; $data = ''; while( $leftBytes > 0) { $toReadBytes = ($leftBytes > $this->chunkSize) ? $this->chunkSize : $leftBytes; $mydata = $this->fread( $this->fp, $toReadBytes ); $reallyReadBytes = akstringlen($mydata); $data .= $mydata; $leftBytes -= $reallyReadBytes; if($reallyReadBytes < $toReadBytes) { // We read less than requested! Why? Did we hit local EOF? if( $this->isEOF(true) && !$this->isEOF(false) ) { // Yeap. Let's go to the next file $this->nextFile(); } else { // Nope. The archive is corrupt $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } } // Try to remove an existing file or directory by the same name if(file_exists($this->fileHeader->realFile)) { @unlink($this->fileHeader->realFile); @rmdir($this->fileHeader->realFile); } // Remove any trailing slash if(substr($this->fileHeader->realFile, -1) == '/') $this->fileHeader->realFile = substr($this->fileHeader->realFile, 0, -1); // Create the symlink - only possible within PHP context. There's no support built in the FTP protocol, so no postproc use is possible here :( if( !AKFactory::get('kickstart.setup.dryrun','0') ) @symlink($data, $this->fileHeader->realFile); $this->runState = AK_STATE_DATAREAD; return true; // No matter if the link was created! } /** * Process the file data of a directory entry * @return bool */ private function processTypeDir() { // Directory entries in the JPA do not have file data, therefore we're done processing the entry $this->runState = AK_STATE_DATAREAD; return true; } /** * Creates the directory this file points to */ protected function createDirectory() { if( AKFactory::get('kickstart.setup.dryrun','0') ) return true; // Do we need to create a directory? if(empty($this->fileHeader->realFile)) $this->fileHeader->realFile = $this->fileHeader->file; $lastSlash = strrpos($this->fileHeader->realFile, '/'); $dirName = substr( $this->fileHeader->realFile, 0, $lastSlash); $perms = $this->flagRestorePermissions ? $retArray['permissions'] : 0755; $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false); if( ($this->postProcEngine->createDirRecursive($dirName, $perms) == false) && (!$ignore) ) { $this->setError( AKText::sprintf('COULDNT_CREATE_DIR', $dirName) ); return false; } else { return true; } } } /** * ZIP archive extraction class * * Since the file data portion of ZIP and JPA are similarly structured (it's empty for dirs, * linked node name for symlinks, dumped binary data for no compressions and dumped gzipped * binary data for gzip compression) we just have to subclass AKUnarchiverJPA and change the * header reading bits. Reusable code ;) */ class AKUnarchiverZIP extends AKUnarchiverJPA { var $expectDataDescriptor = false; protected function readArchiveHeader() { // Initialize header data array $this->archiveHeaderData = new stdClass(); // Open the first part $this->nextFile(); // Fail for unreadable files if( $this->fp === false ) return false; // Read a possible multipart signature $sigBinary = fread( $this->fp, 4 ); $headerData = unpack('Vsig', $sigBinary); // Roll back if it's not a multipart archive if( $headerData['sig'] == 0x04034b50 ) fseek($this->fp, -4, SEEK_CUR); $multiPartSigs = array( 0x08074b50, // Multi-part ZIP 0x30304b50, // Multi-part ZIP (alternate) 0x04034b50 // Single file ); if( !in_array($headerData['sig'], $multiPartSigs) ) { $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); return false; } $this->currentPartOffset = @ftell($this->fp); $this->dataReadLength = 0; return true; } /** * Concrete classes must use this method to read the file header * @return bool True if reading the file was successful, false if an error occured or we reached end of archive */ protected function readFileHeader() { // If the current part is over, proceed to the next part please if( $this->isEOF(true) ) { $this->nextFile(); } if($this->expectDataDescriptor) { // The last file had bit 3 of the general purpose bit flag set. This means that we have a // 12 byte data descriptor we need to skip. To make things worse, there might also be a 4 // byte optional data descriptor header (0x08074b50). $junk = @fread($this->fp, 4); $junk = unpack('Vsig', $junk); if($junk['sig'] == 0x08074b50) { // Yes, there was a signature $junk = @fread($this->fp, 12); if(defined('KSDEBUG')) { debugMsg('Data descriptor (w/ header) skipped at '.(ftell($this->fp)-12)); } } else { // No, there was no signature, just read another 8 bytes $junk = @fread($this->fp, 8); if(defined('KSDEBUG')) { debugMsg('Data descriptor (w/out header) skipped at '.(ftell($this->fp)-8)); } } // And check for EOF, too if( $this->isEOF(true) ) { if(defined('KSDEBUG')) { debugMsg('EOF before reading header'); } $this->nextFile(); } } // Get and decode Local File Header $headerBinary = fread($this->fp, 30); $headerData = unpack('Vsig/C2ver/vbitflag/vcompmethod/vlastmodtime/vlastmoddate/Vcrc/Vcompsize/Vuncomp/vfnamelen/veflen', $headerBinary); // Check signature if(!( $headerData['sig'] == 0x04034b50 )) { if(defined('KSDEBUG')) { debugMsg('Not a file signature at '.(ftell($this->fp)-4)); } // The signature is not the one used for files. Is this a central directory record (i.e. we're done)? if($headerData['sig'] == 0x02014b50) { if(defined('KSDEBUG')) { debugMsg('EOCD signature at '.(ftell($this->fp)-4)); } // End of ZIP file detected. We'll just skip to the end of file... while( $this->nextFile() ) {}; @fseek($this->fp, 0, SEEK_END); // Go to EOF return false; } else { if(defined('KSDEBUG')) { debugMsg( 'Invalid signature ' . dechex($headerData['sig']) . ' at '.ftell($this->fp) ); } $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); return false; } } // If bit 3 of the bitflag is set, expectDataDescriptor is true $this->expectDataDescriptor = ($headerData['bitflag'] & 4) == 4; $this->fileHeader = new stdClass(); $this->fileHeader->timestamp = 0; // Read the last modified data and time $lastmodtime = $headerData['lastmodtime']; $lastmoddate = $headerData['lastmoddate']; if($lastmoddate && $lastmodtime) { // ----- Extract time $v_hour = ($lastmodtime & 0xF800) >> 11; $v_minute = ($lastmodtime & 0x07E0) >> 5; $v_seconde = ($lastmodtime & 0x001F)*2; // ----- Extract date $v_year = (($lastmoddate & 0xFE00) >> 9) + 1980; $v_month = ($lastmoddate & 0x01E0) >> 5; $v_day = $lastmoddate & 0x001F; // ----- Get UNIX date format $this->fileHeader->timestamp = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); } $isBannedFile = false; $this->fileHeader->compressed = $headerData['compsize']; $this->fileHeader->uncompressed = $headerData['uncomp']; $nameFieldLength = $headerData['fnamelen']; $extraFieldLength = $headerData['eflen']; // Read filename field $this->fileHeader->file = fread( $this->fp, $nameFieldLength ); // Handle file renaming $isRenamed = false; if(is_array($this->renameFiles) && (count($this->renameFiles) > 0) ) { if(array_key_exists($this->fileHeader->file, $this->renameFiles)) { $this->fileHeader->file = $this->renameFiles[$this->fileHeader->file]; $isRenamed = true; } } // Handle directory renaming $isDirRenamed = false; if(is_array($this->renameDirs) && (count($this->renameDirs) > 0)) { if(array_key_exists(dirname($file), $this->renameDirs)) { $file = rtrim($this->renameDirs[dirname($file)],'/').'/'.basename($file); $isRenamed = true; $isDirRenamed = true; } } // Read extra field if present if($extraFieldLength > 0) { $extrafield = fread( $this->fp, $extraFieldLength ); } if(defined('KSDEBUG')) { debugMsg( '*'.ftell($this->fp).' IS START OF '.$this->fileHeader->file. ' ('.$this->fileHeader->compressed.' bytes)' ); } // Decide filetype -- Check for directories $this->fileHeader->type = 'file'; if( strrpos($this->fileHeader->file, '/') == strlen($this->fileHeader->file) - 1 ) $this->fileHeader->type = 'dir'; // Decide filetype -- Check for symbolic links if( ($headerData['ver1'] == 10) && ($headerData['ver2'] == 3) )$this->fileHeader->type = 'link'; switch( $headerData['compmethod'] ) { case 0: $this->fileHeader->compression = 'none'; break; case 8: $this->fileHeader->compression = 'gzip'; break; } // Find hard-coded banned files if( (basename($this->fileHeader->file) == ".") || (basename($this->fileHeader->file) == "..") ) { $isBannedFile = true; } // Also try to find banned files passed in class configuration if((count($this->skipFiles) > 0) && (!$isRenamed)) { if(in_array($this->fileHeader->file, $this->skipFiles)) { $isBannedFile = true; } } // If we have a banned file, let's skip it if($isBannedFile) { // Advance the file pointer, skipping exactly the size of the compressed data $seekleft = $this->fileHeader->compressed; while($seekleft > 0) { // Ensure that we can seek past archive part boundaries $curSize = @filesize($this->archiveList[$this->currentPartNumber]); $curPos = @ftell($this->fp); $canSeek = $curSize - $curPos; if($canSeek > $seekleft) $canSeek = $seekleft; @fseek( $this->fp, $canSeek, SEEK_CUR ); $seekleft -= $canSeek; if($seekleft) $this->nextFile(); } $this->currentPartOffset = @ftell($this->fp); $this->runState = AK_STATE_DONE; return true; } // Last chance to prepend a path to the filename if(!empty($this->addPath) && !$isDirRenamed) { $this->fileHeader->file = $this->addPath.$this->fileHeader->file; } // Get the translated path name if($this->fileHeader->type == 'file') { $this->fileHeader->realFile = $this->postProcEngine->processFilename( $this->fileHeader->file ); } elseif($this->fileHeader->type == 'dir') { $this->fileHeader->timestamp = 0; $dir = $this->fileHeader->file; $this->postProcEngine->createDirRecursive( $this->fileHeader->file, 0755 ); $this->postProcEngine->processFilename(null); } else { // Symlink; do not post-process $this->fileHeader->timestamp = 0; $this->postProcEngine->processFilename(null); } $this->createDirectory(); // Header is read $this->runState = AK_STATE_HEADER; return true; } } /** * Timer class */ class AKCoreTimer extends AKAbstractObject { /** @var int Maximum execution time allowance per step */ private $max_exec_time = null; /** @var int Timestamp of execution start */ private $start_time = null; /** * Public constructor, creates the timer object and calculates the execution time limits * @return AECoreTimer */ public function __construct() { parent::__construct(); // Initialize start time $this->start_time = $this->microtime_float(); // Get configured max time per step and bias $config_max_exec_time = AKFactory::get('kickstart.tuning.max_exec_time', 14); $bias = AKFactory::get('kickstart.tuning.run_time_bias', 75)/100; // Get PHP's maximum execution time (our upper limit) if(@function_exists('ini_get')) { $php_max_exec_time = @ini_get("maximum_execution_time"); if ( (!is_numeric($php_max_exec_time)) || ($php_max_exec_time == 0) ) { // If we have no time limit, set a hard limit of about 10 seconds // (safe for Apache and IIS timeouts, verbose enough for users) $php_max_exec_time = 14; } } else { // If ini_get is not available, use a rough default $php_max_exec_time = 14; } // Apply an arbitrary correction to counter CMS load time $php_max_exec_time--; // Apply bias $php_max_exec_time = $php_max_exec_time * $bias; $config_max_exec_time = $config_max_exec_time * $bias; // Use the most appropriate time limit value if( $config_max_exec_time > $php_max_exec_time ) { $this->max_exec_time = $php_max_exec_time; } else { $this->max_exec_time = $config_max_exec_time; } } /** * Wake-up function to reset internal timer when we get unserialized */ public function __wakeup() { // Re-initialize start time on wake-up $this->start_time = $this->microtime_float(); } /** * Gets the number of seconds left, before we hit the "must break" threshold * @return float */ public function getTimeLeft() { return $this->max_exec_time - $this->getRunningTime(); } /** * Gets the time elapsed since object creation/unserialization, effectively how * long Akeeba Engine has been processing data * @return float */ public function getRunningTime() { return $this->microtime_float() - $this->start_time; } /** * Returns the current timestampt in decimal seconds */ private function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); } /** * Enforce the minimum execution time */ public function enforce_min_exec_time() { // Try to get a sane value for PHP's maximum_execution_time INI parameter if(@function_exists('ini_get')) { $php_max_exec = @ini_get("maximum_execution_time"); } else { $php_max_exec = 10; } if ( ($php_max_exec == "") || ($php_max_exec == 0) ) { $php_max_exec = 10; } // Decrease $php_max_exec time by 500 msec we need (approx.) to tear down // the application, as well as another 500msec added for rounding // error purposes. Also make sure this is never gonna be less than 0. $php_max_exec = max($php_max_exec * 1000 - 1000, 0); // Get the "minimum execution time per step" Akeeba Backup configuration variable $minexectime = AKFactory::get('kickstart.tuning.min_exec_time',0); if(!is_numeric($minexectime)) $minexectime = 0; // Make sure we are not over PHP's time limit! if($minexectime > $php_max_exec) $minexectime = $php_max_exec; // Get current running time $elapsed_time = $this->getRunningTime() * 1000; // Only run a sleep delay if we haven't reached the minexectime execution time if( ($minexectime > $elapsed_time) && ($elapsed_time > 0) ) { $sleep_msec = $minexectime - $elapsed_time; if(function_exists('usleep')) { usleep(1000 * $sleep_msec); } elseif(function_exists('time_nanosleep')) { $sleep_sec = floor($sleep_msec / 1000); $sleep_nsec = 1000000 * ($sleep_msec - ($sleep_sec * 1000)); time_nanosleep($sleep_sec, $sleep_nsec); } elseif(function_exists('time_sleep_until')) { $until_timestamp = time() + $sleep_msec / 1000; time_sleep_until($until_timestamp); } elseif(function_exists('sleep')) { $sleep_sec = ceil($sleep_msec/1000); sleep( $sleep_sec ); } } elseif( $elapsed_time > 0 ) { // No sleep required, even if user configured us to be able to do so. } } /** * Reset the timer. It should only be used in CLI mode! */ public function resetTime() { $this->start_time = $this->microtime_float(); } } /** * JPS archive extraction class */ class AKUnarchiverJPS extends AKUnarchiverJPA { private $archiveHeaderData = array(); private $password = ''; public function __construct() { parent::__construct(); $this->password = AKFactory::get('kickstart.jps.password',''); } protected function readArchiveHeader() { // Initialize header data array $this->archiveHeaderData = new stdClass(); // Open the first part $this->nextFile(); // Fail for unreadable files if( $this->fp === false ) return false; // Read the signature $sig = fread( $this->fp, 3 ); if ($sig != 'JPS') { // Not a JPA file $this->setError( AKText::_('ERR_NOT_A_JPS_FILE') ); return false; } // Read and parse the known portion of header data (5 bytes) $bin_data = fread($this->fp, 5); $header_data = unpack('Cmajor/Cminor/cspanned/vextra', $bin_data); // Load any remaining header data (forward compatibility) $rest_length = $header_data['extra']; if( $rest_length > 0 ) $junk = fread($this->fp, $rest_length); else $junk = ''; // Temporary array with all the data we read $temp = array( 'signature' => $sig, 'major' => $header_data['major'], 'minor' => $header_data['minor'], 'spanned' => $header_data['spanned'] ); // Array-to-object conversion foreach($temp as $key => $value) { $this->archiveHeaderData->{$key} = $value; } $this->currentPartOffset = @ftell($this->fp); $this->dataReadLength = 0; return true; } /** * Concrete classes must use this method to read the file header * @return bool True if reading the file was successful, false if an error occured or we reached end of archive */ protected function readFileHeader() { // If the current part is over, proceed to the next part please if( $this->isEOF(true) ) { $this->nextFile(); } // Get and decode Entity Description Block $signature = fread($this->fp, 3); // Check for end-of-archive siganture if($signature == 'JPE') { $this->setState('postrun'); return true; } $this->fileHeader = new stdClass(); $this->fileHeader->timestamp = 0; // Check signature if( $signature != 'JPF' ) { if($this->isEOF(true)) { // This file is finished; make sure it's the last one $this->nextFile(); if(!$this->isEOF(false)) { $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); return false; } // We're just finished return false; } else { fseek($this->fp, -6, SEEK_CUR); $signature = fread($this->fp, 3); if($signature == 'JPE') { return false; } $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); return false; } } // This a JPA Entity Block. Process the header. $isBannedFile = false; // Read and decrypt the header $edbhData = fread($this->fp, 4); $edbh = unpack('vencsize/vdecsize', $edbhData); $bin_data = fread($this->fp, $edbh['encsize']); // Decrypt and truncate $bin_data = AKEncryptionAES::AESDecryptCBC($bin_data, $this->password, 128); $bin_data = substr($bin_data,0,$edbh['decsize']); // Read length of EDB and of the Entity Path Data $length_array = unpack('vpathsize', substr($bin_data,0,2) ); // Read the path data $file = substr($bin_data,2,$length_array['pathsize']); // Handle file renaming $isRenamed = false; if(is_array($this->renameFiles) && (count($this->renameFiles) > 0) ) { if(array_key_exists($file, $this->renameFiles)) { $file = $this->renameFiles[$file]; $isRenamed = true; } } // Handle directory renaming $isDirRenamed = false; if(is_array($this->renameDirs) && (count($this->renameDirs) > 0)) { if(array_key_exists(dirname($file), $this->renameDirs)) { $file = rtrim($this->renameDirs[dirname($file)],'/').'/'.basename($file); $isRenamed = true; $isDirRenamed = true; } } // Read and parse the known data portion $bin_data = substr($bin_data, 2 + $length_array['pathsize']); $header_data = unpack('Ctype/Ccompression/Vuncompsize/Vperms/Vfilectime', $bin_data); $this->fileHeader->timestamp = $header_data['filectime']; $compressionType = $header_data['compression']; // Populate the return array $this->fileHeader->file = $file; $this->fileHeader->uncompressed = $header_data['uncompsize']; switch($header_data['type']) { case 0: $this->fileHeader->type = 'dir'; break; case 1: $this->fileHeader->type = 'file'; break; case 2: $this->fileHeader->type = 'link'; break; } switch( $compressionType ) { case 0: $this->fileHeader->compression = 'none'; break; case 1: $this->fileHeader->compression = 'gzip'; break; case 2: $this->fileHeader->compression = 'bzip2'; break; } $this->fileHeader->permissions = $header_data['perms']; // Find hard-coded banned files if( (basename($this->fileHeader->file) == ".") || (basename($this->fileHeader->file) == "..") ) { $isBannedFile = true; } // Also try to find banned files passed in class configuration if((count($this->skipFiles) > 0) && (!$isRenamed) ) { if(in_array($this->fileHeader->file, $this->skipFiles)) { $isBannedFile = true; } } // If we have a banned file, let's skip it if($isBannedFile) { $done = false; while(!$done) { // Read the Data Chunk Block header $binMiniHead = fread($this->fp, 8); if( in_array( substr($binMiniHead,0,3), array('JPF','JPE') ) ) { // Not a Data Chunk Block header, I am done skipping the file @fseek($this->fp,-8,SEEK_CUR); // Roll back the file pointer $done = true; // Mark as done continue; // Exit loop } else { // Skip forward by the amount of compressed data $miniHead = unpack('Vencsize/Vdecsize'); @fseek($this->fp, $miniHead['encsize'], SEEK_CUR); } } $this->currentPartOffset = @ftell($this->fp); $this->runState = AK_STATE_DONE; return true; } // Last chance to prepend a path to the filename if(!empty($this->addPath) && !$isDirRenamed) { $this->fileHeader->file = $this->addPath.$this->fileHeader->file; } // Get the translated path name $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); if($this->fileHeader->type == 'file') { // Regular file; ask the postproc engine to process its filename if($restorePerms) { $this->fileHeader->realFile = $this->postProcEngine->processFilename( $this->fileHeader->file, $this->fileHeader->permissions ); } else { $this->fileHeader->realFile = $this->postProcEngine->processFilename( $this->fileHeader->file ); } } elseif($this->fileHeader->type == 'dir') { $dir = $this->fileHeader->file; $this->fileHeader->realFile = $dir; // Directory; just create it if($restorePerms) { $this->postProcEngine->createDirRecursive( $this->fileHeader->file, $this->fileHeader->permissions ); } else { $this->postProcEngine->createDirRecursive( $this->fileHeader->file, 0755 ); } $this->postProcEngine->processFilename(null); } else { // Symlink; do not post-process $this->postProcEngine->processFilename(null); } $this->createDirectory(); // Header is read $this->runState = AK_STATE_HEADER; $this->dataReadLength = 0; return true; } /** * Concrete classes must use this method to process file data. It must set $runState to AK_STATE_DATAREAD when * it's finished processing the file data. * @return bool True if processing the file data was successful, false if an error occured */ protected function processFileData() { switch( $this->fileHeader->type ) { case 'dir': return $this->processTypeDir(); break; case 'link': return $this->processTypeLink(); break; case 'file': switch($this->fileHeader->compression) { case 'none': return $this->processTypeFileUncompressed(); break; case 'gzip': case 'bzip2': return $this->processTypeFileCompressedSimple(); break; } break; } } private function processTypeFileUncompressed() { // Uncompressed files are being processed in small chunks, to avoid timeouts if( ($this->dataReadLength == 0) && !AKFactory::get('kickstart.setup.dryrun','0') ) { // Before processing file data, ensure permissions are adequate $this->setCorrectPermissions( $this->fileHeader->file ); } // Open the output file if( !AKFactory::get('kickstart.setup.dryrun','0') ) { $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false); if ($this->dataReadLength == 0) { $outfp = @fopen( $this->fileHeader->realFile, 'wb' ); } else { $outfp = @fopen( $this->fileHeader->realFile, 'ab' ); } // Can we write to the file? if( ($outfp === false) && (!$ignore) ) { // An error occured $this->setError( AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile) ); return false; } } // Does the file have any data, at all? if( $this->fileHeader->uncompressed == 0 ) { // No file data! if( !AKFactory::get('kickstart.setup.dryrun','0') && is_resource($outfp) ) @fclose($outfp); $this->runState = AK_STATE_DATAREAD; return true; } else { $this->setError('An uncompressed file was detected; this is not supported by this archive extraction utility'); return false; } return true; } private function processTypeFileCompressedSimple() { $timer = AKFactory::getTimer(); // Files are being processed in small chunks, to avoid timeouts if( ($this->dataReadLength == 0) && !AKFactory::get('kickstart.setup.dryrun','0') ) { // Before processing file data, ensure permissions are adequate $this->setCorrectPermissions( $this->fileHeader->file ); } // Open the output file if( !AKFactory::get('kickstart.setup.dryrun','0') ) { // Open the output file $outfp = @fopen( $this->fileHeader->realFile, 'wb' ); // Can we write to the file? $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false); if( ($outfp === false) && (!$ignore) ) { // An error occured $this->setError( AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile) ); return false; } } // Does the file have any data, at all? if( $this->fileHeader->uncompressed == 0 ) { // No file data! if( !AKFactory::get('kickstart.setup.dryrun','0') ) if(is_resource($outfp)) @fclose($outfp); $this->runState = AK_STATE_DATAREAD; return true; } $leftBytes = $this->fileHeader->uncompressed - $this->dataReadLength; // Loop while there's data to write and enough time to do it while( ($leftBytes > 0) && ($timer->getTimeLeft() > 0) ) { // Read the mini header $binMiniHeader = fread($this->fp, 8); $reallyReadBytes = akstringlen($binMiniHeader); if($reallyReadBytes < 8) { // We read less than requested! Why? Did we hit local EOF? if( $this->isEOF(true) && !$this->isEOF(false) ) { // Yeap. Let's go to the next file $this->nextFile(); // Retry reading the header $binMiniHeader = fread($this->fp, 8); $reallyReadBytes = akstringlen($binMiniHeader); // Still not enough data? If so, the archive is corrupt or missing parts. if($reallyReadBytes < 8) { $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } else { // Nope. The archive is corrupt $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } // Read the encrypted data $miniHeader = unpack('Vencsize/Vdecsize', $binMiniHeader); $toReadBytes = $miniHeader['encsize']; $data = $this->fread( $this->fp, $toReadBytes ); $reallyReadBytes = akstringlen($data); if($reallyReadBytes < $toReadBytes) { // We read less than requested! Why? Did we hit local EOF? if( $this->isEOF(true) && !$this->isEOF(false) ) { // Yeap. Let's go to the next file $this->nextFile(); // Read the rest of the data $toReadBytes -= $reallyReadBytes; $restData = $this->fread( $this->fp, $toReadBytes ); $reallyReadBytes = akstringlen($restData); if($reallyReadBytes < $toReadBytes) { $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } if(akstringlen($data) == 0) { $data = $restData; } else { $data .= $restData; } } else { // Nope. The archive is corrupt $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } // Decrypt the data $data = AKEncryptionAES::AESDecryptCBC($data, $this->password, 128); // Is the length of the decrypted data less than expected? $data_length = akstringlen($data); if($data_length < $miniHeader['decsize']) { $this->setError(AKText::_('ERR_INVALID_JPS_PASSWORD')); return false; } // Trim the data $data = substr($data,0,$miniHeader['decsize']); // Decompress $data = gzinflate($data); $unc_len = akstringlen($data); // Write the decrypted data if( !AKFactory::get('kickstart.setup.dryrun','0') ) if(is_resource($outfp)) @fwrite( $outfp, $data, akstringlen($data) ); // Update the read length $this->dataReadLength += $unc_len; $leftBytes = $this->fileHeader->uncompressed - $this->dataReadLength; } // Close the file pointer if( !AKFactory::get('kickstart.setup.dryrun','0') ) if(is_resource($outfp)) @fclose($outfp); // Was this a pre-timeout bail out? if( $leftBytes > 0 ) { $this->runState = AK_STATE_DATA; } else { // Oh! We just finished! $this->runState = AK_STATE_DATAREAD; $this->dataReadLength = 0; } } /** * Process the file data of a link entry * @return bool */ private function processTypeLink() { // Does the file have any data, at all? if( $this->fileHeader->uncompressed == 0 ) { // No file data! $this->runState = AK_STATE_DATAREAD; return true; } // Read the mini header $binMiniHeader = fread($this->fp, 8); $reallyReadBytes = akstringlen($binMiniHeader); if($reallyReadBytes < 8) { // We read less than requested! Why? Did we hit local EOF? if( $this->isEOF(true) && !$this->isEOF(false) ) { // Yeap. Let's go to the next file $this->nextFile(); // Retry reading the header $binMiniHeader = fread($this->fp, 8); $reallyReadBytes = akstringlen($binMiniHeader); // Still not enough data? If so, the archive is corrupt or missing parts. if($reallyReadBytes < 8) { $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } else { // Nope. The archive is corrupt $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } // Read the encrypted data $miniHeader = unpack('Vencsize/Vdecsize', $binMiniHeader); $toReadBytes = $miniHeader['encsize']; $data = $this->fread( $this->fp, $toReadBytes ); $reallyReadBytes = akstringlen($data); if($reallyReadBytes < $toReadBytes) { // We read less than requested! Why? Did we hit local EOF? if( $this->isEOF(true) && !$this->isEOF(false) ) { // Yeap. Let's go to the next file $this->nextFile(); // Read the rest of the data $toReadBytes -= $reallyReadBytes; $restData = $this->fread( $this->fp, $toReadBytes ); $reallyReadBytes = akstringlen($data); if($reallyReadBytes < $toReadBytes) { $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } $data .= $restData; } else { // Nope. The archive is corrupt $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } // Decrypt the data $data = AKEncryptionAES::AESDecryptCBC($data, $this->password, 128); // Is the length of the decrypted data less than expected? $data_length = akstringlen($data); if($data_length < $miniHeader['decsize']) { $this->setError(AKText::_('ERR_INVALID_JPS_PASSWORD')); return false; } // Trim the data $data = substr($data,0,$miniHeader['decsize']); // Try to remove an existing file or directory by the same name if(file_exists($this->fileHeader->realFile)) { @unlink($this->fileHeader->realFile); @rmdir($this->fileHeader->realFile); } // Remove any trailing slash if(substr($this->fileHeader->realFile, -1) == '/') $this->fileHeader->realFile = substr($this->fileHeader->realFile, 0, -1); // Create the symlink - only possible within PHP context. There's no support built in the FTP protocol, so no postproc use is possible here :( if( !AKFactory::get('kickstart.setup.dryrun','0') ) @symlink($data, $this->fileHeader->realFile); $this->runState = AK_STATE_DATAREAD; return true; // No matter if the link was created! } /** * Process the file data of a directory entry * @return bool */ private function processTypeDir() { // Directory entries in the JPA do not have file data, therefore we're done processing the entry $this->runState = AK_STATE_DATAREAD; return true; } /** * Creates the directory this file points to */ protected function createDirectory() { if( AKFactory::get('kickstart.setup.dryrun','0') ) return true; // Do we need to create a directory? $lastSlash = strrpos($this->fileHeader->realFile, '/'); $dirName = substr( $this->fileHeader->realFile, 0, $lastSlash); $perms = $this->flagRestorePermissions ? $retArray['permissions'] : 0755; $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false); if( ($this->postProcEngine->createDirRecursive($dirName, $perms) == false) && (!$ignore) ) { $this->setError( AKText::sprintf('COULDNT_CREATE_DIR', $dirName) ); return false; } else { return true; } } } /** * A filesystem scanner which uses opendir() */ class AKUtilsLister extends AKAbstractObject { public function &getFiles($folder, $pattern = '*') { // Initialize variables $arr = array(); $false = false; if(!is_dir($folder)) return $false; $handle = @opendir($folder); // If directory is not accessible, just return FALSE if ($handle === FALSE) { $this->setWarning( 'Unreadable directory '.$folder); return $false; } while (($file = @readdir($handle)) !== false) { if( !fnmatch($pattern, $file) ) continue; if (($file != '.') && ($file != '..')) { $ds = ($folder == '') || ($folder == '/') || (@substr($folder, -1) == '/') || (@substr($folder, -1) == DIRECTORY_SEPARATOR) ? '' : DIRECTORY_SEPARATOR; $dir = $folder . $ds . $file; $isDir = is_dir($dir); if (!$isDir) { $arr[] = $dir; } } } @closedir($handle); return $arr; } public function &getFolders($folder, $pattern = '*') { // Initialize variables $arr = array(); $false = false; if(!is_dir($folder)) return $false; $handle = @opendir($folder); // If directory is not accessible, just return FALSE if ($handle === FALSE) { $this->setWarning( 'Unreadable directory '.$folder); return $false; } while (($file = @readdir($handle)) !== false) { if( !fnmatch($pattern, $file) ) continue; if (($file != '.') && ($file != '..')) { $ds = ($folder == '') || ($folder == '/') || (@substr($folder, -1) == '/') || (@substr($folder, -1) == DIRECTORY_SEPARATOR) ? '' : DIRECTORY_SEPARATOR; $dir = $folder . $ds . $file; $isDir = is_dir($dir); if ($isDir) { $arr[] = $dir; } } } @closedir($handle); return $arr; } } /** * A simple INI-based i18n engine */ class AKText extends AKAbstractObject { /** * The default (en_GB) translation used when no other translation is available * @var array */ private $default_translation = array( 'AUTOMODEON' => 'Auto-mode enabled', 'ERR_NOT_A_JPA_FILE' => 'The file is not a JPA archive', 'ERR_CORRUPT_ARCHIVE' => 'The archive file is corrupt, truncated or archive parts are missing', 'ERR_INVALID_LOGIN' => 'Invalid login', 'COULDNT_CREATE_DIR' => 'Could not create %s folder', 'COULDNT_WRITE_FILE' => 'Could not open %s for writing.', 'WRONG_FTP_HOST' => 'Wrong FTP host or port', 'WRONG_FTP_USER' => 'Wrong FTP username or password', 'WRONG_FTP_PATH1' => 'Wrong FTP initial directory - the directory doesn\'t exist', 'FTP_CANT_CREATE_DIR' => 'Could not create directory %s', 'FTP_TEMPDIR_NOT_WRITABLE' => 'Could not find or create a writable temporary directory', 'FTP_COULDNT_UPLOAD' => 'Could not upload %s', 'THINGS_HEADER' => 'Things you should know about Akeeba Kickstart', 'THINGS_01' => 'Kickstart is not an installer. It is an archive extraction tool. The actual installer was put inside the archive file at backup time.', 'THINGS_02' => 'Kickstart is not the only way to extract the backup archive. You can use Akeeba eXtract Wizard and upload the extracted files using FTP instead.', 'THINGS_03' => 'Kickstart is bound by your server\'s configuration. As such, it may not work at all.', 'THINGS_04' => 'You should download and upload your archive files using FTP in Binary transfer mode. Any other method could lead to a corrupt backup archive and restoration failure.', 'THINGS_05' => 'Post-restoration site load errors are usually caused by .htaccess or php.ini directives. You should understand that blank pages, 404 and 500 errors can usually be worked around by editing the aforementioned files. It is not our job to mess with your configuration files, because this could be dangerous for your site.', 'THINGS_06' => 'Kickstart overwrites files without a warning. If you are not sure that you are OK with that do not continue.', 'THINGS_07' => 'Trying to restore to the temporary URL of a cPanel host (e.g. http://1.2.3.4/~username) will lead to restoration failure and your site will appear to be not working. This is normal and it\'s just how your server and CMS software work.', 'THINGS_08' => 'You are supposed to read the documentation before using this software. Most issues can be avoided, or easily worked around, by understanding how this software works.', 'THINGS_09' => 'This text does not imply that there is a problem detected. It is standard text displayed every time you launch Kickstart.', 'CLOSE_LIGHTBOX' => 'Click here or press ESC to close this message', 'SELECT_ARCHIVE' => 'Select a backup archive', 'ARCHIVE_FILE' => 'Archive file:', 'SELECT_EXTRACTION' => 'Select an extraction method', 'WRITE_TO_FILES' => 'Write to files:', 'WRITE_DIRECTLY' => 'Directly', 'WRITE_FTP' => 'Use FTP', 'FTP_HOST' => 'FTP host name:', 'FTP_PORT' => 'FTP port:', 'FTP_FTPS' => 'Use FTP over SSL (FTPS)', 'FTP_PASSIVE' => 'Use FTP Passive Mode', 'FTP_USER' => 'FTP user name:', 'FTP_PASS' => 'FTP password:', 'FTP_DIR' => 'FTP directory:', 'FTP_TEMPDIR' => 'Temporary directory:', 'FTP_CONNECTION_OK' => 'FTP Connection Established', 'FTP_CONNECTION_FAILURE' => 'The FTP Connection Failed', 'FTP_TEMPDIR_WRITABLE' => 'The temporary directory is writable.', 'FTP_TEMPDIR_UNWRITABLE' => 'The temporary directory is not writable. Please check the permissions.', 'BTN_CHECK' => 'Check', 'BTN_RESET' => 'Reset', 'BTN_TESTFTPCON' => 'Test FTP connection', 'BTN_GOTOSTART' => 'Start over', 'FINE_TUNE' => 'Fine tune', 'MIN_EXEC_TIME' => 'Minimum execution time:', 'MAX_EXEC_TIME' => 'Maximum execution time:', 'SECONDS_PER_STEP' => 'seconds per step', 'EXTRACT_FILES' => 'Extract files', 'BTN_START' => 'Start', 'EXTRACTING' => 'Extracting', 'DO_NOT_CLOSE_EXTRACT' => 'Do not close this window while the extraction is in progress', 'RESTACLEANUP' => 'Restoration and Clean Up', 'BTN_RUNINSTALLER' => 'Run the Installer', 'BTN_CLEANUP' => 'Clean Up', 'BTN_SITEFE' => 'Visit your site\'s front-end', 'BTN_SITEBE' => 'Visit your site\'s back-end', 'WARNINGS' => 'Extraction Warnings', 'ERROR_OCCURED' => 'An error occured', 'STEALTH_MODE' => 'Stealth mode', 'STEALTH_URL' => 'HTML file to show to web visitors', 'ERR_NOT_A_JPS_FILE' => 'The file is not a JPA archive', 'ERR_INVALID_JPS_PASSWORD' => 'The password you gave is wrong or the archive is corrupt', 'JPS_PASSWORD' => 'Archive Password (for JPS files)', 'INVALID_FILE_HEADER' => 'Invalid header in archive file, part %s, offset %s', 'NEEDSOMEHELPKS' => 'Want some help to use this tool? Read this first:', 'QUICKSTART' => 'Quick Start Guide', 'CANTGETITTOWORK' => 'Can\'t get it to work? Click me!', 'NOARCHIVESCLICKHERE' => 'No archives detected. Click here for troubleshooting instructions.', 'POSTRESTORATIONTROUBLESHOOTING' => 'Something not working after the restoration? Click here for troubleshooting instructions.', 'UPDATE_HEADER' => 'An updated version of Akeeba Kickstart (unknown) is available!', 'UPDATE_NOTICE' => 'You are advised to always use the latest version of Akeeba Kickstart available. Older versions may be subject to bugs and will not be supported.', 'UPDATE_DLNOW' => 'Download now', 'UPDATE_MOREINFO' => 'More information' ); /** * The array holding the translation keys * @var array */ private $strings; /** * The currently detected language (ISO code) * @var string */ private $language; /* * Initializes the translation engine * @return AKText */ public function __construct() { // Start with the default translation $this->strings = $this->default_translation; // Try loading the translation file in English, if it exists $this->loadTranslation('en-GB'); // Try loading the translation file in the browser's preferred language, if it exists $this->getBrowserLanguage(); if(!is_null($this->language)) { $this->loadTranslation(); } } /** * Singleton pattern for Language * @return Language The global Language instance */ public static function &getInstance() { static $instance; if(!is_object($instance)) { $instance = new AKText(); } return $instance; } public static function _($string) { $text = self::getInstance(); $key = strtoupper($string); $key = substr($key, 0, 1) == '_' ? substr($key, 1) : $key; if (isset ($text->strings[$key])) { $string = $text->strings[$key]; } else { if (defined($string)) { $string = constant($string); } } return $string; } public static function sprintf($key) { $text = self::getInstance(); $args = func_get_args(); if (count($args) > 0) { $args[0] = $text->_($args[0]); return @call_user_func_array('sprintf', $args); } return ''; } public function dumpLanguage() { $out = ''; foreach($this->strings as $key => $value) { $out .= "$key=$value\n"; } return $out; } public function asJavascript() { $out = ''; foreach($this->strings as $key => $value) { $key = addcslashes($key, '\\\'"'); $value = addcslashes($value, '\\\'"'); if(!empty($out)) $out .= ",\n"; $out .= "'$key':\t'$value'"; } return $out; } public function resetTranslation() { $this->strings = $this->default_translation; } public function getBrowserLanguage() { // Detection code from Full Operating system language detection, by Harald Hope // Retrieved from http://techpatterns.com/downloads/php_language_detection.php $user_languages = array(); //check to see if language is set if ( isset( $_SERVER["HTTP_ACCEPT_LANGUAGE"] ) ) { $languages = strtolower( $_SERVER["HTTP_ACCEPT_LANGUAGE"] ); // $languages = ' fr-ch;q=0.3, da, en-us;q=0.8, en;q=0.5, fr;q=0.3'; // need to remove spaces from strings to avoid error $languages = str_replace( ' ', '', $languages ); $languages = explode( ",", $languages ); foreach ( $languages as $language_list ) { // pull out the language, place languages into array of full and primary // string structure: $temp_array = array(); // slice out the part before ; on first step, the part before - on second, place into array $temp_array[0] = substr( $language_list, 0, strcspn( $language_list, ';' ) );//full language $temp_array[1] = substr( $language_list, 0, 2 );// cut out primary language if( (strlen($temp_array[0]) == 5) && ( (substr($temp_array[0],2,1) == '-') || (substr($temp_array[0],2,1) == '_') ) ) { $langLocation = strtoupper(substr($temp_array[0],3,2)); $temp_array[0] = $temp_array[1].'-'.$langLocation; } //place this array into main $user_languages language array $user_languages[] = $temp_array; } } else// if no languages found { $user_languages[0] = array( '','' ); //return blank array. } $this->language = null; $basename=basename(__FILE__, '.php') . '.ini'; // Try to match main language part of the filename, irrespective of the location, e.g. de_DE will do if de_CH doesn't exist. $fs = new AKUtilsLister(); $iniFiles = $fs->getFiles( dirname(__FILE__), '*.'.$basename ); if(empty($iniFiles) && ($basename != 'kickstart.ini')) { $basename = 'kickstart.ini'; $iniFiles = $fs->getFiles( dirname(__FILE__), '*.'.$basename ); } if (is_array($iniFiles)) { foreach($user_languages as $languageStruct) { if(is_null($this->language)) { // Get files matching the main lang part $iniFiles = $fs->getFiles( dirname(__FILE__), $languageStruct[1].'-??.'.$basename ); if (count($iniFiles) > 0) { $filename = $iniFiles[0]; $filename = substr($filename, strlen(dirname(__FILE__))+1); $this->language = substr($filename, 0, 5); } else { $this->language = null; } } } } if(is_null($this->language)) { // Try to find a full language match foreach($user_languages as $languageStruct) { if (@file_exists($languageStruct[0].'.'.$basename) && is_null($this->language)) { $this->language = $languageStruct[0]; } else { } } } else { // Do we have an exact match? foreach($user_languages as $languageStruct) { if(substr($this->language,0,strlen($languageStruct[1])) == $languageStruct[1]) { if(file_exists($languageStruct[0].'.'.$basename)) { $this->language = $languageStruct[0]; } } } } // Now, scan for full language based on the partial match } private function loadTranslation( $lang = null ) { $dirname = function_exists('getcwd') ? getcwd() : dirname(__FILE__); $basename=basename(__FILE__, '.php') . '.ini'; if( empty($lang) ) $lang = $this->language; $translationFilename = $dirname.DIRECTORY_SEPARATOR.$lang.'.'.$basename; if(!@file_exists($translationFilename) && ($basename != 'kickstart.ini')) { $basename = 'kickstart.ini'; $translationFilename = $dirname.DIRECTORY_SEPARATOR.$lang.'.'.$basename; } if(!@file_exists($translationFilename)) return; $temp = self::parse_ini_file($translationFilename, false); if(!is_array($this->strings)) $this->strings = array(); if(empty($temp)) { $this->strings = array_merge($this->default_translation, $this->strings); } else { $this->strings = array_merge($this->strings, $temp); } } /** * A PHP based INI file parser. * * Thanks to asohn ~at~ aircanopy ~dot~ net for posting this handy function on * the parse_ini_file page on http://gr.php.net/parse_ini_file * * @param string $file Filename to process * @param bool $process_sections True to also process INI sections * @return array An associative array of sections, keys and values * @access private */ public static function parse_ini_file($file, $process_sections = false, $raw_data = false) { $process_sections = ($process_sections !== true) ? false : true; if(!$raw_data) { $ini = @file($file); } else { $ini = $file; } if (count($ini) == 0) {return array();} $sections = array(); $values = array(); $result = array(); $globals = array(); $i = 0; if(!empty($ini)) foreach ($ini as $line) { $line = trim($line); $line = str_replace("\t", " ", $line); // Comments if (!preg_match('/^[a-zA-Z0-9[]/', $line)) {continue;} // Sections if ($line{0} == '[') { $tmp = explode(']', $line); $sections[] = trim(substr($tmp[0], 1)); $i++; continue; } // Key-value pair list($key, $value) = explode('=', $line, 2); $key = trim($key); $value = trim($value); if (strstr($value, ";")) { $tmp = explode(';', $value); if (count($tmp) == 2) { if ((($value{0} != '"') && ($value{0} != "'")) || preg_match('/^".*"\s*;/', $value) || preg_match('/^".*;[^"]*$/', $value) || preg_match("/^'.*'\s*;/", $value) || preg_match("/^'.*;[^']*$/", $value) ){ $value = $tmp[0]; } } else { if ($value{0} == '"') { $value = preg_replace('/^"(.*)".*/', '$1', $value); } elseif ($value{0} == "'") { $value = preg_replace("/^'(.*)'.*/", '$1', $value); } else { $value = $tmp[0]; } } } $value = trim($value); $value = trim($value, "'\""); if ($i == 0) { if (substr($line, -1, 2) == '[]') { $globals[$key][] = $value; } else { $globals[$key] = $value; } } else { if (substr($line, -1, 2) == '[]') { $values[$i-1][$key][] = $value; } else { $values[$i-1][$key] = $value; } } } for($j = 0; $j < $i; $j++) { if ($process_sections === true) { $result[$sections[$j]] = $values[$j]; } else { $result[] = $values[$j]; } } return $result + $globals; } } /** * The Akeeba Kickstart Factory class * This class is reponssible for instanciating all Akeeba Kicsktart classes */ class AKFactory { /** @var array A list of instanciated objects */ private $objectlist = array(); /** @var array Simple hash data storage */ private $varlist = array(); /** Private constructor makes sure we can't directly instanciate the class */ private function __construct() {} /** * Gets a single, internally used instance of the Factory * @param string $serialized_data [optional] Serialized data to spawn the instance from * @return AKFactory A reference to the unique Factory object instance */ protected static function &getInstance( $serialized_data = null ) { static $myInstance; if(!is_object($myInstance) || !is_null($serialized_data)) if(!is_null($serialized_data)) { $myInstance = unserialize($serialized_data); } else { $myInstance = new self(); } return $myInstance; } /** * Internal function which instanciates a class named $class_name. * The autoloader * @param object $class_name * @return */ protected static function &getClassInstance($class_name) { $self = self::getInstance(); if(!isset($self->objectlist[$class_name])) { $self->objectlist[$class_name] = new $class_name; } return $self->objectlist[$class_name]; } // ======================================================================== // Public factory interface // ======================================================================== /** * Gets a serialized snapshot of the Factory for safekeeping (hibernate) * @return string The serialized snapshot of the Factory */ public static function serialize() { $engine = self::getUnarchiver(); $engine->shutdown(); $serialized = serialize(self::getInstance()); if(function_exists('base64_encode') && function_exists('base64_decode')) { $serialized = base64_encode($serialized); } return $serialized; } /** * Regenerates the full Factory state from a serialized snapshot (resume) * @param string $serialized_data The serialized snapshot to resume from */ public static function unserialize($serialized_data) { if(function_exists('base64_encode') && function_exists('base64_decode')) { $serialized_data = base64_decode($serialized_data); } self::getInstance($serialized_data); } /** * Reset the internal factory state, freeing all previously created objects */ public static function nuke() { $self = self::getInstance(); foreach($self->objectlist as $key => $object) { $self->objectlist[$key] = null; } $self->objectlist = array(); } // ======================================================================== // Public hash data storage interface // ======================================================================== public static function set($key, $value) { $self = self::getInstance(); $self->varlist[$key] = $value; } public static function get($key, $default = null) { $self = self::getInstance(); if( array_key_exists($key, $self->varlist) ) { return $self->varlist[$key]; } else { return $default; } } // ======================================================================== // Akeeba Kickstart classes // ======================================================================== /** * Gets the post processing engine * @param string $proc_engine */ public static function &getPostProc($proc_engine = null) { static $class_name; if( empty($class_name) ) { if(empty($proc_engine)) { $proc_engine = self::get('kickstart.procengine','direct'); } $class_name = 'AKPostproc'.ucfirst($proc_engine); } return self::getClassInstance($class_name); } /** * Gets the unarchiver engine */ public static function &getUnarchiver( $configOverride = null ) { static $class_name; if(!empty($configOverride)) { if($configOverride['reset']) { $class_name = null; } } if( empty($class_name) ) { $filetype = self::get('kickstart.setup.filetype', null); if(empty($filetype)) { $filename = self::get('kickstart.setup.sourcefile', null); $basename = basename($filename); $baseextension = strtoupper(substr($basename,-3)); switch($baseextension) { case 'JPA': $filetype = 'JPA'; break; case 'JPS': $filetype = 'JPS'; break; case 'ZIP': $filetype = 'ZIP'; break; default: die('Invalid archive type or extension in file '.$filename); break; } } $class_name = 'AKUnarchiver'.ucfirst($filetype); } $destdir = self::get('kickstart.setup.destdir', null); if(empty($destdir)) { $destdir = function_exists('getcwd') ? getcwd() : dirname(__FILE__); } $object = self::getClassInstance($class_name); if( $object->getState() == 'init') { // Initialize the object $config = array( 'filename' => self::get('kickstart.setup.sourcefile', ''), 'restore_permissions' => self::get('kickstart.setup.restoreperms', 0), 'post_proc' => self::get('kickstart.procengine', 'direct'), 'add_path' => $destdir, 'rename_files' => array( '.htaccess' => 'htaccess.bak', 'php.ini' => 'php.ini.bak' ), 'skip_files' => array( basename(__FILE__), 'kickstart.php', 'abiautomation.ini', 'htaccess.bak', 'php.ini.bak' ) ); if(!defined('KICKSTART')) { // In restore.php mode we have to exclude some more files $config['skip_files'][] = 'administrator/components/com_akeeba/restore.php'; $config['skip_files'][] = 'administrator/components/com_akeeba/restoration.php'; } if(!empty($configOverride)) { foreach($configOverride as $key => $value) { $config[$key] = $value; } } $object->setup($config); } return $object; } /** * Get the a reference to the Akeeba Engine's timer * @return AKCoreTimer */ public static function &getTimer() { return self::getClassInstance('AKCoreTimer'); } } /** * AES implementation in PHP (c) Chris Veness 2005-2011 * (http://www.movable-type.co.uk/scripts/aes-php.html) * I offer these formulæ & scripts for free use and adaptation as my contribution to the * open-source info-sphere from which I have received so much. You are welcome to re-use these * scripts [under a simple attribution license or a GPL licence, without any warranty express or implied] * provided solely that you retain my copyright notice and a link to this page. * licence. No warranty of any form is offered. * * Modified for Akeeba Backup by Nicholas K. Dionysopoulos */ class AKEncryptionAES { // Sbox is pre-computed multiplicative inverse in GF(2^8) used in SubBytes and KeyExpansion [�5.1.1] protected static $Sbox = array(0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76, 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0, 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15, 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75, 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84, 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf, 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8, 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2, 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73, 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb, 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79, 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08, 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a, 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e, 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf, 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16); // Rcon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [�5.2] protected static $Rcon = array( array(0x00, 0x00, 0x00, 0x00), array(0x01, 0x00, 0x00, 0x00), array(0x02, 0x00, 0x00, 0x00), array(0x04, 0x00, 0x00, 0x00), array(0x08, 0x00, 0x00, 0x00), array(0x10, 0x00, 0x00, 0x00), array(0x20, 0x00, 0x00, 0x00), array(0x40, 0x00, 0x00, 0x00), array(0x80, 0x00, 0x00, 0x00), array(0x1b, 0x00, 0x00, 0x00), array(0x36, 0x00, 0x00, 0x00) ); protected static $passwords = array(); /** * AES Cipher function: encrypt 'input' with Rijndael algorithm * * @param input message as byte-array (16 bytes) * @param w key schedule as 2D byte-array (Nr+1 x Nb bytes) - * generated from the cipher key by KeyExpansion() * @return ciphertext as byte-array (16 bytes) */ protected static function Cipher($input, $w) { // main Cipher function [�5.1] $Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES) $Nr = count($w)/$Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys $state = array(); // initialise 4xNb byte-array 'state' with input [�3.4] for ($i=0; $i<4*$Nb; $i++) $state[$i%4][floor($i/4)] = $input[$i]; $state = self::AddRoundKey($state, $w, 0, $Nb); for ($round=1; $round<$Nr; $round++) { // apply Nr rounds $state = self::SubBytes($state, $Nb); $state = self::ShiftRows($state, $Nb); $state = self::MixColumns($state, $Nb); $state = self::AddRoundKey($state, $w, $round, $Nb); } $state = self::SubBytes($state, $Nb); $state = self::ShiftRows($state, $Nb); $state = self::AddRoundKey($state, $w, $Nr, $Nb); $output = array(4*$Nb); // convert state to 1-d array before returning [�3.4] for ($i=0; $i<4*$Nb; $i++) $output[$i] = $state[$i%4][floor($i/4)]; return $output; } protected static function AddRoundKey($state, $w, $rnd, $Nb) { // xor Round Key into state S [�5.1.4] for ($r=0; $r<4; $r++) { for ($c=0; $c<$Nb; $c++) $state[$r][$c] ^= $w[$rnd*4+$c][$r]; } return $state; } protected static function SubBytes($s, $Nb) { // apply SBox to state S [�5.1.1] for ($r=0; $r<4; $r++) { for ($c=0; $c<$Nb; $c++) $s[$r][$c] = self::$Sbox[$s[$r][$c]]; } return $s; } protected static function ShiftRows($s, $Nb) { // shift row r of state S left by r bytes [�5.1.2] $t = array(4); for ($r=1; $r<4; $r++) { for ($c=0; $c<4; $c++) $t[$c] = $s[$r][($c+$r)%$Nb]; // shift into temp copy for ($c=0; $c<4; $c++) $s[$r][$c] = $t[$c]; // and copy back } // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES): return $s; // see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf } protected static function MixColumns($s, $Nb) { // combine bytes of each col of state S [�5.1.3] for ($c=0; $c<4; $c++) { $a = array(4); // 'a' is a copy of the current column from 's' $b = array(4); // 'b' is a�{02} in GF(2^8) for ($i=0; $i<4; $i++) { $a[$i] = $s[$i][$c]; $b[$i] = $s[$i][$c]&0x80 ? $s[$i][$c]<<1 ^ 0x011b : $s[$i][$c]<<1; } // a[n] ^ b[n] is a�{03} in GF(2^8) $s[0][$c] = $b[0] ^ $a[1] ^ $b[1] ^ $a[2] ^ $a[3]; // 2*a0 + 3*a1 + a2 + a3 $s[1][$c] = $a[0] ^ $b[1] ^ $a[2] ^ $b[2] ^ $a[3]; // a0 * 2*a1 + 3*a2 + a3 $s[2][$c] = $a[0] ^ $a[1] ^ $b[2] ^ $a[3] ^ $b[3]; // a0 + a1 + 2*a2 + 3*a3 $s[3][$c] = $a[0] ^ $b[0] ^ $a[1] ^ $a[2] ^ $b[3]; // 3*a0 + a1 + a2 + 2*a3 } return $s; } /** * Key expansion for Rijndael Cipher(): performs key expansion on cipher key * to generate a key schedule * * @param key cipher key byte-array (16 bytes) * @return key schedule as 2D byte-array (Nr+1 x Nb bytes) */ protected static function KeyExpansion($key) { // generate Key Schedule from Cipher Key [�5.2] $Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES) $Nk = count($key)/4; // key length (in words): 4/6/8 for 128/192/256-bit keys $Nr = $Nk + 6; // no of rounds: 10/12/14 for 128/192/256-bit keys $w = array(); $temp = array(); for ($i=0; $i<$Nk; $i++) { $r = array($key[4*$i], $key[4*$i+1], $key[4*$i+2], $key[4*$i+3]); $w[$i] = $r; } for ($i=$Nk; $i<($Nb*($Nr+1)); $i++) { $w[$i] = array(); for ($t=0; $t<4; $t++) $temp[$t] = $w[$i-1][$t]; if ($i % $Nk == 0) { $temp = self::SubWord(self::RotWord($temp)); for ($t=0; $t<4; $t++) $temp[$t] ^= self::$Rcon[$i/$Nk][$t]; } else if ($Nk > 6 && $i%$Nk == 4) { $temp = self::SubWord($temp); } for ($t=0; $t<4; $t++) $w[$i][$t] = $w[$i-$Nk][$t] ^ $temp[$t]; } return $w; } protected static function SubWord($w) { // apply SBox to 4-byte word w for ($i=0; $i<4; $i++) $w[$i] = self::$Sbox[$w[$i]]; return $w; } protected static function RotWord($w) { // rotate 4-byte word w left by one byte $tmp = $w[0]; for ($i=0; $i<3; $i++) $w[$i] = $w[$i+1]; $w[3] = $tmp; return $w; } /* * Unsigned right shift function, since PHP has neither >>> operator nor unsigned ints * * @param a number to be shifted (32-bit integer) * @param b number of bits to shift a to the right (0..31) * @return a right-shifted and zero-filled by b bits */ protected static function urs($a, $b) { $a &= 0xffffffff; $b &= 0x1f; // (bounds check) if ($a&0x80000000 && $b>0) { // if left-most bit set $a = ($a>>1) & 0x7fffffff; // right-shift one bit & clear left-most bit $a = $a >> ($b-1); // remaining right-shifts } else { // otherwise $a = ($a>>$b); // use normal right-shift } return $a; } /** * Encrypt a text using AES encryption in Counter mode of operation * - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf * * Unicode multi-byte character safe * * @param plaintext source text to be encrypted * @param password the password to use to generate a key * @param nBits number of bits to be used in the key (128, 192, or 256) * @return encrypted text */ public static function AESEncryptCtr($plaintext, $password, $nBits) { $blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES if (!($nBits==128 || $nBits==192 || $nBits==256)) return ''; // standard allows 128/192/256 bit keys // note PHP (5) gives us plaintext and password in UTF8 encoding! // use AES itself to encrypt password to get cipher key (using plain password as source for // key expansion) - gives us well encrypted key $nBytes = $nBits/8; // no bytes in key $pwBytes = array(); for ($i=0; $i<$nBytes; $i++) $pwBytes[$i] = ord(substr($password,$i,1)) & 0xff; $key = self::Cipher($pwBytes, self::KeyExpansion($pwBytes)); $key = array_merge($key, array_slice($key, 0, $nBytes-16)); // expand key to 16/24/32 bytes long // initialise counter block (NIST SP800-38A �B.2): millisecond time-stamp for nonce in // 1st 8 bytes, block counter in 2nd 8 bytes $counterBlock = array(); $nonce = floor(microtime(true)*1000); // timestamp: milliseconds since 1-Jan-1970 $nonceSec = floor($nonce/1000); $nonceMs = $nonce%1000; // encode nonce with seconds in 1st 4 bytes, and (repeated) ms part filling 2nd 4 bytes for ($i=0; $i<4; $i++) $counterBlock[$i] = self::urs($nonceSec, $i*8) & 0xff; for ($i=0; $i<4; $i++) $counterBlock[$i+4] = $nonceMs & 0xff; // and convert it to a string to go on the front of the ciphertext $ctrTxt = ''; for ($i=0; $i<8; $i++) $ctrTxt .= chr($counterBlock[$i]); // generate key schedule - an expansion of the key into distinct Key Rounds for each round $keySchedule = self::KeyExpansion($key); $blockCount = ceil(strlen($plaintext)/$blockSize); $ciphertxt = array(); // ciphertext as array of strings for ($b=0; $b<$blockCount; $b++) { // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes) // done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB) for ($c=0; $c<4; $c++) $counterBlock[15-$c] = self::urs($b, $c*8) & 0xff; for ($c=0; $c<4; $c++) $counterBlock[15-$c-4] = self::urs($b/0x100000000, $c*8); $cipherCntr = self::Cipher($counterBlock, $keySchedule); // -- encrypt counter block -- // block size is reduced on final block $blockLength = $b<$blockCount-1 ? $blockSize : (strlen($plaintext)-1)%$blockSize+1; $cipherByte = array(); for ($i=0; $i<$blockLength; $i++) { // -- xor plaintext with ciphered counter byte-by-byte -- $cipherByte[$i] = $cipherCntr[$i] ^ ord(substr($plaintext, $b*$blockSize+$i, 1)); $cipherByte[$i] = chr($cipherByte[$i]); } $ciphertxt[$b] = implode('', $cipherByte); // escape troublesome characters in ciphertext } // implode is more efficient than repeated string concatenation $ciphertext = $ctrTxt . implode('', $ciphertxt); $ciphertext = base64_encode($ciphertext); return $ciphertext; } /** * Decrypt a text encrypted by AES in counter mode of operation * * @param ciphertext source text to be decrypted * @param password the password to use to generate a key * @param nBits number of bits to be used in the key (128, 192, or 256) * @return decrypted text */ public static function AESDecryptCtr($ciphertext, $password, $nBits) { $blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES if (!($nBits==128 || $nBits==192 || $nBits==256)) return ''; // standard allows 128/192/256 bit keys $ciphertext = base64_decode($ciphertext); // use AES to encrypt password (mirroring encrypt routine) $nBytes = $nBits/8; // no bytes in key $pwBytes = array(); for ($i=0; $i<$nBytes; $i++) $pwBytes[$i] = ord(substr($password,$i,1)) & 0xff; $key = self::Cipher($pwBytes, self::KeyExpansion($pwBytes)); $key = array_merge($key, array_slice($key, 0, $nBytes-16)); // expand key to 16/24/32 bytes long // recover nonce from 1st element of ciphertext $counterBlock = array(); $ctrTxt = substr($ciphertext, 0, 8); for ($i=0; $i<8; $i++) $counterBlock[$i] = ord(substr($ctrTxt,$i,1)); // generate key schedule $keySchedule = self::KeyExpansion($key); // separate ciphertext into blocks (skipping past initial 8 bytes) $nBlocks = ceil((strlen($ciphertext)-8) / $blockSize); $ct = array(); for ($b=0; $b<$nBlocks; $b++) $ct[$b] = substr($ciphertext, 8+$b*$blockSize, 16); $ciphertext = $ct; // ciphertext is now array of block-length strings // plaintext will get generated block-by-block into array of block-length strings $plaintxt = array(); for ($b=0; $b<$nBlocks; $b++) { // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes) for ($c=0; $c<4; $c++) $counterBlock[15-$c] = self::urs($b, $c*8) & 0xff; for ($c=0; $c<4; $c++) $counterBlock[15-$c-4] = self::urs(($b+1)/0x100000000-1, $c*8) & 0xff; $cipherCntr = self::Cipher($counterBlock, $keySchedule); // encrypt counter block $plaintxtByte = array(); for ($i=0; $i $data_size) { $plaintext = substr($plaintext, 0, $data_size); } return $plaintext; } } /** * The Master Setup will read the configuration parameters from restoration.php, abiautomation.ini, or * the JSON-encoded "configuration" input variable and return the status. * @return bool True if the master configuration was applied to the Factory object */ function masterSetup() { // ------------------------------------------------------------ // 1. Import basic setup parameters // ------------------------------------------------------------ $ini_data = null; // In restore.php mode, require restoration.php or fail if(!defined('KICKSTART')) { // This is the standalone mode, used by Akeeba Backup Professional. It looks for a restoration.php // file to perform its magic. If the file is not there, we will abort. $setupFile = 'restoration.php'; if( !file_exists($setupFile) ) { // Uh oh... Somebody tried to pooh on our back yard. Lock the gates! Don't let the traitor inside! AKFactory::set('kickstart.enabled', false); return false; } // Load restoration.php. It creates a global variable named $restoration_setup require_once $setupFile; $ini_data = $restoration_setup; if(empty($ini_data)) { // No parameters fetched. Darn, how am I supposed to work like that?! AKFactory::set('kickstart.enabled', false); return false; } AKFactory::set('kickstart.enabled', true); } else { // Maybe we have $restoration_setup defined in the head of kickstart.php global $restoration_setup; if(!empty($restoration_setup) && !is_array($restoration_setup)) { $ini_data = AKText::parse_ini_file($restoration_setup, false, true); } elseif(is_array($restoration_setup)) { $ini_data = $restoration_setup; } } // Import any data from $restoration_setup if(!empty($ini_data)) { foreach($ini_data as $key => $value) { AKFactory::set($key, $value); } AKFactory::set('kickstart.enabled', true); } // Reinitialize $ini_data $ini_data = null; // ------------------------------------------------------------ // 2. Explode JSON parameters into $_REQUEST scope // ------------------------------------------------------------ // Detect a JSON string in the request variable and store it. $json = getQueryParam('json', null); // Remove everything from the request array if(!empty($_REQUEST)) { foreach($_REQUEST as $key => $value) { unset($_REQUEST[$key]); } } // Decrypt a possibly encrypted JSON string if(!empty($json)) { $password = AKFactory::get('kickstart.security.password', null); if(!empty($password)) { $json = AKEncryptionAES::AESDecryptCtr($json, $password, 128); } // Get the raw data $raw = json_decode( $json, true ); // Pass all JSON data to the request array if(!empty($raw)) { foreach($raw as $key => $value) { $_REQUEST[$key] = $value; } } } // ------------------------------------------------------------ // 3. Try the "factory" variable // ------------------------------------------------------------ // A "factory" variable will override all other settings. $serialized = getQueryParam('factory', null); if( !is_null($serialized) ) { // Get the serialized factory AKFactory::unserialize($serialized); AKFactory::set('kickstart.enabled', true); return true; } // ------------------------------------------------------------ // 4. Try abiautomation.ini and the configuration variable for Kickstart // ------------------------------------------------------------ if(defined('KICKSTART')) { // We are in Kickstart mode. abiautomation.ini has precedence. $setupFile = 'abiautomation.ini'; if( file_exists($setupFile) ) { // abiautomation.ini was found $ini_data = AKText::parse_ini_file('restoration.ini', false); } else { // abiautomation.ini was not found. Let's try input parameters. $configuration = getQueryParam('configuration'); if( !is_null($configuration) ) { // Let's decode the configuration from JSON to array $ini_data = json_decode($configuration, true); } else { // Neither exists. Enable Kickstart's interface anyway. $ini_data = array('kickstart.enabled'=>true); } } // Import any INI data we might have from other sources if(!empty($ini_data)) { foreach($ini_data as $key => $value) { AKFactory::set($key, $value); } AKFactory::set('kickstart.enabled', true); return true; } } } // Mini-controller for restore.php if(!defined('KICKSTART')) { // The observer class, used to report number of files and bytes processed class RestorationObserver extends AKAbstractPartObserver { public $compressedTotal = 0; public $uncompressedTotal = 0; public $filesProcessed = 0; public function update($object, $message) { if(!is_object($message)) return; if( !array_key_exists('type', get_object_vars($message)) ) return; if( $message->type == 'startfile' ) { $this->filesProcessed++; $this->compressedTotal += $message->content->compressed; $this->uncompressedTotal += $message->content->uncompressed; } } public function __toString() { return __CLASS__; } } // Import configuration masterSetup(); $retArray = array( 'status' => true, 'message' => null ); $enabled = AKFactory::get('kickstart.enabled', false); if($enabled) { $task = getQueryParam('task'); switch($task) { case 'ping': // ping task - realy does nothing! $timer = AKFactory::getTimer(); $timer->enforce_min_exec_time(); break; case 'startRestore': AKFactory::nuke(); // Reset the factory // Let the control flow to the next step (the rest of the code is common!!) case 'stepRestore': $engine = AKFactory::getUnarchiver(); // Get the engine $observer = new RestorationObserver(); // Create a new observer $engine->attach($observer); // Attach the observer $engine->tick(); $ret = $engine->getStatusArray(); if( $ret['Error'] != '' ) { $retArray['status'] = false; $retArray['done'] = true; $retArray['message'] = $ret['Error']; } elseif( !$ret['HasRun'] ) { $retArray['files'] = $observer->filesProcessed; $retArray['bytesIn'] = $observer->compressedTotal; $retArray['bytesOut'] = $observer->uncompressedTotal; $retArray['status'] = true; $retArray['done'] = true; } else { $retArray['files'] = $observer->filesProcessed; $retArray['bytesIn'] = $observer->compressedTotal; $retArray['bytesOut'] = $observer->uncompressedTotal; $retArray['status'] = true; $retArray['done'] = false; $retArray['factory'] = AKFactory::serialize(); } break; case 'finalizeRestore': $root = AKFactory::get('kickstart.setup.destdir'); // Remove the installation directory recursive_remove_directory( $root.'/installation' ); $postproc = AKFactory::getPostProc(); // Rename htaccess.bak to .htaccess if(file_exists($root.'/htaccess.bak')) { if( file_exists($root.'/.htaccess') ) { $postproc->unlink($root.'/.htaccess'); } $postproc->rename( $root.'/htaccess.bak', $root.'/.htaccess' ); } // Remove restoration.php $basepath = dirname(__FILE__); $basepath = rtrim( str_replace('\\','/',$basepath), '/' ); if(!empty($basepath)) $basepath .= '/'; $postproc->unlink( $basepath.'restoration.php' ); break; default: // Invalid task! $enabled = false; break; } } // Maybe we weren't authorized or the task was invalid? if(!$enabled) { // Maybe the user failed to enter any information $retArray['status'] = false; $retArray['message'] = AKText::_('ERR_INVALID_LOGIN'); } // JSON encode the message $json = json_encode($retArray); // Do I have to encrypt? $password = AKFactory::get('kickstart.security.password', null); if(!empty($password)) { $json = AKEncryptionAES::AESEncryptCtr($json, $password, 128); } // Return the message echo "###$json###"; } // ------------ lixlpixel recursive PHP functions ------------- // recursive_remove_directory( directory to delete, empty ) // expects path to directory and optional TRUE / FALSE to empty // of course PHP has to have the rights to delete the directory // you specify and all files and folders inside the directory // ------------------------------------------------------------ function recursive_remove_directory($directory) { // if the path has a slash at the end we remove it here if(substr($directory,-1) == '/') { $directory = substr($directory,0,-1); } // if the path is not valid or is not a directory ... if(!file_exists($directory) || !is_dir($directory)) { // ... we return false and exit the function return FALSE; // ... if the path is not readable }elseif(!is_readable($directory)) { // ... we return false and exit the function return FALSE; // ... else if the path is readable }else{ // we open the directory $handle = opendir($directory); $postproc = AKFactory::getPostProc(); // and scan through the items inside while (FALSE !== ($item = readdir($handle))) { // if the filepointer is not the current directory // or the parent directory if($item != '.' && $item != '..') { // we build the new path to delete $path = $directory.'/'.$item; // if the new path is a directory if(is_dir($path)) { // we call this function with the new path recursive_remove_directory($path); // if the new path is a file }else{ // we remove the file $postproc->unlink($path); } } } // close the directory closedir($handle); // try to delete the now empty directory if(!$postproc->rmdir($directory)) { // return false if not possible return FALSE; } // return success return TRUE; } } ?>components/com_joomlaupdate/restore.php.backup000066600000523674150771655450015757 0ustar00|'), array('*' => '.*', '?' => '.?')) . '$/i', $string ); } } // Unicode-safe binary data length function if(function_exists('mb_strlen')) { function akstringlen($string) { return mb_strlen($string,'8bit'); } } else { function akstringlen($string) { return strlen($string); } } /** * Gets a query parameter from GET or POST data * @param $key * @param $default */ function getQueryParam( $key, $default = null ) { $value = null; if(array_key_exists($key, $_REQUEST)) { $value = $_REQUEST[$key]; } elseif(array_key_exists($key, $_POST)) { $value = $_POST[$key]; } elseif(array_key_exists($key, $_GET)) { $value = $_GET[$key]; } else { return $default; } if(get_magic_quotes_gpc() && !is_null($value)) $value=stripslashes($value); return $value; } /** * Akeeba Backup's JSON compatibility layer * * On systems where json_encode and json_decode are not available, Akeeba * Backup will attempt to use PEAR's Services_JSON library to emulate them. * A copy of this library is included in this file and will be used if and * only if it isn't already loaded, e.g. due to PEAR's auto-loading, or a * 3PD extension loading it for its own purposes. */ /** * Converts to and from JSON format. * * JSON (JavaScript Object Notation) is a lightweight data-interchange * format. It is easy for humans to read and write. It is easy for machines * to parse and generate. It is based on a subset of the JavaScript * Programming Language, Standard ECMA-262 3rd Edition - December 1999. * This feature can also be found in Python. JSON is a text format that is * completely language independent but uses conventions that are familiar * to programmers of the C-family of languages, including C, C++, C#, Java, * JavaScript, Perl, TCL, and many others. These properties make JSON an * ideal data-interchange language. * * This package provides a simple encoder and decoder for JSON notation. It * is intended for use with client-side Javascript applications that make * use of HTTPRequest to perform server communication functions - data can * be encoded into JSON notation for use in a client-side javascript, or * decoded from incoming Javascript requests. JSON format is native to * Javascript, and can be directly eval()'ed with no further parsing * overhead * * All strings should be in ASCII or UTF-8 format! * * LICENSE: Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: Redistributions of source code must retain the * above copyright notice, this list of conditions and the following * disclaimer. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * @category * @package Services_JSON * @author Michal Migurski * @author Matt Knapp * @author Brett Stimmerman * @copyright 2005 Michal Migurski * @version CVS: $Id: restore.php 612 2011-05-19 08:26:26Z nikosdion $ * @license http://www.opensource.org/licenses/bsd-license.php * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 */ if(!defined('JSON_FORCE_OBJECT')) { define('JSON_FORCE_OBJECT', 1); } if(!defined('SERVICES_JSON_SLICE')) { /** * Marker constant for Services_JSON::decode(), used to flag stack state */ define('SERVICES_JSON_SLICE', 1); /** * Marker constant for Services_JSON::decode(), used to flag stack state */ define('SERVICES_JSON_IN_STR', 2); /** * Marker constant for Services_JSON::decode(), used to flag stack state */ define('SERVICES_JSON_IN_ARR', 3); /** * Marker constant for Services_JSON::decode(), used to flag stack state */ define('SERVICES_JSON_IN_OBJ', 4); /** * Marker constant for Services_JSON::decode(), used to flag stack state */ define('SERVICES_JSON_IN_CMT', 5); /** * Behavior switch for Services_JSON::decode() */ define('SERVICES_JSON_LOOSE_TYPE', 16); /** * Behavior switch for Services_JSON::decode() */ define('SERVICES_JSON_SUPPRESS_ERRORS', 32); } /** * Converts to and from JSON format. * * Brief example of use: * * * // create a new instance of Services_JSON * $json = new Services_JSON(); * * // convert a complexe value to JSON notation, and send it to the browser * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); * $output = $json->encode($value); * * print($output); * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] * * // accept incoming POST data, assumed to be in JSON notation * $input = file_get_contents('php://input', 1000000); * $value = $json->decode($input); * */ if(!class_exists('Akeeba_Services_JSON')) { class Akeeba_Services_JSON { /** * constructs a new JSON instance * * @param int $use object behavior flags; combine with boolean-OR * * possible values: * - SERVICES_JSON_LOOSE_TYPE: loose typing. * "{...}" syntax creates associative arrays * instead of objects in decode(). * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. * Values which can't be encoded (e.g. resources) * appear as NULL instead of throwing errors. * By default, a deeply-nested resource will * bubble up with an error, so all return values * from encode() should be checked with isError() */ function Akeeba_Services_JSON($use = 0) { $this->use = $use; } /** * convert a string from one UTF-16 char to one UTF-8 char * * Normally should be handled by mb_convert_encoding, but * provides a slower PHP-only method for installations * that lack the multibye string extension. * * @param string $utf16 UTF-16 character * @return string UTF-8 character * @access private */ function utf162utf8($utf16) { // oh please oh please oh please oh please oh please if(function_exists('mb_convert_encoding')) { return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); } $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); switch(true) { case ((0x7F & $bytes) == $bytes): // this case should never be reached, because we are in ASCII range // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr(0x7F & $bytes); case (0x07FF & $bytes) == $bytes: // return a 2-byte UTF-8 character // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr(0xC0 | (($bytes >> 6) & 0x1F)) . chr(0x80 | ($bytes & 0x3F)); case (0xFFFF & $bytes) == $bytes: // return a 3-byte UTF-8 character // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr(0xE0 | (($bytes >> 12) & 0x0F)) . chr(0x80 | (($bytes >> 6) & 0x3F)) . chr(0x80 | ($bytes & 0x3F)); } // ignoring UTF-32 for now, sorry return ''; } /** * convert a string from one UTF-8 char to one UTF-16 char * * Normally should be handled by mb_convert_encoding, but * provides a slower PHP-only method for installations * that lack the multibye string extension. * * @param string $utf8 UTF-8 character * @return string UTF-16 character * @access private */ function utf82utf16($utf8) { // oh please oh please oh please oh please oh please if(function_exists('mb_convert_encoding')) { return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); } switch(strlen($utf8)) { case 1: // this case should never be reached, because we are in ASCII range // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return $utf8; case 2: // return a UTF-16 character from a 2-byte UTF-8 char // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr(0x07 & (ord($utf8{0}) >> 2)) . chr((0xC0 & (ord($utf8{0}) << 6)) | (0x3F & ord($utf8{1}))); case 3: // return a UTF-16 character from a 3-byte UTF-8 char // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 return chr((0xF0 & (ord($utf8{0}) << 4)) | (0x0F & (ord($utf8{1}) >> 2))) . chr((0xC0 & (ord($utf8{1}) << 6)) | (0x7F & ord($utf8{2}))); } // ignoring UTF-32 for now, sorry return ''; } /** * encodes an arbitrary variable into JSON format * * @param mixed $var any number, boolean, string, array, or object to be encoded. * see argument 1 to Services_JSON() above for array-parsing behavior. * if var is a strng, note that encode() always expects it * to be in ASCII or UTF-8 format! * * @return mixed JSON string representation of input var or an error if a problem occurs * @access public */ function encode($var) { switch (gettype($var)) { case 'boolean': return $var ? 'true' : 'false'; case 'NULL': return 'null'; case 'integer': return (int) $var; case 'double': case 'float': return (float) $var; case 'string': // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT $ascii = ''; $strlen_var = strlen($var); /* * Iterate over every character in the string, * escaping with a slash or encoding to UTF-8 where necessary */ for ($c = 0; $c < $strlen_var; ++$c) { $ord_var_c = ord($var{$c}); switch (true) { case $ord_var_c == 0x08: $ascii .= '\b'; break; case $ord_var_c == 0x09: $ascii .= '\t'; break; case $ord_var_c == 0x0A: $ascii .= '\n'; break; case $ord_var_c == 0x0C: $ascii .= '\f'; break; case $ord_var_c == 0x0D: $ascii .= '\r'; break; case $ord_var_c == 0x22: case $ord_var_c == 0x2F: case $ord_var_c == 0x5C: // double quote, slash, slosh $ascii .= '\\'.$var{$c}; break; case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): // characters U-00000000 - U-0000007F (same as ASCII) $ascii .= $var{$c}; break; case (($ord_var_c & 0xE0) == 0xC0): // characters U-00000080 - U-000007FF, mask 110XXXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1})); $c += 1; $utf16 = $this->utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xF0) == 0xE0): // characters U-00000800 - U-0000FFFF, mask 1110XXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2})); $c += 2; $utf16 = $this->utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xF8) == 0xF0): // characters U-00010000 - U-001FFFFF, mask 11110XXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2}), ord($var{$c + 3})); $c += 3; $utf16 = $this->utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xFC) == 0xF8): // characters U-00200000 - U-03FFFFFF, mask 111110XX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2}), ord($var{$c + 3}), ord($var{$c + 4})); $c += 4; $utf16 = $this->utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; case (($ord_var_c & 0xFE) == 0xFC): // characters U-04000000 - U-7FFFFFFF, mask 1111110X // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $char = pack('C*', $ord_var_c, ord($var{$c + 1}), ord($var{$c + 2}), ord($var{$c + 3}), ord($var{$c + 4}), ord($var{$c + 5})); $c += 5; $utf16 = $this->utf82utf16($char); $ascii .= sprintf('\u%04s', bin2hex($utf16)); break; } } return '"'.$ascii.'"'; case 'array': /* * As per JSON spec if any array key is not an integer * we must treat the the whole array as an object. We * also try to catch a sparsely populated associative * array with numeric keys here because some JS engines * will create an array with empty indexes up to * max_index which can cause memory issues and because * the keys, which may be relevant, will be remapped * otherwise. * * As per the ECMA and JSON specification an object may * have any string as a property. Unfortunately due to * a hole in the ECMA specification if the key is a * ECMA reserved word or starts with a digit the * parameter is only accessible using ECMAScript's * bracket notation. */ // treat as a JSON object if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { $properties = array_map(array($this, 'name_value'), array_keys($var), array_values($var)); foreach($properties as $property) { if(Akeeba_Services_JSON::isError($property)) { return $property; } } return '{' . join(',', $properties) . '}'; } // treat it like a regular array $elements = array_map(array($this, 'encode'), $var); foreach($elements as $element) { if(Akeeba_Services_JSON::isError($element)) { return $element; } } return '[' . join(',', $elements) . ']'; case 'object': $vars = get_object_vars($var); $properties = array_map(array($this, 'name_value'), array_keys($vars), array_values($vars)); foreach($properties as $property) { if(Akeeba_Services_JSON::isError($property)) { return $property; } } return '{' . join(',', $properties) . '}'; default: return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) ? 'null' : new Akeeba_Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); } } /** * array-walking function for use in generating JSON-formatted name-value pairs * * @param string $name name of key to use * @param mixed $value reference to an array element to be encoded * * @return string JSON-formatted name-value pair, like '"name":value' * @access private */ function name_value($name, $value) { $encoded_value = $this->encode($value); if(Akeeba_Services_JSON::isError($encoded_value)) { return $encoded_value; } return $this->encode(strval($name)) . ':' . $encoded_value; } /** * reduce a string by removing leading and trailing comments and whitespace * * @param $str string string value to strip of comments and whitespace * * @return string string value stripped of comments and whitespace * @access private */ function reduce_string($str) { $str = preg_replace(array( // eliminate single line comments in '// ...' form '#^\s*//(.+)$#m', // eliminate multi-line comments in '/* ... */' form, at start of string '#^\s*/\*(.+)\*/#Us', // eliminate multi-line comments in '/* ... */' form, at end of string '#/\*(.+)\*/\s*$#Us' ), '', $str); // eliminate extraneous space return trim($str); } /** * decodes a JSON string into appropriate variable * * @param string $str JSON-formatted string * * @return mixed number, boolean, string, array, or object * corresponding to given JSON input string. * See argument 1 to Akeeba_Services_JSON() above for object-output behavior. * Note that decode() always returns strings * in ASCII or UTF-8 format! * @access public */ function decode($str) { $str = $this->reduce_string($str); switch (strtolower($str)) { case 'true': return true; case 'false': return false; case 'null': return null; default: $m = array(); if (is_numeric($str)) { // Lookie-loo, it's a number // This would work on its own, but I'm trying to be // good about returning integers where appropriate: // return (float)$str; // Return float or int, as appropriate return ((float)$str == (integer)$str) ? (integer)$str : (float)$str; } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { // STRINGS RETURNED IN UTF-8 FORMAT $delim = substr($str, 0, 1); $chrs = substr($str, 1, -1); $utf8 = ''; $strlen_chrs = strlen($chrs); for ($c = 0; $c < $strlen_chrs; ++$c) { $substr_chrs_c_2 = substr($chrs, $c, 2); $ord_chrs_c = ord($chrs{$c}); switch (true) { case $substr_chrs_c_2 == '\b': $utf8 .= chr(0x08); ++$c; break; case $substr_chrs_c_2 == '\t': $utf8 .= chr(0x09); ++$c; break; case $substr_chrs_c_2 == '\n': $utf8 .= chr(0x0A); ++$c; break; case $substr_chrs_c_2 == '\f': $utf8 .= chr(0x0C); ++$c; break; case $substr_chrs_c_2 == '\r': $utf8 .= chr(0x0D); ++$c; break; case $substr_chrs_c_2 == '\\"': case $substr_chrs_c_2 == '\\\'': case $substr_chrs_c_2 == '\\\\': case $substr_chrs_c_2 == '\\/': if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || ($delim == "'" && $substr_chrs_c_2 != '\\"')) { $utf8 .= $chrs{++$c}; } break; case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): // single, escaped unicode character $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) . chr(hexdec(substr($chrs, ($c + 4), 2))); $utf8 .= $this->utf162utf8($utf16); $c += 5; break; case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): $utf8 .= $chrs{$c}; break; case ($ord_chrs_c & 0xE0) == 0xC0: // characters U-00000080 - U-000007FF, mask 110XXXXX //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $c, 2); ++$c; break; case ($ord_chrs_c & 0xF0) == 0xE0: // characters U-00000800 - U-0000FFFF, mask 1110XXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $c, 3); $c += 2; break; case ($ord_chrs_c & 0xF8) == 0xF0: // characters U-00010000 - U-001FFFFF, mask 11110XXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $c, 4); $c += 3; break; case ($ord_chrs_c & 0xFC) == 0xF8: // characters U-00200000 - U-03FFFFFF, mask 111110XX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $c, 5); $c += 4; break; case ($ord_chrs_c & 0xFE) == 0xFC: // characters U-04000000 - U-7FFFFFFF, mask 1111110X // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $utf8 .= substr($chrs, $c, 6); $c += 5; break; } } return $utf8; } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { // array, or object notation if ($str{0} == '[') { $stk = array(SERVICES_JSON_IN_ARR); $arr = array(); } else { if ($this->use & SERVICES_JSON_LOOSE_TYPE) { $stk = array(SERVICES_JSON_IN_OBJ); $obj = array(); } else { $stk = array(SERVICES_JSON_IN_OBJ); $obj = new stdClass(); } } array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => 0, 'delim' => false)); $chrs = substr($str, 1, -1); $chrs = $this->reduce_string($chrs); if ($chrs == '') { if (reset($stk) == SERVICES_JSON_IN_ARR) { return $arr; } else { return $obj; } } //print("\nparsing {$chrs}\n"); $strlen_chrs = strlen($chrs); for ($c = 0; $c <= $strlen_chrs; ++$c) { $top = end($stk); $substr_chrs_c_2 = substr($chrs, $c, 2); if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { // found a comma that is not inside a string, array, etc., // OR we've reached the end of the character list $slice = substr($chrs, $top['where'], ($c - $top['where'])); array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); if (reset($stk) == SERVICES_JSON_IN_ARR) { // we are in an array, so just push an element onto the stack array_push($arr, $this->decode($slice)); } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { // we are in an object, so figure // out the property name and set an // element in an associative array, // for now $parts = array(); if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { // "name":value pair $key = $this->decode($parts[1]); $val = $this->decode($parts[2]); if ($this->use & SERVICES_JSON_LOOSE_TYPE) { $obj[$key] = $val; } else { $obj->$key = $val; } } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { // name:value pair, where name is unquoted $key = $parts[1]; $val = $this->decode($parts[2]); if ($this->use & SERVICES_JSON_LOOSE_TYPE) { $obj[$key] = $val; } else { $obj->$key = $val; } } } } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { // found a quote, and we are not inside a string array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); //print("Found start of string at {$c}\n"); } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == SERVICES_JSON_IN_STR) && ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { // found a quote, we're in a string, and it's not escaped // we know that it's not escaped becase there is _not_ an // odd number of backslashes at the end of the string so far array_pop($stk); //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); } elseif (($chrs{$c} == '[') && in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { // found a left-bracket, and we are in an array, object, or slice array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); //print("Found start of array at {$c}\n"); } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { // found a right-bracket, and we're in an array array_pop($stk); //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); } elseif (($chrs{$c} == '{') && in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { // found a left-brace, and we are in an array, object, or slice array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); //print("Found start of object at {$c}\n"); } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { // found a right-brace, and we're in an object array_pop($stk); //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { // found a comment start, and we are in an array, object, or slice array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); $c++; //print("Found start of comment at {$c}\n"); } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { // found a comment end, and we're in one now array_pop($stk); $c++; for ($i = $top['where']; $i <= $c; ++$i) $chrs = substr_replace($chrs, ' ', $i, 1); //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); } } if (reset($stk) == SERVICES_JSON_IN_ARR) { return $arr; } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { return $obj; } } } } function isError($data, $code = null) { if (class_exists('pear')) { return PEAR::isError($data, $code); } elseif (is_object($data) && (get_class($data) == 'services_json_error' || is_subclass_of($data, 'services_json_error'))) { return true; } return false; } } class Akeeba_Services_JSON_Error { function Akeeba_Services_JSON_Error($message = 'unknown error', $code = null, $mode = null, $options = null, $userinfo = null) { } } } if(!function_exists('json_encode')) { function json_encode($value, $options = 0) { $flags = SERVICES_JSON_LOOSE_TYPE; if( $options & JSON_FORCE_OBJECT ) $flags = 0; $encoder = new Akeeba_Services_JSON($flags); return $encoder->encode($value); } } if(!function_exists('json_decode')) { function json_decode($value, $assoc = false) { $flags = 0; if($assoc) $flags = SERVICES_JSON_LOOSE_TYPE; $decoder = new Akeeba_Services_JSON($flags); return $decoder->decode($value); } } /** * The base class of Akeeba Engine objects. Allows for error and warnings logging * and propagation. Largely based on the Joomla! 1.5 JObject class. */ abstract class AKAbstractObject { /** @var array An array of errors */ private $_errors = array(); /** @var array The queue size of the $_errors array. Set to 0 for infinite size. */ protected $_errors_queue_size = 0; /** @var array An array of warnings */ private $_warnings = array(); /** @var array The queue size of the $_warnings array. Set to 0 for infinite size. */ protected $_warnings_queue_size = 0; /** * Public constructor, makes sure we are instanciated only by the factory class */ public function __construct() { /* // Assisted Singleton pattern if(function_exists('debug_backtrace')) { $caller=debug_backtrace(); if( ($caller[1]['class'] != 'AKFactory') && ($caller[2]['class'] != 'AKFactory') && ($caller[3]['class'] != 'AKFactory') && ($caller[4]['class'] != 'AKFactory') ) { var_dump(debug_backtrace()); trigger_error("You can't create direct descendants of ".__CLASS__, E_USER_ERROR); } } */ } /** * Get the most recent error message * @param integer $i Optional error index * @return string Error message */ public function getError($i = null) { return $this->getItemFromArray($this->_errors, $i); } /** * Return all errors, if any * @return array Array of error messages */ public function getErrors() { return $this->_errors; } /** * Add an error message * @param string $error Error message */ public function setError($error) { if($this->_errors_queue_size > 0) { if(count($this->_errors) >= $this->_errors_queue_size) { array_shift($this->_errors); } } array_push($this->_errors, $error); } /** * Resets all error messages */ public function resetErrors() { $this->_errors = array(); } /** * Get the most recent warning message * @param integer $i Optional warning index * @return string Error message */ public function getWarning($i = null) { return $this->getItemFromArray($this->_warnings, $i); } /** * Return all warnings, if any * @return array Array of error messages */ public function getWarnings() { return $this->_warnings; } /** * Add an error message * @param string $error Error message */ public function setWarning($warning) { if($this->_warnings_queue_size > 0) { if(count($this->_warnings) >= $this->_warnings_queue_size) { array_shift($this->_warnings); } } array_push($this->_warnings, $warning); } /** * Resets all warning messages */ public function resetWarnings() { $this->_warnings = array(); } /** * Propagates errors and warnings to a foreign object. The foreign object SHOULD * implement the setError() and/or setWarning() methods but DOESN'T HAVE TO be of * AKAbstractObject type. For example, this can even be used to propagate to a * JObject instance in Joomla!. Propagated items will be removed from ourself. * @param object $object The object to propagate errors and warnings to. */ public function propagateToObject(&$object) { // Skip non-objects if(!is_object($object)) return; if( method_exists($object,'setError') ) { if(!empty($this->_errors)) { foreach($this->_errors as $error) { $object->setError($error); } $this->_errors = array(); } } if( method_exists($object,'setWarning') ) { if(!empty($this->_warnings)) { foreach($this->_warnings as $warning) { $object->setWarning($warning); } $this->_warnings = array(); } } } /** * Propagates errors and warnings from a foreign object. Each propagated list is * then cleared on the foreign object, as long as it implements resetErrors() and/or * resetWarnings() methods. * @param object $object The object to propagate errors and warnings from */ public function propagateFromObject(&$object) { if( method_exists($object,'getErrors') ) { $errors = $object->getErrors(); if(!empty($errors)) { foreach($errors as $error) { $this->setError($error); } } if(method_exists($object,'resetErrors')) { $object->resetErrors(); } } if( method_exists($object,'getWarnings') ) { $warnings = $object->getWarnings(); if(!empty($warnings)) { foreach($warnings as $warning) { $this->setWarning($warning); } } if(method_exists($object,'resetWarnings')) { $object->resetWarnings(); } } } /** * Sets the size of the error queue (acts like a LIFO buffer) * @param int $newSize The new queue size. Set to 0 for infinite length. */ protected function setErrorsQueueSize($newSize = 0) { $this->_errors_queue_size = (int)$newSize; } /** * Sets the size of the warnings queue (acts like a LIFO buffer) * @param int $newSize The new queue size. Set to 0 for infinite length. */ protected function setWarningsQueueSize($newSize = 0) { $this->_warnings_queue_size = (int)$newSize; } /** * Returns the last item of a LIFO string message queue, or a specific item * if so specified. * @param array $array An array of strings, holding messages * @param int $i Optional message index * @return mixed The message string, or false if the key doesn't exist */ private function getItemFromArray($array, $i = null) { // Find the item if ( $i === null) { // Default, return the last item $item = end($array); } else if ( ! array_key_exists($i, $array) ) { // If $i has been specified but does not exist, return false return false; } else { $item = $array[$i]; } return $item; } } /** * File post processor engines base class */ abstract class AKAbstractPostproc extends AKAbstractObject { /** @var string The current (real) file path we'll have to process */ protected $filename = null; /** @var int The requested permissions */ protected $perms = 0755; /** @var string The temporary file path we gave to the unarchiver engine */ protected $tempFilename = null; /** @var int The UNIX timestamp of the file's desired modification date */ public $timestamp = 0; /** * Processes the current file, e.g. moves it from temp to final location by FTP */ abstract public function process(); /** * The unarchiver tells us the path to the filename it wants to extract and we give it * a different path instead. * @param string $filename The path to the real file * @param int $perms The permissions we need the file to have * @return string The path to the temporary file */ abstract public function processFilename($filename, $perms = 0755); /** * Recursively creates a directory if it doesn't exist * @param string $dirName The directory to create * @param int $perms The permissions to give to that directory */ abstract public function createDirRecursive( $dirName, $perms ); abstract public function chmod( $file, $perms ); abstract public function unlink( $file ); abstract public function rmdir( $directory ); abstract public function rename( $from, $to ); } /** * The base class of unarchiver classes */ abstract class AKAbstractUnarchiver extends AKAbstractPart { /** @var string Archive filename */ protected $filename = null; /** @var array List of the names of all archive parts */ public $archiveList = array(); /** @var int The total size of all archive parts */ public $totalSize = array(); /** @var integer Current archive part number */ protected $currentPartNumber = -1; /** @var integer The offset inside the current part */ protected $currentPartOffset = 0; /** @var bool Should I restore permissions? */ protected $flagRestorePermissions = false; /** @var AKAbstractPostproc Post processing class */ protected $postProcEngine = null; /** @var string Absolute path to prepend to extracted files */ protected $addPath = ''; /** @var array Which files to rename */ public $renameFiles = array(); /** @var array Which directories to rename */ public $renameDirs = array(); /** @var array Which files to skip */ public $skipFiles = array(); /** @var integer Chunk size for processing */ protected $chunkSize = 524288; /** @var resource File pointer to the current archive part file */ protected $fp = null; /** @var int Run state when processing the current archive file */ protected $runState = null; /** @var stdClass File header data, as read by the readFileHeader() method */ protected $fileHeader = null; /** @var int How much of the uncompressed data we've read so far */ protected $dataReadLength = 0; /** * Public constructor */ public function __construct() { parent::__construct(); } /** * Wakeup function, called whenever the class is unserialized */ public function __wakeup() { if($this->currentPartNumber >= 0) { $this->fp = @fopen($this->archiveList[$this->currentPartNumber], 'rb'); if( (is_resource($this->fp)) && ($this->currentPartOffset > 0) ) { @fseek($this->fp, $this->currentPartOffset); } } } /** * Sleep function, called whenever the class is serialized */ public function shutdown() { if(is_resource($this->fp)) { $this->currentPartOffset = @ftell($this->fp); @fclose($this->fp); } } /** * Implements the abstract _prepare() method */ final protected function _prepare() { parent::__construct(); if( count($this->_parametersArray) > 0 ) { foreach($this->_parametersArray as $key => $value) { switch($key) { case 'filename': // Archive's absolute filename $this->filename = $value; break; case 'restore_permissions': // Should I restore permissions? $this->flagRestorePermissions = $value; break; case 'post_proc': // Should I use FTP? $this->postProcEngine = AKFactory::getpostProc($value); break; case 'add_path': // Path to prepend $this->addPath = $value; $this->addPath = str_replace('\\','/',$this->addPath); $this->addPath = rtrim($this->addPath,'/'); if(!empty($this->addPath)) $this->addPath .= '/'; break; case 'rename_files': // Which files to rename (hash array) $this->renameFiles = $value; break; case 'rename_dirs': // Which files to rename (hash array) $this->renameDirs = $value; break; case 'skip_files': // Which files to skip (indexed array) $this->skipFiles = $value; break; } } } $this->scanArchives(); $this->readArchiveHeader(); $errMessage = $this->getError(); if(!empty($errMessage)) { $this->setState('error', $errMessage); } else { $this->runState = AK_STATE_NOFILE; $this->setState('prepared'); } } protected function _run() { if($this->getState() == 'postrun') return; $this->setState('running'); $timer = AKFactory::getTimer(); $status = true; while( $status && ($timer->getTimeLeft() > 0) ) { switch( $this->runState ) { case AK_STATE_NOFILE: $status = $this->readFileHeader(); if($status) { // Send start of file notification $message = new stdClass; $message->type = 'startfile'; $message->content = new stdClass; if( array_key_exists('realfile', get_object_vars($this->fileHeader)) ) { $message->content->realfile = $this->fileHeader->realFile; } else { $message->content->realfile = $this->fileHeader->file; } $message->content->file = $this->fileHeader->file; if( array_key_exists('compressed', get_object_vars($this->fileHeader)) ) { $message->content->compressed = $this->fileHeader->compressed; } else { $message->content->compressed = 0; } $message->content->uncompressed = $this->fileHeader->uncompressed; $this->notify($message); } break; case AK_STATE_HEADER: case AK_STATE_DATA: $status = $this->processFileData(); break; case AK_STATE_DATAREAD: case AK_STATE_POSTPROC: $this->postProcEngine->timestamp = $this->fileHeader->timestamp; $status = $this->postProcEngine->process(); $this->propagateFromObject( $this->postProcEngine ); $this->runState = AK_STATE_DONE; break; case AK_STATE_DONE: default: if($status) { // Send end of file notification $message = new stdClass; $message->type = 'endfile'; $message->content = new stdClass; if( array_key_exists('realfile', get_object_vars($this->fileHeader)) ) { $message->content->realfile = $this->fileHeader->realFile; } else { $message->content->realfile = $this->fileHeader->file; } $message->content->file = $this->fileHeader->file; if( array_key_exists('compressed', get_object_vars($this->fileHeader)) ) { $message->content->compressed = $this->fileHeader->compressed; } else { $message->content->compressed = 0; } $message->content->uncompressed = $this->fileHeader->uncompressed; $this->notify($message); } $this->runState = AK_STATE_NOFILE; continue; } } $error = $this->getError(); if( !$status && ($this->runState == AK_STATE_NOFILE) && empty( $error ) ) { // We just finished $this->setState('postrun'); } elseif( !empty($error) ) { $this->setState( 'error', $error ); } } protected function _finalize() { // Nothing to do $this->setState('finished'); } /** * Returns the base extension of the file, e.g. '.jpa' * @return string */ private function getBaseExtension() { static $baseextension; if(empty($baseextension)) { $basename = basename($this->filename); $lastdot = strrpos($basename,'.'); $baseextension = substr($basename, $lastdot); } return $baseextension; } /** * Scans for archive parts */ private function scanArchives() { $privateArchiveList = array(); // Get the components of the archive filename $dirname = dirname($this->filename); $base_extension = $this->getBaseExtension(); $basename = basename($this->filename, $base_extension); $this->totalSize = 0; // Scan for multiple parts until we don't find any more of them $count = 0; $found = true; $this->archiveList = array(); while($found) { ++$count; $extension = substr($base_extension, 0, 2).sprintf('%02d', $count); $filename = $dirname.DIRECTORY_SEPARATOR.$basename.$extension; $found = file_exists($filename); if($found) { // Add yet another part, with a numeric-appended filename $this->archiveList[] = $filename; $filesize = @filesize($filename); $this->totalSize += $filesize; $privateArchiveList[] = array($filename, $filesize); } else { // Add the last part, with the regular extension $this->archiveList[] = $this->filename; $filename = $this->filename; $filesize = @filesize($filename); $this->totalSize += $filesize; $privateArchiveList[] = array($filename, $filesize); } } $this->currentPartNumber = -1; $this->currentPartOffset = 0; $this->runState = AK_STATE_NOFILE; // Send start of file notification $message = new stdClass; $message->type = 'totalsize'; $message->content = new stdClass; $message->content->totalsize = $this->totalSize; $message->content->filelist = $privateArchiveList; $this->notify($message); } /** * Opens the next part file for reading */ protected function nextFile() { ++$this->currentPartNumber; if( $this->currentPartNumber > (count($this->archiveList) - 1) ) { $this->setState('postrun'); return false; } else { if( is_resource($this->fp) ) @fclose($this->fp); $this->fp = @fopen( $this->archiveList[$this->currentPartNumber], 'rb' ); fseek($this->fp, 0); $this->currentPartOffset = 0; return true; } } /** * Returns true if we have reached the end of file * @param $local bool True to return EOF of the local file, false (default) to return if we have reached the end of the archive set * @return bool True if we have reached End Of File */ protected function isEOF($local = false) { $eof = @feof($this->fp); if(!$eof) { // Border case: right at the part's end (eeeek!!!). For the life of me, I don't understand why // feof() doesn't report true. It expects the fp to be positioned *beyond* the EOF to report // true. Incredible! :( $position = @ftell($this->fp); $filesize = @filesize( $this->archiveList[$this->currentPartNumber] ); if( $position >= $filesize ) $eof = true; } if($local) { return $eof; } else { return $eof && ($this->currentPartNumber >= (count($this->archiveList)-1) ); } } /** * Tries to make a directory user-writable so that we can write a file to it * @param $path string A path to a file */ protected function setCorrectPermissions($path) { static $rootDir = null; if(is_null($rootDir)) { $rootDir = rtrim(AKFactory::get('kickstart.setup.destdir',''),'/\\'); } $directory = rtrim(dirname($path),'/\\'); if($directory != $rootDir) { // Is this an unwritable directory? if(!is_writeable($directory)) { $this->postProcEngine->chmod( $directory, 0755 ); } } $this->postProcEngine->chmod( $path, 0644 ); } /** * Concrete classes are supposed to use this method in order to read the archive's header and * prepare themselves to the point of being ready to extract the first file. */ protected abstract function readArchiveHeader(); /** * Concrete classes must use this method to read the file header * @return bool True if reading the file was successful, false if an error occured or we reached end of archive */ protected abstract function readFileHeader(); /** * Concrete classes must use this method to process file data. It must set $runState to AK_STATE_DATAREAD when * it's finished processing the file data. * @return bool True if processing the file data was successful, false if an error occured */ protected abstract function processFileData(); /** * Reads data from the archive and notifies the observer with the 'reading' message * @param $fp * @param $length */ protected function fread($fp, $length = null) { if(is_numeric($length)) { if($length > 0) { $data = fread($fp, $length); } else { $data = fread($fp); } } else { $data = fread($fp); } if($data === false) $data = ''; // Send start of file notification $message = new stdClass; $message->type = 'reading'; $message->content = new stdClass; $message->content->length = strlen($data); $this->notify($message); return $data; } } /** * The superclass of all Akeeba Kickstart parts. The "parts" are intelligent stateful * classes which perform a single procedure and have preparation, running and * finalization phases. The transition between phases is handled automatically by * this superclass' tick() final public method, which should be the ONLY public API * exposed to the rest of the Akeeba Engine. */ abstract class AKAbstractPart extends AKAbstractObject { /** * Indicates whether this part has finished its initialisation cycle * @var boolean */ protected $isPrepared = false; /** * Indicates whether this part has more work to do (it's in running state) * @var boolean */ protected $isRunning = false; /** * Indicates whether this part has finished its finalization cycle * @var boolean */ protected $isFinished = false; /** * Indicates whether this part has finished its run cycle * @var boolean */ protected $hasRan = false; /** * The name of the engine part (a.k.a. Domain), used in return table * generation. * @var string */ protected $active_domain = ""; /** * The step this engine part is in. Used verbatim in return table and * should be set by the code in the _run() method. * @var string */ protected $active_step = ""; /** * A more detailed description of the step this engine part is in. Used * verbatim in return table and should be set by the code in the _run() * method. * @var string */ protected $active_substep = ""; /** * Any configuration variables, in the form of an array. * @var array */ protected $_parametersArray = array(); /** @var string The database root key */ protected $databaseRoot = array(); /** @var int Last reported warnings's position in array */ private $warnings_pointer = -1; /** @var array An array of observers */ protected $observers = array(); /** * Runs the preparation for this part. Should set _isPrepared * to true */ abstract protected function _prepare(); /** * Runs the finalisation process for this part. Should set * _isFinished to true. */ abstract protected function _finalize(); /** * Runs the main functionality loop for this part. Upon calling, * should set the _isRunning to true. When it finished, should set * the _hasRan to true. If an error is encountered, setError should * be used. */ abstract protected function _run(); /** * Sets the BREAKFLAG, which instructs this engine part that the current step must break immediately, * in fear of timing out. */ protected function setBreakFlag() { AKFactory::set('volatile.breakflag', true); } /** * Sets the engine part's internal state, in an easy to use manner * * @param string $state One of init, prepared, running, postrun, finished, error * @param string $errorMessage The reported error message, should the state be set to error */ protected function setState($state = 'init', $errorMessage='Invalid setState argument') { switch($state) { case 'init': $this->isPrepared = false; $this->isRunning = false; $this->isFinished = false; $this->hasRun = false; break; case 'prepared': $this->isPrepared = true; $this->isRunning = false; $this->isFinished = false; $this->hasRun = false; break; case 'running': $this->isPrepared = true; $this->isRunning = true; $this->isFinished = false; $this->hasRun = false; break; case 'postrun': $this->isPrepared = true; $this->isRunning = false; $this->isFinished = false; $this->hasRun = true; break; case 'finished': $this->isPrepared = true; $this->isRunning = false; $this->isFinished = true; $this->hasRun = false; break; case 'error': default: $this->setError($errorMessage); break; } } /** * The public interface to an engine part. This method takes care for * calling the correct method in order to perform the initialisation - * run - finalisation cycle of operation and return a proper reponse array. * @return array A Reponse Array */ final public function tick() { // Call the right action method, depending on engine part state switch( $this->getState() ) { case "init": $this->_prepare(); break; case "prepared": $this->_run(); break; case "running": $this->_run(); break; case "postrun": $this->_finalize(); break; } // Send a Return Table back to the caller $out = $this->_makeReturnTable(); return $out; } /** * Returns a copy of the class's status array * @return array */ public function getStatusArray() { return $this->_makeReturnTable(); } /** * Sends any kind of setup information to the engine part. Using this, * we avoid passing parameters to the constructor of the class. These * parameters should be passed as an indexed array and should be taken * into account during the preparation process only. This function will * set the error flag if it's called after the engine part is prepared. * * @param array $parametersArray The parameters to be passed to the * engine part. */ final public function setup( $parametersArray ) { if( $this->isPrepared ) { $this->setState('error', "Can't modify configuration after the preparation of " . $this->active_domain); } else { $this->_parametersArray = $parametersArray; if(array_key_exists('root', $parametersArray)) { $this->databaseRoot = $parametersArray['root']; } } } /** * Returns the state of this engine part. * * @return string The state of this engine part. It can be one of * error, init, prepared, running, postrun, finished. */ final public function getState() { if( $this->getError() ) { return "error"; } if( !($this->isPrepared) ) { return "init"; } if( !($this->isFinished) && !($this->isRunning) && !( $this->hasRun ) && ($this->isPrepared) ) { return "prepared"; } if ( !($this->isFinished) && $this->isRunning && !( $this->hasRun ) ) { return "running"; } if ( !($this->isFinished) && !($this->isRunning) && $this->hasRun ) { return "postrun"; } if ( $this->isFinished ) { return "finished"; } } /** * Constructs a Response Array based on the engine part's state. * @return array The Response Array for the current state */ final protected function _makeReturnTable() { // Get a list of warnings $warnings = $this->getWarnings(); // Report only new warnings if there is no warnings queue size if( $this->_warnings_queue_size == 0 ) { if( ($this->warnings_pointer > 0) && ($this->warnings_pointer < (count($warnings)) ) ) { $warnings = array_slice($warnings, $this->warnings_pointer + 1); $this->warnings_pointer += count($warnings); } else { $this->warnings_pointer = count($warnings); } } $out = array( 'HasRun' => (!($this->isFinished)), 'Domain' => $this->active_domain, 'Step' => $this->active_step, 'Substep' => $this->active_substep, 'Error' => $this->getError(), 'Warnings' => $warnings ); return $out; } final protected function setDomain($new_domain) { $this->active_domain = $new_domain; } final public function getDomain() { return $this->active_domain; } final protected function setStep($new_step) { $this->active_step = $new_step; } final public function getStep() { return $this->active_step; } final protected function setSubstep($new_substep) { $this->active_substep = $new_substep; } final public function getSubstep() { return $this->active_substep; } /** * Attaches an observer object * @param AKAbstractPartObserver $obs */ function attach(AKAbstractPartObserver $obs) { $this->observers["$obs"] = $obs; } /** * Dettaches an observer object * @param AKAbstractPartObserver $obs */ function detach(AKAbstractPartObserver $obs) { delete($this->observers["$obs"]); } /** * Notifies observers each time something interesting happened to the part * @param mixed $message The event object */ protected function notify($message) { foreach ($this->observers as $obs) { $obs->update($this, $message); } } } /** * Descendants of this class can be used in the unarchiver's observer methods (attach, detach and notify) * @author Nicholas * */ abstract class AKAbstractPartObserver { abstract public function update($object, $message); } /** * Direct file writer */ class AKPostprocDirect extends AKAbstractPostproc { public function process() { $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); if($restorePerms) { @chmod($this->filename, $this->perms); } else { if(@is_file($this->filename)) { @chmod($this->filename, 0644); } else { @chmod($this->filename, 0755); } } if($this->timestamp > 0) { @touch($this->filename, $this->timestamp); } return true; } public function processFilename($filename, $perms = 0755) { $this->perms = $perms; $this->filename = $filename; return $filename; } public function createDirRecursive( $dirName, $perms ) { if( AKFactory::get('kickstart.setup.dryrun','0') ) return true; if (@mkdir($dirName, 0755, true)) { @chmod($dirName, 0755); return true; } $root = AKFactory::get('kickstart.setup.destdir'); $root = rtrim(str_replace('\\','/',$root),'/'); $dir = rtrim(str_replace('\\','/',$dirName),'/'); if(strpos($dir, $root) === 0) { $dir = ltrim(substr($dir, strlen($root)), '/'); $root .= '/'; } else { $root = ''; } if(empty($dir)) return true; $dirArray = explode('/', $dir); $path = ''; foreach( $dirArray as $dir ) { $path .= $dir . '/'; $ret = is_dir($root.$path) ? true : @mkdir($root.$path); if( !$ret ) { // Is this a file instead of a directory? if(is_file($root.$path) ) { @unlink($root.$path); $ret = @mkdir($root.$path); } if( !$ret ) { $this->setError( AKText::sprintf('COULDNT_CREATE_DIR',$path) ); return false; } } // Try to set new directory permissions to 0755 @chmod($root.$path, $perms); } return true; } public function chmod( $file, $perms ) { if( AKFactory::get('kickstart.setup.dryrun','0') ) return true; return @chmod( $file, $perms ); } public function unlink( $file ) { return @unlink( $file ); } public function rmdir( $directory ) { return @rmdir( $directory ); } public function rename( $from, $to ) { return @rename($from, $to); } } /** * FTP file writer */ class AKPostprocFTP extends AKAbstractPostproc { /** @var bool Should I use FTP over implicit SSL? */ public $useSSL = false; /** @var bool use Passive mode? */ public $passive = true; /** @var string FTP host name */ public $host = ''; /** @var int FTP port */ public $port = 21; /** @var string FTP user name */ public $user = ''; /** @var string FTP password */ public $pass = ''; /** @var string FTP initial directory */ public $dir = ''; /** @var resource The FTP handle */ private $handle = null; /** @var string The temporary directory where the data will be stored */ private $tempDir = ''; public function __construct() { parent::__construct(); $this->useSSL = AKFactory::get('kickstart.ftp.ssl', false); $this->passive = AKFactory::get('kickstart.ftp.passive', true); $this->host = AKFactory::get('kickstart.ftp.host', ''); $this->port = AKFactory::get('kickstart.ftp.port', 21); if(trim($this->port) == '') $this->port = 21; $this->user = AKFactory::get('kickstart.ftp.user', ''); $this->pass = AKFactory::get('kickstart.ftp.pass', ''); $this->dir = AKFactory::get('kickstart.ftp.dir', ''); $this->tempDir = AKFactory::get('kickstart.ftp.tempdir', ''); $connected = $this->connect(); if($connected) { if(!empty($this->tempDir)) { $tempDir = rtrim($this->tempDir, '/\\').'/'; $writable = $this->isDirWritable($tempDir); } else { $tempDir = ''; $writable = false; } if(!$writable) { // Default temporary directory is the current root $tempDir = function_exists('getcwd') ? getcwd() : dirname(__FILE__); if(empty($tempDir)) { // Oh, we have no directory reported! $tempDir = '.'; } $absoluteDirToHere = $tempDir; $tempDir = rtrim(str_replace('\\','/',$tempDir),'/'); if(!empty($tempDir)) $tempDir .= '/'; $this->tempDir = $tempDir; // Is this directory writable? $writable = $this->isDirWritable($tempDir); } if(!$writable) { // Nope. Let's try creating a temporary directory in the site's root. $tempDir = $absoluteDirToHere.'/kicktemp'; $this->createDirRecursive($tempDir, 0777); // Try making it writable... $this->fixPermissions($tempDir); $writable = $this->isDirWritable($tempDir); } // Was the new directory writable? if(!$writable) { // Let's see if the user has specified one $userdir = AKFactory::get('kickstart.ftp.tempdir', ''); if(!empty($userdir)) { // Is it an absolute or a relative directory? $absolute = false; $absolute = $absolute || ( substr($userdir,0,1) == '/' ); $absolute = $absolute || ( substr($userdir,1,1) == ':' ); $absolute = $absolute || ( substr($userdir,2,1) == ':' ); if(!$absolute) { // Make absolute $tempDir = $absoluteDirToHere.$userdir; } else { // it's already absolute $tempDir = $userdir; } // Does the directory exist? if( is_dir($tempDir) ) { // Yeah. Is it writable? $writable = $this->isDirWritable($tempDir); } } } $this->tempDir = $tempDir; if(!$writable) { // No writable directory found!!! $this->setError(AKText::_('FTP_TEMPDIR_NOT_WRITABLE')); } else { AKFactory::set('kickstart.ftp.tempdir', $tempDir); $this->tempDir = $tempDir; } } } function __wakeup() { $this->connect(); } public function connect() { // Connect to server, using SSL if so required if($this->useSSL) { $this->handle = @ftp_ssl_connect($this->host, $this->port); } else { $this->handle = @ftp_connect($this->host, $this->port); } if($this->handle === false) { $this->setError(AKText::_('WRONG_FTP_HOST')); return false; } // Login if(! @ftp_login($this->handle, $this->user, $this->pass)) { $this->setError(AKText::_('WRONG_FTP_USER')); @ftp_close($this->handle); return false; } // Change to initial directory if(! @ftp_chdir($this->handle, $this->dir)) { $this->setError(AKText::_('WRONG_FTP_PATH1')); @ftp_close($this->handle); return false; } // Enable passive mode if the user requested it if( $this->passive ) { @ftp_pasv($this->handle, true); } else { @ftp_pasv($this->handle, false); } return true; } public function process() { if( is_null($this->tempFilename) ) { // If an empty filename is passed, it means that we shouldn't do any post processing, i.e. // the entity was a directory or symlink return true; } $remotePath = dirname($this->filename); $removePath = AKFactory::get('kickstart.setup.destdir',''); if(!empty($removePath)) { $removePath = ltrim($removePath, "/"); $remotePath = ltrim($remotePath, "/"); $left = substr($remotePath, 0, strlen($removePath)); if($left == $removePath) { $remotePath = substr($remotePath, strlen($removePath)); } } $absoluteFSPath = dirname($this->filename); $relativeFTPPath = trim($remotePath, '/'); $absoluteFTPPath = '/'.trim( $this->dir, '/' ).'/'.trim($remotePath, '/'); $onlyFilename = basename($this->filename); $remoteName = $absoluteFTPPath.'/'.$onlyFilename; $ret = @ftp_chdir($this->handle, $absoluteFTPPath); if($ret === false) { $ret = $this->createDirRecursive( $absoluteFSPath, 0755); if($ret === false) { $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); return false; } $ret = @ftp_chdir($this->handle, $absoluteFTPPath); if($ret === false) { $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); return false; } } $ret = @ftp_put($this->handle, $remoteName, $this->tempFilename, FTP_BINARY); if($ret === false) { // If we couldn't create the file, attempt to fix the permissions in the PHP level and retry! $this->fixPermissions($this->filename); $this->unlink($this->filename); $fp = @fopen($this->tempFilename); if($fp !== false) { $ret = @ftp_fput($this->handle, $remoteName, $fp, FTP_BINARY); @fclose($fp); } else { $ret = false; } } @unlink($this->tempFilename); if($ret === false) { $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); return false; } $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); if($restorePerms) { @ftp_chmod($this->_handle, $perms, $remoteName); } else { @ftp_chmod($this->_handle, 0644, $remoteName); } return true; } public function processFilename($filename, $perms = 0755) { // Catch some error conditions... if($this->getError()) { return false; } // If a null filename is passed, it means that we shouldn't do any post processing, i.e. // the entity was a directory or symlink if(is_null($filename)) { $this->filename = null; $this->tempFilename = null; return null; } // Strip absolute filesystem path to website's root $removePath = AKFactory::get('kickstart.setup.destdir',''); if(!empty($removePath)) { $left = substr($filename, 0, strlen($removePath)); if($left == $removePath) { $filename = substr($filename, strlen($removePath)); } } // Trim slash on the left $filename = ltrim($filename, '/'); $this->filename = $filename; $this->tempFilename = tempnam($this->tempDir, 'kickstart-'); $this->perms = $perms; if( empty($this->tempFilename) ) { // Oops! Let's try something different $this->tempFilename = $this->tempDir.'/kickstart-'.time().'.dat'; } return $this->tempFilename; } private function isDirWritable($dir) { $fp = @fopen($dir.'/kickstart.dat', 'wb'); if($fp === false) { return false; } else { @fclose($fp); unlink($dir.'/kickstart.dat'); return true; } } public function createDirRecursive( $dirName, $perms ) { // Strip absolute filesystem path to website's root $removePath = AKFactory::get('kickstart.setup.destdir',''); if(!empty($removePath)) { // UNIXize the paths $removePath = str_replace('\\','/',$removePath); $dirName = str_replace('\\','/',$dirName); // Make sure they both end in a slash $removePath = rtrim($removePath,'/\\').'/'; $dirName = rtrim($dirName,'/\\').'/'; // Process the path removal $left = substr($dirName, 0, strlen($removePath)); if($left == $removePath) { $dirName = substr($dirName, strlen($removePath)); } } if(empty($dirName)) $dirName = ''; // 'cause the substr() above may return FALSE. $check = '/'.trim($this->dir,'/').'/'.trim($dirName, '/'); if($this->is_dir($check)) return true; $alldirs = explode('/', $dirName); $previousDir = '/'.trim($this->dir); foreach($alldirs as $curdir) { $check = $previousDir.'/'.$curdir; if(!$this->is_dir($check)) { // Proactively try to delete a file by the same name @ftp_delete($this->handle, $check); if(@ftp_mkdir($this->handle, $check) === false) { // If we couldn't create the directory, attempt to fix the permissions in the PHP level and retry! $this->fixPermissions($removePath.$check); if(@ftp_mkdir($this->handle, $check) === false) { // Can we fall back to pure PHP mode, sire? if(!@mkdir($check)) { $this->setError(AKText::sprintf('FTP_CANT_CREATE_DIR',$dir)); return false; } else { // Since the directory was built by PHP, change its permissions @chmod($check, "0777"); return true; } } } @ftp_chmod($this->handle, $perms, $check); } $previousDir = $check; } return true; } public function close() { @ftp_close($this->handle); } /* * Tries to fix directory/file permissions in the PHP level, so that * the FTP operation doesn't fail. * @param $path string The full path to a directory or file */ private function fixPermissions( $path ) { // Turn off error reporting if(!defined('KSDEBUG')) { $oldErrorReporting = @error_reporting(E_NONE); } // Get UNIX style paths $relPath = str_replace('\\','/',$path); $basePath = rtrim(str_replace('\\','/',dirname(__FILE__)),'/'); $basePath = rtrim($basePath,'/'); if(!empty($basePath)) $basePath .= '/'; // Remove the leading relative root if( substr($relPath,0,strlen($basePath)) == $basePath ) $relPath = substr($relPath,strlen($basePath)); $dirArray = explode('/', $relPath); $pathBuilt = rtrim($basePath,'/'); foreach( $dirArray as $dir ) { if(empty($dir)) continue; $oldPath = $pathBuilt; $pathBuilt .= '/'.$dir; if(is_dir($oldPath.$dir)) { @chmod($oldPath.$dir, 0777); } else { if(@chmod($oldPath.$dir, 0777) === false) { @unlink($oldPath.$dir); } } } // Restore error reporting if(!defined('KSDEBUG')) { @error_reporting($oldErrorReporting); } } public function chmod( $file, $perms ) { return @ftp_chmod($this->handle, $perms, $path); } private function is_dir( $dir ) { return @ftp_chdir( $this->handle, $dir ); } public function unlink( $file ) { $removePath = AKFactory::get('kickstart.setup.destdir',''); if(!empty($removePath)) { $left = substr($file, 0, strlen($removePath)); if($left == $removePath) { $file = substr($file, strlen($removePath)); } } $check = '/'.trim($this->dir,'/').'/'.trim($file, '/'); return @ftp_delete( $this->handle, $check ); } public function rmdir( $directory ) { $removePath = AKFactory::get('kickstart.setup.destdir',''); if(!empty($removePath)) { $left = substr($directory, 0, strlen($removePath)); if($left == $removePath) { $directory = substr($directory, strlen($removePath)); } } $check = '/'.trim($this->dir,'/').'/'.trim($directory, '/'); return @ftp_rmdir( $this->handle, $check ); } public function rename( $from, $to ) { $originalFrom = $from; $originalTo = $to; $removePath = AKFactory::get('kickstart.setup.destdir',''); if(!empty($removePath)) { $left = substr($from, 0, strlen($removePath)); if($left == $removePath) { $from = substr($from, strlen($removePath)); } } $from = '/'.trim($this->dir,'/').'/'.trim($from, '/'); if(!empty($removePath)) { $left = substr($to, 0, strlen($removePath)); if($left == $removePath) { $to = substr($to, strlen($removePath)); } } $to = '/'.trim($this->dir,'/').'/'.trim($to, '/'); $result = @ftp_rename( $this->handle, $from, $to ); if($result !== true) { return @rename($from, $to); } else { return true; } } } /** * JPA archive extraction class */ class AKUnarchiverJPA extends AKAbstractUnarchiver { private $archiveHeaderData = array(); protected function readArchiveHeader() { // Initialize header data array $this->archiveHeaderData = new stdClass(); // Open the first part $this->nextFile(); // Fail for unreadable files if( $this->fp === false ) return false; // Read the signature $sig = fread( $this->fp, 3 ); if ($sig != 'JPA') { // Not a JPA file $this->setError( AKText::_('ERR_NOT_A_JPA_FILE') ); return false; } // Read and parse header length $header_length_array = unpack( 'v', fread( $this->fp, 2 ) ); $header_length = $header_length_array[1]; // Read and parse the known portion of header data (14 bytes) $bin_data = fread($this->fp, 14); $header_data = unpack('Cmajor/Cminor/Vcount/Vuncsize/Vcsize', $bin_data); // Load any remaining header data (forward compatibility) $rest_length = $header_length - 19; if( $rest_length > 0 ) $junk = fread($this->fp, $rest_length); else $junk = ''; // Temporary array with all the data we read $temp = array( 'signature' => $sig, 'length' => $header_length, 'major' => $header_data['major'], 'minor' => $header_data['minor'], 'filecount' => $header_data['count'], 'uncompressedsize' => $header_data['uncsize'], 'compressedsize' => $header_data['csize'], 'unknowndata' => $junk ); // Array-to-object conversion foreach($temp as $key => $value) { $this->archiveHeaderData->{$key} = $value; } $this->currentPartOffset = @ftell($this->fp); $this->dataReadLength = 0; return true; } /** * Concrete classes must use this method to read the file header * @return bool True if reading the file was successful, false if an error occured or we reached end of archive */ protected function readFileHeader() { // If the current part is over, proceed to the next part please if( $this->isEOF(true) ) { $this->nextFile(); } // Get and decode Entity Description Block $signature = fread($this->fp, 3); $this->fileHeader = new stdClass(); $this->fileHeader->timestamp = 0; // Check signature if( $signature != 'JPF' ) { if($this->isEOF(true)) { // This file is finished; make sure it's the last one $this->nextFile(); if(!$this->isEOF(false)) { $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); return false; } // We're just finished return false; } else { // This is not a file block! The archive is corrupt. $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); return false; } } // This a JPA Entity Block. Process the header. $isBannedFile = false; // Read length of EDB and of the Entity Path Data $length_array = unpack('vblocksize/vpathsize', fread($this->fp, 4)); // Read the path data if($length_array['pathsize'] > 0) { $file = fread( $this->fp, $length_array['pathsize'] ); } else { $file = ''; } // Handle file renaming $isRenamed = false; if(is_array($this->renameFiles) && (count($this->renameFiles) > 0) ) { if(array_key_exists($file, $this->renameFiles)) { $file = $this->renameFiles[$file]; $isRenamed = true; } } // Handle directory renaming $isDirRenamed = false; if(is_array($this->renameDirs) && (count($this->renameDirs) > 0)) { if(array_key_exists(dirname($file), $this->renameDirs)) { $file = rtrim($this->renameDirs[dirname($file)],'/').'/'.basename($file); $isRenamed = true; $isDirRenamed = true; } } // Read and parse the known data portion $bin_data = fread( $this->fp, 14 ); $header_data = unpack('Ctype/Ccompression/Vcompsize/Vuncompsize/Vperms', $bin_data); // Read any unknown data $restBytes = $length_array['blocksize'] - (21 + $length_array['pathsize']); if( $restBytes > 0 ) { // Start reading the extra fields while($restBytes >= 4) { $extra_header_data = fread($this->fp, 4); $extra_header = unpack('vsignature/vlength', $extra_header_data); $restBytes -= 4; $extra_header['length'] -= 4; switch($extra_header['signature']) { case 256: // File modified timestamp if($extra_header['length'] > 0) { $bindata = fread($this->fp, $extra_header['length']); $restBytes -= $extra_header['length']; $timestamps = unpack('Vmodified', substr($bindata,0,4)); $filectime = $timestamps['modified']; $this->fileHeader->timestamp = $filectime; } break; default: // Unknown field if($extra_header['length']>0) { $junk = fread($this->fp, $extra_header['length']); $restBytes -= $extra_header['length']; } break; } } if($restBytes > 0) $junk = fread($this->fp, $restBytes); } $compressionType = $header_data['compression']; // Populate the return array $this->fileHeader->file = $file; $this->fileHeader->compressed = $header_data['compsize']; $this->fileHeader->uncompressed = $header_data['uncompsize']; switch($header_data['type']) { case 0: $this->fileHeader->type = 'dir'; break; case 1: $this->fileHeader->type = 'file'; break; case 2: $this->fileHeader->type = 'link'; break; } switch( $compressionType ) { case 0: $this->fileHeader->compression = 'none'; break; case 1: $this->fileHeader->compression = 'gzip'; break; case 2: $this->fileHeader->compression = 'bzip2'; break; } $this->fileHeader->permissions = $header_data['perms']; // Find hard-coded banned files if( (basename($this->fileHeader->file) == ".") || (basename($this->fileHeader->file) == "..") ) { $isBannedFile = true; } // Also try to find banned files passed in class configuration if((count($this->skipFiles) > 0) && (!$isRenamed) ) { if(in_array($this->fileHeader->file, $this->skipFiles)) { $isBannedFile = true; } } // If we have a banned file, let's skip it if($isBannedFile) { // Advance the file pointer, skipping exactly the size of the compressed data $seekleft = $this->fileHeader->compressed; while($seekleft > 0) { // Ensure that we can seek past archive part boundaries $curSize = @filesize($this->archiveList[$this->currentPartNumber]); $curPos = @ftell($this->fp); $canSeek = $curSize - $curPos; if($canSeek > $seekleft) $canSeek = $seekleft; @fseek( $this->fp, $canSeek, SEEK_CUR ); $seekleft -= $canSeek; if($seekleft) $this->nextFile(); } $this->currentPartOffset = @ftell($this->fp); $this->runState = AK_STATE_DONE; return true; } // Last chance to prepend a path to the filename if(!empty($this->addPath) && !$isDirRenamed) { $this->fileHeader->file = $this->addPath.$this->fileHeader->file; } // Get the translated path name $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); if($this->fileHeader->type == 'file') { // Regular file; ask the postproc engine to process its filename if($restorePerms) { $this->fileHeader->realFile = $this->postProcEngine->processFilename( $this->fileHeader->file, $this->fileHeader->permissions ); } else { $this->fileHeader->realFile = $this->postProcEngine->processFilename( $this->fileHeader->file ); } } elseif($this->fileHeader->type == 'dir') { $dir = $this->fileHeader->file; // Directory; just create it if($restorePerms) { $this->postProcEngine->createDirRecursive( $this->fileHeader->file, $this->fileHeader->permissions ); } else { $this->postProcEngine->createDirRecursive( $this->fileHeader->file, 0755 ); } $this->postProcEngine->processFilename(null); } else { // Symlink; do not post-process $this->postProcEngine->processFilename(null); } $this->createDirectory(); // Header is read $this->runState = AK_STATE_HEADER; $this->dataReadLength = 0; return true; } /** * Concrete classes must use this method to process file data. It must set $runState to AK_STATE_DATAREAD when * it's finished processing the file data. * @return bool True if processing the file data was successful, false if an error occured */ protected function processFileData() { switch( $this->fileHeader->type ) { case 'dir': return $this->processTypeDir(); break; case 'link': return $this->processTypeLink(); break; case 'file': switch($this->fileHeader->compression) { case 'none': return $this->processTypeFileUncompressed(); break; case 'gzip': case 'bzip2': return $this->processTypeFileCompressedSimple(); break; } break; } } private function processTypeFileUncompressed() { // Uncompressed files are being processed in small chunks, to avoid timeouts if( ($this->dataReadLength == 0) && !AKFactory::get('kickstart.setup.dryrun','0') ) { // Before processing file data, ensure permissions are adequate $this->setCorrectPermissions( $this->fileHeader->file ); } // Open the output file if( !AKFactory::get('kickstart.setup.dryrun','0') ) { $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false); if ($this->dataReadLength == 0) { $outfp = @fopen( $this->fileHeader->realFile, 'wb' ); } else { $outfp = @fopen( $this->fileHeader->realFile, 'ab' ); } // Can we write to the file? if( ($outfp === false) && (!$ignore) ) { // An error occured $this->setError( AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile) ); return false; } } // Does the file have any data, at all? if( $this->fileHeader->compressed == 0 ) { // No file data! if( !AKFactory::get('kickstart.setup.dryrun','0') && is_resource($outfp) ) @fclose($outfp); $this->runState = AK_STATE_DATAREAD; return true; } // Reference to the global timer $timer = AKFactory::getTimer(); $toReadBytes = 0; $leftBytes = $this->fileHeader->compressed - $this->dataReadLength; // Loop while there's data to read and enough time to do it while( ($leftBytes > 0) && ($timer->getTimeLeft() > 0) ) { $toReadBytes = ($leftBytes > $this->chunkSize) ? $this->chunkSize : $leftBytes; $data = $this->fread( $this->fp, $toReadBytes ); $reallyReadBytes = akstringlen($data); $leftBytes -= $reallyReadBytes; $this->dataReadLength += $reallyReadBytes; if($reallyReadBytes < $toReadBytes) { // We read less than requested! Why? Did we hit local EOF? if( $this->isEOF(true) && !$this->isEOF(false) ) { // Yeap. Let's go to the next file $this->nextFile(); } else { // Nope. The archive is corrupt $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } if( !AKFactory::get('kickstart.setup.dryrun','0') ) if(is_resource($outfp)) @fwrite( $outfp, $data ); } // Close the file pointer if( !AKFactory::get('kickstart.setup.dryrun','0') ) if(is_resource($outfp)) @fclose($outfp); // Was this a pre-timeout bail out? if( $leftBytes > 0 ) { $this->runState = AK_STATE_DATA; } else { // Oh! We just finished! $this->runState = AK_STATE_DATAREAD; $this->dataReadLength = 0; } return true; } private function processTypeFileCompressedSimple() { if( !AKFactory::get('kickstart.setup.dryrun','0') ) { // Before processing file data, ensure permissions are adequate $this->setCorrectPermissions( $this->fileHeader->file ); // Open the output file $outfp = @fopen( $this->fileHeader->realFile, 'wb' ); // Can we write to the file? $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false); if( ($outfp === false) && (!$ignore) ) { // An error occured $this->setError( AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile) ); return false; } } // Does the file have any data, at all? if( $this->fileHeader->compressed == 0 ) { // No file data! if( !AKFactory::get('kickstart.setup.dryrun','0') ) if(is_resource($outfp)) @fclose($outfp); $this->runState = AK_STATE_DATAREAD; return true; } // Simple compressed files are processed as a whole; we can't do chunk processing $zipData = $this->fread( $this->fp, $this->fileHeader->compressed ); while( akstringlen($zipData) < $this->fileHeader->compressed ) { // End of local file before reading all data, but have more archive parts? if($this->isEOF(true) && !$this->isEOF(false)) { // Yeap. Read from the next file $this->nextFile(); $bytes_left = $this->fileHeader->compressed - akstringlen($zipData); $zipData .= $this->fread( $this->fp, $bytes_left ); } else { $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } if($this->fileHeader->compression == 'gzip') { $unzipData = gzinflate( $zipData ); } elseif($this->fileHeader->compression == 'bzip2') { $unzipData = bzdecompress( $zipData ); } unset($zipData); // Write to the file. if( !AKFactory::get('kickstart.setup.dryrun','0') && is_resource($outfp) ) { @fwrite( $outfp, $unzipData, $this->fileHeader->uncompressed ); @fclose( $outfp ); } unset($unzipData); $this->runState = AK_STATE_DATAREAD; return true; } /** * Process the file data of a link entry * @return bool */ private function processTypeLink() { $readBytes = 0; $toReadBytes = 0; $leftBytes = $this->fileHeader->compressed; $data = ''; while( $leftBytes > 0) { $toReadBytes = ($leftBytes > $this->chunkSize) ? $this->chunkSize : $leftBytes; $mydata = $this->fread( $this->fp, $toReadBytes ); $reallyReadBytes = akstringlen($mydata); $data .= $mydata; $leftBytes -= $reallyReadBytes; if($reallyReadBytes < $toReadBytes) { // We read less than requested! Why? Did we hit local EOF? if( $this->isEOF(true) && !$this->isEOF(false) ) { // Yeap. Let's go to the next file $this->nextFile(); } else { // Nope. The archive is corrupt $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } } // Try to remove an existing file or directory by the same name if(file_exists($this->fileHeader->realFile)) { @unlink($this->fileHeader->realFile); @rmdir($this->fileHeader->realFile); } // Remove any trailing slash if(substr($this->fileHeader->realFile, -1) == '/') $this->fileHeader->realFile = substr($this->fileHeader->realFile, 0, -1); // Create the symlink - only possible within PHP context. There's no support built in the FTP protocol, so no postproc use is possible here :( if( !AKFactory::get('kickstart.setup.dryrun','0') ) @symlink($data, $this->fileHeader->realFile); $this->runState = AK_STATE_DATAREAD; return true; // No matter if the link was created! } /** * Process the file data of a directory entry * @return bool */ private function processTypeDir() { // Directory entries in the JPA do not have file data, therefore we're done processing the entry $this->runState = AK_STATE_DATAREAD; return true; } /** * Creates the directory this file points to */ protected function createDirectory() { if( AKFactory::get('kickstart.setup.dryrun','0') ) return true; // Do we need to create a directory? if(empty($this->fileHeader->realFile)) $this->fileHeader->realFile = $this->fileHeader->file; $lastSlash = strrpos($this->fileHeader->realFile, '/'); $dirName = substr( $this->fileHeader->realFile, 0, $lastSlash); $perms = $this->flagRestorePermissions ? $retArray['permissions'] : 0755; $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false); if( ($this->postProcEngine->createDirRecursive($dirName, $perms) == false) && (!$ignore) ) { $this->setError( AKText::sprintf('COULDNT_CREATE_DIR', $dirName) ); return false; } else { return true; } } } /** * ZIP archive extraction class * * Since the file data portion of ZIP and JPA are similarly structured (it's empty for dirs, * linked node name for symlinks, dumped binary data for no compressions and dumped gzipped * binary data for gzip compression) we just have to subclass AKUnarchiverJPA and change the * header reading bits. Reusable code ;) */ class AKUnarchiverZIP extends AKUnarchiverJPA { var $expectDataDescriptor = false; protected function readArchiveHeader() { // Initialize header data array $this->archiveHeaderData = new stdClass(); // Open the first part $this->nextFile(); // Fail for unreadable files if( $this->fp === false ) return false; // Read a possible multipart signature $sigBinary = fread( $this->fp, 4 ); $headerData = unpack('Vsig', $sigBinary); // Roll back if it's not a multipart archive if( $headerData['sig'] == 0x04034b50 ) fseek($this->fp, -4, SEEK_CUR); $multiPartSigs = array( 0x08074b50, // Multi-part ZIP 0x30304b50, // Multi-part ZIP (alternate) 0x04034b50 // Single file ); if( !in_array($headerData['sig'], $multiPartSigs) ) { $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); return false; } $this->currentPartOffset = @ftell($this->fp); $this->dataReadLength = 0; return true; } /** * Concrete classes must use this method to read the file header * @return bool True if reading the file was successful, false if an error occured or we reached end of archive */ protected function readFileHeader() { // If the current part is over, proceed to the next part please if( $this->isEOF(true) ) { $this->nextFile(); } if($this->expectDataDescriptor) { // The last file had bit 3 of the general purpose bit flag set. This means that we have a // 12 byte data descriptor we need to skip. To make things worse, there might also be a 4 // byte optional data descriptor header (0x08074b50). $junk = @fread($this->fp, 4); $junk = unpack('Vsig', $junk); if($junk['sig'] == 0x08074b50) { // Yes, there was a signature $junk = @fread($this->fp, 12); if(defined('KSDEBUG')) { debugMsg('Data descriptor (w/ header) skipped at '.(ftell($this->fp)-12)); } } else { // No, there was no signature, just read another 8 bytes $junk = @fread($this->fp, 8); if(defined('KSDEBUG')) { debugMsg('Data descriptor (w/out header) skipped at '.(ftell($this->fp)-8)); } } // And check for EOF, too if( $this->isEOF(true) ) { if(defined('KSDEBUG')) { debugMsg('EOF before reading header'); } $this->nextFile(); } } // Get and decode Local File Header $headerBinary = fread($this->fp, 30); $headerData = unpack('Vsig/C2ver/vbitflag/vcompmethod/vlastmodtime/vlastmoddate/Vcrc/Vcompsize/Vuncomp/vfnamelen/veflen', $headerBinary); // Check signature if(!( $headerData['sig'] == 0x04034b50 )) { if(defined('KSDEBUG')) { debugMsg('Not a file signature at '.(ftell($this->fp)-4)); } // The signature is not the one used for files. Is this a central directory record (i.e. we're done)? if($headerData['sig'] == 0x02014b50) { if(defined('KSDEBUG')) { debugMsg('EOCD signature at '.(ftell($this->fp)-4)); } // End of ZIP file detected. We'll just skip to the end of file... while( $this->nextFile() ) {}; @fseek($this->fp, 0, SEEK_END); // Go to EOF return false; } else { if(defined('KSDEBUG')) { debugMsg( 'Invalid signature ' . dechex($headerData['sig']) . ' at '.ftell($this->fp) ); } $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); return false; } } // If bit 3 of the bitflag is set, expectDataDescriptor is true $this->expectDataDescriptor = ($headerData['bitflag'] & 4) == 4; $this->fileHeader = new stdClass(); $this->fileHeader->timestamp = 0; // Read the last modified data and time $lastmodtime = $headerData['lastmodtime']; $lastmoddate = $headerData['lastmoddate']; if($lastmoddate && $lastmodtime) { // ----- Extract time $v_hour = ($lastmodtime & 0xF800) >> 11; $v_minute = ($lastmodtime & 0x07E0) >> 5; $v_seconde = ($lastmodtime & 0x001F)*2; // ----- Extract date $v_year = (($lastmoddate & 0xFE00) >> 9) + 1980; $v_month = ($lastmoddate & 0x01E0) >> 5; $v_day = $lastmoddate & 0x001F; // ----- Get UNIX date format $this->fileHeader->timestamp = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); } $isBannedFile = false; $this->fileHeader->compressed = $headerData['compsize']; $this->fileHeader->uncompressed = $headerData['uncomp']; $nameFieldLength = $headerData['fnamelen']; $extraFieldLength = $headerData['eflen']; // Read filename field $this->fileHeader->file = fread( $this->fp, $nameFieldLength ); // Handle file renaming $isRenamed = false; if(is_array($this->renameFiles) && (count($this->renameFiles) > 0) ) { if(array_key_exists($this->fileHeader->file, $this->renameFiles)) { $this->fileHeader->file = $this->renameFiles[$this->fileHeader->file]; $isRenamed = true; } } // Handle directory renaming $isDirRenamed = false; if(is_array($this->renameDirs) && (count($this->renameDirs) > 0)) { if(array_key_exists(dirname($file), $this->renameDirs)) { $file = rtrim($this->renameDirs[dirname($file)],'/').'/'.basename($file); $isRenamed = true; $isDirRenamed = true; } } // Read extra field if present if($extraFieldLength > 0) { $extrafield = fread( $this->fp, $extraFieldLength ); } if(defined('KSDEBUG')) { debugMsg( '*'.ftell($this->fp).' IS START OF '.$this->fileHeader->file. ' ('.$this->fileHeader->compressed.' bytes)' ); } // Decide filetype -- Check for directories $this->fileHeader->type = 'file'; if( strrpos($this->fileHeader->file, '/') == strlen($this->fileHeader->file) - 1 ) $this->fileHeader->type = 'dir'; // Decide filetype -- Check for symbolic links if( ($headerData['ver1'] == 10) && ($headerData['ver2'] == 3) )$this->fileHeader->type = 'link'; switch( $headerData['compmethod'] ) { case 0: $this->fileHeader->compression = 'none'; break; case 8: $this->fileHeader->compression = 'gzip'; break; } // Find hard-coded banned files if( (basename($this->fileHeader->file) == ".") || (basename($this->fileHeader->file) == "..") ) { $isBannedFile = true; } // Also try to find banned files passed in class configuration if((count($this->skipFiles) > 0) && (!$isRenamed)) { if(in_array($this->fileHeader->file, $this->skipFiles)) { $isBannedFile = true; } } // If we have a banned file, let's skip it if($isBannedFile) { // Advance the file pointer, skipping exactly the size of the compressed data $seekleft = $this->fileHeader->compressed; while($seekleft > 0) { // Ensure that we can seek past archive part boundaries $curSize = @filesize($this->archiveList[$this->currentPartNumber]); $curPos = @ftell($this->fp); $canSeek = $curSize - $curPos; if($canSeek > $seekleft) $canSeek = $seekleft; @fseek( $this->fp, $canSeek, SEEK_CUR ); $seekleft -= $canSeek; if($seekleft) $this->nextFile(); } $this->currentPartOffset = @ftell($this->fp); $this->runState = AK_STATE_DONE; return true; } // Last chance to prepend a path to the filename if(!empty($this->addPath) && !$isDirRenamed) { $this->fileHeader->file = $this->addPath.$this->fileHeader->file; } // Get the translated path name if($this->fileHeader->type == 'file') { $this->fileHeader->realFile = $this->postProcEngine->processFilename( $this->fileHeader->file ); } elseif($this->fileHeader->type == 'dir') { $this->fileHeader->timestamp = 0; $dir = $this->fileHeader->file; $this->postProcEngine->createDirRecursive( $this->fileHeader->file, 0755 ); $this->postProcEngine->processFilename(null); } else { // Symlink; do not post-process $this->fileHeader->timestamp = 0; $this->postProcEngine->processFilename(null); } $this->createDirectory(); // Header is read $this->runState = AK_STATE_HEADER; return true; } } /** * Timer class */ class AKCoreTimer extends AKAbstractObject { /** @var int Maximum execution time allowance per step */ private $max_exec_time = null; /** @var int Timestamp of execution start */ private $start_time = null; /** * Public constructor, creates the timer object and calculates the execution time limits * @return AECoreTimer */ public function __construct() { parent::__construct(); // Initialize start time $this->start_time = $this->microtime_float(); // Get configured max time per step and bias $config_max_exec_time = AKFactory::get('kickstart.tuning.max_exec_time', 14); $bias = AKFactory::get('kickstart.tuning.run_time_bias', 75)/100; // Get PHP's maximum execution time (our upper limit) if(@function_exists('ini_get')) { $php_max_exec_time = @ini_get("maximum_execution_time"); if ( (!is_numeric($php_max_exec_time)) || ($php_max_exec_time == 0) ) { // If we have no time limit, set a hard limit of about 10 seconds // (safe for Apache and IIS timeouts, verbose enough for users) $php_max_exec_time = 14; } } else { // If ini_get is not available, use a rough default $php_max_exec_time = 14; } // Apply an arbitrary correction to counter CMS load time $php_max_exec_time--; // Apply bias $php_max_exec_time = $php_max_exec_time * $bias; $config_max_exec_time = $config_max_exec_time * $bias; // Use the most appropriate time limit value if( $config_max_exec_time > $php_max_exec_time ) { $this->max_exec_time = $php_max_exec_time; } else { $this->max_exec_time = $config_max_exec_time; } } /** * Wake-up function to reset internal timer when we get unserialized */ public function __wakeup() { // Re-initialize start time on wake-up $this->start_time = $this->microtime_float(); } /** * Gets the number of seconds left, before we hit the "must break" threshold * @return float */ public function getTimeLeft() { return $this->max_exec_time - $this->getRunningTime(); } /** * Gets the time elapsed since object creation/unserialization, effectively how * long Akeeba Engine has been processing data * @return float */ public function getRunningTime() { return $this->microtime_float() - $this->start_time; } /** * Returns the current timestampt in decimal seconds */ private function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); } /** * Enforce the minimum execution time */ public function enforce_min_exec_time() { // Try to get a sane value for PHP's maximum_execution_time INI parameter if(@function_exists('ini_get')) { $php_max_exec = @ini_get("maximum_execution_time"); } else { $php_max_exec = 10; } if ( ($php_max_exec == "") || ($php_max_exec == 0) ) { $php_max_exec = 10; } // Decrease $php_max_exec time by 500 msec we need (approx.) to tear down // the application, as well as another 500msec added for rounding // error purposes. Also make sure this is never gonna be less than 0. $php_max_exec = max($php_max_exec * 1000 - 1000, 0); // Get the "minimum execution time per step" Akeeba Backup configuration variable $minexectime = AKFactory::get('kickstart.tuning.min_exec_time',0); if(!is_numeric($minexectime)) $minexectime = 0; // Make sure we are not over PHP's time limit! if($minexectime > $php_max_exec) $minexectime = $php_max_exec; // Get current running time $elapsed_time = $this->getRunningTime() * 1000; // Only run a sleep delay if we haven't reached the minexectime execution time if( ($minexectime > $elapsed_time) && ($elapsed_time > 0) ) { $sleep_msec = $minexectime - $elapsed_time; if(function_exists('usleep')) { usleep(1000 * $sleep_msec); } elseif(function_exists('time_nanosleep')) { $sleep_sec = floor($sleep_msec / 1000); $sleep_nsec = 1000000 * ($sleep_msec - ($sleep_sec * 1000)); time_nanosleep($sleep_sec, $sleep_nsec); } elseif(function_exists('time_sleep_until')) { $until_timestamp = time() + $sleep_msec / 1000; time_sleep_until($until_timestamp); } elseif(function_exists('sleep')) { $sleep_sec = ceil($sleep_msec/1000); sleep( $sleep_sec ); } } elseif( $elapsed_time > 0 ) { // No sleep required, even if user configured us to be able to do so. } } /** * Reset the timer. It should only be used in CLI mode! */ public function resetTime() { $this->start_time = $this->microtime_float(); } } /** * JPS archive extraction class */ class AKUnarchiverJPS extends AKUnarchiverJPA { private $archiveHeaderData = array(); private $password = ''; public function __construct() { parent::__construct(); $this->password = AKFactory::get('kickstart.jps.password',''); } protected function readArchiveHeader() { // Initialize header data array $this->archiveHeaderData = new stdClass(); // Open the first part $this->nextFile(); // Fail for unreadable files if( $this->fp === false ) return false; // Read the signature $sig = fread( $this->fp, 3 ); if ($sig != 'JPS') { // Not a JPA file $this->setError( AKText::_('ERR_NOT_A_JPS_FILE') ); return false; } // Read and parse the known portion of header data (5 bytes) $bin_data = fread($this->fp, 5); $header_data = unpack('Cmajor/Cminor/cspanned/vextra', $bin_data); // Load any remaining header data (forward compatibility) $rest_length = $header_data['extra']; if( $rest_length > 0 ) $junk = fread($this->fp, $rest_length); else $junk = ''; // Temporary array with all the data we read $temp = array( 'signature' => $sig, 'major' => $header_data['major'], 'minor' => $header_data['minor'], 'spanned' => $header_data['spanned'] ); // Array-to-object conversion foreach($temp as $key => $value) { $this->archiveHeaderData->{$key} = $value; } $this->currentPartOffset = @ftell($this->fp); $this->dataReadLength = 0; return true; } /** * Concrete classes must use this method to read the file header * @return bool True if reading the file was successful, false if an error occured or we reached end of archive */ protected function readFileHeader() { // If the current part is over, proceed to the next part please if( $this->isEOF(true) ) { $this->nextFile(); } // Get and decode Entity Description Block $signature = fread($this->fp, 3); // Check for end-of-archive siganture if($signature == 'JPE') { $this->setState('postrun'); return true; } $this->fileHeader = new stdClass(); $this->fileHeader->timestamp = 0; // Check signature if( $signature != 'JPF' ) { if($this->isEOF(true)) { // This file is finished; make sure it's the last one $this->nextFile(); if(!$this->isEOF(false)) { $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); return false; } // We're just finished return false; } else { fseek($this->fp, -6, SEEK_CUR); $signature = fread($this->fp, 3); if($signature == 'JPE') { return false; } $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); return false; } } // This a JPA Entity Block. Process the header. $isBannedFile = false; // Read and decrypt the header $edbhData = fread($this->fp, 4); $edbh = unpack('vencsize/vdecsize', $edbhData); $bin_data = fread($this->fp, $edbh['encsize']); // Decrypt and truncate $bin_data = AKEncryptionAES::AESDecryptCBC($bin_data, $this->password, 128); $bin_data = substr($bin_data,0,$edbh['decsize']); // Read length of EDB and of the Entity Path Data $length_array = unpack('vpathsize', substr($bin_data,0,2) ); // Read the path data $file = substr($bin_data,2,$length_array['pathsize']); // Handle file renaming $isRenamed = false; if(is_array($this->renameFiles) && (count($this->renameFiles) > 0) ) { if(array_key_exists($file, $this->renameFiles)) { $file = $this->renameFiles[$file]; $isRenamed = true; } } // Handle directory renaming $isDirRenamed = false; if(is_array($this->renameDirs) && (count($this->renameDirs) > 0)) { if(array_key_exists(dirname($file), $this->renameDirs)) { $file = rtrim($this->renameDirs[dirname($file)],'/').'/'.basename($file); $isRenamed = true; $isDirRenamed = true; } } // Read and parse the known data portion $bin_data = substr($bin_data, 2 + $length_array['pathsize']); $header_data = unpack('Ctype/Ccompression/Vuncompsize/Vperms/Vfilectime', $bin_data); $this->fileHeader->timestamp = $header_data['filectime']; $compressionType = $header_data['compression']; // Populate the return array $this->fileHeader->file = $file; $this->fileHeader->uncompressed = $header_data['uncompsize']; switch($header_data['type']) { case 0: $this->fileHeader->type = 'dir'; break; case 1: $this->fileHeader->type = 'file'; break; case 2: $this->fileHeader->type = 'link'; break; } switch( $compressionType ) { case 0: $this->fileHeader->compression = 'none'; break; case 1: $this->fileHeader->compression = 'gzip'; break; case 2: $this->fileHeader->compression = 'bzip2'; break; } $this->fileHeader->permissions = $header_data['perms']; // Find hard-coded banned files if( (basename($this->fileHeader->file) == ".") || (basename($this->fileHeader->file) == "..") ) { $isBannedFile = true; } // Also try to find banned files passed in class configuration if((count($this->skipFiles) > 0) && (!$isRenamed) ) { if(in_array($this->fileHeader->file, $this->skipFiles)) { $isBannedFile = true; } } // If we have a banned file, let's skip it if($isBannedFile) { $done = false; while(!$done) { // Read the Data Chunk Block header $binMiniHead = fread($this->fp, 8); if( in_array( substr($binMiniHead,0,3), array('JPF','JPE') ) ) { // Not a Data Chunk Block header, I am done skipping the file @fseek($this->fp,-8,SEEK_CUR); // Roll back the file pointer $done = true; // Mark as done continue; // Exit loop } else { // Skip forward by the amount of compressed data $miniHead = unpack('Vencsize/Vdecsize'); @fseek($this->fp, $miniHead['encsize'], SEEK_CUR); } } $this->currentPartOffset = @ftell($this->fp); $this->runState = AK_STATE_DONE; return true; } // Last chance to prepend a path to the filename if(!empty($this->addPath) && !$isDirRenamed) { $this->fileHeader->file = $this->addPath.$this->fileHeader->file; } // Get the translated path name $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); if($this->fileHeader->type == 'file') { // Regular file; ask the postproc engine to process its filename if($restorePerms) { $this->fileHeader->realFile = $this->postProcEngine->processFilename( $this->fileHeader->file, $this->fileHeader->permissions ); } else { $this->fileHeader->realFile = $this->postProcEngine->processFilename( $this->fileHeader->file ); } } elseif($this->fileHeader->type == 'dir') { $dir = $this->fileHeader->file; $this->fileHeader->realFile = $dir; // Directory; just create it if($restorePerms) { $this->postProcEngine->createDirRecursive( $this->fileHeader->file, $this->fileHeader->permissions ); } else { $this->postProcEngine->createDirRecursive( $this->fileHeader->file, 0755 ); } $this->postProcEngine->processFilename(null); } else { // Symlink; do not post-process $this->postProcEngine->processFilename(null); } $this->createDirectory(); // Header is read $this->runState = AK_STATE_HEADER; $this->dataReadLength = 0; return true; } /** * Concrete classes must use this method to process file data. It must set $runState to AK_STATE_DATAREAD when * it's finished processing the file data. * @return bool True if processing the file data was successful, false if an error occured */ protected function processFileData() { switch( $this->fileHeader->type ) { case 'dir': return $this->processTypeDir(); break; case 'link': return $this->processTypeLink(); break; case 'file': switch($this->fileHeader->compression) { case 'none': return $this->processTypeFileUncompressed(); break; case 'gzip': case 'bzip2': return $this->processTypeFileCompressedSimple(); break; } break; } } private function processTypeFileUncompressed() { // Uncompressed files are being processed in small chunks, to avoid timeouts if( ($this->dataReadLength == 0) && !AKFactory::get('kickstart.setup.dryrun','0') ) { // Before processing file data, ensure permissions are adequate $this->setCorrectPermissions( $this->fileHeader->file ); } // Open the output file if( !AKFactory::get('kickstart.setup.dryrun','0') ) { $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false); if ($this->dataReadLength == 0) { $outfp = @fopen( $this->fileHeader->realFile, 'wb' ); } else { $outfp = @fopen( $this->fileHeader->realFile, 'ab' ); } // Can we write to the file? if( ($outfp === false) && (!$ignore) ) { // An error occured $this->setError( AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile) ); return false; } } // Does the file have any data, at all? if( $this->fileHeader->uncompressed == 0 ) { // No file data! if( !AKFactory::get('kickstart.setup.dryrun','0') && is_resource($outfp) ) @fclose($outfp); $this->runState = AK_STATE_DATAREAD; return true; } else { $this->setError('An uncompressed file was detected; this is not supported by this archive extraction utility'); return false; } return true; } private function processTypeFileCompressedSimple() { $timer = AKFactory::getTimer(); // Files are being processed in small chunks, to avoid timeouts if( ($this->dataReadLength == 0) && !AKFactory::get('kickstart.setup.dryrun','0') ) { // Before processing file data, ensure permissions are adequate $this->setCorrectPermissions( $this->fileHeader->file ); } // Open the output file if( !AKFactory::get('kickstart.setup.dryrun','0') ) { // Open the output file $outfp = @fopen( $this->fileHeader->realFile, 'wb' ); // Can we write to the file? $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false); if( ($outfp === false) && (!$ignore) ) { // An error occured $this->setError( AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile) ); return false; } } // Does the file have any data, at all? if( $this->fileHeader->uncompressed == 0 ) { // No file data! if( !AKFactory::get('kickstart.setup.dryrun','0') ) if(is_resource($outfp)) @fclose($outfp); $this->runState = AK_STATE_DATAREAD; return true; } $leftBytes = $this->fileHeader->uncompressed - $this->dataReadLength; // Loop while there's data to write and enough time to do it while( ($leftBytes > 0) && ($timer->getTimeLeft() > 0) ) { // Read the mini header $binMiniHeader = fread($this->fp, 8); $reallyReadBytes = akstringlen($binMiniHeader); if($reallyReadBytes < 8) { // We read less than requested! Why? Did we hit local EOF? if( $this->isEOF(true) && !$this->isEOF(false) ) { // Yeap. Let's go to the next file $this->nextFile(); // Retry reading the header $binMiniHeader = fread($this->fp, 8); $reallyReadBytes = akstringlen($binMiniHeader); // Still not enough data? If so, the archive is corrupt or missing parts. if($reallyReadBytes < 8) { $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } else { // Nope. The archive is corrupt $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } // Read the encrypted data $miniHeader = unpack('Vencsize/Vdecsize', $binMiniHeader); $toReadBytes = $miniHeader['encsize']; $data = $this->fread( $this->fp, $toReadBytes ); $reallyReadBytes = akstringlen($data); if($reallyReadBytes < $toReadBytes) { // We read less than requested! Why? Did we hit local EOF? if( $this->isEOF(true) && !$this->isEOF(false) ) { // Yeap. Let's go to the next file $this->nextFile(); // Read the rest of the data $toReadBytes -= $reallyReadBytes; $restData = $this->fread( $this->fp, $toReadBytes ); $reallyReadBytes = akstringlen($restData); if($reallyReadBytes < $toReadBytes) { $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } if(akstringlen($data) == 0) { $data = $restData; } else { $data .= $restData; } } else { // Nope. The archive is corrupt $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } // Decrypt the data $data = AKEncryptionAES::AESDecryptCBC($data, $this->password, 128); // Is the length of the decrypted data less than expected? $data_length = akstringlen($data); if($data_length < $miniHeader['decsize']) { $this->setError(AKText::_('ERR_INVALID_JPS_PASSWORD')); return false; } // Trim the data $data = substr($data,0,$miniHeader['decsize']); // Decompress $data = gzinflate($data); $unc_len = akstringlen($data); // Write the decrypted data if( !AKFactory::get('kickstart.setup.dryrun','0') ) if(is_resource($outfp)) @fwrite( $outfp, $data, akstringlen($data) ); // Update the read length $this->dataReadLength += $unc_len; $leftBytes = $this->fileHeader->uncompressed - $this->dataReadLength; } // Close the file pointer if( !AKFactory::get('kickstart.setup.dryrun','0') ) if(is_resource($outfp)) @fclose($outfp); // Was this a pre-timeout bail out? if( $leftBytes > 0 ) { $this->runState = AK_STATE_DATA; } else { // Oh! We just finished! $this->runState = AK_STATE_DATAREAD; $this->dataReadLength = 0; } } /** * Process the file data of a link entry * @return bool */ private function processTypeLink() { // Does the file have any data, at all? if( $this->fileHeader->uncompressed == 0 ) { // No file data! $this->runState = AK_STATE_DATAREAD; return true; } // Read the mini header $binMiniHeader = fread($this->fp, 8); $reallyReadBytes = akstringlen($binMiniHeader); if($reallyReadBytes < 8) { // We read less than requested! Why? Did we hit local EOF? if( $this->isEOF(true) && !$this->isEOF(false) ) { // Yeap. Let's go to the next file $this->nextFile(); // Retry reading the header $binMiniHeader = fread($this->fp, 8); $reallyReadBytes = akstringlen($binMiniHeader); // Still not enough data? If so, the archive is corrupt or missing parts. if($reallyReadBytes < 8) { $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } else { // Nope. The archive is corrupt $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } // Read the encrypted data $miniHeader = unpack('Vencsize/Vdecsize', $binMiniHeader); $toReadBytes = $miniHeader['encsize']; $data = $this->fread( $this->fp, $toReadBytes ); $reallyReadBytes = akstringlen($data); if($reallyReadBytes < $toReadBytes) { // We read less than requested! Why? Did we hit local EOF? if( $this->isEOF(true) && !$this->isEOF(false) ) { // Yeap. Let's go to the next file $this->nextFile(); // Read the rest of the data $toReadBytes -= $reallyReadBytes; $restData = $this->fread( $this->fp, $toReadBytes ); $reallyReadBytes = akstringlen($data); if($reallyReadBytes < $toReadBytes) { $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } $data .= $restData; } else { // Nope. The archive is corrupt $this->setError( AKText::_('ERR_CORRUPT_ARCHIVE') ); return false; } } // Decrypt the data $data = AKEncryptionAES::AESDecryptCBC($data, $this->password, 128); // Is the length of the decrypted data less than expected? $data_length = akstringlen($data); if($data_length < $miniHeader['decsize']) { $this->setError(AKText::_('ERR_INVALID_JPS_PASSWORD')); return false; } // Trim the data $data = substr($data,0,$miniHeader['decsize']); // Try to remove an existing file or directory by the same name if(file_exists($this->fileHeader->realFile)) { @unlink($this->fileHeader->realFile); @rmdir($this->fileHeader->realFile); } // Remove any trailing slash if(substr($this->fileHeader->realFile, -1) == '/') $this->fileHeader->realFile = substr($this->fileHeader->realFile, 0, -1); // Create the symlink - only possible within PHP context. There's no support built in the FTP protocol, so no postproc use is possible here :( if( !AKFactory::get('kickstart.setup.dryrun','0') ) @symlink($data, $this->fileHeader->realFile); $this->runState = AK_STATE_DATAREAD; return true; // No matter if the link was created! } /** * Process the file data of a directory entry * @return bool */ private function processTypeDir() { // Directory entries in the JPA do not have file data, therefore we're done processing the entry $this->runState = AK_STATE_DATAREAD; return true; } /** * Creates the directory this file points to */ protected function createDirectory() { if( AKFactory::get('kickstart.setup.dryrun','0') ) return true; // Do we need to create a directory? $lastSlash = strrpos($this->fileHeader->realFile, '/'); $dirName = substr( $this->fileHeader->realFile, 0, $lastSlash); $perms = $this->flagRestorePermissions ? $retArray['permissions'] : 0755; $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false); if( ($this->postProcEngine->createDirRecursive($dirName, $perms) == false) && (!$ignore) ) { $this->setError( AKText::sprintf('COULDNT_CREATE_DIR', $dirName) ); return false; } else { return true; } } } /** * A filesystem scanner which uses opendir() */ class AKUtilsLister extends AKAbstractObject { public function &getFiles($folder, $pattern = '*') { // Initialize variables $arr = array(); $false = false; if(!is_dir($folder)) return $false; $handle = @opendir($folder); // If directory is not accessible, just return FALSE if ($handle === FALSE) { $this->setWarning( 'Unreadable directory '.$folder); return $false; } while (($file = @readdir($handle)) !== false) { if( !fnmatch($pattern, $file) ) continue; if (($file != '.') && ($file != '..')) { $ds = ($folder == '') || ($folder == '/') || (@substr($folder, -1) == '/') || (@substr($folder, -1) == DIRECTORY_SEPARATOR) ? '' : DIRECTORY_SEPARATOR; $dir = $folder . $ds . $file; $isDir = is_dir($dir); if (!$isDir) { $arr[] = $dir; } } } @closedir($handle); return $arr; } public function &getFolders($folder, $pattern = '*') { // Initialize variables $arr = array(); $false = false; if(!is_dir($folder)) return $false; $handle = @opendir($folder); // If directory is not accessible, just return FALSE if ($handle === FALSE) { $this->setWarning( 'Unreadable directory '.$folder); return $false; } while (($file = @readdir($handle)) !== false) { if( !fnmatch($pattern, $file) ) continue; if (($file != '.') && ($file != '..')) { $ds = ($folder == '') || ($folder == '/') || (@substr($folder, -1) == '/') || (@substr($folder, -1) == DIRECTORY_SEPARATOR) ? '' : DIRECTORY_SEPARATOR; $dir = $folder . $ds . $file; $isDir = is_dir($dir); if ($isDir) { $arr[] = $dir; } } } @closedir($handle); return $arr; } } /** * A simple INI-based i18n engine */ class AKText extends AKAbstractObject { /** * The default (en_GB) translation used when no other translation is available * @var array */ private $default_translation = array( 'AUTOMODEON' => 'Auto-mode enabled', 'ERR_NOT_A_JPA_FILE' => 'The file is not a JPA archive', 'ERR_CORRUPT_ARCHIVE' => 'The archive file is corrupt, truncated or archive parts are missing', 'ERR_INVALID_LOGIN' => 'Invalid login', 'COULDNT_CREATE_DIR' => 'Could not create %s folder', 'COULDNT_WRITE_FILE' => 'Could not open %s for writing.', 'WRONG_FTP_HOST' => 'Wrong FTP host or port', 'WRONG_FTP_USER' => 'Wrong FTP username or password', 'WRONG_FTP_PATH1' => 'Wrong FTP initial directory - the directory doesn\'t exist', 'FTP_CANT_CREATE_DIR' => 'Could not create directory %s', 'FTP_TEMPDIR_NOT_WRITABLE' => 'Could not find or create a writable temporary directory', 'FTP_COULDNT_UPLOAD' => 'Could not upload %s', 'THINGS_HEADER' => 'Things you should know about Akeeba Kickstart', 'THINGS_01' => 'Kickstart is not an installer. It is an archive extraction tool. The actual installer was put inside the archive file at backup time.', 'THINGS_02' => 'Kickstart is not the only way to extract the backup archive. You can use Akeeba eXtract Wizard and upload the extracted files using FTP instead.', 'THINGS_03' => 'Kickstart is bound by your server\'s configuration. As such, it may not work at all.', 'THINGS_04' => 'You should download and upload your archive files using FTP in Binary transfer mode. Any other method could lead to a corrupt backup archive and restoration failure.', 'THINGS_05' => 'Post-restoration site load errors are usually caused by .htaccess or php.ini directives. You should understand that blank pages, 404 and 500 errors can usually be worked around by editing the aforementioned files. It is not our job to mess with your configuration files, because this could be dangerous for your site.', 'THINGS_06' => 'Kickstart overwrites files without a warning. If you are not sure that you are OK with that do not continue.', 'THINGS_07' => 'Trying to restore to the temporary URL of a cPanel host (e.g. http://1.2.3.4/~username) will lead to restoration failure and your site will appear to be not working. This is normal and it\'s just how your server and CMS software work.', 'THINGS_08' => 'You are supposed to read the documentation before using this software. Most issues can be avoided, or easily worked around, by understanding how this software works.', 'THINGS_09' => 'This text does not imply that there is a problem detected. It is standard text displayed every time you launch Kickstart.', 'CLOSE_LIGHTBOX' => 'Click here or press ESC to close this message', 'SELECT_ARCHIVE' => 'Select a backup archive', 'ARCHIVE_FILE' => 'Archive file:', 'SELECT_EXTRACTION' => 'Select an extraction method', 'WRITE_TO_FILES' => 'Write to files:', 'WRITE_DIRECTLY' => 'Directly', 'WRITE_FTP' => 'Use FTP', 'FTP_HOST' => 'FTP host name:', 'FTP_PORT' => 'FTP port:', 'FTP_FTPS' => 'Use FTP over SSL (FTPS)', 'FTP_PASSIVE' => 'Use FTP Passive Mode', 'FTP_USER' => 'FTP user name:', 'FTP_PASS' => 'FTP password:', 'FTP_DIR' => 'FTP directory:', 'FTP_TEMPDIR' => 'Temporary directory:', 'FTP_CONNECTION_OK' => 'FTP Connection Established', 'FTP_CONNECTION_FAILURE' => 'The FTP Connection Failed', 'FTP_TEMPDIR_WRITABLE' => 'The temporary directory is writable.', 'FTP_TEMPDIR_UNWRITABLE' => 'The temporary directory is not writable. Please check the permissions.', 'BTN_CHECK' => 'Check', 'BTN_RESET' => 'Reset', 'BTN_TESTFTPCON' => 'Test FTP connection', 'BTN_GOTOSTART' => 'Start over', 'FINE_TUNE' => 'Fine tune', 'MIN_EXEC_TIME' => 'Minimum execution time:', 'MAX_EXEC_TIME' => 'Maximum execution time:', 'SECONDS_PER_STEP' => 'seconds per step', 'EXTRACT_FILES' => 'Extract files', 'BTN_START' => 'Start', 'EXTRACTING' => 'Extracting', 'DO_NOT_CLOSE_EXTRACT' => 'Do not close this window while the extraction is in progress', 'RESTACLEANUP' => 'Restoration and Clean Up', 'BTN_RUNINSTALLER' => 'Run the Installer', 'BTN_CLEANUP' => 'Clean Up', 'BTN_SITEFE' => 'Visit your site\'s front-end', 'BTN_SITEBE' => 'Visit your site\'s back-end', 'WARNINGS' => 'Extraction Warnings', 'ERROR_OCCURED' => 'An error occured', 'STEALTH_MODE' => 'Stealth mode', 'STEALTH_URL' => 'HTML file to show to web visitors', 'ERR_NOT_A_JPS_FILE' => 'The file is not a JPA archive', 'ERR_INVALID_JPS_PASSWORD' => 'The password you gave is wrong or the archive is corrupt', 'JPS_PASSWORD' => 'Archive Password (for JPS files)', 'INVALID_FILE_HEADER' => 'Invalid header in archive file, part %s, offset %s', 'NEEDSOMEHELPKS' => 'Want some help to use this tool? Read this first:', 'QUICKSTART' => 'Quick Start Guide', 'CANTGETITTOWORK' => 'Can\'t get it to work? Click me!', 'NOARCHIVESCLICKHERE' => 'No archives detected. Click here for troubleshooting instructions.', 'POSTRESTORATIONTROUBLESHOOTING' => 'Something not working after the restoration? Click here for troubleshooting instructions.', 'UPDATE_HEADER' => 'An updated version of Akeeba Kickstart (unknown) is available!', 'UPDATE_NOTICE' => 'You are advised to always use the latest version of Akeeba Kickstart available. Older versions may be subject to bugs and will not be supported.', 'UPDATE_DLNOW' => 'Download now', 'UPDATE_MOREINFO' => 'More information' ); /** * The array holding the translation keys * @var array */ private $strings; /** * The currently detected language (ISO code) * @var string */ private $language; /* * Initializes the translation engine * @return AKText */ public function __construct() { // Start with the default translation $this->strings = $this->default_translation; // Try loading the translation file in English, if it exists $this->loadTranslation('en-GB'); // Try loading the translation file in the browser's preferred language, if it exists $this->getBrowserLanguage(); if(!is_null($this->language)) { $this->loadTranslation(); } } /** * Singleton pattern for Language * @return Language The global Language instance */ public static function &getInstance() { static $instance; if(!is_object($instance)) { $instance = new AKText(); } return $instance; } public static function _($string) { $text = self::getInstance(); $key = strtoupper($string); $key = substr($key, 0, 1) == '_' ? substr($key, 1) : $key; if (isset ($text->strings[$key])) { $string = $text->strings[$key]; } else { if (defined($string)) { $string = constant($string); } } return $string; } public static function sprintf($key) { $text = self::getInstance(); $args = func_get_args(); if (count($args) > 0) { $args[0] = $text->_($args[0]); return @call_user_func_array('sprintf', $args); } return ''; } public function dumpLanguage() { $out = ''; foreach($this->strings as $key => $value) { $out .= "$key=$value\n"; } return $out; } public function asJavascript() { $out = ''; foreach($this->strings as $key => $value) { $key = addcslashes($key, '\\\'"'); $value = addcslashes($value, '\\\'"'); if(!empty($out)) $out .= ",\n"; $out .= "'$key':\t'$value'"; } return $out; } public function resetTranslation() { $this->strings = $this->default_translation; } public function getBrowserLanguage() { // Detection code from Full Operating system language detection, by Harald Hope // Retrieved from http://techpatterns.com/downloads/php_language_detection.php $user_languages = array(); //check to see if language is set if ( isset( $_SERVER["HTTP_ACCEPT_LANGUAGE"] ) ) { $languages = strtolower( $_SERVER["HTTP_ACCEPT_LANGUAGE"] ); // $languages = ' fr-ch;q=0.3, da, en-us;q=0.8, en;q=0.5, fr;q=0.3'; // need to remove spaces from strings to avoid error $languages = str_replace( ' ', '', $languages ); $languages = explode( ",", $languages ); foreach ( $languages as $language_list ) { // pull out the language, place languages into array of full and primary // string structure: $temp_array = array(); // slice out the part before ; on first step, the part before - on second, place into array $temp_array[0] = substr( $language_list, 0, strcspn( $language_list, ';' ) );//full language $temp_array[1] = substr( $language_list, 0, 2 );// cut out primary language if( (strlen($temp_array[0]) == 5) && ( (substr($temp_array[0],2,1) == '-') || (substr($temp_array[0],2,1) == '_') ) ) { $langLocation = strtoupper(substr($temp_array[0],3,2)); $temp_array[0] = $temp_array[1].'-'.$langLocation; } //place this array into main $user_languages language array $user_languages[] = $temp_array; } } else// if no languages found { $user_languages[0] = array( '','' ); //return blank array. } $this->language = null; $basename=basename(__FILE__, '.php') . '.ini'; // Try to match main language part of the filename, irrespective of the location, e.g. de_DE will do if de_CH doesn't exist. $fs = new AKUtilsLister(); $iniFiles = $fs->getFiles( dirname(__FILE__), '*.'.$basename ); if(empty($iniFiles) && ($basename != 'kickstart.ini')) { $basename = 'kickstart.ini'; $iniFiles = $fs->getFiles( dirname(__FILE__), '*.'.$basename ); } if (is_array($iniFiles)) { foreach($user_languages as $languageStruct) { if(is_null($this->language)) { // Get files matching the main lang part $iniFiles = $fs->getFiles( dirname(__FILE__), $languageStruct[1].'-??.'.$basename ); if (count($iniFiles) > 0) { $filename = $iniFiles[0]; $filename = substr($filename, strlen(dirname(__FILE__))+1); $this->language = substr($filename, 0, 5); } else { $this->language = null; } } } } if(is_null($this->language)) { // Try to find a full language match foreach($user_languages as $languageStruct) { if (@file_exists($languageStruct[0].'.'.$basename) && is_null($this->language)) { $this->language = $languageStruct[0]; } else { } } } else { // Do we have an exact match? foreach($user_languages as $languageStruct) { if(substr($this->language,0,strlen($languageStruct[1])) == $languageStruct[1]) { if(file_exists($languageStruct[0].'.'.$basename)) { $this->language = $languageStruct[0]; } } } } // Now, scan for full language based on the partial match } private function loadTranslation( $lang = null ) { $dirname = function_exists('getcwd') ? getcwd() : dirname(__FILE__); $basename=basename(__FILE__, '.php') . '.ini'; if( empty($lang) ) $lang = $this->language; $translationFilename = $dirname.DIRECTORY_SEPARATOR.$lang.'.'.$basename; if(!@file_exists($translationFilename) && ($basename != 'kickstart.ini')) { $basename = 'kickstart.ini'; $translationFilename = $dirname.DIRECTORY_SEPARATOR.$lang.'.'.$basename; } if(!@file_exists($translationFilename)) return; $temp = self::parse_ini_file($translationFilename, false); if(!is_array($this->strings)) $this->strings = array(); if(empty($temp)) { $this->strings = array_merge($this->default_translation, $this->strings); } else { $this->strings = array_merge($this->strings, $temp); } } /** * A PHP based INI file parser. * * Thanks to asohn ~at~ aircanopy ~dot~ net for posting this handy function on * the parse_ini_file page on http://gr.php.net/parse_ini_file * * @param string $file Filename to process * @param bool $process_sections True to also process INI sections * @return array An associative array of sections, keys and values * @access private */ public static function parse_ini_file($file, $process_sections = false, $raw_data = false) { $process_sections = ($process_sections !== true) ? false : true; if(!$raw_data) { $ini = @file($file); } else { $ini = $file; } if (count($ini) == 0) {return array();} $sections = array(); $values = array(); $result = array(); $globals = array(); $i = 0; if(!empty($ini)) foreach ($ini as $line) { $line = trim($line); $line = str_replace("\t", " ", $line); // Comments if (!preg_match('/^[a-zA-Z0-9[]/', $line)) {continue;} // Sections if ($line{0} == '[') { $tmp = explode(']', $line); $sections[] = trim(substr($tmp[0], 1)); $i++; continue; } // Key-value pair list($key, $value) = explode('=', $line, 2); $key = trim($key); $value = trim($value); if (strstr($value, ";")) { $tmp = explode(';', $value); if (count($tmp) == 2) { if ((($value{0} != '"') && ($value{0} != "'")) || preg_match('/^".*"\s*;/', $value) || preg_match('/^".*;[^"]*$/', $value) || preg_match("/^'.*'\s*;/", $value) || preg_match("/^'.*;[^']*$/", $value) ){ $value = $tmp[0]; } } else { if ($value{0} == '"') { $value = preg_replace('/^"(.*)".*/', '$1', $value); } elseif ($value{0} == "'") { $value = preg_replace("/^'(.*)'.*/", '$1', $value); } else { $value = $tmp[0]; } } } $value = trim($value); $value = trim($value, "'\""); if ($i == 0) { if (substr($line, -1, 2) == '[]') { $globals[$key][] = $value; } else { $globals[$key] = $value; } } else { if (substr($line, -1, 2) == '[]') { $values[$i-1][$key][] = $value; } else { $values[$i-1][$key] = $value; } } } for($j = 0; $j < $i; $j++) { if ($process_sections === true) { $result[$sections[$j]] = $values[$j]; } else { $result[] = $values[$j]; } } return $result + $globals; } } /** * The Akeeba Kickstart Factory class * This class is reponssible for instanciating all Akeeba Kicsktart classes */ class AKFactory { /** @var array A list of instanciated objects */ private $objectlist = array(); /** @var array Simple hash data storage */ private $varlist = array(); /** Private constructor makes sure we can't directly instanciate the class */ private function __construct() {} /** * Gets a single, internally used instance of the Factory * @param string $serialized_data [optional] Serialized data to spawn the instance from * @return AKFactory A reference to the unique Factory object instance */ protected static function &getInstance( $serialized_data = null ) { static $myInstance; if(!is_object($myInstance) || !is_null($serialized_data)) if(!is_null($serialized_data)) { $myInstance = unserialize($serialized_data); } else { $myInstance = new self(); } return $myInstance; } /** * Internal function which instanciates a class named $class_name. * The autoloader * @param object $class_name * @return */ protected static function &getClassInstance($class_name) { $self = self::getInstance(); if(!isset($self->objectlist[$class_name])) { $self->objectlist[$class_name] = new $class_name; } return $self->objectlist[$class_name]; } // ======================================================================== // Public factory interface // ======================================================================== /** * Gets a serialized snapshot of the Factory for safekeeping (hibernate) * @return string The serialized snapshot of the Factory */ public static function serialize() { $engine = self::getUnarchiver(); $engine->shutdown(); $serialized = serialize(self::getInstance()); if(function_exists('base64_encode') && function_exists('base64_decode')) { $serialized = base64_encode($serialized); } return $serialized; } /** * Regenerates the full Factory state from a serialized snapshot (resume) * @param string $serialized_data The serialized snapshot to resume from */ public static function unserialize($serialized_data) { if(function_exists('base64_encode') && function_exists('base64_decode')) { $serialized_data = base64_decode($serialized_data); } self::getInstance($serialized_data); } /** * Reset the internal factory state, freeing all previously created objects */ public static function nuke() { $self = self::getInstance(); foreach($self->objectlist as $key => $object) { $self->objectlist[$key] = null; } $self->objectlist = array(); } // ======================================================================== // Public hash data storage interface // ======================================================================== public static function set($key, $value) { $self = self::getInstance(); $self->varlist[$key] = $value; } public static function get($key, $default = null) { $self = self::getInstance(); if( array_key_exists($key, $self->varlist) ) { return $self->varlist[$key]; } else { return $default; } } // ======================================================================== // Akeeba Kickstart classes // ======================================================================== /** * Gets the post processing engine * @param string $proc_engine */ public static function &getPostProc($proc_engine = null) { static $class_name; if( empty($class_name) ) { if(empty($proc_engine)) { $proc_engine = self::get('kickstart.procengine','direct'); } $class_name = 'AKPostproc'.ucfirst($proc_engine); } return self::getClassInstance($class_name); } /** * Gets the unarchiver engine */ public static function &getUnarchiver( $configOverride = null ) { static $class_name; if(!empty($configOverride)) { if($configOverride['reset']) { $class_name = null; } } if( empty($class_name) ) { $filetype = self::get('kickstart.setup.filetype', null); if(empty($filetype)) { $filename = self::get('kickstart.setup.sourcefile', null); $basename = basename($filename); $baseextension = strtoupper(substr($basename,-3)); switch($baseextension) { case 'JPA': $filetype = 'JPA'; break; case 'JPS': $filetype = 'JPS'; break; case 'ZIP': $filetype = 'ZIP'; break; default: die('Invalid archive type or extension in file '.$filename); break; } } $class_name = 'AKUnarchiver'.ucfirst($filetype); } $destdir = self::get('kickstart.setup.destdir', null); if(empty($destdir)) { $destdir = function_exists('getcwd') ? getcwd() : dirname(__FILE__); } $object = self::getClassInstance($class_name); if( $object->getState() == 'init') { // Initialize the object $config = array( 'filename' => self::get('kickstart.setup.sourcefile', ''), 'restore_permissions' => self::get('kickstart.setup.restoreperms', 0), 'post_proc' => self::get('kickstart.procengine', 'direct'), 'add_path' => $destdir, 'rename_files' => array( '.htaccess' => 'htaccess.bak', 'php.ini' => 'php.ini.bak' ), 'skip_files' => array( basename(__FILE__), 'kickstart.php', 'abiautomation.ini', 'htaccess.bak', 'php.ini.bak' ) ); if(!defined('KICKSTART')) { // In restore.php mode we have to exclude some more files $config['skip_files'][] = 'administrator/components/com_akeeba/restore.php'; $config['skip_files'][] = 'administrator/components/com_akeeba/restoration.php'; } if(!empty($configOverride)) { foreach($configOverride as $key => $value) { $config[$key] = $value; } } $object->setup($config); } return $object; } /** * Get the a reference to the Akeeba Engine's timer * @return AKCoreTimer */ public static function &getTimer() { return self::getClassInstance('AKCoreTimer'); } } /** * AES implementation in PHP (c) Chris Veness 2005-2011 * (http://www.movable-type.co.uk/scripts/aes-php.html) * I offer these formulæ & scripts for free use and adaptation as my contribution to the * open-source info-sphere from which I have received so much. You are welcome to re-use these * scripts [under a simple attribution license or a GPL licence, without any warranty express or implied] * provided solely that you retain my copyright notice and a link to this page. * licence. No warranty of any form is offered. * * Modified for Akeeba Backup by Nicholas K. Dionysopoulos */ class AKEncryptionAES { // Sbox is pre-computed multiplicative inverse in GF(2^8) used in SubBytes and KeyExpansion [�5.1.1] protected static $Sbox = array(0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76, 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0, 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15, 0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75, 0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84, 0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf, 0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8, 0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2, 0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73, 0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb, 0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79, 0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08, 0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a, 0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e, 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf, 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16); // Rcon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [�5.2] protected static $Rcon = array( array(0x00, 0x00, 0x00, 0x00), array(0x01, 0x00, 0x00, 0x00), array(0x02, 0x00, 0x00, 0x00), array(0x04, 0x00, 0x00, 0x00), array(0x08, 0x00, 0x00, 0x00), array(0x10, 0x00, 0x00, 0x00), array(0x20, 0x00, 0x00, 0x00), array(0x40, 0x00, 0x00, 0x00), array(0x80, 0x00, 0x00, 0x00), array(0x1b, 0x00, 0x00, 0x00), array(0x36, 0x00, 0x00, 0x00) ); protected static $passwords = array(); /** * AES Cipher function: encrypt 'input' with Rijndael algorithm * * @param input message as byte-array (16 bytes) * @param w key schedule as 2D byte-array (Nr+1 x Nb bytes) - * generated from the cipher key by KeyExpansion() * @return ciphertext as byte-array (16 bytes) */ protected static function Cipher($input, $w) { // main Cipher function [�5.1] $Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES) $Nr = count($w)/$Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys $state = array(); // initialise 4xNb byte-array 'state' with input [�3.4] for ($i=0; $i<4*$Nb; $i++) $state[$i%4][floor($i/4)] = $input[$i]; $state = self::AddRoundKey($state, $w, 0, $Nb); for ($round=1; $round<$Nr; $round++) { // apply Nr rounds $state = self::SubBytes($state, $Nb); $state = self::ShiftRows($state, $Nb); $state = self::MixColumns($state, $Nb); $state = self::AddRoundKey($state, $w, $round, $Nb); } $state = self::SubBytes($state, $Nb); $state = self::ShiftRows($state, $Nb); $state = self::AddRoundKey($state, $w, $Nr, $Nb); $output = array(4*$Nb); // convert state to 1-d array before returning [�3.4] for ($i=0; $i<4*$Nb; $i++) $output[$i] = $state[$i%4][floor($i/4)]; return $output; } protected static function AddRoundKey($state, $w, $rnd, $Nb) { // xor Round Key into state S [�5.1.4] for ($r=0; $r<4; $r++) { for ($c=0; $c<$Nb; $c++) $state[$r][$c] ^= $w[$rnd*4+$c][$r]; } return $state; } protected static function SubBytes($s, $Nb) { // apply SBox to state S [�5.1.1] for ($r=0; $r<4; $r++) { for ($c=0; $c<$Nb; $c++) $s[$r][$c] = self::$Sbox[$s[$r][$c]]; } return $s; } protected static function ShiftRows($s, $Nb) { // shift row r of state S left by r bytes [�5.1.2] $t = array(4); for ($r=1; $r<4; $r++) { for ($c=0; $c<4; $c++) $t[$c] = $s[$r][($c+$r)%$Nb]; // shift into temp copy for ($c=0; $c<4; $c++) $s[$r][$c] = $t[$c]; // and copy back } // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES): return $s; // see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf } protected static function MixColumns($s, $Nb) { // combine bytes of each col of state S [�5.1.3] for ($c=0; $c<4; $c++) { $a = array(4); // 'a' is a copy of the current column from 's' $b = array(4); // 'b' is a�{02} in GF(2^8) for ($i=0; $i<4; $i++) { $a[$i] = $s[$i][$c]; $b[$i] = $s[$i][$c]&0x80 ? $s[$i][$c]<<1 ^ 0x011b : $s[$i][$c]<<1; } // a[n] ^ b[n] is a�{03} in GF(2^8) $s[0][$c] = $b[0] ^ $a[1] ^ $b[1] ^ $a[2] ^ $a[3]; // 2*a0 + 3*a1 + a2 + a3 $s[1][$c] = $a[0] ^ $b[1] ^ $a[2] ^ $b[2] ^ $a[3]; // a0 * 2*a1 + 3*a2 + a3 $s[2][$c] = $a[0] ^ $a[1] ^ $b[2] ^ $a[3] ^ $b[3]; // a0 + a1 + 2*a2 + 3*a3 $s[3][$c] = $a[0] ^ $b[0] ^ $a[1] ^ $a[2] ^ $b[3]; // 3*a0 + a1 + a2 + 2*a3 } return $s; } /** * Key expansion for Rijndael Cipher(): performs key expansion on cipher key * to generate a key schedule * * @param key cipher key byte-array (16 bytes) * @return key schedule as 2D byte-array (Nr+1 x Nb bytes) */ protected static function KeyExpansion($key) { // generate Key Schedule from Cipher Key [�5.2] $Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES) $Nk = count($key)/4; // key length (in words): 4/6/8 for 128/192/256-bit keys $Nr = $Nk + 6; // no of rounds: 10/12/14 for 128/192/256-bit keys $w = array(); $temp = array(); for ($i=0; $i<$Nk; $i++) { $r = array($key[4*$i], $key[4*$i+1], $key[4*$i+2], $key[4*$i+3]); $w[$i] = $r; } for ($i=$Nk; $i<($Nb*($Nr+1)); $i++) { $w[$i] = array(); for ($t=0; $t<4; $t++) $temp[$t] = $w[$i-1][$t]; if ($i % $Nk == 0) { $temp = self::SubWord(self::RotWord($temp)); for ($t=0; $t<4; $t++) $temp[$t] ^= self::$Rcon[$i/$Nk][$t]; } else if ($Nk > 6 && $i%$Nk == 4) { $temp = self::SubWord($temp); } for ($t=0; $t<4; $t++) $w[$i][$t] = $w[$i-$Nk][$t] ^ $temp[$t]; } return $w; } protected static function SubWord($w) { // apply SBox to 4-byte word w for ($i=0; $i<4; $i++) $w[$i] = self::$Sbox[$w[$i]]; return $w; } protected static function RotWord($w) { // rotate 4-byte word w left by one byte $tmp = $w[0]; for ($i=0; $i<3; $i++) $w[$i] = $w[$i+1]; $w[3] = $tmp; return $w; } /* * Unsigned right shift function, since PHP has neither >>> operator nor unsigned ints * * @param a number to be shifted (32-bit integer) * @param b number of bits to shift a to the right (0..31) * @return a right-shifted and zero-filled by b bits */ protected static function urs($a, $b) { $a &= 0xffffffff; $b &= 0x1f; // (bounds check) if ($a&0x80000000 && $b>0) { // if left-most bit set $a = ($a>>1) & 0x7fffffff; // right-shift one bit & clear left-most bit $a = $a >> ($b-1); // remaining right-shifts } else { // otherwise $a = ($a>>$b); // use normal right-shift } return $a; } /** * Encrypt a text using AES encryption in Counter mode of operation * - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf * * Unicode multi-byte character safe * * @param plaintext source text to be encrypted * @param password the password to use to generate a key * @param nBits number of bits to be used in the key (128, 192, or 256) * @return encrypted text */ public static function AESEncryptCtr($plaintext, $password, $nBits) { $blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES if (!($nBits==128 || $nBits==192 || $nBits==256)) return ''; // standard allows 128/192/256 bit keys // note PHP (5) gives us plaintext and password in UTF8 encoding! // use AES itself to encrypt password to get cipher key (using plain password as source for // key expansion) - gives us well encrypted key $nBytes = $nBits/8; // no bytes in key $pwBytes = array(); for ($i=0; $i<$nBytes; $i++) $pwBytes[$i] = ord(substr($password,$i,1)) & 0xff; $key = self::Cipher($pwBytes, self::KeyExpansion($pwBytes)); $key = array_merge($key, array_slice($key, 0, $nBytes-16)); // expand key to 16/24/32 bytes long // initialise counter block (NIST SP800-38A �B.2): millisecond time-stamp for nonce in // 1st 8 bytes, block counter in 2nd 8 bytes $counterBlock = array(); $nonce = floor(microtime(true)*1000); // timestamp: milliseconds since 1-Jan-1970 $nonceSec = floor($nonce/1000); $nonceMs = $nonce%1000; // encode nonce with seconds in 1st 4 bytes, and (repeated) ms part filling 2nd 4 bytes for ($i=0; $i<4; $i++) $counterBlock[$i] = self::urs($nonceSec, $i*8) & 0xff; for ($i=0; $i<4; $i++) $counterBlock[$i+4] = $nonceMs & 0xff; // and convert it to a string to go on the front of the ciphertext $ctrTxt = ''; for ($i=0; $i<8; $i++) $ctrTxt .= chr($counterBlock[$i]); // generate key schedule - an expansion of the key into distinct Key Rounds for each round $keySchedule = self::KeyExpansion($key); $blockCount = ceil(strlen($plaintext)/$blockSize); $ciphertxt = array(); // ciphertext as array of strings for ($b=0; $b<$blockCount; $b++) { // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes) // done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB) for ($c=0; $c<4; $c++) $counterBlock[15-$c] = self::urs($b, $c*8) & 0xff; for ($c=0; $c<4; $c++) $counterBlock[15-$c-4] = self::urs($b/0x100000000, $c*8); $cipherCntr = self::Cipher($counterBlock, $keySchedule); // -- encrypt counter block -- // block size is reduced on final block $blockLength = $b<$blockCount-1 ? $blockSize : (strlen($plaintext)-1)%$blockSize+1; $cipherByte = array(); for ($i=0; $i<$blockLength; $i++) { // -- xor plaintext with ciphered counter byte-by-byte -- $cipherByte[$i] = $cipherCntr[$i] ^ ord(substr($plaintext, $b*$blockSize+$i, 1)); $cipherByte[$i] = chr($cipherByte[$i]); } $ciphertxt[$b] = implode('', $cipherByte); // escape troublesome characters in ciphertext } // implode is more efficient than repeated string concatenation $ciphertext = $ctrTxt . implode('', $ciphertxt); $ciphertext = base64_encode($ciphertext); return $ciphertext; } /** * Decrypt a text encrypted by AES in counter mode of operation * * @param ciphertext source text to be decrypted * @param password the password to use to generate a key * @param nBits number of bits to be used in the key (128, 192, or 256) * @return decrypted text */ public static function AESDecryptCtr($ciphertext, $password, $nBits) { $blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES if (!($nBits==128 || $nBits==192 || $nBits==256)) return ''; // standard allows 128/192/256 bit keys $ciphertext = base64_decode($ciphertext); // use AES to encrypt password (mirroring encrypt routine) $nBytes = $nBits/8; // no bytes in key $pwBytes = array(); for ($i=0; $i<$nBytes; $i++) $pwBytes[$i] = ord(substr($password,$i,1)) & 0xff; $key = self::Cipher($pwBytes, self::KeyExpansion($pwBytes)); $key = array_merge($key, array_slice($key, 0, $nBytes-16)); // expand key to 16/24/32 bytes long // recover nonce from 1st element of ciphertext $counterBlock = array(); $ctrTxt = substr($ciphertext, 0, 8); for ($i=0; $i<8; $i++) $counterBlock[$i] = ord(substr($ctrTxt,$i,1)); // generate key schedule $keySchedule = self::KeyExpansion($key); // separate ciphertext into blocks (skipping past initial 8 bytes) $nBlocks = ceil((strlen($ciphertext)-8) / $blockSize); $ct = array(); for ($b=0; $b<$nBlocks; $b++) $ct[$b] = substr($ciphertext, 8+$b*$blockSize, 16); $ciphertext = $ct; // ciphertext is now array of block-length strings // plaintext will get generated block-by-block into array of block-length strings $plaintxt = array(); for ($b=0; $b<$nBlocks; $b++) { // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes) for ($c=0; $c<4; $c++) $counterBlock[15-$c] = self::urs($b, $c*8) & 0xff; for ($c=0; $c<4; $c++) $counterBlock[15-$c-4] = self::urs(($b+1)/0x100000000-1, $c*8) & 0xff; $cipherCntr = self::Cipher($counterBlock, $keySchedule); // encrypt counter block $plaintxtByte = array(); for ($i=0; $i $data_size) { $plaintext = substr($plaintext, 0, $data_size); } return $plaintext; } } /** * The Master Setup will read the configuration parameters from restoration.php, abiautomation.ini, or * the JSON-encoded "configuration" input variable and return the status. * @return bool True if the master configuration was applied to the Factory object */ function masterSetup() { // ------------------------------------------------------------ // 1. Import basic setup parameters // ------------------------------------------------------------ $ini_data = null; // In restore.php mode, require restoration.php or fail if(!defined('KICKSTART')) { // This is the standalone mode, used by Akeeba Backup Professional. It looks for a restoration.php // file to perform its magic. If the file is not there, we will abort. $setupFile = 'restoration.php'; if( !file_exists($setupFile) ) { // Uh oh... Somebody tried to pooh on our back yard. Lock the gates! Don't let the traitor inside! AKFactory::set('kickstart.enabled', false); return false; } // Load restoration.php. It creates a global variable named $restoration_setup require_once $setupFile; $ini_data = $restoration_setup; if(empty($ini_data)) { // No parameters fetched. Darn, how am I supposed to work like that?! AKFactory::set('kickstart.enabled', false); return false; } AKFactory::set('kickstart.enabled', true); } else { // Maybe we have $restoration_setup defined in the head of kickstart.php global $restoration_setup; if(!empty($restoration_setup) && !is_array($restoration_setup)) { $ini_data = AKText::parse_ini_file($restoration_setup, false, true); } elseif(is_array($restoration_setup)) { $ini_data = $restoration_setup; } } // Import any data from $restoration_setup if(!empty($ini_data)) { foreach($ini_data as $key => $value) { AKFactory::set($key, $value); } AKFactory::set('kickstart.enabled', true); } // Reinitialize $ini_data $ini_data = null; // ------------------------------------------------------------ // 2. Explode JSON parameters into $_REQUEST scope // ------------------------------------------------------------ // Detect a JSON string in the request variable and store it. $json = getQueryParam('json', null); // Remove everything from the request array if(!empty($_REQUEST)) { foreach($_REQUEST as $key => $value) { unset($_REQUEST[$key]); } } // Decrypt a possibly encrypted JSON string if(!empty($json)) { $password = AKFactory::get('kickstart.security.password', null); if(!empty($password)) { $json = AKEncryptionAES::AESDecryptCtr($json, $password, 128); } // Get the raw data $raw = json_decode( $json, true ); // Pass all JSON data to the request array if(!empty($raw)) { foreach($raw as $key => $value) { $_REQUEST[$key] = $value; } } } // ------------------------------------------------------------ // 3. Try the "factory" variable // ------------------------------------------------------------ // A "factory" variable will override all other settings. $serialized = getQueryParam('factory', null); if( !is_null($serialized) ) { // Get the serialized factory AKFactory::unserialize($serialized); AKFactory::set('kickstart.enabled', true); return true; } // ------------------------------------------------------------ // 4. Try abiautomation.ini and the configuration variable for Kickstart // ------------------------------------------------------------ if(defined('KICKSTART')) { // We are in Kickstart mode. abiautomation.ini has precedence. $setupFile = 'abiautomation.ini'; if( file_exists($setupFile) ) { // abiautomation.ini was found $ini_data = AKText::parse_ini_file('restoration.ini', false); } else { // abiautomation.ini was not found. Let's try input parameters. $configuration = getQueryParam('configuration'); if( !is_null($configuration) ) { // Let's decode the configuration from JSON to array $ini_data = json_decode($configuration, true); } else { // Neither exists. Enable Kickstart's interface anyway. $ini_data = array('kickstart.enabled'=>true); } } // Import any INI data we might have from other sources if(!empty($ini_data)) { foreach($ini_data as $key => $value) { AKFactory::set($key, $value); } AKFactory::set('kickstart.enabled', true); return true; } } } // Mini-controller for restore.php if(!defined('KICKSTART')) { // The observer class, used to report number of files and bytes processed class RestorationObserver extends AKAbstractPartObserver { public $compressedTotal = 0; public $uncompressedTotal = 0; public $filesProcessed = 0; public function update($object, $message) { if(!is_object($message)) return; if( !array_key_exists('type', get_object_vars($message)) ) return; if( $message->type == 'startfile' ) { $this->filesProcessed++; $this->compressedTotal += $message->content->compressed; $this->uncompressedTotal += $message->content->uncompressed; } } public function __toString() { return __CLASS__; } } // Import configuration masterSetup(); $retArray = array( 'status' => true, 'message' => null ); $enabled = AKFactory::get('kickstart.enabled', false); if($enabled) { $task = getQueryParam('task'); switch($task) { case 'ping': // ping task - realy does nothing! $timer = AKFactory::getTimer(); $timer->enforce_min_exec_time(); break; case 'startRestore': AKFactory::nuke(); // Reset the factory // Let the control flow to the next step (the rest of the code is common!!) case 'stepRestore': $engine = AKFactory::getUnarchiver(); // Get the engine $observer = new RestorationObserver(); // Create a new observer $engine->attach($observer); // Attach the observer $engine->tick(); $ret = $engine->getStatusArray(); if( $ret['Error'] != '' ) { $retArray['status'] = false; $retArray['done'] = true; $retArray['message'] = $ret['Error']; } elseif( !$ret['HasRun'] ) { $retArray['files'] = $observer->filesProcessed; $retArray['bytesIn'] = $observer->compressedTotal; $retArray['bytesOut'] = $observer->uncompressedTotal; $retArray['status'] = true; $retArray['done'] = true; } else { $retArray['files'] = $observer->filesProcessed; $retArray['bytesIn'] = $observer->compressedTotal; $retArray['bytesOut'] = $observer->uncompressedTotal; $retArray['status'] = true; $retArray['done'] = false; $retArray['factory'] = AKFactory::serialize(); } break; case 'finalizeRestore': $root = AKFactory::get('kickstart.setup.destdir'); // Remove the installation directory recursive_remove_directory( $root.'/installation' ); $postproc = AKFactory::getPostProc(); // Rename htaccess.bak to .htaccess if(file_exists($root.'/htaccess.bak')) { if( file_exists($root.'/.htaccess') ) { $postproc->unlink($root.'/.htaccess'); } $postproc->rename( $root.'/htaccess.bak', $root.'/.htaccess' ); } // Remove restoration.php $basepath = dirname(__FILE__); $basepath = rtrim( str_replace('\\','/',$basepath), '/' ); if(!empty($basepath)) $basepath .= '/'; $postproc->unlink( $basepath.'restoration.php' ); break; default: // Invalid task! $enabled = false; break; } } // Maybe we weren't authorized or the task was invalid? if(!$enabled) { // Maybe the user failed to enter any information $retArray['status'] = false; $retArray['message'] = AKText::_('ERR_INVALID_LOGIN'); } // JSON encode the message $json = json_encode($retArray); // Do I have to encrypt? $password = AKFactory::get('kickstart.security.password', null); if(!empty($password)) { $json = AKEncryptionAES::AESEncryptCtr($json, $password, 128); } // Return the message echo "###$json###"; } // ------------ lixlpixel recursive PHP functions ------------- // recursive_remove_directory( directory to delete, empty ) // expects path to directory and optional TRUE / FALSE to empty // of course PHP has to have the rights to delete the directory // you specify and all files and folders inside the directory // ------------------------------------------------------------ function recursive_remove_directory($directory) { // if the path has a slash at the end we remove it here if(substr($directory,-1) == '/') { $directory = substr($directory,0,-1); } // if the path is not valid or is not a directory ... if(!file_exists($directory) || !is_dir($directory)) { // ... we return false and exit the function return FALSE; // ... if the path is not readable }elseif(!is_readable($directory)) { // ... we return false and exit the function return FALSE; // ... else if the path is readable }else{ // we open the directory $handle = opendir($directory); $postproc = AKFactory::getPostProc(); // and scan through the items inside while (FALSE !== ($item = readdir($handle))) { // if the filepointer is not the current directory // or the parent directory if($item != '.' && $item != '..') { // we build the new path to delete $path = $directory.'/'.$item; // if the new path is a directory if(is_dir($path)) { // we call this function with the new path recursive_remove_directory($path); // if the new path is a file }else{ // we remove the file $postproc->unlink($path); } } } // close the directory closedir($handle); // try to delete the now empty directory if(!$postproc->rmdir($directory)) { // return false if not possible return FALSE; } // return success return TRUE; } } ?>components/com_joomlaupdate/controller.php000066600000003317150771655450015176 0ustar00input->get('view', 'default'); $vFormat = $document->getType(); $lName = $this->input->get('layout', 'default', 'string'); // Get and render the view. if ($view = $this->getView($vName, $vFormat)) { $ftp = JClientHelper::setCredentialsFromRequest('ftp'); $view->ftp = &$ftp; // Get the model for the view. $model = $this->getModel($vName); // Perform update source preference check and refresh update information $model->applyUpdateSite(); $model->refreshUpdates(); // Push the model into the view (as default). $view->setModel($model, true); $view->setLayout($lName); // Push document object into the view. $view->document = $document; $view->display(); } return $this; } } components/com_joomlaupdate/controllers/index.html000066600000000037150771655450016641 0ustar00 components/com_joomlaupdate/controllers/update.php000066600000013270150771655450016642 0ustar00id, $user->name, JVERSION), JLog::INFO, 'Update'); $this->_applyCredentials(); $model = $this->getModel('Default'); $file = $model->download(); $message = null; $messageType = null; if ($file) { JFactory::getApplication()->setUserState('com_joomlaupdate.file', $file); $url = 'index.php?option=com_joomlaupdate&task=update.install'; JLog::add(JText::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_FILE', $file), JLog::INFO, 'Update'); } else { JFactory::getApplication()->setUserState('com_joomlaupdate.file', null); $url = 'index.php?option=com_joomlaupdate'; $message = JText::_('COM_JOOMLAUPDATE_VIEW_UPDATE_DOWNLOADFAILED'); } $this->setRedirect($url, $message, $messageType); } /** * Start the installation of the new Joomla! version * * @return void * * @since 2.5.4 */ public function install() { $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'joomla_update.php'; JLog::addLogger($options, JLog::INFO, array('Update', 'databasequery', 'jerror')); JLog::add(JText::_('COM_JOOMLAUPDATE_UPDATE_LOG_INSTALL'), JLog::INFO, 'Update'); $this->_applyCredentials(); $model = $this->getModel('Default'); $file = JFactory::getApplication()->getUserState('com_joomlaupdate.file', null); $model->createRestorationFile($file); $this->display(); } /** * Finalise the upgrade by running the necessary scripts * * @return void * * @since 2.5.4 */ public function finalise() { $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'joomla_update.php'; JLog::addLogger($options, JLog::INFO, array('Update', 'databasequery', 'jerror')); JLog::add(JText::_('COM_JOOMLAUPDATE_UPDATE_LOG_FINALISE'), JLog::INFO, 'Update'); $this->_applyCredentials(); $model = $this->getModel('Default'); $model->finaliseUpgrade(); $url = 'index.php?option=com_joomlaupdate&task=update.cleanup'; $this->setRedirect($url); } /** * Clean up after ourselves * * @return void * * @since 2.5.4 */ public function cleanup() { $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'joomla_update.php'; JLog::addLogger($options, JLog::INFO, array('Update', 'databasequery', 'jerror')); JLog::add(JText::_('COM_JOOMLAUPDATE_UPDATE_LOG_CLEANUP'), JLog::INFO, 'Update'); $this->_applyCredentials(); $model = $this->getModel('Default'); $model->cleanUp(); $url = 'index.php?option=com_joomlaupdate&layout=complete'; $this->setRedirect($url); JLog::add(JText::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_COMPLETE', JVERSION), JLog::INFO, 'Update'); } /** * Purges updates. * * @return void * * @since 3.0 */ public function purge() { // Purge updates // Check for request forgeries JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); $model = $this->getModel('Default'); $model->purge(); $url = 'index.php?option=com_joomlaupdate'; $this->setRedirect($url, $model->_message); } /** * Method to display a view. * * @param boolean $cachable If true, the view output will be cached * @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()}. * * @return JoomlaupdateControllerUpdate This object to support chaining. * * @since 2.5.4 */ public function display($cachable = false, $urlparams = array()) { // Get the document object. $document = JFactory::getDocument(); // Set the default view name and format from the Request. $vName = $this->input->get('view', 'update'); $vFormat = $document->getType(); $lName = $this->input->get('layout', 'default', 'string'); // Get and render the view. if ($view = $this->getView($vName, $vFormat)) { // Get the model for the view. $model = $this->getModel('Default'); // Push the model into the view (as default). $view->setModel($model, true); $view->setLayout($lName); // Push document object into the view. $view->document = $document; $view->display(); } return $this; } /** * Applies FTP credentials to Joomla! itself, when required * * @return void * * @since 2.5.4 */ protected function _applyCredentials() { if (!JClientHelper::hasCredentials('ftp')) { $user = JFactory::getApplication()->getUserStateFromRequest('com_joomlaupdate.ftp_user', 'ftp_user', null, 'raw'); $pass = JFactory::getApplication()->getUserStateFromRequest('com_joomlaupdate.ftp_pass', 'ftp_pass', null, 'raw'); if ($user != '' && $pass != '') { // Add credentials to the session if (!JClientHelper::setCredentials('ftp', $user, $pass)) { JError::raiseWarning('SOME_ERROR_CODE', JText::_('JLIB_CLIENT_ERROR_HELPER_SETCREDENTIALSFROMREQUEST_FAILED')); } } } } } components/com_joomlaupdate/access.xml000066600000001023150771655450014255 0ustar00
    components/com_joomlaupdate/helpers/download.php000066600000021347150771655450016267 0ustar00 0777) ) { $mode = 0755; } } $ftpOptions = JClientHelper::getCredentials('ftp'); // Check to make sure the path valid and clean $path = JPath::clean($path); if ($ftpOptions['enabled'] == 1) { // Connect the FTP client $ftp = JClientFtp::getInstance( $ftpOptions['host'], $ftpOptions['port'], array(), $ftpOptions['user'], $ftpOptions['pass'] ); } if (@chmod($path, $mode)) { $ret = true; } elseif ($ftpOptions['enabled'] == 1) { // Translate path and delete $path = JPath::clean(str_replace(JPATH_ROOT, $ftpOptions['root'], $path), '/'); // FTP connector throws an error $ret = $ftp->chmod($path, $mode); } else { return false; } return $ret; } } components/com_joomlaupdate/helpers/index.html000066600000000037150771655450015735 0ustar00 components/com_joomlaupdate/helpers/select.php000066600000002063150771655450015731 0ustar00 'Joomla/' . JVERSION); $context = stream_context_create(array( 'http' => $httpopts )); $ih = @fopen($url, 'r', false, $context); } else { // PHP 4 way (actually, it's just a fallback) if ( function_exists('ini_set') ) { ini_set('user_agent', 'Joomla/' . JVERSION); } $ih = @fopen($url, 'r'); } // If fopen() fails, abort if ( !is_resource($ih) ) { return $result; } // Try to download $bytes = 0; $result = true; $return = ''; while (!feof($ih) && $result) { $contents = fread($ih, 4096); if ($contents === false) { @fclose($ih); $result = false; return $result; } else { $bytes += strlen($contents); if (is_resource($fp)) { $result = @fwrite($fp, $contents); } else { $return .= $contents; unset($contents); } } } @fclose($ih); if (is_resource($fp)) { return $result; } elseif ( $result === true ) { return $return; } else { return $result; } } /** * Detect and return available download "adapters" (not really adapters, as * we don't follow the Adapter pattern, yet) * * @return array * * @since 2.5.4 */ private static function getAdapters() { // Detect available adapters $adapters = array(); if (self::hasCURL()) { $adapters[] = 'curl'; } if (self::hasFOPEN()) { $adapters[] = 'fopen'; } return $adapters; } /** * Change the permissions of a file, optionally using FTP * * @param string $path Absolute path to file * @param int $mode Permissions, e.g. 0755 * * @return boolean True on success * * @since 2.5.4 */ private static function chmod($path, $mode) { if (is_string($mode)) { $mode = octdec($mode); if ( ($mode < 0600) || ($mode > 0777) ) { $mode = 0755; } } $ftpOptions = JClientHelper::getCredentials('ftp'); // Check to make sure the path valid and clean $path = JPath::clean($path); if ($ftpOptions['enabled'] == 1) { // Connect the FTP client $ftp = JClientFtp::getInstance( $ftpOptions['host'], $ftpOptions['port'], null, $ftpOptions['user'], $ftpOptions['pass'] ); } if (@chmod($path, $mode)) { $ret = true; } elseif ($ftpOptions['enabled'] == 1) { // Translate path and delete $path = JPath::clean(str_replace(JPATH_ROOT, $ftpOptions['root'], $path), '/'); // FTP connector throws an error $ret = $ftp->chmod($path, $mode); } else { return false; } } } components/com_joomlaupdate/helpers/joomlaupdate.php000066600000001657150771655450017146 0ustar00 * @since 2.5.4 */ class JoomlaupdateModelDefault extends JModelLegacy { /** * Detects if the Joomla! update site currently in use matches the one * configured in this component. If they don't match, it changes it. * * @return void * * @since 2.5.4 */ public function applyUpdateSite() { // Determine the intended update URL $params = JComponentHelper::getParams('com_joomlaupdate'); switch ($params->get('updatesource', 'nochange')) { // "Long Term Support (LTS) branch - Recommended" case 'lts': $updateURL = 'http://update.joomla.org/core/list.xml'; break; // "Short term support (STS) branch" case 'sts': $updateURL = 'http://update.joomla.org/core/sts/list_sts.xml'; break; // "Testing" case 'testing': $updateURL = 'http://update.joomla.org/core/test/list_test.xml'; break; // "Custom" if custom URL empty no changes case 'custom': if ($params->get('customurl', '') != '') { $updateURL = $params->get('customurl', ''); } else { return JError::raiseWarning(403, JText::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_CUSTOM_ERROR')); } break; // "Do not change" case 'nochange': default: return; break; } $db = $this->getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('us') . '.*') ->from($db->quoteName('#__update_sites_extensions') . ' AS ' . $db->quoteName('map')) ->join( 'INNER', $db->quoteName('#__update_sites') . ' AS ' . $db->quoteName('us') . ' ON (' . 'us.update_site_id = map.update_site_id)' ) ->where('map.extension_id = ' . $db->quote(700)); $db->setQuery($query); $update_site = $db->loadObject(); if ($update_site->location != $updateURL) { // Modify the database record $update_site->last_check_timestamp = 0; $update_site->location = $updateURL; $db->updateObject('#__update_sites', $update_site, 'update_site_id'); // Remove cached updates $query->clear() ->delete($db->quoteName('#__updates')) ->where($db->quoteName('extension_id') . ' = ' . $db->quote('700')); $db->setQuery($query); $db->execute(); } } /** * Makes sure that the Joomla! update cache is up-to-date * * @param boolean $force Force reload, ignoring the cache timeout * * @return void * * @since 2.5.4 */ public function refreshUpdates($force = false) { if ($force) { $cache_timeout = 0; } else { $update_params = JComponentHelper::getParams('com_installer'); $cache_timeout = $update_params->get('cachetimeout', 6, 'int'); $cache_timeout = 3600 * $cache_timeout; } $updater = JUpdater::getInstance(); $updater->findUpdates(700, $cache_timeout); } /** * Returns an array with the Joomla! update information * * @return array * * @since 2.5.4 */ public function getUpdateInformation() { // Initialise the return array $ret = array( 'installed' => JVERSION, 'latest' => null, 'object' => null ); // Fetch the update information from the database $db = $this->getDbo(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__updates')) ->where($db->quoteName('extension_id') . ' = ' . $db->quote(700)); $db->setQuery($query); $updateObject = $db->loadObject(); if (is_null($updateObject)) { $ret['latest'] = JVERSION; return $ret; } else { $ret['latest'] = $updateObject->version; } // Fetch the full update details from the update details URL jimport('joomla.updater.update'); $update = new JUpdate; $update->loadFromXML($updateObject->detailsurl); // Pass the update object if ($ret['latest'] == JVERSION) { $ret['object'] = null; } else { $ret['object'] = $update; } return $ret; } /** * Returns an array with the configured FTP options * * @return array * * @since 2.5.4 */ public function getFTPOptions() { $config = JFactory::getConfig(); return array( 'host' => $config->get('ftp_host'), 'port' => $config->get('ftp_port'), 'username' => $config->get('ftp_user'), 'password' => $config->get('ftp_pass'), 'directory' => $config->get('ftp_root'), 'enabled' => $config->get('ftp_enable'), ); } /** * Removes all of the updates from the table and enable all update streams. * * @return boolean Result of operation * * @since 3.0 */ public function purge() { $db = JFactory::getDbo(); // Modify the database record $update_site = new stdClass; $update_site->last_check_timestamp = 0; $update_site->enabled = 1; $update_site->update_site_id = 1; $db->updateObject('#__update_sites', $update_site, 'update_site_id'); $query = $db->getQuery(true) ->delete($db->quoteName('#__updates')) ->where($db->quoteName('update_site_id') . ' = ' . $db->quote('1')); $db->setQuery($query); if ($db->execute()) { $this->_message = JText::_('JLIB_INSTALLER_PURGED_UPDATES'); return true; } else { $this->_message = JText::_('JLIB_INSTALLER_FAILED_TO_PURGE_UPDATES'); return false; } } /** * Downloads the update package to the site * * @return bool|string False on failure, basename of the file in any other case * * @since 2.5.4 */ public function download() { $updateInfo = $this->getUpdateInformation(); $packageURL = $updateInfo['object']->downloadurl->_data; $basename = basename($packageURL); // Find the path to the temp directory and the local package $config = JFactory::getConfig(); $tempdir = $config->get('tmp_path'); $target = $tempdir . '/' . $basename; // Do we have a cached file? $exists = JFile::exists($target); if (!$exists) { // Not there, let's fetch it return $this->downloadPackage($packageURL, $target); } else { // Is it a 0-byte file? If so, re-download please. $filesize = @filesize($target); if (empty($filesize)) { return $this->downloadPackage($packageURL, $target); } // Yes, it's there, skip downloading return $basename; } } /** * Downloads a package file to a specific directory * * @param string $url The URL to download from * @param string $target The directory to store the file * * @return boolean True on success * * @since 2.5.4 */ protected function downloadPackage($url, $target) { JLoader::import('helpers.download', JPATH_COMPONENT_ADMINISTRATOR); JLog::add(JText::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_URL', $packageURL), JLog::INFO, 'Update'); $result = AdmintoolsHelperDownload::download($url, $target); if (!$result) { return false; } else { return basename($target); } } /** * @since 2.5.4 */ public function createRestorationFile($basename = null) { // Get a password $password = JUserHelper::genRandomPassword(32); $app = JFactory::getApplication(); $app->setUserState('com_joomlaupdate.password', $password); // Do we have to use FTP? $method = $app->input->get('method', 'direct'); // Get the absolute path to site's root $siteroot = JPATH_SITE; // If the package name is not specified, get it from the update info if (empty($basename)) { $updateInfo = $this->getUpdateInformation(); $packageURL = $updateInfo['object']->downloadurl->_data; $basename = basename($packageURL); } // Get the package name $config = JFactory::getConfig(); $tempdir = $config->get('tmp_path'); $file = $tempdir . '/' . $basename; $filesize = @filesize($file); $app->setUserState('com_joomlaupdate.password', $password); $app->setUserState('com_joomlaupdate.filesize', $filesize); $data = " '$password', 'kickstart.tuning.max_exec_time' => '5', 'kickstart.tuning.run_time_bias' => '75', 'kickstart.tuning.min_exec_time' => '0', 'kickstart.procengine' => '$method', 'kickstart.setup.sourcefile' => '$file', 'kickstart.setup.destdir' => '$siteroot', 'kickstart.setup.restoreperms' => '0', 'kickstart.setup.filetype' => 'zip', 'kickstart.setup.dryrun' => '0' ENDDATA; if ($method == 'ftp') { // Fetch the FTP parameters from the request. Note: The password should be // allowed as raw mode, otherwise something like !@43H% would be // sanitised to !@43H% which is just plain wrong. $ftp_host = $app->input->get('ftp_host', ''); $ftp_port = $app->input->get('ftp_port', '21'); $ftp_user = $app->input->get('ftp_user', ''); $ftp_pass = $app->input->get('ftp_pass', '', 'default', 'none', 2); $ftp_root = $app->input->get('ftp_root', ''); // Is the tempdir really writable? $writable = @is_writeable($tempdir); if ($writable) { // Let's be REALLY sure $fp = @fopen($tempdir . '/test.txt', 'w'); if ($fp === false) { $writable = false; } else { fclose($fp); unlink($tempdir . '/test.txt'); } } // If the tempdir is not writable, create a new writable subdirectory if (!$writable) { $FTPOptions = JClientHelper::getCredentials('ftp'); $ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], null, $FTPOptions['user'], $FTPOptions['pass']); $dest = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $tempdir . '/admintools'), '/'); if (!@mkdir($tempdir . '/admintools')) { $ftp->mkdir($dest); } if (!@chmod($tempdir . '/admintools', 511)) { $ftp->chmod($dest, 511); } $tempdir .= '/admintools'; } // Just in case the temp-directory was off-root, try using the default tmp directory $writable = @is_writeable($tempdir); if (!$writable) { $tempdir = JPATH_ROOT . '/tmp'; // Does the JPATH_ROOT/tmp directory exist? if (!is_dir($tempdir)) { JFolder::create($tempdir, 511); JFile::write($tempdir . '/.htaccess', "order deny, allow\ndeny from all\nallow from none\n"); } // If it exists and it is unwritable, try creating a writable admintools subdirectory if (!is_writable($tempdir)) { $FTPOptions = JClientHelper::getCredentials('ftp'); $ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], null, $FTPOptions['user'], $FTPOptions['pass']); $dest = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $tempdir . '/admintools'), '/'); if (!@mkdir($tempdir . '/admintools')) { $ftp->mkdir($dest); } if (!@chmod($tempdir . '/admintools', 511)) { $ftp->chmod($dest, 511); } $tempdir .= '/admintools'; } } // If we still have no writable directory, we'll try /tmp and the system's temp-directory $writable = @is_writeable($tempdir); if (!$writable) { if (@is_dir('/tmp') && @is_writable('/tmp')) { $tempdir = '/tmp'; } else { // Try to find the system temp path $tmpfile = @tempnam("dummy", ""); $systemp = @dirname($tmpfile); @unlink($tmpfile); if (!empty($systemp)) { if (@is_dir($systemp) && @is_writable($systemp)) { $tempdir = $systemp; } } } } $data .= << '0', 'kickstart.ftp.passive' => '1', 'kickstart.ftp.host' => '$ftp_host', 'kickstart.ftp.port' => '$ftp_port', 'kickstart.ftp.user' => '$ftp_user', 'kickstart.ftp.pass' => '$ftp_pass', 'kickstart.ftp.dir' => '$ftp_root', 'kickstart.ftp.tempdir' => '$tempdir' ENDDATA; } $data .= ');'; // Remove the old file, if it's there... $configpath = JPATH_COMPONENT_ADMINISTRATOR . '/restoration.php'; if (JFile::exists($configpath)) { JFile::delete($configpath); } // Write new file. First try with JFile. $result = JFile::write($configpath, $data); // In case JFile used FTP but direct access could help if (!$result) { if (function_exists('file_put_contents')) { $result = @file_put_contents($configpath, $data); if ($result !== false) { $result = true; } } else { $fp = @fopen($configpath, 'wt'); if ($fp !== false) { $result = @fwrite($fp, $data); if ($result !== false) { $result = true; } @fclose($fp); } } } return $result; } /** * Runs the schema update SQL files, the PHP update script and updates the * manifest cache and #__extensions entry. Essentially, it is identical to * JInstallerFile::install() without the file copy. * * @return boolean True on success * * @since 2.5.4 */ public function finaliseUpgrade() { $installer = JInstaller::getInstance(); $installer->setPath('source', JPATH_ROOT); $installer->setPath('extension_root', JPATH_ROOT); if (!$installer->setupInstall()) { $installer->abort(JText::_('JLIB_INSTALLER_ABORT_DETECTMANIFEST')); return false; } $installer->extension = JTable::getInstance('extension'); $installer->extension->load(700); $installer->setAdapter($installer->extension->type); $manifest = $installer->getManifest(); $manifestPath = JPath::clean($installer->getPath('manifest')); $element = preg_replace('/\.xml/', '', basename($manifestPath)); // Run the script file $manifestScript = (string) $manifest->scriptfile; if ($manifestScript) { $manifestScriptFile = JPATH_ROOT . '/' . $manifestScript; if (is_file($manifestScriptFile)) { // load the file include_once $manifestScriptFile; } $classname = 'JoomlaInstallerScript'; if (class_exists($classname)) { $manifestClass = new $classname($this); } } ob_start(); ob_implicit_flush(false); if ($manifestClass && method_exists($manifestClass, 'preflight')) { if ($manifestClass->preflight('update', $this) === false) { $installer->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE')); return false; } } $msg = ob_get_contents(); // create msg object; first use here ob_end_clean(); // Get a database connector object $db = JFactory::getDbo(); // Check to see if a file extension by the same name is already installed // If it is, then update the table because if the files aren't there // we can assume that it was (badly) uninstalled // If it isn't, add an entry to extensions $query = $db->getQuery(true) ->select($db->quoteName('extension_id')) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('type') . ' = ' . $db->quote('file')) ->where($db->quoteName('element') . ' = ' . $db->quote('joomla')); $db->setQuery($query); try { $db->execute(); } catch (RuntimeException $e) { // Install failed, roll back changes $installer->abort( JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', JText::_('JLIB_INSTALLER_UPDATE'), $db->stderr(true)) ); return false; } $id = $db->loadResult(); $row = JTable::getInstance('extension'); if ($id) { // Load the entry and update the manifest_cache $row->load($id); // Update name $row->set('name', 'files_joomla'); // Update manifest $row->manifest_cache = $installer->generateManifestCache(); if (!$row->store()) { // Install failed, roll back changes $installer->abort( JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', JText::_('JLIB_INSTALLER_UPDATE'), $db->stderr(true)) ); return false; } } else { // Add an entry to the extension table with a whole heap of defaults $row->set('name', 'files_joomla'); $row->set('type', 'file'); $row->set('element', 'joomla'); // There is no folder for files so leave it blank $row->set('folder', ''); $row->set('enabled', 1); $row->set('protected', 0); $row->set('access', 0); $row->set('client_id', 0); $row->set('params', ''); $row->set('system_data', ''); $row->set('manifest_cache', $installer->generateManifestCache()); if (!$row->store()) { // Install failed, roll back changes $installer->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_ROLLBACK', $db->stderr(true))); return false; } // Set the insert id $row->set('extension_id', $db->insertid()); // Since we have created a module item, we add it to the installation step stack // so that if we have to rollback the changes we can undo it. $installer->pushStep(array('type' => 'extension', 'extension_id' => $row->extension_id)); } /* * Let's run the queries for the file */ if ($manifest->update) { $result = $installer->parseSchemaUpdates($manifest->update->schemas, $row->extension_id); if ($result === false) { // Install failed, rollback changes $installer->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_UPDATE_SQL_ERROR', $db->stderr(true))); return false; } } // Start Joomla! 1.6 ob_start(); ob_implicit_flush(false); if ($manifestClass && method_exists($manifestClass, 'update')) { if ($manifestClass->update($installer) === false) { // Install failed, rollback changes $installer->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE')); return false; } } $msg .= ob_get_contents(); // append messages ob_end_clean(); // Lastly, we will copy the manifest file to its appropriate place. $manifest = array(); $manifest['src'] = $installer->getPath('manifest'); $manifest['dest'] = JPATH_MANIFESTS . '/files/' . basename($installer->getPath('manifest')); if (!$installer->copyFiles(array($manifest), true)) { // Install failed, rollback changes $installer->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_COPY_SETUP')); return false; } // Clobber any possible pending updates $update = JTable::getInstance('update'); $uid = $update->find( array('element' => $element, 'type' => 'file', 'client_id' => '0', 'folder' => '') ); if ($uid) { $update->delete($uid); } // And now we run the postflight ob_start(); ob_implicit_flush(false); if ($manifestClass && method_exists($manifestClass, 'postflight')) { $manifestClass->postflight('update', $this); } $msg .= ob_get_contents(); // append messages ob_end_clean(); if ($msg != '') { $installer->set('extension_message', $msg); } // Refresh versionable assets cache JFactory::getApplication()->flushAssets(); return true; } /** * Removes the extracted package file * * @return void * * @since 2.5.4 */ public function cleanUp() { // Remove the update package $config = JFactory::getConfig(); $tempdir = $config->get('tmp_path'); $file = JFactory::getApplication()->getUserState('com_joomlaupdate.file', null); $target = $tempdir . '/' . $file; if (!@unlink($target)) { JFile::delete($target); } // Remove the restoration.php file $target = JPATH_COMPONENT_ADMINISTRATOR . '/restoration.php'; if (!@unlink($target)) { JFile::delete($target); } // Remove joomla.xml from the site's root $target = JPATH_ROOT . '/joomla.xml'; if (!@unlink($target)) { JFile::delete($target); } // Unset the update filename from the session JFactory::getApplication()->setUserState('com_joomlaupdate.file', null); } } components/com_joomlaupdate/models/index.html000066600000000037150771655450015556 0ustar00 components/com_joomlaupdate/joomlaupdate.xml000066600000002143150771655450015504 0ustar00 com_joomlaupdate Joomla! Project February 2012 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_JOOMLAUPDATE_XML_DESCRIPTION config.xml controller.php index.html joomlaupdate.php restore.php controllers helpers models views language/en-GB.com_joomlaupdate.ini language/en-GB.com_joomlaupdate.sys.ini components/com_joomlaupdate/joomlaupdate.php000066600000001112150771655450015466 0ustar00authorise('core.manage', 'com_joomlaupdate')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } $controller = JControllerLegacy::getInstance('Joomlaupdate'); $controller->execute(JFactory::getApplication()->input->get('task')); $controller->redirect(); components/com_newsfeeds/tables/index.html000066600000000037150771655450015044 0ustar00 components/com_newsfeeds/tables/newsfeed.php000066600000010740150771655450015362 0ustar00loadArray($array['params']); $array['params'] = (string) $registry; } if (isset($array['metadata']) && is_array($array['metadata'])) { $registry = new JRegistry; $registry->loadArray($array['metadata']); $array['metadata'] = (string) $registry; } if (isset($array['images']) && is_array($array['images'])) { $registry = new JRegistry; $registry->loadArray($array['images']); $array['images'] = (string) $registry; } return parent::bind($array, $ignore); } /** * Overloaded check method to ensure data integrity. * * @return boolean True on success. */ public function check() { // Check for valid name. if (trim($this->name) == '') { $this->setError(JText::_('COM_NEWSFEEDS_WARNING_PROVIDE_VALID_NAME')); return false; } if (empty($this->alias)) { $this->alias = $this->name; } $this->alias = JApplication::stringURLSafe($this->alias); if (trim(str_replace('-', '', $this->alias)) == '') { $this->alias = JFactory::getDate()->format("Y-m-d-H-i-s"); } // Check the publish down date is not earlier than publish up. if ((int) $this->publish_down > 0 && $this->publish_down < $this->publish_up) { $this->setError(JText::_('JGLOBAL_START_PUBLISH_AFTER_FINISH')); return false; } // clean up keywords -- eliminate extra spaces between phrases // and cr (\r) and lf (\n) characters from string if (!empty($this->metakey)) { // only process if not empty $bad_characters = array("\n", "\r", "\"", "<", ">"); // array of characters to remove $after_clean = JString::str_ireplace($bad_characters, "", $this->metakey); // remove bad characters $keys = explode(',', $after_clean); // create array using commas as delimiter $clean_keys = array(); foreach ($keys as $key) { if (trim($key)) { // ignore blank keywords $clean_keys[] = trim($key); } } $this->metakey = implode(", ", $clean_keys); // put array back together delimited by ", " } // clean up description -- eliminate quotes and <> brackets if (!empty($this->metadesc)) { // only process if not empty $bad_characters = array("\"", "<", ">"); $this->metadesc = JString::str_ireplace($bad_characters, "", $this->metadesc); } return true; } /** * Overriden JTable::store to set modified data. * * @param boolean $updateNulls True to update fields even if they are null. * * @return boolean True on success. * * @since 1.6 */ public function store($updateNulls = false) { $date = JFactory::getDate(); $user = JFactory::getUser(); if ($this->id) { // Existing item $this->modified = $date->toSql(); $this->modified_by = $user->get('id'); } else { // New newsfeed. A feed created and created_by field can be set by the user, // so we don't touch either of these if they are set. if (!(int) $this->created) { $this->created = $date->toSql(); } if (empty($this->created_by)) { $this->created_by = $user->get('id'); } } // Verify that the alias is unique $table = JTable::getInstance('Newsfeed', 'NewsfeedsTable'); if ($table->load(array('alias' => $this->alias, 'catid' => $this->catid)) && ($table->id != $this->id || $this->id == 0)) { $this->setError(JText::_('COM_NEWSFEEDS_ERROR_UNIQUE_ALIAS')); return false; } // Save links as punycode. $this->link = JStringPunycode::urlToPunycode($this->link); return parent::store($updateNulls); } } components/com_newsfeeds/views/index.html000066600000000037150771655450014727 0ustar00 components/com_newsfeeds/views/newsfeeds/view.html.php000066600000011400150771655450017337 0ustar00items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); NewsfeedsHelper::addSubmenu('newsfeeds'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { $state = $this->get('State'); $canDo = JHelperContent::getActions('com_newsfeeds', 'category', $state->get('filter.category_id')); $user = JFactory::getUser(); // Get the toolbar object instance $bar = JToolBar::getInstance('toolbar'); JToolbarHelper::title(JText::_('COM_NEWSFEEDS_MANAGER_NEWSFEEDS'), 'feed newsfeeds'); if (count($user->getAuthorisedCategories('com_newsfeeds', 'core.create')) > 0) { JToolbarHelper::addNew('newsfeed.add'); } if ($canDo->get('core.edit')) { JToolbarHelper::editList('newsfeed.edit'); } if ($canDo->get('core.edit.state')) { JToolbarHelper::publish('newsfeeds.publish', 'JTOOLBAR_PUBLISH', true); JToolbarHelper::unpublish('newsfeeds.unpublish', 'JTOOLBAR_UNPUBLISH', true); JToolbarHelper::archiveList('newsfeeds.archive'); } if ($canDo->get('core.admin')) { JToolbarHelper::checkin('newsfeeds.checkin'); } if ($state->get('filter.published') == -2 && $canDo->get('core.delete')) { JToolbarHelper::deleteList('', 'newsfeeds.delete', 'JTOOLBAR_EMPTY_TRASH'); } elseif ($canDo->get('core.edit.state')) { JToolbarHelper::trash('newsfeeds.trash'); } // Add a batch button if ($user->authorise('core.create', 'com_newsfeeds') && $user->authorise('core.edit', 'com_newsfeeds') && $user->authorise('core.edit.state', 'com_newsfeeds')) { JHtml::_('bootstrap.modal', 'collapseModal'); $title = JText::_('JTOOLBAR_BATCH'); // Instantiate a new JLayoutFile instance and render the batch button $layout = new JLayoutFile('joomla.toolbar.batch'); $dhtml = $layout->render(array('title' => $title)); $bar->appendButton('Custom', $dhtml, 'batch'); } if ($user->authorise('core.admin', 'com_newsfeeds')) { JToolbarHelper::preferences('com_newsfeeds'); } JToolbarHelper::help('JHELP_COMPONENTS_NEWSFEEDS_FEEDS'); JHtmlSidebar::setAction('index.php?option=com_newsfeeds&view=newsfeeds'); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_PUBLISHED'), 'filter_published', JHtml::_('select.options', JHtml::_('jgrid.publishedOptions'), 'value', 'text', $this->state->get('filter.published'), true) ); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_CATEGORY'), 'filter_category_id', JHtml::_('select.options', JHtml::_('category.options', 'com_newsfeeds'), 'value', 'text', $this->state->get('filter.category_id')) ); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_ACCESS'), 'filter_access', JHtml::_('select.options', JHtml::_('access.assetgroups'), 'value', 'text', $this->state->get('filter.access')) ); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_LANGUAGE'), 'filter_language', JHtml::_('select.options', JHtml::_('contentlanguage.existing', true, true), 'value', 'text', $this->state->get('filter.language')) ); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_TAG'), 'filter_tag', JHtml::_('select.options', JHtml::_('tag.options', true, true), 'value', 'text', $this->state->get('filter.tag')) ); } /** * Returns an array of fields the table can be sorted by * * @return array Array containing the field name to sort by as the key and display text as value * * @since 3.0 */ protected function getSortFields() { return array( 'a.ordering' => JText::_('JGRID_HEADING_ORDERING'), 'a.published' => JText::_('JSTATUS'), 'a.name' => JText::_('JGLOBAL_TITLE'), 'category_title' => JText::_('JCATEGORY'), 'a.access' => JText::_('JGRID_HEADING_ACCESS'), 'numarticles' => JText::_('COM_NEWSFEEDS_NUM_ARTICLES_HEADING'), 'a.cache_time' => JText::_('COM_NEWSFEEDS_CACHE_TIME_HEADING'), 'a.language' => JText::_('JGRID_HEADING_LANGUAGE'), 'a.id' => JText::_('JGRID_HEADING_ID') ); } } components/com_newsfeeds/views/newsfeeds/tmpl/default.php000066600000024353150771655450020035 0ustar00get('id'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $archived = $this->state->get('filter.published') == 2 ? true : false; $trashed = $this->state->get('filter.published') == -2 ? true : false; $canOrder = $user->authorise('core.edit.state', 'com_newsfeeds.category'); $saveOrder = $listOrder == 'a.ordering'; if ($saveOrder) { $saveOrderingUrl = 'index.php?option=com_newsfeeds&task=newsfeeds.saveOrderAjax&tmpl=component'; JHtml::_('sortablelist.sortable', 'articleList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); } $sortFields = $this->getSortFields(); $assoc = JLanguageAssociations::isEnabled(); ?>
    sidebar)) : ?>
    sidebar; ?>
    pagination->getLimitBox(); ?>
    items as $i => $item) : $ordering = ($listOrder == 'a.ordering'); $canCreate = $user->authorise('core.create', 'com_newsfeeds.category.' . $item->catid); $canEdit = $user->authorise('core.edit', 'com_newsfeeds.category.' . $item->catid); $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; $canChange = $user->authorise('core.edit.state', 'com_newsfeeds.category.' . $item->catid) && $canCheckin; ?>
    ', 'a.ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING'); ?>
    pagination->getListFooter(); ?>
    id); ?>
    published, $i, 'newsfeeds.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> escape($item->name)); ?>
    checked_out) : ?> editor, $item->checked_out_time, 'newsfeeds.', $canCheckin); ?> escape($item->name); ?> escape($item->name); ?> escape($item->alias));?>
    escape($item->category_title); ?>
    escape($item->access_level); ?> numarticles; ?> cache_time; ?> association) : ?> id); ?> language == '*'):?> language_title ? $this->escape($item->language_title) : JText::_('JUNDEFINED'); ?> id; ?>
    loadTemplate('batch'); ?>
    components/com_newsfeeds/views/newsfeeds/tmpl/index.html000066600000000037150771655450017666 0ustar00 components/com_newsfeeds/views/newsfeeds/tmpl/default_batch.php000066600000003424150771655450021172 0ustar00state->get('filter.published'); ?> components/com_newsfeeds/views/newsfeeds/tmpl/modal.php000066600000015312150771655450017500 0ustar00input; $function = JFactory::getApplication()->input->getCmd('function', 'jSelectNewsfeed'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?>

    state->get('filter.forcedLanguage')) : ?>
    items as $i => $item) : ?> language && JLanguageMultilang::isEnabled()) { $tag = strlen($item->language); if ($tag == 5) { $lang = substr($item->language, 0, 2); } elseif ($tag == 6) { $lang = substr($item->language, 0, 3); } else { $lang = ""; } } elseif (!JLanguageMultilang::isEnabled()) { $lang = ""; } ?>
    pagination->getListFooter(); ?>
    escape($item->name); ?> escape($item->access_level); ?> escape($item->category_title); ?> language == '*'):?> language_title ? $this->escape($item->language_title) : JText::_('JUNDEFINED'); ?> id; ?>
    components/com_newsfeeds/views/newsfeeds/index.html000066600000000037150771655450016712 0ustar00 components/com_newsfeeds/views/newsfeed/view.html.php000066600000005157150771655450017170 0ustar00state = $this->get('State'); $this->item = $this->get('Item'); $this->form = $this->get('Form'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } if ($this->getLayout() == 'modal') { $this->form->setFieldAttribute('language', 'readonly', 'true'); $this->form->setFieldAttribute('catid', 'readonly', 'true'); } $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { JFactory::getApplication()->input->set('hidemainmenu', true); $user = JFactory::getUser(); $isNew = ($this->item->id == 0); $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); // Since we don't track these assets at the item level, use the category id. $canDo = JHelperContent::getActions('com_newsfeeds', 'category', $this->item->catid); JToolbarHelper::title(JText::_('COM_NEWSFEEDS_MANAGER_NEWSFEED'), 'feed newsfeeds'); // If not checked out, can save the item. if (!$checkedOut && ($canDo->get('core.edit') || count($user->getAuthorisedCategories('com_newsfeeds', 'core.create')) > 0)) { JToolbarHelper::apply('newsfeed.apply'); JToolbarHelper::save('newsfeed.save'); } if (!$checkedOut && count($user->getAuthorisedCategories('com_newsfeeds', 'core.create')) > 0) { JToolbarHelper::save2new('newsfeed.save2new'); } // If an existing item, can save to a copy. if (!$isNew && $canDo->get('core.create')) { JToolbarHelper::save2copy('newsfeed.save2copy'); } if (empty($this->item->id)) { JToolbarHelper::cancel('newsfeed.cancel'); } else { if ($this->state->params->get('save_history', 0) && $user->authorise('core.edit')) { JToolbarHelper::versions('com_newsfeeds.newsfeed', $this->item->id); } JToolbarHelper::cancel('newsfeed.cancel', 'JTOOLBAR_CLOSE'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_COMPONENTS_NEWSFEEDS_FEEDS_EDIT'); } } components/com_newsfeeds/views/newsfeed/tmpl/modal_associations.php000066600000000527150771655450022076 0ustar00input; $assoc = JLanguageAssociations::isEnabled(); ?>
    'details')); ?> item->id) ? JText::_('COM_NEWSFEEDS_NEW_NEWSFEED', true) : JText::_('COM_NEWSFEEDS_EDIT_NEWSFEED', true)); ?>
    form->getControlGroup('link'); ?> form->getControlGroup('description'); ?>
    form->getControlGroup('images'); ?> form->getGroup('images') as $field) : ?> getControlGroup(); ?>
    loadTemplate('display'); ?> set('ignore_fieldsets', array('jbasic')); ?> loadTemplate('associations'); ?>
    components/com_newsfeeds/views/newsfeed/tmpl/edit_metadata.php000066600000000523150771655450021004 0ustar00form->getFieldsets('params'); foreach ($fieldSets as $name => $fieldSet) : ?>
    description) && trim($fieldSet->description)) : echo '

    '.$this->escape(JText::_($fieldSet->description)).'

    '; endif; ?> form->getFieldset($name) as $field) : ?>
    label; ?>
    input; ?>
    components/com_newsfeeds/views/newsfeed/tmpl/index.html000066600000000037150771655450017503 0ustar00 components/com_newsfeeds/views/newsfeed/tmpl/edit_display.php000066600000000557150771655450020700 0ustar00fieldset = 'jbasic'; echo JLayoutHelper::render('joomla.edit.fieldset', $this); components/com_newsfeeds/views/newsfeed/tmpl/edit_params.php000066600000001615150771655450020512 0ustar00form->getFieldsets('params'); foreach ($fieldSets as $name => $fieldSet) : ?>
    description) && trim($fieldSet->description)) : echo '

    '.$this->escape(JText::_($fieldSet->description)).'

    '; endif; ?> form->getFieldset($name) as $field) : ?>
    label; ?>
    input; ?>
    components/com_newsfeeds/views/newsfeed/tmpl/modal.php000066600000007760150771655450017325 0ustar00input; $assoc = JLanguageAssociations::isEnabled(); ?>

    'details')); ?> item->id) ? JText::_('COM_NEWSFEEDS_NEW_NEWSFEED', true) : JText::_('COM_NEWSFEEDS_EDIT_NEWSFEED', true)); ?>
    form->getControlGroup('link'); ?> form->getControlGroup('description'); ?>
    form->getControlGroup('images'); ?> form->getGroup('images') as $field) : ?> getControlGroup(); ?>
    loadTemplate('display'); ?> set('ignore_fieldsets', array('jbasic')); ?>
    components/com_newsfeeds/views/newsfeed/tmpl/modal_metadata.php000066600000000523150771655450021153 0ustar00fieldset = 'jbasic'; echo JLayoutHelper::render('joomla.edit.fieldset', $this); components/com_newsfeeds/views/newsfeed/tmpl/edit_associations.php000066600000000527150771655450021727 0ustar00 components/com_newsfeeds/sql/install.mysql.utf8.sql000066600000003216150771655450016616 0ustar00CREATE TABLE `#__newsfeeds` ( `catid` integer NOT NULL default '0', `id` integer(10) UNSIGNED NOT NULL auto_increment, `name` varchar(100) NOT NULL DEFAULT '', `alias` varchar(100) NOT NULL default '', `link` varchar(200) NOT NULL DEFAULT '', `filename` varchar(200) default NULL, `published` tinyint(1) NOT NULL default '0', `numarticles` integer unsigned NOT NULL default '1', `cache_time` integer unsigned NOT NULL default '3600', `checked_out` integer(10) unsigned NOT NULL default '0', `checked_out_time` datetime NOT NULL default '0000-00-00 00:00:00', `ordering` integer NOT NULL default '0', `rtl` tinyint(4) NOT NULL default '0', `access` tinyint UNSIGNED NOT NULL DEFAULT '0', `language` char(7) NOT NULL DEFAULT '', `params` text NOT NULL, `created` datetime NOT NULL default '0000-00-00 00:00:00', `created_by` int(10) unsigned NOT NULL default '0', `created_by_alias` varchar(255) NOT NULL default '', `modified` datetime NOT NULL default '0000-00-00 00:00:00', `modified_by` int(10) unsigned NOT NULL default '0', `metakey` text NOT NULL, `metadesc` text NOT NULL, `metadata` text NOT NULL, `xreference` varchar(50) NOT NULL COMMENT 'A reference to enable linkages to external data sets.', `publish_up` datetime NOT NULL default '0000-00-00 00:00:00', `publish_down` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`), KEY `idx_access` (`access`), KEY `idx_checkout` (`checked_out`), KEY `idx_state` (`published`), KEY `idx_catid` (`catid`), KEY `idx_createdby` (`created_by`), KEY `idx_language` (`language`), KEY `idx_xreference` (`xreference`) ) DEFAULT CHARSET=utf8; components/com_newsfeeds/sql/uninstall.mysql.utf8.sql000066600000000046150771655450017157 0ustar00DROP TABLE IF EXISTS `#__newsfeeds`; components/com_newsfeeds/sql/index.html000066600000000037150771655450014371 0ustar00 components/com_newsfeeds/index.html000066600000000037150771655450013572 0ustar00 components/com_newsfeeds/config.xml000066600000024231150771655450013566 0ustar00
    components/com_newsfeeds/newsfeeds.php000066600000001140150771655450014265 0ustar00authorise('core.manage', 'com_newsfeeds')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } $controller = JControllerLegacy::getInstance('Newsfeeds'); $controller->execute(JFactory::getApplication()->input->get('task')); $controller->redirect(); components/com_newsfeeds/controller.php000066600000002774150771655450014503 0ustar00input->get('view', 'newsfeeds'); $layout = $this->input->get('layout', 'default'); $id = $this->input->getInt('id'); // Check for edit form. if ($view == 'newsfeed' && $layout == 'edit' && !$this->checkEditId('com_newsfeeds.edit.newsfeed', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_newsfeeds&view=newsfeeds', false)); return false; } parent::display(); } } components/com_newsfeeds/controllers/index.html000066600000000037150771655450016140 0ustar00 components/com_newsfeeds/controllers/newsfeeds.php000066600000001416150771655450016641 0ustar00 true)) { $model = parent::getModel($name, $prefix, $config); return $model; } protected function postDeleteHook(JModelLegacy $model, $ids = null) { } } components/com_newsfeeds/controllers/newsfeed.php000066600000005565150771655450016467 0ustar00input->getInt('filter_category_id'), 'int'); $allow = null; if ($categoryId) { // If the category has been passed in the URL check it. $allow = $user->authorise('core.create', $this->option . '.category.' . $categoryId); } if ($allow === null) { // In the absence of better information, revert to the component permissions. return parent::allowAdd($data); } else { return $allow; } } /** * Method to check if you can edit a record. * * @param array $data An array of input data. * @param string $key The name of the key for the primary key. * * @return boolean * * @since 1.6 */ protected function allowEdit($data = array(), $key = 'id') { $user = JFactory::getUser(); $recordId = (int) isset($data[$key]) ? $data[$key] : 0; $categoryId = 0; if ($recordId) { $categoryId = (int) $this->getModel()->getItem($recordId)->catid; } if ($categoryId) { // The category has been set. Check the category permissions. return $user->authorise('core.edit', $this->option . '.category.' . $categoryId); } else { // Since there is no asset tracking, revert to the component permissions. return parent::allowEdit($data, $key); } } /** * Method to run batch operations. * * @param object $model The model. * * @return boolean True if successful, false otherwise and internal error is set. * * @since 2.5 */ public function batch($model = null) { JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Set the model $model = $this->getModel('Newsfeed', '', array()); // Preset the redirect $this->setRedirect(JRoute::_('index.php?option=com_newsfeeds&view=newsfeeds' . $this->getRedirectToListAppend(), false)); return parent::batch($model); } /** * Function that allows child controller access to model data after the data has been saved. * * @param JModelLegacy $model The data model object. * @param array $validData The validated data. * * @return void * * @since 3.1 */ protected function postSaveHook(JModelLegacy $model, $validData = array()) { } } components/com_newsfeeds/access.xml000066600000002547150771655450013570 0ustar00
    components/com_newsfeeds/newsfeeds.xml000066600000004447150771655450014313 0ustar00 com_newsfeeds Joomla! Project April 2006 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_NEWSFEEDS_XML_DESCRIPTION sql/install.mysql.utf8.sql sql/uninstall.mysql.utf8.sql controller.php index.html metadata.xml newsfeeds.php router.php helpers models views language/en-GB.com_newsfeeds.ini com_newsfeeds com_newsfeeds_feeds com_newsfeeds_categories access.xml config.xml controller.php index.html newsfeeds.php controllers elements helpers models tables views language/en-GB.com_newsfeeds.ini language/en-GB.com_newsfeeds.sys.ini components/com_newsfeeds/helpers/html/index.html000066600000000037150771655450016200 0ustar00 components/com_newsfeeds/helpers/html/newsfeed.php000066600000004704150771655450016521 0ustar00 $associated) { $associations[$tag] = (int) $associated->id; } // Get the associated newsfeed items $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('c.id, c.name as title') ->select('l.sef as lang_sef') ->from('#__newsfeeds as c') ->select('cat.title as category_title') ->join('LEFT', '#__categories as cat ON cat.id=c.catid') ->where('c.id IN (' . implode(',', array_values($associations)) . ')') ->join('LEFT', '#__languages as l ON c.language=l.lang_code') ->select('l.image') ->select('l.title as language_title'); $db->setQuery($query); try { $items = $db->loadObjectList('id'); } catch (RuntimeException $e) { throw new Exception($e->getMessage(), 500); } if ($items) { foreach ($items as &$item) { $text = strtoupper($item->lang_sef); $url = JRoute::_('index.php?option=com_newsfeeds&task=newsfeed.edit&id=' . (int) $item->id); $tooltipParts = array( JHtml::_('image', 'mod_languages/' . $item->image . '.gif', $item->language_title, array('title' => $item->language_title), true ), $item->title, '(' . $item->category_title . ')' ); $item->link = JHtml::_('tooltip', implode(' ', $tooltipParts), null, null, $text, $url, null, 'hasTooltip label label-association label-' . $item->lang_sef); } } $html = JLayoutHelper::render('joomla.content.associations', $items); } return $html; } } components/com_newsfeeds/helpers/index.html000066600000000037150771655450015234 0ustar00 components/com_newsfeeds/helpers/newsfeeds.php000066600000001750150771655450015736 0ustar00 components/com_newsfeeds/models/newsfeeds.php000066600000017116150771655450015562 0ustar00getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $accessId = $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', null, 'int'); $this->setState('filter.access', $accessId); $state = $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', '', 'string'); $this->setState('filter.published', $state); $categoryId = $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id', null); $this->setState('filter.category_id', $categoryId); $language = $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', ''); $this->setState('filter.language', $language); // force a language $forcedLanguage = $app->input->get('forcedLanguage'); if (!empty($forcedLanguage)) { $this->setState('filter.language', $forcedLanguage); $this->setState('filter.forcedLanguage', $forcedLanguage); } $tag = $this->getUserStateFromRequest($this->context . '.filter.tag', 'filter_tag', ''); $this->setState('filter.tag', $tag); // Load the parameters. $params = JComponentHelper::getParams('com_newsfeeds'); $this->setState('params', $params); // List state information. parent::populateState('a.name', 'asc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string A prefix for the store id. * * @return string A store id. */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.access'); $id .= ':' . $this->getState('filter.published'); $id .= ':' . $this->getState('filter.category_id'); $id .= ':' . $this->getState('filter.language'); return parent::getStoreId($id); } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); $user = JFactory::getUser(); $app = JFactory::getApplication(); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.id, a.name, a.alias, a.checked_out, a.checked_out_time, a.catid,' . ' a.numarticles, a.cache_time,' . ' a.published, a.access, a.ordering, a.language, a.publish_up, a.publish_down' ) ); $query->from($db->quoteName('#__newsfeeds') . ' AS a'); // Join over the language $query->select('l.title AS language_title') ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); // Join over the users for the checked out user. $query->select('uc.name AS editor') ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); // Join over the asset groups. $query->select('ag.title AS access_level') ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); // Join over the categories. $query->select('c.title AS category_title') ->join('LEFT', '#__categories AS c ON c.id = a.catid'); // Join over the associations. $assoc = JLanguageAssociations::isEnabled(); if ($assoc) { $query->select('COUNT(asso2.id)>1 as association') ->join('LEFT', '#__associations AS asso ON asso.id = a.id AND asso.context=' . $db->quote('com_newsfeeds.item')) ->join('LEFT', '#__associations AS asso2 ON asso2.key = asso.key') ->group('a.id'); } // Filter by access level. if ($access = $this->getState('filter.access')) { $query->where('a.access = ' . (int) $access); } // Implement View Level Access if (!$user->authorise('core.admin')) { $groups = implode(',', $user->getAuthorisedViewLevels()); $query->where('a.access IN (' . $groups . ')'); } // Filter by published state. $published = $this->getState('filter.published'); if (is_numeric($published)) { $query->where('a.published = ' . (int) $published); } elseif ($published === '') { $query->where('(a.published IN (0, 1))'); } // Filter by category. $categoryId = $this->getState('filter.category_id'); if (is_numeric($categoryId)) { $query->where('a.catid = ' . (int) $categoryId); } // Filter by search in title $search = $this->getState('filter.search'); if (!empty($search)) { if (stripos($search, 'id:') === 0) { $query->where('a.id = ' . (int) substr($search, 3)); } else { $search = $db->quote('%' . $db->escape($search, true) . '%'); $query->where('(a.name LIKE ' . $search . ' OR a.alias LIKE ' . $search . ')'); } } // Filter on the language. if ($language = $this->getState('filter.language')) { $query->where('a.language = ' . $db->quote($language)); } // Filter by a single tag. $tagId = $this->getState('filter.tag'); if (is_numeric($tagId)) { $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId) ->join( 'LEFT', $db->quoteName('#__contentitem_tag_map', 'tagmap') . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id') . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_newsfeeds.newsfeed') ); } // Add the list ordering clause. $orderCol = $this->state->get('list.ordering'); $orderDirn = $this->state->get('list.direction'); if ($orderCol == 'a.ordering' || $orderCol == 'category_title') { $orderCol = 'c.title ' . $orderDirn . ', a.ordering'; } $query->order($db->escape($orderCol . ' ' . $orderDirn)); //echo nl2br(str_replace('#__','jos_',$query)); return $query; } } components/com_newsfeeds/models/fields/modal/index.html000066600000000037150771655450017417 0ustar00 components/com_newsfeeds/models/fields/modal/newsfeed.php000066600000011465150771655450017742 0ustar00element['edit'] == 'true') ? true : false; $allowClear = ((string) $this->element['clear'] != 'false') ? true : false; // Load language JFactory::getLanguage()->load('com_newsfeeds', JPATH_ADMINISTRATOR); // Load the javascript JHtml::_('behavior.framework'); JHtml::_('behavior.modal', 'a.modal'); JHtml::_('bootstrap.tooltip'); // Build the script. $script = array(); // Select button script $script[] = ' function jSelectNewsfeed_'.$this->id.'(id, name, object) {'; $script[] = ' document.id("'.$this->id.'_id").value = id;'; $script[] = ' document.id("'.$this->id.'_name").value = name;'; if ($allowEdit) { $script[] = ' jQuery("#'.$this->id.'_edit").removeClass("hidden");'; } if ($allowClear) { $script[] = ' jQuery("#'.$this->id.'_clear").removeClass("hidden");'; } $script[] = ' SqueezeBox.close();'; $script[] = ' }'; // Clear button script static $scriptClear; if ($allowClear && !$scriptClear) { $scriptClear = true; $script[] = ' function jClearNewsfeed(id) {'; $script[] = ' document.getElementById(id + "_id").value = "";'; $script[] = ' document.getElementById(id + "_name").value = "'.htmlspecialchars(JText::_('COM_NEWSFEEDS_SELECT_A_FEED', true), ENT_COMPAT, 'UTF-8').'";'; $script[] = ' jQuery("#"+id + "_clear").addClass("hidden");'; $script[] = ' if (document.getElementById(id + "_edit")) {'; $script[] = ' jQuery("#"+id + "_edit").addClass("hidden");'; $script[] = ' }'; $script[] = ' return false;'; $script[] = ' }'; } // Add the script to the document head. JFactory::getDocument()->addScriptDeclaration(implode("\n", $script)); // Setup variables for display. $html = array(); $link = 'index.php?option=com_newsfeeds&view=newsfeeds&layout=modal&tmpl=component&function=jSelectNewsfeed_'.$this->id; if (isset($this->element['language'])) { $link .= '&forcedLanguage='.$this->element['language']; } // Get the title of the linked chart if ((int) $this->value > 0) { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('name')) ->from($db->quoteName('#__newsfeeds')) ->where($db->quoteName('id') . ' = ' . (int) $this->value); $db->setQuery($query); try { $title = $db->loadResult(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage); } } if (empty($title)) { $title = JText::_('COM_NEWSFEEDS_SELECT_A_FEED'); } $title = htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); // The active newsfeed id field. if (0 == (int) $this->value) { $value = ''; } else { $value = (int) $this->value; } // The current newsfeed display field. $html[] = ''; $html[] = ''; $html[] = ' '.JText::_('JSELECT').''; // Edit newsfeed button if ($allowEdit) { $html[] = ' ' . JText::_('JACTION_EDIT') . ''; } // Clear newsfeed button if ($allowClear) { $html[] = ''; } $html[] = ''; // class='required' for client side validation $class = ''; if ($this->required) { $class = ' class="required modal-value"'; } $html[] = ''; return implode("\n", $html); } } components/com_newsfeeds/models/fields/index.html000066600000000037150771655450016323 0ustar00 components/com_newsfeeds/models/fields/newsfeeds.php000066600000002376150771655450017032 0ustar00getQuery(true) ->select('id As value, name As text') ->from('#__newsfeeds AS a') ->order('a.name'); // Get the options. $db->setQuery($query); try { $options = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseWarning(500, $db->getMessage()); } // Merge any additional options in the XML definition. $options = array_merge(parent::getOptions(), $options); return $options; } } components/com_newsfeeds/models/forms/index.html000066600000000037150771655450016203 0ustar00 components/com_newsfeeds/models/forms/newsfeed.xml000066600000024233150771655450016534 0ustar00
    components/com_newsfeeds/models/newsfeed.php000066600000033263150771655450015400 0ustar00table->reset(); // Check that the row actually exists if (!$this->table->load($pk)) { if ($error = $this->table->getError()) { // Fatal error $this->setError($error); return false; } else { // Not fatal error $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk)); continue; } } // Alter the title & alias $data = $this->generateNewTitle($categoryId, $this->table->alias, $this->table->name); $this->table->name = $data['0']; $this->table->alias = $data['1']; // Reset the ID because we are making a copy $this->table->id = 0; // New category ID $this->table->catid = $categoryId; // TODO: Deal with ordering? //$this->table->ordering = 1; // Check the row. if (!$this->table->check()) { $this->setError($this->table->getError()); return false; } parent::createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table); // Store the row. if (!$this->table->store()) { $this->setError($this->table->getError()); return false; } // Get the new item ID $newId = $this->table->get('id'); // Add the new ID to the array $newIds[$i] = $newId; $i++; } // Clean the cache $this->cleanCache(); return $newIds; } /** * Method to test whether a record can be deleted. * * @param object A record object. * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. * @since 1.6 */ protected function canDelete($record) { if (!empty($record->id)) { if ($record->published != -2) { return; } $user = JFactory::getUser(); if (!empty($record->catid)) { return $user->authorise('core.delete', 'com_newsfeed.category.' . (int) $record->catid); } else { return parent::canDelete($record); } } } /** * Method to test whether a record can have its state changed. * * @param object A record object. * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. * @since 1.6 */ protected function canEditState($record) { $user = JFactory::getUser(); if (!empty($record->catid)) { return $user->authorise('core.edit.state', 'com_newsfeeds.category.' . (int) $record->catid); } else { return parent::canEditState($record); } } /** * Returns a Table object, always creating it. * * @param type The table type to instantiate * @param string A prefix for the table class name. Optional. * @param array Configuration array for model. Optional. * @return JTable A database object */ public function getTable($type = 'Newsfeed', $prefix = 'NewsfeedsTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Method to get the record form. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * @return JForm A JForm object on success, false on failure * @since 1.6 */ public function getForm($data = array(), $loadData = true) { // Get the form. $form = $this->loadForm('com_newsfeeds.newsfeed', 'newsfeed', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } // Determine correct permissions to check. if ($this->getState('newsfeed.id')) { // Existing record. Can only edit in selected categories. $form->setFieldAttribute('catid', 'action', 'core.edit'); } else { // New record. Can only create in selected categories. $form->setFieldAttribute('catid', 'action', 'core.create'); } // Modify the form based on access controls. if (!$this->canEditState((object) $data)) { // Disable fields for display. $form->setFieldAttribute('ordering', 'disabled', 'true'); $form->setFieldAttribute('published', 'disabled', 'true'); $form->setFieldAttribute('publish_up', 'disabled', 'true'); $form->setFieldAttribute('publish_down', 'disabled', 'true'); // Disable fields while saving. // The controller has already verified this is a record you can edit. $form->setFieldAttribute('ordering', 'filter', 'unset'); $form->setFieldAttribute('published', 'filter', 'unset'); $form->setFieldAttribute('publish_up', 'filter', 'unset'); $form->setFieldAttribute('publish_down', 'filter', 'unset'); } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * @since 1.6 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_newsfeeds.edit.newsfeed.data', array()); if (empty($data)) { $data = $this->getItem(); // Prime some default values. if ($this->getState('newsfeed.id') == 0) { $app = JFactory::getApplication(); $data->set('catid', $app->input->get('catid', $app->getUserState('com_newsfeeds.newsfeeds.filter.category_id'), 'int')); } } $this->preprocessData('com_newsfeeds.newsfeed', $data); return $data; } /** * Method to save the form data. * * @param array The form data. * * @return boolean True on success. * @since 3.0 */ public function save($data) { $app = JFactory::getApplication(); // Alter the title for save as copy if ($app->input->get('task') == 'save2copy') { list($name, $alias) = $this->generateNewTitle($data['catid'], $data['alias'], $data['name']); $data['name'] = $name; $data['alias'] = $alias; $data['published'] = 0; } if (parent::save($data)) { $assoc = JLanguageAssociations::isEnabled(); if ($assoc) { $id = (int) $this->getState($this->getName() . '.id'); $item = $this->getItem($id); // Adding self to the association $associations = $data['associations']; foreach ($associations as $tag => $id) { if (empty($id)) { unset($associations[$tag]); } } // Detecting all item menus $all_language = $item->language == '*'; if ($all_language && !empty($associations)) { JError::raiseNotice(403, JText::_('COM_NEWSFEEDS_ERROR_ALL_LANGUAGE_ASSOCIATED')); } $associations[$item->language] = $item->id; // Deleting old association for these items $db = JFactory::getDbo(); $query = $db->getQuery(true) ->delete('#__associations') ->where($db->quoteName('context') . ' = ' . $db->quote('com_newsfeeds.item')) ->where($db->quoteName('id') . ' IN (' . implode(',', $associations) . ')'); $db->setQuery($query); $db->execute(); if ($error = $db->getErrorMsg()) { $this->setError($error); return false; } if (!$all_language && count($associations)) { // Adding new association for these items $key = md5(json_encode($associations)); $query->clear() ->insert('#__associations'); foreach ($associations as $id) { $query->values($id . ',' . $db->quote('com_newsfeeds.item') . ',' . $db->quote($key)); } $db->setQuery($query); $db->execute(); if ($error = $db->getErrorMsg()) { $this->setError($error); return false; } } } return true; } return false; } /** * Method to get a single record. * * @param integer The id of the primary key. * * @return mixed Object on success, false on failure. * @since 1.6 */ public function getItem($pk = null) { if ($item = parent::getItem($pk)) { // Convert the params field to an array. $registry = new JRegistry; $registry->loadString($item->metadata); $item->metadata = $registry->toArray(); // Convert the images field to an array. $registry = new JRegistry; $registry->loadString($item->images); $item->images = $registry->toArray(); } // Load associated newsfeeds items $app = JFactory::getApplication(); $assoc = JLanguageAssociations::isEnabled(); if ($assoc) { $item->associations = array(); if ($item->id != null) { $associations = JLanguageAssociations::getAssociations('com_newsfeeds', '#__newsfeeds', 'com_newsfeeds.item', $item->id); foreach ($associations as $tag => $association) { $item->associations[$tag] = $association->id; } } } if (!empty($item->id)) { $item->tags = new JHelperTags; $item->tags->getTagIds($item->id, 'com_newsfeeds.newsfeed'); $item->metadata['tags'] = $item->tags; } return $item; } /** * Prepare and sanitise the table prior to saving. */ protected function prepareTable($table) { $date = JFactory::getDate(); $user = JFactory::getUser(); $table->name = htmlspecialchars_decode($table->name, ENT_QUOTES); $table->alias = JApplication::stringURLSafe($table->alias); if (empty($table->alias)) { $table->alias = JApplication::stringURLSafe($table->name); } if (empty($table->id)) { // Set the values $table->created = $date->toSql(); // Set ordering to the last item if not set if (empty($table->ordering)) { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('MAX(ordering)') ->from($db->quoteName('#__newsfeeds')); $db->setQuery($query); $max = $db->loadResult(); $table->ordering = $max + 1; } } else { // Set the values $table->modified = $date->toSql(); $table->modified_by = $user->get('id'); } // Increment the content version number. $table->version++; } /** * Method to change the published state of one or more records. * * @param array $pks A list of the primary keys to change. * @param integer $value The value of the published state. * * @return boolean True on success. * @since 1.6 */ public function publish(&$pks, $value = 1) { $result = parent::publish($pks, $value); // Clean extra cache for newsfeeds $this->cleanCache('feed_parser'); return $result; } /** * A protected method to get a set of ordering conditions. * * @param object A record object. * @return array An array of conditions to add to add to ordering queries. * @since 1.6 */ protected function getReorderConditions($table) { $condition = array(); $condition[] = 'catid = ' . (int) $table->catid; return $condition; } protected function preprocessForm(JForm $form, $data, $group = 'content') { // Association newsfeeds items $app = JFactory::getApplication(); $assoc = JLanguageAssociations::isEnabled(); if ($assoc) { $languages = JLanguageHelper::getLanguages('lang_code'); // force to array (perhaps move to $this->loadFormData()) $data = (array) $data; $addform = new SimpleXMLElement('
    '); $fields = $addform->addChild('fields'); $fields->addAttribute('name', 'associations'); $fieldset = $fields->addChild('fieldset'); $fieldset->addAttribute('name', 'item_associations'); $fieldset->addAttribute('description', 'COM_NEWSFEEDS_ITEM_ASSOCIATIONS_FIELDSET_DESC'); $add = false; foreach ($languages as $tag => $language) { if (empty($data['language']) || $tag != $data['language']) { $add = true; $field = $fieldset->addChild('field'); $field->addAttribute('name', $tag); $field->addAttribute('type', 'modal_newsfeed'); $field->addAttribute('language', $tag); $field->addAttribute('label', $language->title); $field->addAttribute('translate_label', 'false'); $field->addAttribute('edit', 'true'); $field->addAttribute('clear', 'true'); } } if ($add) { $form->load($addform, false); } } parent::preprocessForm($form, $data, $group); } /** * Method to change the title & alias. * * @param integer $parent_id The id of the parent. * @param string $alias The alias. * @param string $title The title. * * @return array Contains the modified title and alias. * * @since 3.1 */ protected function generateNewTitle($category_id, $alias, $name) { // Alter the title & alias $table = $this->getTable(); while ($table->load(array('alias' => $alias, 'catid' => $category_id))) { if ($name == $table->name) { $name = JString::increment($name); } $alias = JString::increment($alias, 'dash'); } return array($name, $alias); } } components/index.html000066600000000037150771655450010751 0ustar00 components/com_categories/tables/index.html000066600000000037150771655450015206 0ustar00 components/com_categories/tables/category.php000066600000001644150771655450015544 0ustar00 components/com_categories/views/categories/view.html.php000066600000016133150771655450017653 0ustar00state = $this->get('State'); $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->assoc = $this->get('Assoc'); $this->filterForm = $this->get('FilterForm'); $this->activeFilters = $this->get('ActiveFilters'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } // Preprocess the list of items to find ordering divisions. foreach ($this->items as &$item) { $this->ordering[$item->parent_id][] = $item->id; } // Levels filter. $options = array(); $options[] = JHtml::_('select.option', '1', JText::_('J1')); $options[] = JHtml::_('select.option', '2', JText::_('J2')); $options[] = JHtml::_('select.option', '3', JText::_('J3')); $options[] = JHtml::_('select.option', '4', JText::_('J4')); $options[] = JHtml::_('select.option', '5', JText::_('J5')); $options[] = JHtml::_('select.option', '6', JText::_('J6')); $options[] = JHtml::_('select.option', '7', JText::_('J7')); $options[] = JHtml::_('select.option', '8', JText::_('J8')); $options[] = JHtml::_('select.option', '9', JText::_('J9')); $options[] = JHtml::_('select.option', '10', JText::_('J10')); $this->f_levels = $options; $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { $categoryId = $this->state->get('filter.category_id'); $component = $this->state->get('filter.component'); $section = $this->state->get('filter.section'); $canDo = JHelperContent::getActions($component, 'category', $categoryId); $user = JFactory::getUser(); $extension = JFactory::getApplication()->input->get('extension', '', 'word'); // Get the toolbar object instance $bar = JToolBar::getInstance('toolbar'); // Avoid nonsense situation. if ($component == 'com_categories') { return; } // Need to load the menu language file as mod_menu hasn't been loaded yet. $lang = JFactory::getLanguage(); $lang->load($component, JPATH_BASE, null, false, true) || $lang->load($component, JPATH_ADMINISTRATOR . '/components/' . $component, null, false, true); // Load the category helper. require_once JPATH_COMPONENT . '/helpers/categories.php'; // If a component categories title string is present, let's use it. if ($lang->hasKey($component_title_key = strtoupper($component . ($section ? "_$section" : '')) . '_CATEGORIES_TITLE')) { $title = JText::_($component_title_key); } elseif ($lang->hasKey($component_section_key = strtoupper($component . ($section ? "_$section" : '')))) // Else if the component section string exits, let's use it { $title = JText::sprintf('COM_CATEGORIES_CATEGORIES_TITLE', $this->escape(JText::_($component_section_key))); } else // Else use the base title { $title = JText::_('COM_CATEGORIES_CATEGORIES_BASE_TITLE'); } // Load specific css component JHtml::_('stylesheet', $component . '/administrator/categories.css', array(), true); // Prepare the toolbar. JToolbarHelper::title($title, 'folder categories ' . substr($component, 4) . ($section ? "-$section" : '') . '-categories'); if ($canDo->get('core.create') || (count($user->getAuthorisedCategories($component, 'core.create'))) > 0) { JToolbarHelper::addNew('category.add'); } if ($canDo->get('core.edit') || $canDo->get('core.edit.own')) { JToolbarHelper::editList('category.edit'); } if ($canDo->get('core.edit.state')) { JToolbarHelper::publish('categories.publish', 'JTOOLBAR_PUBLISH', true); JToolbarHelper::unpublish('categories.unpublish', 'JTOOLBAR_UNPUBLISH', true); JToolbarHelper::archiveList('categories.archive'); } if (JFactory::getUser()->authorise('core.admin')) { JToolbarHelper::checkin('categories.checkin'); } if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete', $component)) { JToolbarHelper::deleteList('', 'categories.delete', 'JTOOLBAR_EMPTY_TRASH'); } elseif ($canDo->get('core.edit.state')) { JToolbarHelper::trash('categories.trash'); } // Add a batch button if ($user->authorise('core.create', $extension) & $user->authorise('core.edit', $extension) && $user->authorise('core.edit.state', $extension)) { JHtml::_('bootstrap.modal', 'collapseModal'); $title = JText::_('JTOOLBAR_BATCH'); // Instantiate a new JLayoutFile instance and render the batch button $layout = new JLayoutFile('joomla.toolbar.batch'); $dhtml = $layout->render(array('title' => $title)); $bar->appendButton('Custom', $dhtml, 'batch'); } if ($canDo->get('core.admin')) { JToolbarHelper::custom('categories.rebuild', 'refresh.png', 'refresh_f2.png', 'JTOOLBAR_REBUILD', false); JToolbarHelper::preferences($component); } // Compute the ref_key if it does exist in the component if (!$lang->hasKey($ref_key = strtoupper($component . ($section ? "_$section" : '')) . '_CATEGORIES_HELP_KEY')) { $ref_key = 'JHELP_COMPONENTS_' . strtoupper(substr($component, 4) . ($section ? "_$section" : '')) . '_CATEGORIES'; } /* * Get help for the categories view for the component by * -remotely searching in a language defined dedicated URL: *component*_HELP_URL * -locally searching in a component help file if helpURL param exists in the component and is set to '' * -remotely searching in a component URL if helpURL param exists in the component and is NOT set to '' */ if ($lang->hasKey($lang_help_url = strtoupper($component) . '_HELP_URL')) { $debug = $lang->setDebug(false); $url = JText::_($lang_help_url); $lang->setDebug($debug); } else { $url = null; } JToolbarHelper::help($ref_key, JComponentHelper::getParams($component)->exists('helpURL'), $url); } /** * Returns an array of fields the table can be sorted by * * @return array Array containing the field name to sort by as the key and display text as value * * @since 3.0 */ protected function getSortFields() { return array( 'a.lft' => JText::_('JGRID_HEADING_ORDERING'), 'a.published' => JText::_('JSTATUS'), 'a.title' => JText::_('JGLOBAL_TITLE'), 'a.access' => JText::_('JGRID_HEADING_ACCESS'), 'language' => JText::_('JGRID_HEADING_LANGUAGE'), 'a.id' => JText::_('JGRID_HEADING_ID') ); } } components/com_categories/views/categories/tmpl/default.php000066600000020460150771655450020334 0ustar00get('id'); $extension = $this->escape($this->state->get('filter.extension')); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $ordering = ($listOrder == 'a.lft'); $saveOrder = ($listOrder == 'a.lft' && strtolower($listDirn) == 'asc'); if ($saveOrder) { $saveOrderingUrl = 'index.php?option=com_categories&task=categories.saveOrderAjax&tmpl=component'; JHtml::_('sortablelist.sortable', 'categoryList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true); } $sortFields = $this->getSortFields(); ?>
    sidebar; ?>
    $this)); ?> items)) : ?>
    assoc) : ?> items as $i => $item) : ?> id, $this->ordering[$item->parent_id]); $canEdit = $user->authorise('core.edit', $extension . '.category.' . $item->id); $canCheckin = $user->authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; $canEditOwn = $user->authorise('core.edit.own', $extension . '.category.' . $item->id) && $item->created_user_id == $userId; $canChange = $user->authorise('core.edit.state', $extension . '.category.' . $item->id) && $canCheckin; // Get the parents of item for sorting if ($item->level > 1) { $parentsStr = ""; $_currentParentId = $item->parent_id; $parentsStr = " " . $_currentParentId; for ($i2 = 0; $i2 < $item->level; $i2++) { foreach ($this->ordering as $k => $v) { $v = implode("-", $v); $v = "-" . $v . "-"; if (strpos($v, "-" . $_currentParentId . "-") !== false) { $parentsStr .= " " . $k; $_currentParentId = $k; break; } } } } else { $parentsStr = ""; } ?> assoc) : ?>
    state->get('list.direction'), $this->state->get('list.ordering')); ?>
    pagination->getListFooter(); ?>
    id); ?> published, $i, 'categories.', $canChange); ?> —', $item->level - 1) ?> checked_out) : ?> editor, $item->checked_out_time, 'categories.', $canCheckin); ?> escape($item->title); ?> escape($item->title); ?> note)) : ?> escape($item->alias)); ?> escape($item->alias), $this->escape($item->note)); ?> escape($item->access_level); ?> association): ?> id, $extension); ?> language == '*') : ?> language_title ? $this->escape($item->language_title) : JText::_('JUNDEFINED'); ?> id; ?>
    loadTemplate('batch'); ?>
    components/com_categories/views/categories/tmpl/index.html000066600000000037150771655450020172 0ustar00 components/com_categories/views/categories/tmpl/default_batch.php000066600000005146150771655450021501 0ustar00state->get('filter.published'); $extension = $this->escape($this->state->get('filter.extension')); ?> components/com_categories/views/categories/tmpl/modal.php000066600000014624150771655450020011 0ustar00isSite()) { JSession::checkToken('get') or die(JText::_('JINVALID_TOKEN')); } require_once JPATH_ROOT . '/components/com_content/helpers/route.php'; // Include the component HTML helpers. JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); JHtml::_('bootstrap.tooltip'); $extension = $this->escape($this->state->get('filter.extension')); $function = $app->input->getCmd('function', 'jSelectCategory'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?>

    state->get('filter.forcedLanguage')) : ?>
    items as $i => $item) : ?> language && JLanguageMultilang::isEnabled()) { $tag = strlen($item->language); if ($tag == 5) { $lang = substr($item->language, 0, 2); } elseif ($tag == 6) { $lang = substr($item->language, 0, 3); } else { $lang = ""; } } elseif (!JLanguageMultilang::isEnabled()) { $lang = ""; } ?>
    state->get('list.direction'), $this->state->get('list.ordering') ); ?>
    pagination->getListFooter(); ?>
    —', $item->level - 1) ?> escape($item->title); ?> escape($item->access_level); ?> language == '*'): ?> language_title ? $this->escape($item->language_title) : JText::_('JUNDEFINED'); ?> id; ?>
    components/com_categories/views/categories/index.html000066600000000037150771655450017216 0ustar00 components/com_categories/views/category/view.html.php000066600000013616150771655450017346 0ustar00form = $this->get('Form'); $this->item = $this->get('Item'); $this->state = $this->get('State'); $this->canDo = JHelperContent::getActions($this->state->get('category.extension'), 'category', $this->item->id); $this->assoc = $this->get('Assoc'); $input = JFactory::getApplication()->input; // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } // Check for tag type $this->checkTags = JHelperTags::getTypes('objectList', array($this->state->get('category.extension') . '.category'), true); $input->set('hidemainmenu', true); if ($this->getLayout() == 'modal') { $this->form->setFieldAttribute('language', 'readonly', 'true'); $this->form->setFieldAttribute('parent_id', 'readonly', 'true'); } $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { $input = JFactory::getApplication()->input; $extension = $input->get('extension'); $user = JFactory::getUser(); $userId = $user->get('id'); $isNew = ($this->item->id == 0); $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); // Check to see if the type exists $ucmType = new JUcmType; $this->typeId = $ucmType->getTypeId($extension . '.category'); // Avoid nonsense situation. if ($extension == 'com_categories') { return; } // The extension can be in the form com_foo.section $parts = explode('.', $extension); $component = $parts[0]; $section = (count($parts) > 1) ? $parts[1] : null; $componentParams = JComponentHelper::getParams($component); // Need to load the menu language file as mod_menu hasn't been loaded yet. $lang = JFactory::getLanguage(); $lang->load($component, JPATH_BASE, null, false, true) || $lang->load($component, JPATH_ADMINISTRATOR . '/components/' . $component, null, false, true); // Load the category helper. require_once JPATH_COMPONENT . '/helpers/categories.php'; // Get the results for each action. $canDo = $this->canDo; // If a component categories title string is present, let's use it. if ($lang->hasKey($component_title_key = $component . ($section ? "_$section" : '') . '_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE')) { $title = JText::_($component_title_key); } // Else if the component section string exits, let's use it elseif ($lang->hasKey($component_section_key = $component . ($section ? "_$section" : ''))) { $title = JText::sprintf('COM_CATEGORIES_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE', $this->escape(JText::_($component_section_key))); } // Else use the base title else { $title = JText::_('COM_CATEGORIES_CATEGORY_BASE_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE'); } // Load specific css component JHtml::_('stylesheet', $component . '/administrator/categories.css', array(), true); // Prepare the toolbar. JToolbarHelper::title($title, 'folder category-' . ($isNew ? 'add' : 'edit') . ' ' . substr($component, 4) . ($section ? "-$section" : '') . '-category-' . ($isNew ? 'add' : 'edit')); // For new records, check the create permission. if ($isNew && (count($user->getAuthorisedCategories($component, 'core.create')) > 0)) { JToolbarHelper::apply('category.apply'); JToolbarHelper::save('category.save'); JToolbarHelper::save2new('category.save2new'); } // If not checked out, can save the item. elseif (!$checkedOut && ($canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_user_id == $userId))) { JToolbarHelper::apply('category.apply'); JToolbarHelper::save('category.save'); if ($canDo->get('core.create')) { JToolbarHelper::save2new('category.save2new'); } } // If an existing item, can save to a copy. if (!$isNew && $canDo->get('core.create')) { JToolbarHelper::save2copy('category.save2copy'); } if (empty($this->item->id)) { JToolbarHelper::cancel('category.cancel'); } else { if ($componentParams->get('save_history', 0) && $user->authorise('core.edit')) { $typeAlias = $extension . '.category'; JToolbarHelper::versions($typeAlias, $this->item->id); } JToolbarHelper::cancel('category.cancel', 'JTOOLBAR_CLOSE'); } JToolbarHelper::divider(); // Compute the ref_key if it does exist in the component if (!$lang->hasKey($ref_key = strtoupper($component . ($section ? "_$section" : '')) . '_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT') . '_HELP_KEY')) { $ref_key = 'JHELP_COMPONENTS_' . strtoupper(substr($component, 4) . ($section ? "_$section" : '')) . '_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT'); } // Get help for the category/section view for the component by // -remotely searching in a language defined dedicated URL: *component*_HELP_URL // -locally searching in a component help file if helpURL param exists in the component and is set to '' // -remotely searching in a component URL if helpURL param exists in the component and is NOT set to '' if ($lang->hasKey($lang_help_url = strtoupper($component) . '_HELP_URL')) { $debug = $lang->setDebug(false); $url = JText::_($lang_help_url); $lang->setDebug($debug); } else { $url = null; } JToolbarHelper::help($ref_key, $componentParams->exists('helpURL'), $url, $component); } } components/com_categories/views/category/tmpl/modal_associations.php000066600000000530150771655450022247 0ustar00input; $assoc = JLanguageAssociations::isEnabled(); ?>
    'general')); ?>
    form->getLabel('description'); ?> form->getInput('description'); ?>
    loadTemplate('associations'); ?> canDo->get('core.admin')) : ?> form->getInput('rules'); ?> form->getInput('extension'); ?>
    components/com_categories/views/category/tmpl/edit_metadata.php000066600000000524150771655450021164 0ustar00 components/com_categories/views/category/tmpl/modal_options.php000066600000002744150771655450021254 0ustar00 'collapse0')); $fieldSets = $this->form->getFieldsets('params'); $i = 0; ?> $fieldSet) : ?> label) ? $fieldSet->label : 'COM_CATEGORIES_' . $name . '_FIELDSET_LABEL'; echo JHtml::_('bootstrap.addSlide', 'categoryOptions', JText::_($label), 'collapse' . $i++); if (isset($fieldSet->description) && trim($fieldSet->description)) { echo '

    ' . $this->escape(JText::_($fieldSet->description)) . '

    '; } ?> form->getFieldset($name) as $field) : ?>
    label; ?>
    input; ?>
    form->getLabel('note'); ?>
    form->getInput('note'); ?>
    components/com_categories/views/category/tmpl/modal_extrafields.php000066600000000430150771655450022061 0ustar00input; $assoc = JLanguageAssociations::isEnabled(); ?>

    'general')); ?>
    form->getLabel('description'); ?> form->getInput('description'); ?>
    canDo->get('core.admin')) : ?> form->getInput('rules'); ?> form->getInput('extension'); ?>
    components/com_categories/views/category/tmpl/modal_metadata.php000066600000000524150771655450021333 0ustar00 components/com_categories/index.html000066600000000037150771655450013734 0ustar00 components/com_categories/categories.php000066600000001454150771655450014601 0ustar00input; if (!JFactory::getUser()->authorise('core.manage', $input->get('extension'))) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } JLoader::register('JHtmlCategoriesAdministrator', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/html/categoriesadministrator.php'); $task = $input->get('task'); $controller = JControllerLegacy::getInstance('Categories'); $controller->execute($input->get('task')); $controller->redirect(); components/com_categories/controller.php000066600000005471150771655450014642 0ustar00extension)) { $this->extension = $this->input->get('extension', 'com_content'); } } /** * Method to display a view. * * @param boolean $cachable If true, the view output will be cached * @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()}. * * @return JController This object to support chaining. * * @since 1.5 */ public function display($cachable = false, $urlparams = false) { // Get the document object. $document = JFactory::getDocument(); // Set the default view name and format from the Request. $vName = $this->input->get('view', 'categories'); $vFormat = $document->getType(); $lName = $this->input->get('layout', 'default', 'string'); $id = $this->input->getInt('id'); // Check for edit form. if ($vName == 'category' && $lName == 'edit' && !$this->checkEditId('com_categories.edit.category', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_categories&view=categories&extension=' . $this->extension, false)); return false; } // Get and render the view. if ($view = $this->getView($vName, $vFormat)) { // Get the model for the view. $model = $this->getModel($vName, 'CategoriesModel', array('name' => $vName . '.' . substr($this->extension, 4))); // Push the model into the view (as default). $view->setModel($model, true); $view->setLayout($lName); // Push document object into the view. $view->document = $document; // Load the submenu. require_once JPATH_COMPONENT . '/helpers/categories.php'; CategoriesHelper::addSubmenu($model->getState('filter.extension')); $view->display(); } return $this; } } components/com_categories/controllers/index.html000066600000000037150771655450016302 0ustar00 components/com_categories/controllers/categories.php000066600000006667150771655450017162 0ustar00 true)) { $model = parent::getModel($name, $prefix, $config); return $model; } /** * Rebuild the nested set tree. * * @return bool False on failure or error, true on success. * * @since 1.6 */ public function rebuild() { JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); $extension = $this->input->get('extension'); $this->setRedirect(JRoute::_('index.php?option=com_categories&view=categories&extension=' . $extension, false)); $model = $this->getModel(); if ($model->rebuild()) { // Rebuild succeeded. $this->setMessage(JText::_('COM_CATEGORIES_REBUILD_SUCCESS')); return true; } else { // Rebuild failed. $this->setMessage(JText::_('COM_CATEGORIES_REBUILD_FAILURE')); return false; } } /** * Save the manual order inputs from the categories list page. * * @return void * * @since 1.6 * @see JControllerAdmin::saveorder() * @deprecated 4.0 */ public function saveorder() { JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); JLog::add('CategoriesControllerCategories::saveorder() is deprecated. Function will be removed in 4.0', JLog::WARNING, 'deprecated'); // Get the arrays from the Request $order = $this->input->post->get('order', null, 'array'); $originalOrder = explode(',', $this->input->getString('original_order_values')); // Make sure something has changed if (!($order === $originalOrder)) { parent::saveorder(); } else { // Nothing to reorder $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); return true; } } /** * Deletes and returns correctly. * * @return void * * @since 3.1.2 */ public function delete() { JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Get items to remove from the request. $cid = $this->input->get('cid', array(), 'array'); $extension = $this->input->getCmd('extension', null); if (!is_array($cid) || count($cid) < 1) { JError::raiseWarning(500, JText::_($this->text_prefix . '_NO_ITEM_SELECTED')); } else { // Get the model. $model = $this->getModel(); // Make sure the item ids are integers jimport('joomla.utilities.arrayhelper'); JArrayHelper::toInteger($cid); // Remove the items. if ($model->delete($cid)) { $this->setMessage(JText::plural($this->text_prefix . '_N_ITEMS_DELETED', count($cid))); } else { $this->setMessage($model->getError()); } } $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&extension=' . $extension, false)); } } components/com_categories/controllers/category.php000066600000011446150771655450016641 0ustar00extension)) { $this->extension = $this->input->get('extension', 'com_content'); } } /** * Method to check if you can add a new record. * * @param array $data An array of input data. * * @return boolean * * @since 1.6 */ protected function allowAdd($data = array()) { $user = JFactory::getUser(); return ($user->authorise('core.create', $this->extension) || count($user->getAuthorisedCategories($this->extension, 'core.create'))); } /** * Method to check if you can edit a record. * * @param array $data An array of input data. * @param string $key The name of the key for the primary key. * * @return boolean * * @since 1.6 */ protected function allowEdit($data = array(), $key = 'parent_id') { $recordId = (int) isset($data[$key]) ? $data[$key] : 0; $user = JFactory::getUser(); $userId = $user->get('id'); // Check general edit permission first. if ($user->authorise('core.edit', $this->extension)) { return true; } // Check specific edit permission. if ($user->authorise('core.edit', $this->extension . '.category.' . $recordId)) { return true; } // Fallback on edit.own. // First test if the permission is available. if ($user->authorise('core.edit.own', $this->extension . '.category.' . $recordId) || $user->authorise('core.edit.own', $this->extension)) { // Now test the owner is the user. $ownerId = (int) isset($data['created_user_id']) ? $data['created_user_id'] : 0; if (empty($ownerId) && $recordId) { // Need to do a lookup from the model. $record = $this->getModel()->getItem($recordId); if (empty($record)) { return false; } $ownerId = $record->created_user_id; } // If the owner matches 'me' then do the test. if ($ownerId == $userId) { return true; } } return false; } /** * Method to run batch operations. * * @param object $model The model. * * @return boolean True if successful, false otherwise and internal error is set. * * @since 1.6 */ public function batch($model = null) { JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Set the model $model = $this->getModel('Category'); // Preset the redirect $this->setRedirect('index.php?option=com_categories&view=categories&extension=' . $this->extension); return parent::batch($model); } /** * Gets the URL arguments to append to an item redirect. * * @param integer $recordId The primary key id for the item. * @param string $urlVar The name of the URL variable for the id. * * @return string The arguments to append to the redirect URL. * * @since 1.6 */ protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') { $append = parent::getRedirectToItemAppend($recordId); $append .= '&extension=' . $this->extension; return $append; } /** * Gets the URL arguments to append to a list redirect. * * @return string The arguments to append to the redirect URL. * * @since 1.6 */ protected function getRedirectToListAppend() { $append = parent::getRedirectToListAppend(); $append .= '&extension=' . $this->extension; return $append; } /** * Function that allows child controller access to model data after the data has been saved. * * @param JModelLegacy $model The data model object. * @param array $validData The validated data. * * @return void * * @since 3.1 */ protected function postSaveHook(JModelLegacy $model, $validData = array()) { $item = $model->getItem(); if (isset($item->params) && is_array($item->params)) { $registry = new JRegistry; $registry->loadArray($item->params); $item->params = (string) $registry; } if (isset($item->metadata) && is_array($item->metadata)) { $registry = new JRegistry; $registry->loadArray($item->metadata); $item->metadata = (string) $registry; } return; } } components/com_categories/categories.xml000066600000002047150771655450014611 0ustar00 com_categories Joomla! Project December 2007 (C) 2005 - 2014 Open Source Matters. All rights reserved. http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL admin@joomla.org www.joomla.org 3.0.0 COM_CATEGORIES_XML_DESCRIPTION categories.php config.xml controller.php index.html controllers helpers models views language/en-GB.com_categories.ini language/en-GB.com_categories.sys.ini components/com_categories/helpers/association.php000066600000003071150771655450016427 0ustar00 $item) { if (class_exists($helperClassname) && is_callable(array($helperClassname, 'getCategoryRoute'))) { $return[$tag] = $helperClassname::getCategoryRoute($item, $tag); } else { $return[$tag] = 'index.php?option=' . $extension . '&view=category&id=' . $item; } } } return $return; } } components/com_categories/helpers/html/index.html000066600000000037150771655450016342 0ustar00 components/com_categories/helpers/html/categoriesadministrator.php000066600000004500150771655450022003 0ustar00getQuery(true) ->select('c.id, c.title') ->select('l.sef as lang_sef') ->from('#__categories as c') ->where('c.id IN (' . implode(',', array_values($associations)) . ')') ->join('LEFT', '#__languages as l ON c.language=l.lang_code') ->select('l.image') ->select('l.title as language_title'); $db->setQuery($query); try { $items = $db->loadObjectList('id'); } catch (RuntimeException $e) { throw new Exception($e->getMessage(), 500); } if ($items) { foreach ($items as &$item) { $text = strtoupper($item->lang_sef); $url = JRoute::_('index.php?option=com_categories&task=category.edit&id=' . (int) $item->id . '&extension=' . $extension); $tooltipParts = array( JHtml::_( 'image', 'mod_languages/' . $item->image . '.gif', $item->language_title, array('title' => $item->language_title), true ), $item->title ); $item->link = JHtml::_('tooltip', implode(' ', $tooltipParts), null, null, $text, $url, null, 'hasTooltip label label-association label-' . $item->lang_sef); } } $html = JLayoutHelper::render('joomla.content.associations', $items); } return $html; } } components/com_categories/helpers/index.html000066600000000037150771655450015376 0ustar00 components/com_categories/helpers/categories.php000066600000006742150771655450016250 0ustar00 1) { $section = $parts[1]; } // Try to find the component helper. $eName = str_replace('com_', '', $component); $file = JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/helpers/' . $eName . '.php'); if (file_exists($file)) { require_once $file; $prefix = ucfirst(str_replace('com_', '', $component)); $cName = $prefix . 'Helper'; if (class_exists($cName)) { if (is_callable(array($cName, 'addSubmenu'))) { $lang = JFactory::getLanguage(); // Loading language file from the administrator/language directory then // loading language file from the administrator/components/*extension*/language directory $lang->load($component, JPATH_BASE, null, false, true) || $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component), null, false, true); call_user_func(array($cName, 'addSubmenu'), 'categories' . (isset($section) ? '.' . $section : '')); } } } } /** * Gets a list of the actions that can be performed. * * @param string $extension The extension. * @param integer $categoryId The category ID. * * @return JObject * * @since 1.6 * @deprecated 3.2 Use JHelperContent::getActions() instead */ public static function getActions($extension, $categoryId = 0) { // Log usage of deprecated function JLog::add(__METHOD__ . '() is deprecated, use JHelperContent::getActions() with new arguments order instead.', JLog::WARNING, 'deprecated'); // Get list of actions $result = JHelperContent::getActions($extension, 'category', $categoryId); return $result; } public static function getAssociations($pk, $extension = 'com_content') { $associations = array(); $db = JFactory::getDbo(); $query = $db->getQuery(true) ->from('#__categories as c') ->join('INNER', '#__associations as a ON a.id = c.id AND a.context=' . $db->quote('com_categories.item')) ->join('INNER', '#__associations as a2 ON a.key = a2.key') ->join('INNER', '#__categories as c2 ON a2.id = c2.id AND c2.extension = ' . $db->quote($extension)) ->where('c.id =' . (int) $pk) ->where('c.extension = ' . $db->quote($extension)); $select = array( 'c2.language', $query->concatenate(array('c2.id', 'c2.alias'), ':') . ' AS id' ); $query->select($select); $db->setQuery($query); $contentitems = $db->loadObjectList('language'); // Check for a database error. if ($error = $db->getErrorMsg()) { JError::raiseWarning(500, $error); return false; } foreach ($contentitems as $tag => $item) { // Do not return itself as result if ((int) $item->id != $pk) { $associations[$tag] = $item->id; } } return $associations; } } components/com_categories/models/index.html000066600000000037150771655450015217 0ustar00 components/com_categories/models/fields/modal/index.html000066600000000037150771655450017561 0ustar00 components/com_categories/models/fields/modal/category.php000066600000012037150771655450020115 0ustar00element['extension'] ? (string) $this->element['extension'] : (string) JFactory::getApplication()->input->get('extension', 'com_content'); $allowEdit = ((string) $this->element['edit'] == 'true') ? true : false; $allowClear = ((string) $this->element['clear'] != 'false') ? true : false; // Load language JFactory::getLanguage()->load('com_categories', JPATH_ADMINISTRATOR); // Load the modal behavior script. JHtml::_('behavior.modal', 'a.modal'); // Build the script. $script = array(); // Select button script $script[] = ' function jSelectCategory_' . $this->id . '(id, title, object) {'; $script[] = ' document.getElementById("' . $this->id . '_id").value = id;'; $script[] = ' document.getElementById("' . $this->id . '_name").value = title;'; if ($allowEdit) { $script[] = ' jQuery("#' . $this->id . '_edit").removeClass("hidden");'; } if ($allowClear) { $script[] = ' jQuery("#' . $this->id . '_clear").removeClass("hidden");'; } $script[] = ' SqueezeBox.close();'; $script[] = ' }'; // Clear button script static $scriptClear; if ($allowClear && !$scriptClear) { $scriptClear = true; $script[] = ' function jClearCategory(id) {'; $script[] = ' document.getElementById(id + "_id").value = "";'; $script[] = ' document.getElementById(id + "_name").value = "' . htmlspecialchars(JText::_('COM_CATEGORIES_SELECT_A_CATEGORY', true), ENT_COMPAT, 'UTF-8') . '";'; $script[] = ' jQuery("#"+id + "_clear").addClass("hidden");'; $script[] = ' if (document.getElementById(id + "_edit")) {'; $script[] = ' jQuery("#"+id + "_edit").addClass("hidden");'; $script[] = ' }'; $script[] = ' return false;'; $script[] = ' }'; } // Add the script to the document head. JFactory::getDocument()->addScriptDeclaration(implode("\n", $script)); // Setup variables for display. $html = array(); $link = 'index.php?option=com_categories&view=categories&layout=modal&tmpl=component&extension=' . $extension . '&function=jSelectCategory_' . $this->id; if (isset($this->element['language'])) { $link .= '&forcedLanguage=' . $this->element['language']; } if ((int) $this->value > 0) { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('title')) ->from($db->quoteName('#__categories')) ->where($db->quoteName('id') . ' = ' . (int) $this->value); $db->setQuery($query); try { $title = $db->loadResult(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage()); } } if (empty($title)) { $title = JText::_('COM_CATEGORIES_SELECT_A_CATEGORY'); } $title = htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); // The active category id field. if (0 == (int) $this->value) { $value = ''; } else { $value = (int) $this->value; } // The current category display field. $html[] = ''; $html[] = ''; $html[] = ' ' . JText::_('JSELECT') . ''; // Edit category button if ($allowEdit) { $html[] = ' ' . JText::_('JACTION_EDIT') . ''; } // Clear category button if ($allowClear) { $html[] = ''; } $html[] = ''; // class='required' for client side validation $class = ''; if ($this->required) { $class = ' class="required modal-value"'; } $html[] = ''; return implode("\n", $html); } } components/com_categories/models/fields/categoryedit.php000066600000016117150771655450017672 0ustar00element['published'] ? $this->element['published'] : array(0, 1); $name = (string) $this->element['name']; // Let's get the id for the current item, either category or content item. $jinput = JFactory::getApplication()->input; // Load the category options for a given extension. // For categories the old category is the category id or 0 for new category. if ($this->element['parent'] || $jinput->get('option') == 'com_categories') { $oldCat = $jinput->get('id', 0); $oldParent = $this->form->getValue($name, 0); $extension = $this->element['extension'] ? (string) $this->element['extension'] : (string) $jinput->get('extension', 'com_content'); } else // For items the old category is the category they are in when opened or 0 if new. { $oldCat = $this->form->getValue($name, 0); $extension = $this->element['extension'] ? (string) $this->element['extension'] : (string) $jinput->get('option', 'com_content'); } $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('a.id AS value, a.title AS text, a.level, a.published') ->from('#__categories AS a') ->join('LEFT', $db->quoteName('#__categories') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt'); // Filter by the extension type if ($this->element['parent'] == true || $jinput->get('option') == 'com_categories') { $query->where('(a.extension = ' . $db->quote($extension) . ' OR a.parent_id = 0)'); } else { $query->where('(a.extension = ' . $db->quote($extension) . ')'); } // If parent isn't explicitly stated but we are in com_categories assume we want parents if ($oldCat != 0 && ($this->element['parent'] == true || $jinput->get('option') == 'com_categories')) { // Prevent parenting to children of this item. // To rearrange parents and children move the children up, not the parents down. $query->join('LEFT', $db->quoteName('#__categories') . ' AS p ON p.id = ' . (int) $oldCat) ->where('NOT(a.lft >= p.lft AND a.rgt <= p.rgt)'); $rowQuery = $db->getQuery(true); $rowQuery->select('a.id AS value, a.title AS text, a.level, a.parent_id') ->from('#__categories AS a') ->where('a.id = ' . (int) $oldCat); $db->setQuery($rowQuery); $row = $db->loadObject(); } // Filter language if (!empty($this->element['language'])) { $query->where('a.language = ' . $db->quote($this->element['language'])); } // Filter on the published state if (is_numeric($published)) { $query->where('a.published = ' . (int) $published); } elseif (is_array($published)) { JArrayHelper::toInteger($published); $query->where('a.published IN (' . implode(',', $published) . ')'); } $query->group('a.id, a.title, a.level, a.lft, a.rgt, a.extension, a.parent_id, a.published') ->order('a.lft ASC'); // Get the options. $db->setQuery($query); try { $options = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage); } // Pad the option text with spaces using depth level as a multiplier. for ($i = 0, $n = count($options); $i < $n; $i++) { // Translate ROOT if ($this->element['parent'] == true || $jinput->get('option') == 'com_categories') { if ($options[$i]->level == 0) { $options[$i]->text = JText::_('JGLOBAL_ROOT_PARENT'); } } if ($options[$i]->published == 1) { $options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->text; } else { $options[$i]->text = str_repeat('- ', $options[$i]->level) . '[' . $options[$i]->text . ']'; } } // Get the current user object. $user = JFactory::getUser(); // For new items we want a list of categories you are allowed to create in. if ($oldCat == 0) { foreach ($options as $i => $option) { // To take save or create in a category you need to have create rights for that category // unless the item is already in that category. // Unset the option if the user isn't authorised for it. In this field assets are always categories. if ($user->authorise('core.create', $extension . '.category.' . $option->value) != true) { unset($options[$i]); } } } // If you have an existing category id things are more complex. else { // If you are only allowed to edit in this category but not edit.state, you should not get any // option to change the category parent for a category or the category for a content item, // but you should be able to save in that category. foreach ($options as $i => $option) { if ($user->authorise('core.edit.state', $extension . '.category.' . $oldCat) != true && !isset($oldParent)) { if ($option->value != $oldCat) { unset($options[$i]); } } if ($user->authorise('core.edit.state', $extension . '.category.' . $oldCat) != true && (isset($oldParent)) && $option->value != $oldParent ) { unset($options[$i]); } // However, if you can edit.state you can also move this to another category for which you have // create permission and you should also still be able to save in the current category. if (($user->authorise('core.create', $extension . '.category.' . $option->value) != true) && ($option->value != $oldCat && !isset($oldParent)) ) { { unset($options[$i]); } } if (($user->authorise('core.create', $extension . '.category.' . $option->value) != true) && (isset($oldParent)) && $option->value != $oldParent ) { { unset($options[$i]); } } } } if (($this->element['parent'] == true || $jinput->get('option') == 'com_categories') && (isset($row) && !isset($options[0])) && isset($this->element['show_root']) ) { if ($row->parent_id == '1') { $parent = new stdClass; $parent->text = JText::_('JGLOBAL_ROOT_PARENT'); array_unshift($options, $parent); } array_unshift($options, JHtml::_('select.option', '0', JText::_('JGLOBAL_ROOT'))); } // Merge any additional options in the XML definition. $options = array_merge(parent::getOptions(), $options); return $options; } } components/com_categories/models/fields/categoryparent.php000066600000011442150771655450020232 0ustar00element['name']; // Let's get the id for the current item, either category or content item. $jinput = JFactory::getApplication()->input; // For categories the old category is the category id 0 for new category. if ($this->element['parent']) { $oldCat = $jinput->get('id', 0); } else // For items the old category is the category they are in when opened or 0 if new. { $oldCat = $this->form->getValue($name); } $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('a.id AS value, a.title AS text, a.level') ->from('#__categories AS a') ->join('LEFT', $db->quoteName('#__categories') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt'); // Filter by the type if ($extension = $this->form->getValue('extension')) { $query->where('(a.extension = ' . $db->quote($extension) . ' OR a.parent_id = 0)'); } if ($this->element['parent']) { // Prevent parenting to children of this item. if ($id = $this->form->getValue('id')) { $query->join('LEFT', $db->quoteName('#__categories') . ' AS p ON p.id = ' . (int) $id) ->where('NOT(a.lft >= p.lft AND a.rgt <= p.rgt)'); $rowQuery = $db->getQuery(true); $rowQuery->select('a.id AS value, a.title AS text, a.level, a.parent_id') ->from('#__categories AS a') ->where('a.id = ' . (int) $id); $db->setQuery($rowQuery); $row = $db->loadObject(); } } $query->where('a.published IN (0,1)') ->group('a.id, a.title, a.level, a.lft, a.rgt, a.extension, a.parent_id') ->order('a.lft ASC'); // Get the options. $db->setQuery($query); try { $options = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage()); } // Pad the option text with spaces using depth level as a multiplier. for ($i = 0, $n = count($options); $i < $n; $i++) { // Translate ROOT if ($options[$i]->level == 0) { $options[$i]->text = JText::_('JGLOBAL_ROOT_PARENT'); } $options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->text; } // Get the current user object. $user = JFactory::getUser(); // For new items we want a list of categories you are allowed to create in. if ($oldCat == 0) { foreach ($options as $i => $option) { // To take save or create in a category you need to have create rights for that category // unless the item is already in that category. // Unset the option if the user isn't authorised for it. In this field assets are always categories. if ($user->authorise('core.create', $extension . '.category.' . $option->value) != true) { unset($options[$i]); } } } // If you have an existing category id things are more complex. else { //$categoryOld = $this->form->getValue($name); foreach ($options as $i => $option) { // If you are only allowed to edit in this category but not edit.state, you should not get any // option to change the category parent for a category or the category for a content item, // but you should be able to save in that category. if ($user->authorise('core.edit.state', $extension . '.category.' . $oldCat) != true) { if ($option->value != $oldCat) { echo 'y'; unset($options[$i]); } } // However, if you can edit.state you can also move this to another category for which you have // create permission and you should also still be able to save in the current category. elseif (($user->authorise('core.create', $extension . '.category.' . $option->value) != true) && $option->value != $oldCat ) { echo 'x'; unset($options[$i]); } } } if (isset($row) && !isset($options[0])) { if ($row->parent_id == '1') { $parent = new stdClass; $parent->text = JText::_('JGLOBAL_ROOT_PARENT'); array_unshift($options, $parent); } } // Merge any additional options in the XML definition. $options = array_merge(parent::getOptions(), $options); return $options; } } components/com_categories/models/fields/index.html000066600000000037150771655450016465 0ustar00 components/com_categories/models/forms/index.html000066600000000037150771655450016345 0ustar00 components/com_categories/models/forms/category.xml000066600000011732150771655450016713 0ustar00
    components/com_categories/models/forms/filter_categories.xml000066600000005303150771655450020565 0ustar00
    components/com_categories/models/categories.php000066600000021157150771655450016066 0ustar00context; $extension = $app->getUserStateFromRequest('com_categories.categories.filter.extension', 'extension', 'com_content', 'cmd'); $this->setState('filter.extension', $extension); $parts = explode('.', $extension); // Extract the component name $this->setState('filter.component', $parts[0]); // Extract the optional section name $this->setState('filter.section', (count($parts) > 1) ? $parts[1] : null); $search = $this->getUserStateFromRequest($context . '.search', 'filter_search'); $this->setState('filter.search', $search); $level = $this->getUserStateFromRequest($context . '.filter.level', 'filter_level'); $this->setState('filter.level', $level); $access = $this->getUserStateFromRequest($context . '.filter.access', 'filter_access'); $this->setState('filter.access', $access); $published = $this->getUserStateFromRequest($context . '.filter.published', 'filter_published', ''); $this->setState('filter.published', $published); $language = $this->getUserStateFromRequest($context . '.filter.language', 'filter_language', ''); $this->setState('filter.language', $language); $tag = $this->getUserStateFromRequest($this->context . '.filter.tag', 'filter_tag', ''); $this->setState('filter.tag', $tag); // List state information. parent::populateState('a.lft', 'asc'); // Force a language $forcedLanguage = $app->input->get('forcedLanguage'); if (!empty($forcedLanguage)) { $this->setState('filter.language', $forcedLanguage); $this->setState('filter.forcedLanguage', $forcedLanguage); } } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. * * @return string A store id. * * @since 1.6 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.extension'); $id .= ':' . $this->getState('filter.published'); $id .= ':' . $this->getState('filter.language'); return parent::getStoreId($id); } /** * @return string * * @since 1.6 */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); $user = JFactory::getUser(); // Select the required fields from the table. $query->select( $this->getState( 'list.select', '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' ) ); $query->from('#__categories AS a'); // Join over the language $query->select('l.title AS language_title') ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); // Join over the users for the checked out user. $query->select('uc.name AS editor') ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); // Join over the asset groups. $query->select('ag.title AS access_level') ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); // Join over the users for the author. $query->select('ua.name AS author_name') ->join('LEFT', '#__users AS ua ON ua.id = a.created_user_id'); // Join over the associations. $assoc = $this->getAssoc(); if ($assoc) { $query->select('COUNT(asso2.id)>1 as association') ->join('LEFT', '#__associations AS asso ON asso.id = a.id AND asso.context=' . $db->quote('com_categories.item')) ->join('LEFT', '#__associations AS asso2 ON asso2.key = asso.key') ->group('a.id'); } // Filter by extension if ($extension = $this->getState('filter.extension')) { $query->where('a.extension = ' . $db->quote($extension)); } // Filter on the level. if ($level = $this->getState('filter.level')) { $query->where('a.level <= ' . (int) $level); } // Filter by access level. if ($access = $this->getState('filter.access')) { $query->where('a.access = ' . (int) $access); } // Implement View Level Access if (!$user->authorise('core.admin')) { $groups = implode(',', $user->getAuthorisedViewLevels()); $query->where('a.access IN (' . $groups . ')'); } // Filter by published state $published = $this->getState('filter.published'); if (is_numeric($published)) { $query->where('a.published = ' . (int) $published); } elseif ($published === '') { $query->where('(a.published IN (0, 1))'); } // Filter by search in title $search = $this->getState('filter.search'); if (!empty($search)) { if (stripos($search, 'id:') === 0) { $query->where('a.id = ' . (int) substr($search, 3)); } elseif (stripos($search, 'author:') === 0) { $search = $db->quote('%' . $db->escape(substr($search, 7), true) . '%'); $query->where('(ua.name LIKE ' . $search . ' OR ua.username LIKE ' . $search . ')'); } else { $search = $db->quote('%' . $db->escape($search, true) . '%'); $query->where('(a.title LIKE ' . $search . ' OR a.alias LIKE ' . $search . ' OR a.note LIKE ' . $search . ')'); } } // Filter on the language. if ($language = $this->getState('filter.language')) { $query->where('a.language = ' . $db->quote($language)); } // Filter by a single tag. $tagId = $this->getState('filter.tag'); if (is_numeric($tagId)) { $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId) ->join( 'LEFT', $db->quoteName('#__contentitem_tag_map', 'tagmap') . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id') . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote($extension . '.category') ); } // Add the list ordering clause $listOrdering = $this->getState('list.ordering', 'a.lft'); $listDirn = $db->escape($this->getState('list.direction', 'ASC')); if ($listOrdering == 'a.access') { $query->order('a.access ' . $listDirn . ', a.lft ' . $listDirn); } else { $query->order($db->escape($listOrdering) . ' ' . $listDirn); } //echo nl2br(str_replace('#__','jos_',$query)); return $query; } /** * Method to determine if an association exists * * @return boolean True if the association exists * * @since 3.0 */ public function getAssoc() { static $assoc = null; if (!is_null($assoc)) { return $assoc; } $app = JFactory::getApplication(); $extension = $this->getState('filter.extension'); $assoc = JLanguageAssociations::isEnabled(); $extension = explode('.', $extension); $component = array_shift($extension); $cname = str_replace('com_', '', $component); if (!$assoc || !$component || !$cname) { $assoc = false; } else { $hname = $cname . 'HelperAssociation'; JLoader::register($hname, JPATH_SITE . '/components/' . $component . '/helpers/association.php'); $assoc = class_exists($hname) && !empty($hname::$category_association); } return $assoc; } } components/com_categories/models/category.php000066600000071653150771655450015564 0ustar00input->get('extension', 'com_content'); $this->typeAlias = $extension . '.category'; } /** * Method to test whether a record can be deleted. * * @param object $record A record object. * * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. * * @since 1.6 */ protected function canDelete($record) { if (!empty($record->id)) { if ($record->published != -2) { return; } $user = JFactory::getUser(); return $user->authorise('core.delete', $record->extension . '.category.' . (int) $record->id); } } /** * Method to test whether a record can have its state changed. * * @param object $record A record object. * * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. * * @since 1.6 */ protected function canEditState($record) { $user = JFactory::getUser(); // Check for existing category. if (!empty($record->id)) { return $user->authorise('core.edit.state', $record->extension . '.category.' . (int) $record->id); } // New category, so check against the parent. elseif (!empty($record->parent_id)) { return $user->authorise('core.edit.state', $record->extension . '.category.' . (int) $record->parent_id); } // Default to component settings if neither category nor parent known. else { return $user->authorise('core.edit.state', $record->extension); } } /** * Method to get a table object, load it if necessary. * * @param string $type The table name. Optional. * @param string $prefix The class prefix. Optional. * @param array $config Configuration array for model. Optional. * * @return JTable A JTable object * * @since 1.6 */ public function getTable($type = 'Category', $prefix = 'CategoriesTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @return void * * @since 1.6 */ protected function populateState() { $app = JFactory::getApplication('administrator'); $parentId = $app->input->getInt('parent_id'); $this->setState('category.parent_id', $parentId); // Load the User state. $pk = $app->input->getInt('id'); $this->setState($this->getName() . '.id', $pk); $extension = $app->input->get('extension', 'com_content'); $this->setState('category.extension', $extension); $parts = explode('.', $extension); // Extract the component name $this->setState('category.component', $parts[0]); // Extract the optional section name $this->setState('category.section', (count($parts) > 1) ? $parts[1] : null); // Load the parameters. $params = JComponentHelper::getParams('com_categories'); $this->setState('params', $params); } /** * Method to get a category. * * @param integer $pk An optional id of the object to get, otherwise the id from the model state is used. * * @return mixed Category data object on success, false on failure. * * @since 1.6 */ public function getItem($pk = null) { if ($result = parent::getItem($pk)) { // Prime required properties. if (empty($result->id)) { $result->parent_id = $this->getState('category.parent_id'); $result->extension = $this->getState('category.extension'); } // Convert the metadata field to an array. $registry = new JRegistry; $registry->loadString($result->metadata); $result->metadata = $registry->toArray(); // Convert the created and modified dates to local user time for display in the form. $tz = new DateTimeZone(JFactory::getApplication()->getCfg('offset')); if ((int) $result->created_time) { $date = new JDate($result->created_time); $date->setTimezone($tz); $result->created_time = $date->toSql(true); } else { $result->created_time = null; } if ((int) $result->modified_time) { $date = new JDate($result->modified_time); $date->setTimezone($tz); $result->modified_time = $date->toSql(true); } else { $result->modified_time = null; } if (!empty($result->id)) { $result->tags = new JHelperTags; $result->tags->getTagIds($result->id, $result->extension . '.category'); } } $assoc = $this->getAssoc(); if ($assoc) { if ($result->id != null) { $result->associations = CategoriesHelper::getAssociations($result->id, $result->extension); JArrayHelper::toInteger($result->associations); } else { $result->associations = array(); } } return $result; } /** * Method to get the row form. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return mixed A JForm object on success, false on failure * * @since 1.6 */ public function getForm($data = array(), $loadData = true) { $extension = $this->getState('category.extension'); $jinput = JFactory::getApplication()->input; // A workaround to get the extension into the model for save requests. if (empty($extension) && isset($data['extension'])) { $extension = $data['extension']; $parts = explode('.', $extension); $this->setState('category.extension', $extension); $this->setState('category.component', $parts[0]); $this->setState('category.section', @$parts[1]); } // Get the form. $form = $this->loadForm('com_categories.category' . $extension, 'category', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } // Modify the form based on Edit State access controls. if (empty($data['extension'])) { $data['extension'] = $extension; } $user = JFactory::getUser(); if (!$user->authorise('core.edit.state', $extension . '.category.' . $jinput->get('id'))) { // Disable fields for display. $form->setFieldAttribute('ordering', 'disabled', 'true'); $form->setFieldAttribute('published', 'disabled', 'true'); // Disable fields while saving. // The controller has already verified this is a record you can edit. $form->setFieldAttribute('ordering', 'filter', 'unset'); $form->setFieldAttribute('published', 'filter', 'unset'); } return $form; } /** * A protected method to get the where clause for the reorder * This ensures that the row will be moved relative to a row with the same extension * * @param JCategoryTable $table Current table instance * * @return array An array of conditions to add to add to ordering queries. * * @since 1.6 */ protected function getReorderConditions($table) { return 'extension = ' . $this->_db->quote($table->extension); } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * * @since 1.6 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_categories.edit.' . $this->getName() . '.data', array()); if (empty($data)) { $data = $this->getItem(); } $this->preprocessData('com_categories.category', $data); return $data; } /** * Method to preprocess the form. * * @param JForm $form A JForm object. * @param mixed $data The data expected for the form. * @param string $group The name of the plugin group to import. * * @return void * * @see JFormField * @since 1.6 * @throws Exception if there is an error in the form event. */ protected function preprocessForm(JForm $form, $data, $group = 'content') { jimport('joomla.filesystem.path'); $lang = JFactory::getLanguage(); $component = $this->getState('category.component'); $section = $this->getState('category.section'); $extension = JFactory::getApplication()->input->get('extension', null); // Get the component form if it exists $name = 'category' . ($section ? ('.' . $section) : ''); // Looking first in the component models/forms folder $path = JPath::clean(JPATH_ADMINISTRATOR . "/components/$component/models/forms/$name.xml"); // Old way: looking in the component folder if (!file_exists($path)) { $path = JPath::clean(JPATH_ADMINISTRATOR . "/components/$component/$name.xml"); } if (file_exists($path)) { $lang->load($component, JPATH_BASE, null, false, true); $lang->load($component, JPATH_BASE . '/components/' . $component, null, false, true); if (!$form->loadFile($path, false)) { throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); } } // Try to find the component helper. $eName = str_replace('com_', '', $component); $path = JPath::clean(JPATH_ADMINISTRATOR . "/components/$component/helpers/category.php"); if (file_exists($path)) { require_once $path; $cName = ucfirst($eName) . ucfirst($section) . 'HelperCategory'; if (class_exists($cName) && is_callable(array($cName, 'onPrepareForm'))) { $lang->load($component, JPATH_BASE, null, false, false) || $lang->load($component, JPATH_BASE . '/components/' . $component, null, false, false) || $lang->load($component, JPATH_BASE, $lang->getDefault(), false, false) || $lang->load($component, JPATH_BASE . '/components/' . $component, $lang->getDefault(), false, false); call_user_func_array(array($cName, 'onPrepareForm'), array(&$form)); // Check for an error. if ($form instanceof Exception) { $this->setError($form->getMessage()); return false; } } } // Set the access control rules field component value. $form->setFieldAttribute('rules', 'component', $component); $form->setFieldAttribute('rules', 'section', $name); // Association category items $assoc = $this->getAssoc(); if ($assoc) { $languages = JLanguageHelper::getLanguages('lang_code'); // Force to array (perhaps move to $this->loadFormData()) $data = (array) $data; $addform = new SimpleXMLElement('
    '); $fields = $addform->addChild('fields'); $fields->addAttribute('name', 'associations'); $fieldset = $fields->addChild('fieldset'); $fieldset->addAttribute('name', 'item_associations'); $fieldset->addAttribute('description', 'COM_CATEGORIES_ITEM_ASSOCIATIONS_FIELDSET_DESC'); $add = false; foreach ($languages as $tag => $language) { if (empty($data['language']) || $tag != $data['language']) { $add = true; $field = $fieldset->addChild('field'); $field->addAttribute('name', $tag); $field->addAttribute('type', 'modal_category'); $field->addAttribute('language', $tag); $field->addAttribute('label', $language->title); $field->addAttribute('translate_label', 'false'); $field->addAttribute('extension', $extension); $field->addAttribute('edit', 'true'); $field->addAttribute('clear', 'true'); } } if ($add) { $form->load($addform, false); } } // Trigger the default form events. parent::preprocessForm($form, $data, $group); } /** * Method to save the form data. * * @param array $data The form data. * * @return boolean True on success. * * @since 1.6 */ public function save($data) { $dispatcher = JEventDispatcher::getInstance(); $table = $this->getTable(); $input = JFactory::getApplication()->input; $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState($this->getName() . '.id'); $isNew = true; if ((!empty($data['tags']) && $data['tags'][0] != '')) { $table->newTags = $data['tags']; } // Include the content plugins for the on save events. JPluginHelper::importPlugin('content'); // Load the row if saving an existing category. if ($pk > 0) { $table->load($pk); $isNew = false; } // Set the new parent id if parent id not matched OR while New/Save as Copy . if ($table->parent_id != $data['parent_id'] || $data['id'] == 0) { $table->setLocation($data['parent_id'], 'last-child'); } // Alter the title for save as copy if ($input->get('task') == 'save2copy') { list($title, $alias) = $this->generateNewTitle($data['parent_id'], $data['alias'], $data['title']); $data['title'] = $title; $data['alias'] = $alias; $data['published'] = 0; } // Bind the data. if (!$table->bind($data)) { $this->setError($table->getError()); return false; } // Bind the rules. if (isset($data['rules'])) { $rules = new JAccessRules($data['rules']); $table->setRules($rules); } // Check the data. if (!$table->check()) { $this->setError($table->getError()); return false; } // Trigger the onContentBeforeSave event. $result = $dispatcher->trigger($this->event_before_save, array($this->option . '.' . $this->name, &$table, $isNew)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } // Store the data. if (!$table->store()) { $this->setError($table->getError()); return false; } $assoc = $this->getAssoc(); if ($assoc) { // Adding self to the association $associations = $data['associations']; foreach ($associations as $tag => $id) { if (empty($id)) { unset($associations[$tag]); } } // Detecting all item menus $all_language = $table->language == '*'; if ($all_language && !empty($associations)) { JError::raiseNotice(403, JText::_('COM_CATEGORIES_ERROR_ALL_LANGUAGE_ASSOCIATED')); } $associations[$table->language] = $table->id; // Deleting old association for these items $db = JFactory::getDbo(); $query = $db->getQuery(true) ->delete('#__associations') ->where($db->quoteName('context') . ' = ' . $db->quote('com_categories.item')) ->where($db->quoteName('id') . ' IN (' . implode(',', $associations) . ')'); $db->setQuery($query); $db->execute(); if ($error = $db->getErrorMsg()) { $this->setError($error); return false; } if (!$all_language && count($associations)) { // Adding new association for these items $key = md5(json_encode($associations)); $query->clear() ->insert('#__associations'); foreach ($associations as $id) { $query->values($id . ',' . $db->quote('com_categories.item') . ',' . $db->quote($key)); } $db->setQuery($query); $db->execute(); if ($error = $db->getErrorMsg()) { $this->setError($error); return false; } } } // Trigger the onContentAfterSave event. $dispatcher->trigger($this->event_after_save, array($this->option . '.' . $this->name, &$table, $isNew)); // Rebuild the path for the category: if (!$table->rebuildPath($table->id)) { $this->setError($table->getError()); return false; } // Rebuild the paths of the category's children: if (!$table->rebuild($table->id, $table->lft, $table->level, $table->path)) { $this->setError($table->getError()); return false; } $this->setState($this->getName() . '.id', $table->id); // Clear the cache $this->cleanCache(); return true; } /** * Method to change the published state of one or more records. * * @param array &$pks A list of the primary keys to change. * @param integer $value The value of the published state. * * @return boolean True on success. * * @since 2.5 */ public function publish(&$pks, $value = 1) { if (parent::publish($pks, $value)) { $dispatcher = JEventDispatcher::getInstance(); $extension = JFactory::getApplication()->input->get('extension'); // Include the content plugins for the change of category state event. JPluginHelper::importPlugin('content'); // Trigger the onCategoryChangeState event. $dispatcher->trigger('onCategoryChangeState', array($extension, $pks, $value)); return true; } } /** * Method rebuild the entire nested set tree. * * @return boolean False on failure or error, true otherwise. * * @since 1.6 */ public function rebuild() { // Get an instance of the table object. $table = $this->getTable(); if (!$table->rebuild()) { $this->setError($table->getError()); return false; } // Clear the cache $this->cleanCache(); return true; } /** * Method to save the reordered nested set tree. * First we save the new order values in the lft values of the changed ids. * Then we invoke the table rebuild to implement the new ordering. * * @param array $idArray An array of primary key ids. * @param integer $lft_array The lft value * * @return boolean False on failure or error, True otherwise * * @since 1.6 */ public function saveorder($idArray = null, $lft_array = null) { // Get an instance of the table object. $table = $this->getTable(); if (!$table->saveorder($idArray, $lft_array)) { $this->setError($table->getError()); return false; } // Clear the cache $this->cleanCache(); return true; } protected function batchTag($value, $pks, $contexts) { // Set the variables $user = JFactory::getUser(); $table = $this->getTable(); foreach ($pks as $pk) { if ($user->authorise('core.edit', $contexts[$pk])) { $table->reset(); $table->load($pk); $tags = array($value); /** * @var JTableObserverTags $tagsObserver */ $tagsObserver = $table->getObserverOfClass('JTableObserverTags'); $result = $tagsObserver->setNewTags($tags, false); if (!$result) { $this->setError($table->getError()); return false; } } else { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); return false; } } // Clean the cache $this->cleanCache(); return true; } /** * Batch copy categories to a new category. * * @param integer $value The new category. * @param array $pks An array of row IDs. * @param array $contexts An array of item contexts. * * @return mixed An array of new IDs on success, boolean false on failure. * * @since 1.6 */ protected function batchCopy($value, $pks, $contexts) { $type = new JUcmType; $this->type = $type->getTypeByAlias($this->typeAlias); // $value comes as {parent_id}.{extension} $parts = explode('.', $value); $parentId = (int) JArrayHelper::getValue($parts, 0, 1); $db = $this->getDbo(); $extension = JFactory::getApplication()->input->get('extension', '', 'word'); $i = 0; // Check that the parent exists if ($parentId) { if (!$this->table->load($parentId)) { if ($error = $this->table->getError()) { // Fatal error $this->setError($error); return false; } else { // Non-fatal error $this->setError(JText::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); $parentId = 0; } } // Check that user has create permission for parent category $canCreate = ($parentId == $this->table->getRootId()) ? $this->user->authorise('core.create', $extension) : $this->user->authorise('core.create', $extension . '.category.' . $parentId); if (!$canCreate) { // Error since user cannot create in parent category $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); return false; } } // If the parent is 0, set it to the ID of the root item in the tree if (empty($parentId)) { if (!$parentId = $this->table->getRootId()) { $this->setError($db->getErrorMsg()); return false; } // Make sure we can create in root elseif (!$this->user->authorise('core.create', $extension)) { $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); return false; } } // We need to log the parent ID $parents = array(); // Calculate the emergency stop count as a precaution against a runaway loop bug $query = $db->getQuery(true) ->select('COUNT(id)') ->from($db->quoteName('#__categories')); $db->setQuery($query); try { $count = $db->loadResult(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } // Parent exists so let's proceed while (!empty($pks) && $count > 0) { // Pop the first id off the stack $pk = array_shift($pks); $this->table->reset(); // Check that the row actually exists if (!$this->table->load($pk)) { if ($error = $this->table->getError()) { // Fatal error $this->setError($error); return false; } else { // Not fatal error $this->setError(JText::sprintf('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); continue; } } // Copy is a bit tricky, because we also need to copy the children $query->clear() ->select('id') ->from($db->quoteName('#__categories')) ->where('lft > ' . (int) $this->table->lft) ->where('rgt < ' . (int) $this->table->rgt); $db->setQuery($query); $childIds = $db->loadColumn(); // Add child ID's to the array only if they aren't already there. foreach ($childIds as $childId) { if (!in_array($childId, $pks)) { array_push($pks, $childId); } } // Make a copy of the old ID and Parent ID $oldId = $this->table->id; $oldParentId = $this->table->parent_id; // Reset the id because we are making a copy. $this->table->id = 0; // If we a copying children, the Old ID will turn up in the parents list // otherwise it's a new top level item $this->table->parent_id = isset($parents[$oldParentId]) ? $parents[$oldParentId] : $parentId; // Set the new location in the tree for the node. $this->table->setLocation($this->table->parent_id, 'last-child'); // TODO: Deal with ordering? // $this->table->ordering = 1; $this->table->level = null; $this->table->asset_id = null; $this->table->lft = null; $this->table->rgt = null; // Alter the title & alias list($title, $alias) = $this->generateNewTitle($this->table->parent_id, $this->table->alias, $this->table->title); $this->table->title = $title; $this->table->alias = $alias; parent::createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table); // Store the row. if (!$this->table->store()) { $this->setError($this->table->getError()); return false; } // Get the new item ID $newId = $this->table->get('id'); // Add the new ID to the array $newIds[$i] = $newId; $i++; // Now we log the old 'parent' to the new 'parent' $parents[$oldId] = $this->table->id; $count--; } // Rebuild the hierarchy. if (!$this->table->rebuild()) { $this->setError($this->table->getError()); return false; } // Rebuild the tree path. if (!$this->table->rebuildPath($this->table->id)) { $this->setError($this->table->getError()); return false; } return $newIds; } /** * Batch move categories to a new category. * * @param integer $value The new category ID. * @param array $pks An array of row IDs. * @param array $contexts An array of item contexts. * * @return boolean True on success. * * @since 1.6 */ protected function batchMove($value, $pks, $contexts) { $parentId = (int) $value; $type = new JUcmType; $this->type = $type->getTypeByAlias($this->typeAlias); $db = $this->getDbo(); $query = $db->getQuery(true); $extension = JFactory::getApplication()->input->get('extension', '', 'word'); // Check that the parent exists. if ($parentId) { if (!$this->table->load($parentId)) { if ($error = $this->table->getError()) { // Fatal error $this->setError($error); return false; } else { // Non-fatal error $this->setError(JText::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); $parentId = 0; } } // Check that user has create permission for parent category $canCreate = ($parentId == $this->table->getRootId()) ? $this->user->authorise('core.create', $extension) : $this->user->authorise('core.create', $extension . '.category.' . $parentId); if (!$canCreate) { // Error since user cannot create in parent category $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); return false; } // Check that user has edit permission for every category being moved // Note that the entire batch operation fails if any category lacks edit permission foreach ($pks as $pk) { if (!$this->user->authorise('core.edit', $extension . '.category.' . $pk)) { // Error since user cannot edit this category $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_EDIT')); return false; } } } // We are going to store all the children and just move the category $children = array(); // Parent exists so let's proceed foreach ($pks as $pk) { // Check that the row actually exists if (!$this->table->load($pk)) { if ($error = $this->table->getError()) { // Fatal error $this->setError($error); return false; } else { // Not fatal error $this->setError(JText::sprintf('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); continue; } } // Set the new location in the tree for the node. $this->table->setLocation($parentId, 'last-child'); // Check if we are moving to a different parent if ($parentId != $this->table->parent_id) { // Add the child node ids to the children array. $query->clear() ->select('id') ->from($db->quoteName('#__categories')) ->where($db->quoteName('lft') . ' BETWEEN ' . (int) $this->table->lft . ' AND ' . (int) $this->table->rgt); $db->setQuery($query); try { $children = array_merge($children, (array) $db->loadColumn()); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } } parent::createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table); // Store the row. if (!$this->table->store()) { $this->setError($this->table->getError()); return false; } // Rebuild the tree path. if (!$this->table->rebuildPath()) { $this->setError($this->table->getError()); return false; } } // Process the child rows if (!empty($children)) { // Remove any duplicates and sanitize ids. $children = array_unique($children); JArrayHelper::toInteger($children); } return true; } /** * Custom clean the cache of com_content and content modules * * @since 1.6 */ protected function cleanCache($group = null, $client_id = 0) { $extension = JFactory::getApplication()->input->get('extension'); switch ($extension) { case 'com_content': parent::cleanCache('com_content'); parent::cleanCache('mod_articles_archive'); parent::cleanCache('mod_articles_categories'); parent::cleanCache('mod_articles_category'); parent::cleanCache('mod_articles_latest'); parent::cleanCache('mod_articles_news'); parent::cleanCache('mod_articles_popular'); break; default: parent::cleanCache($extension); break; } } /** * Method to change the title & alias. * * @param integer $parent_id The id of the parent. * @param string $alias The alias. * @param string $title The title. * * @return array Contains the modified title and alias. * * @since 1.7 */ protected function generateNewTitle($parent_id, $alias, $title) { // Alter the title & alias $table = $this->getTable(); while ($table->load(array('alias' => $alias, 'parent_id' => $parent_id))) { $title = JString::increment($title); $alias = JString::increment($alias, 'dash'); } return array($title, $alias); } public function getAssoc() { static $assoc = null; if (!is_null($assoc)) { return $assoc; } $app = JFactory::getApplication(); $extension = $this->getState('category.extension'); $assoc = JLanguageAssociations::isEnabled(); $extension = explode('.', $extension); $component = array_shift($extension); $cname = str_replace('com_', '', $component); if (!$assoc || !$component || !$cname) { $assoc = false; } else { $hname = $cname . 'HelperAssociation'; JLoader::register($hname, JPATH_SITE . '/components/' . $component . '/helpers/association.php'); $assoc = class_exists($hname) && !empty($hname::$category_association); } return $assoc; } } components/com_users/users.xml000066600000002633150771655450012642 0ustar00 com_users Joomla! Project April 2006 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_USERS_XML_DESCRIPTION controller.php index.html router.php users.php controllers helpers models views language/en-GB.com_users.ini config.xml controller.php index.html users.php controllers helpers models views language/en-GB.com_users.ini language/en-GB.com_users.sys.ini components/com_users/tables/index.html000066600000000037150771655450014222 0ustar00 components/com_users/tables/note.php000066600000007204150771655450013706 0ustar00toSql(); $userId = JFactory::getUser()->get('id'); if (empty($this->id)) { // New record. $this->created_time = $date; $this->created_user_id = $userId; } else { // Existing record. $this->modified_time = $date; $this->modified_user_id = $userId; } // Attempt to store the data. return parent::store($updateNulls); } /** * Method to set the publishing state for a row or list of rows in the database * table. The method respects checked out rows by other users and will attempt * to check-in rows that it can after adjustments are made. * * @param mixed $pks An optional array of primary key values to update. If not set the instance property value is used. * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published] * @param integer $userId The user id of the user performing the operation. * * @return boolean True on success. * * @link http://docs.joomla.org/JTable/publish * @since 2.5 */ public function publish($pks = null, $state = 1, $userId = 0) { $k = $this->_tbl_key; // Sanitize input. JArrayHelper::toInteger($pks); $userId = (int) $userId; $state = (int) $state; // If there are no primary keys set check to see if the instance key is set. if (empty($pks)) { if ($this->$k) { $pks = array($this->$k); } // Nothing to set publishing state on, return false. else { $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); return false; } } $query = $this->_db->getQuery(true) ->update($this->_db->quoteName($this->_tbl)) ->set($this->_db->quoteName('state') . ' = ' . (int) $state); // Build the WHERE clause for the primary keys. $query->where($k . '=' . implode(' OR ' . $k . '=', $pks)); // Determine if there is checkin support for the table. if (!property_exists($this, 'checked_out') || !property_exists($this, 'checked_out_time')) { $checkin = false; } else { $query->where('(checked_out = 0 OR checked_out = ' . (int) $userId . ')'); $checkin = true; } // Update the publishing state for rows with the given primary keys. $this->_db->setQuery($query); try { $this->_db->execute(); } catch (RuntimeException $e) { $this->setError($this->_db->getMessage()); return false; } // If checkin is supported and all rows were adjusted, check them in. if ($checkin && (count($pks) == $this->_db->getAffectedRows())) { // Checkin the rows. foreach ($pks as $pk) { $this->checkin($pk); } } // If the JTable instance value is in the list of primary keys that were set, set the instance. if (in_array($this->$k, $pks)) { $this->state = $state; } $this->setError(''); return true; } } components/com_users/views/users/view.html.php000066600000007333150771655450015705 0ustar00items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); $this->filterForm = $this->get('FilterForm'); $this->activeFilters = $this->get('ActiveFilters'); $this->canDo = JHelperContent::getActions('com_users'); UsersHelper::addSubmenu('users'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } // Include the component HTML helpers. JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { $canDo = $this->canDo; $user = JFactory::getUser(); // Get the toolbar object instance $bar = JToolBar::getInstance('toolbar'); JToolbarHelper::title(JText::_('COM_USERS_VIEW_USERS_TITLE'), 'users user'); if ($canDo->get('core.create')) { JToolbarHelper::addNew('user.add'); } if ($canDo->get('core.edit')) { JToolbarHelper::editList('user.edit'); } if ($canDo->get('core.edit.state')) { JToolbarHelper::divider(); JToolbarHelper::publish('users.activate', 'COM_USERS_TOOLBAR_ACTIVATE', true); JToolbarHelper::unpublish('users.block', 'COM_USERS_TOOLBAR_BLOCK', true); JToolbarHelper::custom('users.unblock', 'unblock.png', 'unblock_f2.png', 'COM_USERS_TOOLBAR_UNBLOCK', true); JToolbarHelper::divider(); } if ($canDo->get('core.delete')) { JToolbarHelper::deleteList('', 'users.delete'); JToolbarHelper::divider(); } // Add a batch button if ($user->authorise('core.create', 'com_users') && $user->authorise('core.edit', 'com_users') && $user->authorise('core.edit.state', 'com_users')) { JHtml::_('bootstrap.modal', 'collapseModal'); $title = JText::_('JTOOLBAR_BATCH'); // Instantiate a new JLayoutFile instance and render the batch button $layout = new JLayoutFile('joomla.toolbar.batch'); $dhtml = $layout->render(array('title' => $title)); $bar->appendButton('Custom', $dhtml, 'batch'); } if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_users'); JToolbarHelper::divider(); } JToolbarHelper::help('JHELP_USERS_USER_MANAGER'); } /** * Returns an array of fields the table can be sorted by * * @return array Array containing the field name to sort by as the key and display text as value * * @since 3.0 */ protected function getSortFields() { return array( 'a.name' => JText::_('COM_USERS_HEADING_NAME'), 'a.username' => JText::_('JGLOBAL_USERNAME'), 'a.block' => JText::_('COM_USERS_HEADING_ENABLED'), 'a.activation' => JText::_('COM_USERS_HEADING_ACTIVATED'), 'a.email' => JText::_('JGLOBAL_EMAIL'), 'a.lastvisitDate' => JText::_('COM_USERS_HEADING_LAST_VISIT_DATE'), 'a.registerDate' => JText::_('COM_USERS_HEADING_REGISTRATION_DATE'), 'a.id' => JText::_('JGRID_HEADING_ID') ); } } components/com_users/views/users/tmpl/default.php000066600000015160150771655450016365 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $loggeduser = JFactory::getUser(); $sortFields = $this->getSortFields(); ?> sidebar)) : ?>
    sidebar; ?>
    $this)); ?> items as $i => $item) : $canEdit = $this->canDo->get('core.edit'); $canChange = $loggeduser->authorise('core.edit.state', 'com_users'); // If this group is super admin and this user is not super admin, $canEdit is false if ((!$loggeduser->authorise('core.admin')) && JAccess::check($item->id, 'core.admin')) { $canEdit = false; $canChange = false; } ?>
    pagination->getListFooter(); ?>
    id); ?> escape($item->name); ?> escape($item->name); ?>
    note_count, $item->id); ?> note_count, $item->id); ?> id); ?> requireReset == '1') : ?>
    escape($item->username); ?> id == $item->id; echo JHtml::_('jgrid.state', JHtmlUsers::blockStates($self), $item->block, $i, 'users.', !$self); ?> block ? 'JNO' : 'JYES'); ?> activation) ? 0 : 1; echo JHtml::_('jgrid.state', JHtmlUsers::activateStates(), $activated, $i, 'users.', (boolean) $activated); ?> group_names, "\n") > 1) : ?> group_names); ?> escape($item->email)); ?> lastvisitDate != '0000-00-00 00:00:00'):?> lastvisitDate, 'Y-m-d H:i:s'); ?> registerDate, 'Y-m-d H:i:s'); ?> id; ?>
    loadTemplate('batch'); ?>
    components/com_users/views/users/tmpl/index.html000066600000000037150771655450016222 0ustar00 components/com_users/views/users/tmpl/default_batch.php000066600000004546150771655450017534 0ustar00 components/com_users/views/users/tmpl/modal.php000066600000010121150771655450016025 0ustar00input; $field = $input->getCmd('field'); $function = 'jSelectUser_' . $field; $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?>
    state->get('filter.group_id'), 'onchange="this.form.submit()"'); ?>
    items as $item) : ?>
    pagination->getListFooter(); ?>
    name; ?> username; ?> group_names); ?>
    components/com_users/views/users/index.html000066600000000037150771655450015246 0ustar00 components/com_users/views/note/view.html.php000066600000005723150771655450015512 0ustar00state = $this->get('State'); $this->item = $this->get('Item'); $this->form = $this->get('Form'); // Check for errors. if (count($errors = $this->get('Errors'))) { throw new Exception(implode("\n", $errors), 500); } // Get the component HTML helpers JHtml::addIncludePath(JPATH_COMPONENT.'/helpers/html'); parent::display($tpl); $this->addToolbar(); } /** * Display the toolbar. * * @return void * * @since 2.5 */ protected function addToolbar() { $input = JFactory::getApplication()->input; $input->set('hidemainmenu', 1); $user = JFactory::getUser(); $isNew = ($this->item->id == 0); $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); // Since we don't track these assets at the item level, use the category id. $canDo = JHelperContent::getActions('com_users', 'category', $this->item->catid); JToolbarHelper::title(JText::_('COM_USERS_NOTES'), 'users user'); // If not checked out, can save the item. if (!$checkedOut && ($canDo->get('core.edit') || (count($user->getAuthorisedCategories('com_users', 'core.create'))))) { JToolbarHelper::apply('note.apply'); JToolbarHelper::save('note.save'); } if (!$checkedOut && (count($user->getAuthorisedCategories('com_users', 'core.create')))) { JToolbarHelper::save2new('note.save2new'); } // If an existing item, can save to a copy. if (!$isNew && (count($user->getAuthorisedCategories('com_users', 'core.create')) > 0)) { JToolbarHelper::save2copy('note.save2copy'); } if (empty($this->item->id)) { JToolbarHelper::cancel('note.cancel'); } else { if ($this->state->params->get('save_history', 0) && $user->authorise('core.edit')) { JToolbarHelper::versions('com_users.note', $this->item->id); } JToolbarHelper::cancel('note.cancel', 'JTOOLBAR_CLOSE'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_USERS_USER_NOTES_EDIT'); } } components/com_users/views/note/tmpl/edit.php000066600000004775150771655450015504 0ustar00
    form->getLabel('subject'); ?>
    form->getInput('subject'); ?>
    form->getLabel('user_id'); ?>
    form->getInput('user_id'); ?>
    form->getLabel('catid'); ?>
    form->getInput('catid'); ?>
    form->getLabel('state'); ?>
    form->getInput('state'); ?>
    form->getLabel('review_time'); ?>
    form->getInput('review_time'); ?>
    form->getLabel('version_note'); ?>
    form->getInput('version_note'); ?>
    form->getLabel('body'); ?>
    form->getInput('body'); ?>
    components/com_users/views/note/tmpl/index.html000066600000000036150771655450016025 0ustar00components/com_users/views/note/index.html000066600000000036150771655450015051 0ustar00components/com_users/views/debuggroup/view.html.php000066600000004726150771655450016712 0ustar00authorise('core.manage', 'com_users') || !JFactory::getConfig()->get('debug')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } $this->actions = $this->get('DebugActions'); $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); $this->group = $this->get('Group'); $this->levels = UsersHelperDebug::getLevelsOptions(); $this->components = UsersHelperDebug::getComponents(); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { JToolbarHelper::title(JText::sprintf('COM_USERS_VIEW_DEBUG_GROUP_TITLE', $this->group->id, $this->group->title), 'users groups'); JToolbarHelper::help('JHELP_USERS_DEBUG_GROUPS'); JHtmlSidebar::setAction('index.php?option=com_users&view=debuggroup&user_id=' . (int) $this->state->get('filter.user_id')); $option = ''; if (!empty($this->components)) { $option = JHtml::_('select.options', $this->components, 'value', 'text', $this->state->get('filter.component')); } JHtmlSidebar::addFilter( JText::_('COM_USERS_OPTION_SELECT_COMPONENT'), 'filter_component', $option ); JHtmlSidebar::addFilter( JText::_('COM_USERS_OPTION_SELECT_LEVEL_START'), 'filter_level_start', JHtml::_('select.options', $this->levels, 'value', 'text', $this->state->get('filter.level_start')) ); JHtmlSidebar::addFilter( JText::_('COM_USERS_OPTION_SELECT_LEVEL_END'), 'filter_level_end', JHtml::_('select.options', $this->levels, 'value', 'text', $this->state->get('filter.level_end')) ); } } components/com_users/views/debuggroup/tmpl/default.php000066600000011754150771655450017374 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?>
    sidebar)) : ?>
    sidebar; ?>
    actions as $key => $action) : ?> items as $i => $item) : ?> actions as $action) : ?> checks[$name]; if ($check === true) : $class = 'icon-ok'; $button = 'btn-success'; elseif ($check === false) : $class = 'icon-remove'; $button = 'btn-danger'; elseif ($check === null) : $class = 'icon-ban-circle'; $button = 'btn-warning'; else : $class = ''; $button = ''; endif; ?>
    pagination->getListFooter(); ?>
    escape($item->title); ?> |—', $item->level) ?> escape($item->name); ?> lft; ?> - rgt; ?> id; ?>
    components/com_users/views/debuggroup/tmpl/index.html000066600000000037150771655450017224 0ustar00 components/com_users/views/debuggroup/index.html000066600000000037150771655450016250 0ustar00 components/com_users/views/user/view.html.php000066600000004346150771655450015523 0ustar00form = $this->get('Form'); $this->item = $this->get('Item'); $this->grouplist = $this->get('Groups'); $this->groups = $this->get('AssignedGroups'); $this->state = $this->get('State'); $this->tfaform = $this->get('Twofactorform'); $this->otpConfig = $this->get('otpConfig'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->form->setValue('password', null); $this->form->setValue('password2', null); parent::display($tpl); $this->addToolbar(); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { JFactory::getApplication()->input->set('hidemainmenu', true); $user = JFactory::getUser(); $canDo = JHelperContent::getActions('com_users'); $isNew = ($this->item->id == 0); $isProfile = $this->item->id == $user->id; JToolbarHelper::title(JText::_($isNew ? 'COM_USERS_VIEW_NEW_USER_TITLE' : ($isProfile ? 'COM_USERS_VIEW_EDIT_PROFILE_TITLE' : 'COM_USERS_VIEW_EDIT_USER_TITLE')), 'user ' . ($isNew ? 'user-add' : ($isProfile ? 'user-profile' : 'user-edit'))); if ($canDo->get('core.edit')||$canDo->get('core.create')) { JToolbarHelper::apply('user.apply'); JToolbarHelper::save('user.save'); } if ($canDo->get('core.create')&&$canDo->get('core.manage')) { JToolbarHelper::save2new('user.save2new'); } if (empty($this->item->id)) { JToolbarHelper::cancel('user.cancel'); } else { JToolbarHelper::cancel('user.cancel', 'JTOOLBAR_CLOSE'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_USERS_USER_MANAGER_EDIT'); } } components/com_users/views/user/tmpl/edit_groups.php000066600000000711150771655450017076 0ustar00 groups, true); ?> components/com_users/views/user/tmpl/edit.php000066600000012167150771655450015507 0ustar00form->getFieldsets(); ?>
    'details')); ?> form->getFieldset('user_details') as $field) : ?>
    label; ?>
    input; ?>
    grouplist) : ?> loadTemplate('groups'); ?> name == 'user_details') : continue; endif; ?> name, JText::_($fieldset->label, true)); ?> form->getFieldset($fieldset->name) as $field) : ?> hidden) : ?>
    input; ?>
    label; ?>
    input; ?>
    tfaform) && $this->item->id): ?>
    'Joomla.twoFactorMethodChange()'), 'value', 'text', $this->otpConfig->method, 'jform_twofactor_method', false) ?>
    tfaform as $form): ?> otpConfig->method ? 'display: block' : 'display: none'; ?>
    otpConfig->otep)): ?>
    otpConfig->otep as $otep): ?> ---
    components/com_users/views/user/tmpl/index.html000066600000000037150771655450016037 0ustar00 components/com_users/views/user/index.html000066600000000037150771655450015063 0ustar00 components/com_users/views/debuguser/view.html.php000066600000004770150771655450016533 0ustar00authorise('core.manage', 'com_users') || !JFactory::getConfig()->get('debug')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } $this->actions = $this->get('DebugActions'); $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); $this->user = $this->get('User'); $this->levels = UsersHelperDebug::getLevelsOptions(); $this->components = UsersHelperDebug::getComponents(); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { JToolbarHelper::title(JText::sprintf('COM_USERS_VIEW_DEBUG_USER_TITLE', $this->user->id, $this->user->name), 'users user'); JToolbarHelper::help('JHELP_USERS_DEBUG_USERS'); JHtmlSidebar::setAction('index.php?option=com_users&view=debuguser&user_id=' . (int) $this->state->get('filter.user_id')); $option = ''; if (!empty($this->components)) { $option = JHtml::_('select.options', $this->components, 'value', 'text', $this->state->get('filter.component')); } JHtmlSidebar::addFilter( JText::_('COM_USERS_OPTION_SELECT_COMPONENT'), 'filter_component', $option ); JHtmlSidebar::addFilter( JText::_('COM_USERS_OPTION_SELECT_LEVEL_START'), 'filter_level_start', JHtml::_('select.options', $this->levels, 'value', 'text', $this->state->get('filter.level_start')) ); JHtmlSidebar::addFilter( JText::_('COM_USERS_OPTION_SELECT_LEVEL_END'), 'filter_level_end', JHtml::_('select.options', $this->levels, 'value', 'text', $this->state->get('filter.level_end')) ); $this->sidebar = JHtmlSidebar::render(); } } components/com_users/views/debuguser/tmpl/default.php000066600000011764150771655450017217 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?>
    sidebar)) : ?>
    sidebar; ?>
    actions as $key => $action) : ?> items as $i => $item) : ?> actions as $action) : ?> checks[$name]; if ($check === true) : $class = 'icon-ok'; $button = 'btn-success'; elseif ($check === false) : $class = 'icon-remove'; $button = 'btn-danger'; elseif ($check === null) : $class = 'icon-ban-circle'; $button = 'btn-warning'; else : $class = ''; $button = ''; endif; ?>
    pagination->getListFooter(); ?>
    escape($item->title); ?> |—', $item->level) ?> escape($item->name); ?> lft; ?> - rgt; ?> id; ?>
    components/com_users/views/debuguser/tmpl/index.html000066600000000037150771655450017046 0ustar00 components/com_users/views/debuguser/index.html000066600000000037150771655450016072 0ustar00 components/com_users/views/notes/view.html.php000066600000010245150771655450015670 0ustar00items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); $this->user = $this->get('User'); UsersHelper::addSubmenu('notes'); // Check for errors. if (count($errors = $this->get('Errors'))) { throw new Exception(implode("\n", $errors), 500); } // Get the component HTML helpers JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); // turn parameters into registry objects foreach ($this->items as $item) { $item->cparams = new JRegistry; $item->cparams->loadString($item->category_params); } $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Display the toolbar. * * @return void * * @since 2.5 */ protected function addToolbar() { $canDo = JHelperContent::getActions('com_users', 'category', $this->state->get('filter.category_id')); JToolbarHelper::title(JText::_('COM_USERS_VIEW_NOTES_TITLE'), 'users user'); if ($canDo->get('core.create')) { JToolbarHelper::addNew('note.add'); } if ($canDo->get('core.edit')) { JToolbarHelper::editList('note.edit'); } if ($canDo->get('core.edit.state')) { JToolbarHelper::divider(); JToolbarHelper::publish('notes.publish', 'JTOOLBAR_PUBLISH', true); JToolbarHelper::unpublish('notes.unpublish', 'JTOOLBAR_UNPUBLISH', true); JToolbarHelper::divider(); JToolbarHelper::archiveList('notes.archive'); JToolbarHelper::checkin('notes.checkin'); } if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete')) { JToolbarHelper::deleteList('', 'notes.delete', 'JTOOLBAR_EMPTY_TRASH'); JToolbarHelper::divider(); } elseif ($canDo->get('core.edit.state')) { JToolbarHelper::trash('notes.trash'); JToolbarHelper::divider(); } if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_users'); JToolbarHelper::divider(); } JToolbarHelper::help('JHELP_USERS_USER_NOTES'); JHtmlSidebar::setAction('index.php?option=com_users&view=notes'); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_PUBLISHED'), 'filter_published', JHtml::_('select.options', JHtml::_('jgrid.publishedOptions'), 'value', 'text', $this->state->get('filter.state'), true) ); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_CATEGORY'), 'filter_category_id', JHtml::_('select.options', JHtml::_('category.options', 'com_users.notes'), 'value', 'text', $this->state->get('filter.category_id')) ); } /** * Returns an array of fields the table can be sorted by * * @return array Array containing the field name to sort by as the key and display text as value * * @since 3.0 */ protected function getSortFields() { return array( 'u.name' => JText::_('COM_USERS_USER_HEADING'), 'a.subject' => JText::_('COM_USERS_SUBJECT_HEADING'), 'c.title' => JText::_('COM_USERS_CATEGORY_HEADING'), 'a.state' => JText::_('JSTATUS'), 'a.review_time' => JText::_('COM_USERS_REVIEW_HEADING'), 'a.id' => JText::_('JGRID_HEADING_ID') ); } } components/com_users/views/notes/tmpl/default.php000066600000015420150771655450016353 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $canEdit = $user->authorise('core.edit', 'com_users'); $sortFields = $this->getSortFields(); ?>
    sidebar)) : ?>
    sidebar; ?>
    pagination->getLimitBox(); ?>
    items as $i => $item) : ?> authorise('core.edit.state', 'com_users'); ?>
    pagination->getListFooter(); ?>
    id); ?> checked_out) : ?> editor, $item->checked_out_time); ?> escape($item->user_name); ?> escape($item->user_name); ?> subject) : ?> escape($item->subject); ?> catid && $item->cparams->get('image')) : ?> cparams->get('image')); ?> escape($item->category_title); ?> state, $i, 'notes.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> review_time)) : ?> escape($item->review_time); ?> id; ?>
    components/com_users/views/notes/tmpl/index.html000066600000000036150771655450016210 0ustar00components/com_users/views/notes/tmpl/modal.php000066600000003106150771655450016021 0ustar00

    user->name, $this->user->id); ?>

    items)) : ?>
      items as $item) : ?>
    1. subject) : ?>

      id, $this->escape($item->subject)); ?>

      id, JText::_('COM_USERS_EMPTY_SUBJECT')); ?>

      created_time, 'D d M Y H:i'); ?>
      cparams->get('image'); ?> catid && isset($category_image)) : ?>
      escape($item->category_title); ?>
      body; ?>
    components/com_users/views/notes/index.html000066600000000036150771655450015234 0ustar00components/com_users/views/index.html000066600000000037150771655450014105 0ustar00 components/com_users/views/groups/view.html.php000066600000004044150771655450016057 0ustar00items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); UsersHelper::addSubmenu('groups'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { $canDo = JHelperContent::getActions('com_users'); JToolbarHelper::title(JText::_('COM_USERS_VIEW_GROUPS_TITLE'), 'users groups'); if ($canDo->get('core.create')) { JToolbarHelper::addNew('group.add'); } if ($canDo->get('core.edit')) { JToolbarHelper::editList('group.edit'); JToolbarHelper::divider(); } if ($canDo->get('core.delete')) { JToolbarHelper::deleteList('', 'groups.delete'); JToolbarHelper::divider(); } if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_users'); JToolbarHelper::divider(); } JToolbarHelper::help('JHELP_USERS_GROUPS'); } /** * Returns an array of fields the table can be sorted by * * @return array Array containing the field name to sort by as the key and display text as value * * @since 3.0 */ protected function getSortFields() { return array( 'a.title' => JText::_('COM_USERS_HEADING_GROUP_TITLE'), 'a.id' => JText::_('JGRID_HEADING_ID') ); } } components/com_users/views/groups/tmpl/default.php000066600000015076150771655450016551 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $sortFields = $this->getSortFields(); JText::script('COM_USERS_GROUPS_CONFIRM_DELETE'); ?>
    sidebar)) : ?>
    sidebar; ?>
    pagination->getLimitBox(); ?>
    items as $i => $item) : $canCreate = $user->authorise('core.create', 'com_users'); $canEdit = $user->authorise('core.edit', 'com_users'); // If this group is super admin and this user is not super admin, $canEdit is false if (!$user->authorise('core.admin') && (JAccess::checkGroup($item->id, 'core.admin'))) { $canEdit = false; } $canChange = $user->authorise('core.edit.state', 'com_users'); ?>
    pagination->getListFooter(); ?>
    id); ?> |—', $item->level) ?> escape($item->title); ?> escape($item->title); ?> user_count ? $item->user_count : ''; ?> id; ?>
    components/com_users/views/groups/tmpl/index.html000066600000000037150771655450016400 0ustar00 components/com_users/views/groups/index.html000066600000000037150771655450015424 0ustar00 components/com_users/views/mail/view.html.php000066600000002303150771655450015456 0ustar00form = $this->get('Form'); $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { JFactory::getApplication()->input->set('hidemainmenu', true); JToolbarHelper::title(JText::_('COM_USERS_MASS_MAIL'), 'users massmail'); JToolbarHelper::custom('mail.send', 'envelope.png', 'send_f2.png', 'COM_USERS_TOOLBAR_MAIL_SEND_MAIL', false); JToolbarHelper::cancel('mail.cancel'); JToolbarHelper::divider(); JToolbarHelper::preferences('com_users'); JToolbarHelper::divider(); JToolbarHelper::help('JHELP_USERS_MASS_MAIL_USERS'); } } components/com_users/views/mail/tmpl/default.php000066600000006165150771655450016153 0ustar00addScriptDeclaration($script); ?>
    form->getLabel('subject'); ?>
    form->getInput('subject'); ?>
    form->getLabel('message'); ?>
    form->getInput('message'); ?>
    form->getInput('recurse'); ?> form->getLabel('recurse'); ?>
    form->getInput('mode'); ?> form->getLabel('mode'); ?>
    form->getInput('disabled'); ?> form->getLabel('disabled'); ?>
    form->getInput('bcc'); ?> form->getLabel('bcc'); ?>
    form->getLabel('group'); ?>
    form->getInput('group'); ?>
    components/com_users/views/mail/tmpl/index.html000066600000000037150771655450016003 0ustar00 components/com_users/views/mail/index.html000066600000000037150771655450015027 0ustar00 components/com_users/views/group/view.html.php000066600000003562150771655450015700 0ustar00state = $this->get('State'); $this->item = $this->get('Item'); $this->form = $this->get('Form'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { JFactory::getApplication()->input->set('hidemainmenu', true); $isNew = ($this->item->id == 0); $canDo = JHelperContent::getActions('com_users'); JToolbarHelper::title(JText::_($isNew ? 'COM_USERS_VIEW_NEW_GROUP_TITLE' : 'COM_USERS_VIEW_EDIT_GROUP_TITLE'), 'users groups-add'); if ($canDo->get('core.edit') || $canDo->get('core.create')) { JToolbarHelper::apply('group.apply'); JToolbarHelper::save('group.save'); } if ($canDo->get('core.create')) { JToolbarHelper::save2new('group.save2new'); } // If an existing item, can save to a copy. if (!$isNew && $canDo->get('core.create')) { JToolbarHelper::save2copy('group.save2copy'); } if (empty($this->item->id)) { JToolbarHelper::cancel('group.cancel'); } else { JToolbarHelper::cancel('group.cancel', 'JTOOLBAR_CLOSE'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_USERS_GROUPS_EDIT'); } } components/com_users/views/group/tmpl/edit.php000066600000003124150771655450015656 0ustar00
    form->getLabel('title'); ?>
    form->getInput('title'); ?>
    form->getField('parent_id');?> hidden) : ?>
    label; ?>
    input; ?>
    components/com_users/views/group/tmpl/index.html000066600000000037150771655450016215 0ustar00 components/com_users/views/group/index.html000066600000000037150771655450015241 0ustar00 components/com_users/views/levels/view.html.php000066600000004135150771655450016033 0ustar00items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); UsersHelper::addSubmenu('levels'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); $this->sidebar = JHtmlSidebar::render(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { $canDo = JHelperContent::getActions('com_users'); JToolbarHelper::title(JText::_('COM_USERS_VIEW_LEVELS_TITLE'), 'users levels'); if ($canDo->get('core.create')) { JToolbarHelper::addNew('level.add'); } if ($canDo->get('core.edit')) { JToolbarHelper::editList('level.edit'); JToolbarHelper::divider(); } if ($canDo->get('core.delete')) { JToolbarHelper::deleteList('', 'level.delete'); JToolbarHelper::divider(); } if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_users'); JToolbarHelper::divider(); } JToolbarHelper::help('JHELP_USERS_ACCESS_LEVELS'); } /** * Returns an array of fields the table can be sorted by * * @return array Array containing the field name to sort by as the key and display text as value * * @since 3.0 */ protected function getSortFields() { return array( 'a.ordering' => JText::_('JGRID_HEADING_ORDERING'), 'a.title' => JText::_('COM_USERS_HEADING_LEVEL_NAME'), 'a.id' => JText::_('JGRID_HEADING_ID') ); } } components/com_users/views/levels/tmpl/default.php000066600000015073150771655450016521 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $canOrder = $user->authorise('core.edit.state', 'com_users'); $saveOrder = $listOrder == 'a.ordering'; $sortFields = $this->getSortFields(); $saveOrder = $listOrder == 'a.ordering'; if ($saveOrder) { $saveOrderingUrl = 'index.php?option=com_users&task=levels.saveOrderAjax&tmpl=component'; JHtml::_('sortablelist.sortable', 'levelList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); } ?>
    sidebar)) : ?>
    sidebar; ?>
    pagination->getLimitBox(); ?>
    items); ?> items as $i => $item) : $ordering = ($listOrder == 'a.ordering'); $canCreate = $user->authorise('core.create', 'com_users'); $canEdit = $user->authorise('core.edit', 'com_users'); $canChange = $user->authorise('core.edit.state', 'com_users'); ?>
    ', 'a.ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING'); ?>
    pagination->getListFooter(); ?>
    id); ?> escape($item->title); ?> escape($item->title); ?> id; ?>
    components/com_users/views/levels/tmpl/index.html000066600000000037150771655450016353 0ustar00 components/com_users/views/levels/index.html000066600000000037150771655450015377 0ustar00 components/com_users/views/level/view.html.php000066600000003574150771655450015656 0ustar00form = $this->get('Form'); $this->item = $this->get('Item'); $this->state = $this->get('State'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { JFactory::getApplication()->input->set('hidemainmenu', true); $isNew = ($this->item->id == 0); $canDo = JHelperContent::getActions('com_users'); JToolbarHelper::title(JText::_($isNew ? 'COM_USERS_VIEW_NEW_LEVEL_TITLE' : 'COM_USERS_VIEW_EDIT_LEVEL_TITLE'), 'users levels-add'); if ($canDo->get('core.edit')||$canDo->get('core.create')) { JToolbarHelper::apply('level.apply'); JToolbarHelper::save('level.save'); } if ($canDo->get('core.create')) { JToolbarHelper::save2new('level.save2new'); } // If an existing item, can save to a copy. if (!$isNew && $canDo->get('core.create')){ JToolbarHelper::save2copy('level.save2copy'); } if (empty($this->item->id)){ JToolbarHelper::cancel('level.cancel'); } else { JToolbarHelper::cancel('level.cancel', 'JTOOLBAR_CLOSE'); } JToolbarHelper::divider(); JToolbarHelper::help('JHELP_USERS_ACCESS_LEVELS_EDIT'); } } components/com_users/views/level/tmpl/edit.php000066600000006116150771655450015635 0ustar00
    form->getLabel('title'); ?>
    form->getInput('title'); ?>
    item->rules); ?>
    components/com_users/views/level/tmpl/index.html000066600000000037150771655450016170 0ustar00 components/com_users/views/level/index.html000066600000000037150771655450015214 0ustar00 components/com_users/index.html000066600000000037150771655450012750 0ustar00 components/com_users/config.xml000066600000013324150771655450012745 0ustar00
    components/com_users/users.php000066600000001227150771655450012627 0ustar00authorise('core.manage', 'com_users')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } JLoader::register('UsersHelper', __DIR__ . '/helpers/users.php'); $controller = JControllerLegacy::getInstance('Users'); $controller->execute(JFactory::getApplication()->input->get('task')); $controller->redirect(); components/com_users/controller.php000066600000006247150771655450013660 0ustar00get('core.admin'); break; // Default permissions. default: return true; } } /** * Method to display a view. * * @param boolean If true, the view output will be cached * @param array An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()}. * * @return JController This object to support chaining. * @since 1.5 */ public function display($cachable = false, $urlparams = false) { $view = $this->input->get('view', 'users'); $layout = $this->input->get('layout', 'default'); $id = $this->input->getInt('id'); if (!$this->canView($view)) { JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); return; } // Check for edit form. if ($view == 'user' && $layout == 'edit' && !$this->checkEditId('com_users.edit.user', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_users&view=users', false)); return false; } elseif ($view == 'group' && $layout == 'edit' && !$this->checkEditId('com_users.edit.group', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_users&view=groups', false)); return false; } elseif ($view == 'level' && $layout == 'edit' && !$this->checkEditId('com_users.edit.level', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_users&view=levels', false)); return false; } elseif ($view == 'note' && $layout == 'edit' && !$this->checkEditId('com_users.edit.note', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_users&view=notes', false)); return false; } return parent::display(); } } components/com_users/controllers/levels.php000066600000001451150771655450015325 0ustar00 true)); } } components/com_users/controllers/groups.php000066600000005135150771655450015355 0ustar00 true)); } /** * Removes an item. * * Overrides JControllerAdmin::delete to check the core.admin permission. * * @since 1.6 */ public function delete() { if (!JFactory::getUser()->authorise('core.admin', $this->option)) { JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); jexit(); } return parent::delete(); } /** * Method to publish a list of records. * * Overrides JControllerAdmin::publish to check the core.admin permission. * * @since 1.6 */ public function publish() { if (!JFactory::getUser()->authorise('core.admin', $this->option)) { JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); jexit(); } return parent::publish(); } /** * Changes the order of one or more records. * * Overrides JControllerAdmin::reorder to check the core.admin permission. * * @since 1.6 */ public function reorder() { if (!JFactory::getUser()->authorise('core.admin', $this->option)) { JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); jexit(); } return parent::reorder(); } /** * Method to save the submitted ordering values for records. * * Overrides JControllerAdmin::saveorder to check the core.admin permission. * * @since 1.6 */ public function saveorder() { if (!JFactory::getUser()->authorise('core.admin', $this->option)) { JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); jexit(); } return parent::saveorder(); } /** * Check in of one or more records. * * Overrides JControllerAdmin::checkin to check the core.admin permission. * * @since 1.6 */ public function checkin() { if (!JFactory::getUser()->authorise('core.admin', $this->option)) { JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); jexit(); } return parent::checkin(); } } components/com_users/controllers/level.php000066600000003601150771655450015141 0ustar00authorise('core.admin', $this->option) && parent::allowSave($data, $key)); } /** * Method to remove a record. */ public function delete() { // Check for request forgeries. JSession::checkToken() or jexit(JText::_('JInvalid_Token')); $ids = $this->input->get('cid', array(), 'array'); if (!JFactory::getUser()->authorise('core.admin', $this->option)) { JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); jexit(); } elseif (empty($ids)) { JError::raiseWarning(500, JText::_('COM_USERS_NO_LEVELS_SELECTED')); } else { // Get the model. $model = $this->getModel(); JArrayHelper::toInteger($ids); // Remove the items. if (!$model->delete($ids)) { JError::raiseWarning(500, $model->getError()); } else { $this->setMessage(JText::plural('COM_USERS_N_LEVELS_DELETED', count($ids))); } } $this->setRedirect('index.php?option=com_users&view=levels'); } } components/com_users/controllers/mail.php000066600000001713150771655450014756 0ustar00getModel('Mail'); if ($model->send()) { $type = 'message'; } else { $type = 'error'; } $msg = $model->getError(); $this->setredirect('index.php?option=com_users&view=mail', $msg, $type); } public function cancel() { // Check for request forgeries. JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); $this->setRedirect('index.php'); } } components/com_users/controllers/group.php000066600000003224150771655450015167 0ustar00authorise('core.admin', $this->option) && parent::allowSave($data, $key)); } /** * Overrides JControllerForm::allowEdit * * Checks that non-Super Admins are not editing Super Admins. * * @param array An array of input data. * @param string The name of the key for the primary key. * * @return boolean * @since 1.6 */ protected function allowEdit($data = array(), $key = 'id') { // Check if this group is a Super Admin if (JAccess::checkGroup($data[$key], 'core.admin')) { // If I'm not a Super Admin, then disallow the edit. if (!JFactory::getUser()->authorise('core.admin')) { return false; } } return parent::allowEdit($data, $key); } } components/com_users/controllers/notes.php000066600000001774150771655450015173 0ustar00 true)) { return parent::getModel($name, $prefix, $config); } } components/com_users/controllers/index.html000066600000000037150771655450015316 0ustar00 components/com_users/controllers/users.php000066600000006234150771655450015200 0ustar00registerTask('block', 'changeBlock'); $this->registerTask('unblock', 'changeBlock'); } /** * Proxy for getModel. * * @param string $name The model name. Optional. * @param string $prefix The class prefix. Optional. * @param array $config Configuration array for model. Optional. * * @return object The model. * * @since 1.6 */ public function getModel($name = 'User', $prefix = 'UsersModel', $config = array('ignore_request' => true)) { return parent::getModel($name, $prefix, $config); } /** * Method to change the block status on a record. * * @return void * * @since 1.6 */ public function changeBlock() { // Check for request forgeries. JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); $ids = $this->input->get('cid', array(), 'array'); $values = array('block' => 1, 'unblock' => 0); $task = $this->getTask(); $value = JArrayHelper::getValue($values, $task, 0, 'int'); if (empty($ids)) { JError::raiseWarning(500, JText::_('COM_USERS_USERS_NO_ITEM_SELECTED')); } else { // Get the model. $model = $this->getModel(); // Change the state of the records. if (!$model->block($ids, $value)) { JError::raiseWarning(500, $model->getError()); } else { if ($value == 1) { $this->setMessage(JText::plural('COM_USERS_N_USERS_BLOCKED', count($ids))); } elseif ($value == 0) { $this->setMessage(JText::plural('COM_USERS_N_USERS_UNBLOCKED', count($ids))); } } } $this->setRedirect('index.php?option=com_users&view=users'); } /** * Method to activate a record. * * @return void * * @since 1.6 */ public function activate() { // Check for request forgeries. JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); $ids = $this->input->get('cid', array(), 'array'); if (empty($ids)) { JError::raiseWarning(500, JText::_('COM_USERS_USERS_NO_ITEM_SELECTED')); } else { // Get the model. $model = $this->getModel(); // Change the state of the records. if (!$model->activate($ids)) { JError::raiseWarning(500, $model->getError()); } else { $this->setMessage(JText::plural('COM_USERS_N_USERS_ACTIVATED', count($ids))); } } $this->setRedirect('index.php?option=com_users&view=users'); } } components/com_users/controllers/user.php000066600000004137150771655450015015 0ustar00authorise('core.admin')) { return false; } } return parent::allowEdit($data, $key); } /** * Method to run batch operations. * * @param object $model The model. * * @return boolean True on success, false on failure * * @since 2.5 */ public function batch($model = null) { JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Set the model $model = $this->getModel('User', '', array()); // Preset the redirect $this->setRedirect(JRoute::_('index.php?option=com_users&view=users' . $this->getRedirectToListAppend(), false)); return parent::batch($model); } /** * Function that allows child controller access to model data after the data has been saved. * * @param JModelLegacy $model The data model object. * @param array $validData The validated data. * * @return void * * @since 3.1 */ protected function postSaveHook(JModelLegacy $model, $validData = array()) { return; } } components/com_users/controllers/note.php000066600000002243150771655450015000 0ustar00input->get('u_id', 0, 'int'); if ($userId) { $append .= '&u_id=' . $userId; } return $append; } } components/com_users/access.xml000066600000002376150771655450012746 0ustar00
    components/com_users/helpers/html/index.html000066600000000037150771655450015356 0ustar00 components/com_users/helpers/html/users.php000066600000011576150771655450015245 0ustar00 element if the specified file exists, otherwise, a null string * * @since 2.5 */ public static function image($src) { $src = preg_replace('#[^A-Z0-9\-_\./]#i', '', $src); $file = JPATH_SITE . '/' . $src; jimport('joomla.filesystem.path'); JPath::check($file); if (!file_exists($file)) { return ''; } return ''; } /** * Displays an icon to add a note for this user. * * @param integer $userId The user ID * * @return string A link to add a note * * @since 2.5 */ public static function addNote($userId) { $title = JText::_('COM_USERS_ADD_NOTE'); return '' . '' . $title . ''; } /** * Displays an icon to filter the notes list on this user. * * @param integer $count The number of notes for the user * @param integer $userId The user ID * * @return string A link to apply a filter * * @since 2.5 */ public static function filterNotes($count, $userId) { if (empty($count)) { return ''; } $title = JText::_('COM_USERS_FILTER_NOTES'); return '' . JHtml::_('image', 'admin/filter_16.png', 'COM_USERS_NOTES', array('title' => $title), true) . ''; } /** * Displays a note icon. * * @param integer $count The number of notes for the user * @param integer $userId The user ID * * @return string A link to a modal window with the user notes * * @since 2.5 */ public static function notes($count, $userId) { if (empty($count)) { return ''; } $title = JText::plural('COM_USERS_N_USER_NOTES', $count); return '' . '' . $title . ''; } /** * Build an array of block/unblock user states to be used by jgrid.state, * State options will be different for any user * and for currently logged in user * * @param boolean $self True if state array is for currently logged in user * * @return array a list of possible states to display * * @since 3.0 */ public static function blockStates( $self = false) { if ($self) { $states = array( 1 => array( 'task' => 'unblock', 'text' => '', 'active_title' => 'COM_USERS_USER_FIELD_BLOCK_DESC', 'inactive_title' => '', 'tip' => true, 'active_class' => 'unpublish', 'inactive_class' => 'unpublish' ), 0 => array( 'task' => 'block', 'text' => '', 'active_title' => '', 'inactive_title' => 'COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF', 'tip' => true, 'active_class' => 'publish', 'inactive_class' => 'publish' ) ); } else { $states = array( 1 => array( 'task' => 'unblock', 'text' => '', 'active_title' => 'COM_USERS_TOOLBAR_UNBLOCK', 'inactive_title' => '', 'tip' => true, 'active_class' => 'unpublish', 'inactive_class' => 'unpublish' ), 0 => array( 'task' => 'block', 'text' => '', 'active_title' => 'COM_USERS_USER_FIELD_BLOCK_DESC', 'inactive_title' => '', 'tip' => true, 'active_class' => 'publish', 'inactive_class' => 'publish' ) ); } return $states; } /** * Build an array of activate states to be used by jgrid.state, * * @return array a list of possible states to display * * @since 3.0 */ public static function activateStates() { $states = array( 1 => array( 'task' => 'activate', 'text' => '', 'active_title' => 'COM_USERS_TOOLBAR_ACTIVATE', 'inactive_title' => '', 'tip' => true, 'active_class' => 'unpublish', 'inactive_class' => 'unpublish' ), 0 => array( 'task' => '', 'text' => '', 'active_title' => '', 'inactive_title' => 'COM_USERS_ACTIVATED', 'tip' => true, 'active_class' => 'publish', 'inactive_class' => 'publish' ) ); return $states; } } components/com_users/helpers/index.html000066600000000037150771655450014412 0ustar00 components/com_users/helpers/debug.php000066600000007576150771655450014233 0ustar00getQuery(true) ->select('name AS text, element AS value') ->from('#__extensions') ->where('enabled >= 1') ->where('type =' . $db->quote('component')); $items = $db->setQuery($query)->loadObjectList(); if (count($items)) { $lang = JFactory::getLanguage(); foreach ($items as &$item) { // Load language $extension = $item->value; $source = JPATH_ADMINISTRATOR . '/components/' . $extension; $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) || $lang->load("$extension.sys", $source, null, false, true); // Translate component name $item->text = JText::_($item->text); } // Sort by component name JArrayHelper::sortObjects($items, 'text', 1, true, true); } return $items; } /** * Get a list of the actions for the component or code actions. * * @param string The name of the component. * * @return array * @since 1.6 */ public static function getDebugActions($component = null) { $actions = array(); // Try to get actions for the component if (!empty($component)) { $component_actions = JAccess::getActions($component); if (!empty($component_actions)) { foreach ($component_actions as &$action) { $actions[$action->title] = array($action->name, $action->description); } } } // Use default actions from configuration if no component selected or component doesn't have actions if (empty($actions)) { $filename = JPATH_ADMINISTRATOR . '/components/com_config/models/forms/application.xml'; if (is_file($filename)) { $xml = simplexml_load_file($filename); foreach ($xml->children()->fieldset as $fieldset) { if ('permissions' == (string) $fieldset['name']) { foreach ($fieldset->children() as $field) { if ('rules' == (string) $field['name']) { foreach ($field->children() as $action) { $actions[(string) $action['title']] = array( (string) $action['name'], (string) $action['description'] ); } break; break; break; } } } } // Load language $lang = JFactory::getLanguage(); $extension = 'com_config'; $source = JPATH_ADMINISTRATOR . '/components/' . $extension; $lang->load($extension, JPATH_ADMINISTRATOR, null, false, false) || $lang->load($extension, $source, null, false, false) || $lang->load($extension, JPATH_ADMINISTRATOR, $lang->getDefault(), false, false) || $lang->load($extension, $source, $lang->getDefault(), false, false); } } return $actions; } /** * Get a list of filter options for the levels. * * @return array An array of JHtmlOption elements. */ public static function getLevelsOptions() { // Build the filter options. $options = array(); $options[] = JHtml::_('select.option', '1', JText::sprintf('COM_USERS_OPTION_LEVEL_COMPONENT', 1)); $options[] = JHtml::_('select.option', '2', JText::sprintf('COM_USERS_OPTION_LEVEL_CATEGORY', 2)); $options[] = JHtml::_('select.option', '3', JText::sprintf('COM_USERS_OPTION_LEVEL_DEEPER', 3)); $options[] = JHtml::_('select.option', '4', '4'); $options[] = JHtml::_('select.option', '5', '5'); $options[] = JHtml::_('select.option', '6', '6'); return $options; } } components/com_users/helpers/users.php000066600000012743150771655450014276 0ustar00get('core.admin')) { JHtmlSidebar::addEntry( JText::_('COM_USERS_SUBMENU_GROUPS'), 'index.php?option=com_users&view=groups', $vName == 'groups' ); JHtmlSidebar::addEntry( JText::_('COM_USERS_SUBMENU_LEVELS'), 'index.php?option=com_users&view=levels', $vName == 'levels' ); JHtmlSidebar::addEntry( JText::_('COM_USERS_SUBMENU_NOTES'), 'index.php?option=com_users&view=notes', $vName == 'notes' ); $extension = JFactory::getApplication()->input->getString('extension'); JHtmlSidebar::addEntry( JText::_('COM_USERS_SUBMENU_NOTE_CATEGORIES'), 'index.php?option=com_categories&extension=com_users', $vName == 'categories' || $extension == 'com_users' ); } } /** * Gets a list of the actions that can be performed. * * @return JObject * * @deprecated 3.2 Use JHelperContent::getActions() instead */ public static function getActions() { // Log usage of deprecated function JLog::add(__METHOD__ . '() is deprecated, use JHelperContent::getActions() with new arguments order instead.', JLog::WARNING, 'deprecated'); // Get list of actions $result = JHelperContent::getActions('com_users'); return $result; } /** * Get a list of filter options for the blocked state of a user. * * @return array An array of JHtmlOption elements. * * @since 1.6 */ public static function getStateOptions() { // Build the filter options. $options = array(); $options[] = JHtml::_('select.option', '0', JText::_('JENABLED')); $options[] = JHtml::_('select.option', '1', JText::_('JDISABLED')); return $options; } /** * Get a list of filter options for the activated state of a user. * * @return array An array of JHtmlOption elements. * * @since 1.6 */ public static function getActiveOptions() { // Build the filter options. $options = array(); $options[] = JHtml::_('select.option', '0', JText::_('COM_USERS_ACTIVATED')); $options[] = JHtml::_('select.option', '1', JText::_('COM_USERS_UNACTIVATED')); return $options; } /** * Get a list of the user groups for filtering. * * @return array An array of JHtmlOption elements. * * @since 1.6 */ public static function getGroups() { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('a.id AS value') ->select('a.title AS text') ->select('COUNT(DISTINCT b.id) AS level') ->from('#__usergroups as a') ->join('LEFT', '#__usergroups AS b ON a.lft > b.lft AND a.rgt < b.rgt') ->group('a.id, a.title, a.lft, a.rgt') ->order('a.lft ASC'); $db->setQuery($query); try { $options = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseNotice(500, $e->getMessage()); return null; } foreach ($options as &$option) { $option->text = str_repeat('- ', $option->level).$option->text; } return $options; } /** * Creates a list of range options used in filter select list * used in com_users on users view * * @return array * * @since 2.5 */ public static function getRangeOptions() { $options = array( JHtml::_('select.option', 'today', JText::_('COM_USERS_OPTION_RANGE_TODAY')), JHtml::_('select.option', 'past_week', JText::_('COM_USERS_OPTION_RANGE_PAST_WEEK')), JHtml::_('select.option', 'past_1month', JText::_('COM_USERS_OPTION_RANGE_PAST_1MONTH')), JHtml::_('select.option', 'past_3month', JText::_('COM_USERS_OPTION_RANGE_PAST_3MONTH')), JHtml::_('select.option', 'past_6month', JText::_('COM_USERS_OPTION_RANGE_PAST_6MONTH')), JHtml::_('select.option', 'past_year', JText::_('COM_USERS_OPTION_RANGE_PAST_YEAR')), JHtml::_('select.option', 'post_year', JText::_('COM_USERS_OPTION_RANGE_POST_YEAR')), ); return $options; } /** * Creates a list of two factor authentication methods used in com_users * on user view * * @return array * * @since 3.2.0 */ public static function getTwoFactorMethods() { // Load the Joomla! RAD layer if (!defined('FOF_INCLUDED')) { include_once JPATH_LIBRARIES . '/fof/include.php'; } FOFPlatform::getInstance()->importPlugin('twofactorauth'); $identities = FOFPlatform::getInstance()->runPlugins('onUserTwofactorIdentify', array()); $options = array( JHtml::_('select.option', 'none', JText::_('JGLOBAL_OTPMETHOD_NONE'), 'value', 'text'), ); if (!empty($identities)) { foreach ($identities as $identity) { if (!is_object($identity)) { continue; } $options[] = JHtml::_('select.option', $identity->method, $identity->title, 'value', 'text'); } } return $options; } } components/com_users/models/debuggroup.php000066600000013643150771655450015121 0ustar00getState('filter.component'); return UsersHelperDebug::getDebugActions($component); } /** * Override getItems method. * * @return array * @since 1.6 */ public function getItems() { $groupId = $this->getState('filter.group_id'); if (($assets = parent::getItems()) && $groupId) { $actions = $this->getDebugActions(); foreach ($assets as &$asset) { $asset->checks = array(); foreach ($actions as $action) { $name = $action[0]; $level = $action[1]; // Check that we check this action for the level of the asset. if ($level === null || $level >= $asset->level) { // We need to test this action. $asset->checks[$name] = JAccess::checkGroup($groupId, $name, $asset->name); } else { // We ignore this action. $asset->checks[$name] = 'skip'; } } } } return $assets; } /** * Method to auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @return void * @since 1.6 */ protected function populateState($ordering = null, $direction = null) { $app = JFactory::getApplication('administrator'); // Adjust the context to support modal layouts. $layout = $app->input->get('layout', 'default'); if ($layout) { $this->context .= '.' . $layout; } // Load the filter state. $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $value = $this->getUserStateFromRequest($this->context . '.filter.group_id', 'group_id', 0, 'int', false); $this->setState('filter.group_id', $value); $levelStart = $this->getUserStateFromRequest($this->context . '.filter.level_start', 'filter_level_start', 0, 'int'); $this->setState('filter.level_start', $levelStart); $value = $this->getUserStateFromRequest($this->context . '.filter.level_end', 'filter_level_end', 0, 'int'); if ($value > 0 && $value < $levelStart) { $value = $levelStart; } $this->setState('filter.level_end', $value); $component = $this->getUserStateFromRequest($this->context . '.filter.component', 'filter_component'); $this->setState('filter.component', $component); // Load the parameters. $params = JComponentHelper::getParams('com_users'); $this->setState('params', $params); // List state information. parent::populateState('a.lft', 'asc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. * * @return string A store id. * @since 1.6 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.level_start'); $id .= ':' . $this->getState('filter.level_end'); $id .= ':' . $this->getState('filter.component'); return parent::getStoreId($id); } /** * Get the group being debugged. * * @return JObject * @since 1.6 */ public function getGroup() { $groupId = (int) $this->getState('filter.group_id'); $db = $this->getDbo(); $query = $db->getQuery(true) ->select('id, title') ->from('#__usergroups') ->where('id = ' . $groupId); $db->setQuery($query); try { $group = $db->loadObject(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } return $group; } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery * @since 1.6 */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.id, a.name, a.title, a.level, a.lft, a.rgt' ) ); $query->from($db->quoteName('#__assets') . ' AS a'); // Filter the items over the search string if set. if ($this->getState('filter.search')) { // Escape the search token. $token = $db->quote('%' . $db->escape($this->getState('filter.search')) . '%'); // Compile the different search clauses. $searches = array(); $searches[] = 'a.name LIKE ' . $token; $searches[] = 'a.title LIKE ' . $token; // Add the clauses to the query. $query->where('(' . implode(' OR ', $searches) . ')'); } // Filter on the start and end levels. $levelStart = (int) $this->getState('filter.level_start'); $levelEnd = (int) $this->getState('filter.level_end'); if ($levelEnd > 0 && $levelEnd < $levelStart) { $levelEnd = $levelStart; } if ($levelStart > 0) { $query->where('a.level >= ' . $levelStart); } if ($levelEnd > 0) { $query->where('a.level <= ' . $levelEnd); } // Filter the items over the component if set. if ($this->getState('filter.component')) { $component = $this->getState('filter.component'); $query->where('(a.name = ' . $db->quote($component) . ' OR a.name LIKE ' . $db->quote($component . '.%') . ')'); } // Add the list ordering clause. $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); return $query; } } components/com_users/models/levels.php000066600000012002150771655450014234 0ustar00getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); // Load the parameters. $params = JComponentHelper::getParams('com_users'); $this->setState('params', $params); // List state information. parent::populateState('a.title', 'asc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. * * @return string A store id. */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); return parent::getStoreId($id); } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.*' ) ); $query->from($db->quoteName('#__viewlevels') . ' AS a'); // Add the level in the tree. $query->group('a.id, a.title, a.ordering, a.rules'); // Filter the items over the search string if set. $search = $this->getState('filter.search'); if (!empty($search)) { if (stripos($search, 'id:') === 0) { $query->where('a.id = ' . (int) substr($search, 3)); } else { $search = $db->quote('%' . $db->escape($search, true) . '%'); $query->where('a.title LIKE ' . $search); } } $query->group('a.id'); // Add the list ordering clause. $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); //echo nl2br(str_replace('#__','jos_',$query)); return $query; } /** * Method to adjust the ordering of a row. * * @param integer The ID of the primary key to move. * @param integer Increment, usually +1 or -1 * @return boolean False on failure or error, true otherwise. */ public function reorder($pk, $direction = 0) { // Sanitize the id and adjustment. $pk = (!empty($pk)) ? $pk : (int) $this->getState('level.id'); $user = JFactory::getUser(); // Get an instance of the record's table. $table = JTable::getInstance('viewlevel'); // Load the row. if (!$table->load($pk)) { $this->setError($table->getError()); return false; } // Access checks. $allow = $user->authorise('core.edit.state', 'com_users'); if (!$allow) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); return false; } // Move the row. // TODO: Where clause to restrict category. $table->move($pk); return true; } /** * Saves the manually set order of records. * * @param array An array of primary key ids. * @param integer +/-1 */ public function saveorder($pks, $order) { $table = JTable::getInstance('viewlevel'); $user = JFactory::getUser(); $conditions = array(); if (empty($pks)) { return JError::raiseWarning(500, JText::_('COM_USERS_ERROR_LEVELS_NOLEVELS_SELECTED')); } // update ordering values foreach ($pks as $i => $pk) { $table->load((int) $pk); // Access checks. $allow = $user->authorise('core.edit.state', 'com_users'); if (!$allow) { // Prune items that you can't change. unset($pks[$i]); JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); } elseif ($table->ordering != $order[$i]) { $table->ordering = $order[$i]; if (!$table->store()) { $this->setError($table->getError()); return false; } } } // Execute reorder for each category. foreach ($conditions as $cond) { $table->load($cond[0]); $table->reorder($cond[1]); } return true; } } components/com_users/models/groups.php000066600000011617150771655450014274 0ustar00getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); // Load the parameters. $params = JComponentHelper::getParams('com_users'); $this->setState('params', $params); // List state information. parent::populateState('a.lft', 'asc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. * * @return string A store id. */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.search'); return parent::getStoreId($id); } /** * Gets the list of groups and adds expensive joins to the result set. * * @return mixed An array of data items on success, false on failure. * @since 1.6 */ public function getItems() { $db = $this->getDbo(); // Get a storage key. $store = $this->getStoreId(); // Try to load the data from internal storage. if (empty($this->cache[$store])) { $items = parent::getItems(); // Bail out on an error or empty list. if (empty($items)) { $this->cache[$store] = $items; return $items; } // First pass: get list of the group id's and reset the counts. $groupIds = array(); foreach ($items as $item) { $groupIds[] = (int) $item->id; $item->user_count = 0; } // Get the counts from the database only for the users in the list. $query = $db->getQuery(true); // Count the objects in the user group. $query->select('map.group_id, COUNT(DISTINCT map.user_id) AS user_count') ->from($db->quoteName('#__user_usergroup_map') . ' AS map') ->where('map.group_id IN (' . implode(',', $groupIds) . ')') ->group('map.group_id'); $db->setQuery($query); // Load the counts into an array indexed on the user id field. try { $users = $db->loadObjectList('group_id'); } catch (RuntimeException $e) { $this->setError($e->getMessage); return false; } // Second pass: collect the group counts into the master items array. foreach ($items as &$item) { if (isset($users[$item->id])) { $item->user_count = $users[$item->id]->user_count; } } // Add the items to the internal cache. $this->cache[$store] = $items; } return $this->cache[$store]; } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.*' ) ); $query->from($db->quoteName('#__usergroups') . ' AS a'); // Add the level in the tree. $query->select('COUNT(DISTINCT c2.id) AS level') ->join('LEFT OUTER', $db->quoteName('#__usergroups') . ' AS c2 ON a.lft > c2.lft AND a.rgt < c2.rgt') ->group('a.id, a.lft, a.rgt, a.parent_id, a.title'); // Filter the comments over the search string if set. $search = $this->getState('filter.search'); if (!empty($search)) { if (stripos($search, 'id:') === 0) { $query->where('a.id = ' . (int) substr($search, 3)); } else { $search = $db->quote('%' . $db->escape($search, true) . '%'); $query->where('a.title LIKE ' . $search); } } // Add the list ordering clause. $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); //echo nl2br(str_replace('#__','jos_',$query)); return $query; } } components/com_users/models/level.php000066600000012034150771655450014056 0ustar00levelsInUse === null) { // Populate the list once. $this->levelsInUse = array(); $db = $this->getDbo(); $query = $db->getQuery(true) ->select('DISTINCT access'); // from is added dynamically // Get all the tables and the prefix $tables = $db->getTableList(); //$fields = $db->getTableFields($tables); $prefix = $db->getPrefix(); foreach ($tables as $table) { // Get all of the columns in the table $fields = $db->getTableColumns($table); // We are looking for the access field. If custom tables are using something other // than the 'access' field they are on their own unfortunately. // Also make sure the table prefix matches the live db prefix (eg, it is not a "bak_" table) if ((strpos($table, $prefix) === 0) && (isset($fields['access']))) { // Lookup the distinct values of the field. $query->clear('from') ->from($db->quoteName($table)); $db->setQuery($query); try { $values = $db->loadColumn(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } $this->levelsInUse = array_merge($this->levelsInUse, $values); // TODO Could assemble an array of the tables used by each view level list those, // giving the user a clue in the error where to look. } } // Get uniques. $this->levelsInUse = array_unique($this->levelsInUse); // Ok, after all that we are ready to check the record :) } if (in_array($record->id, $this->levelsInUse)) { $this->setError(JText::sprintf('COM_USERS_ERROR_VIEW_LEVEL_IN_USE', $record->id, $record->title)); return false; } return parent::canDelete($record); } /** * Returns a reference to the a Table object, always creating it. * * @param type The table type to instantiate * @param string A prefix for the table class name. Optional. * @param array Configuration array for model. Optional. * @return JTable A database object * @since 1.6 */ public function getTable($type = 'Viewlevel', $prefix = 'JTable', $config = array()) { $return = JTable::getInstance($type, $prefix, $config); return $return; } /** * Method to get a single record. * * @param integer The id of the primary key. * @return mixed Object on success, false on failure. * @since 1.6 */ public function getItem($pk = null) { $result = parent::getItem($pk); // Convert the params field to an array. $result->rules = json_decode($result->rules); return $result; } /** * Method to get the record form. * * @param array $data An optional array of data for the form to interogate. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * @return JForm A JForm object on success, false on failure * @since 1.6 */ public function getForm($data = array(), $loadData = true) { // Get the form. $form = $this->loadForm('com_users.level', 'level', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * @since 1.6 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_users.edit.level.data', array()); if (empty($data)) { $data = $this->getItem(); } $this->preprocessData('com_users.level', $data); return $data; } /** * Override preprocessForm to load the user plugin group instead of content. * * @param object A form object. * @param mixed The data expected for the form. * @throws Exception if there is an error in the form event. * @since 1.6 */ protected function preprocessForm(JForm $form, $data, $groups = '') { parent::preprocessForm($form, $data, 'user'); } /** * Method to save the form data. * * @param array The form data. * @return boolean True on success. * @since 1.6 */ public function save($data) { if (!isset($data['rules'])) { $data['rules'] = array(); } return parent::save($data); } } components/com_users/models/mail.php000066600000012461150771655450013675 0ustar00loadForm('com_users.mail', 'mail', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * @since 1.6 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_users.display.mail.data', array()); $this->preprocessData('com_users.mail', $data); return $data; } /** * Override preprocessForm to load the user plugin group instead of content. * * @param object A form object. * @param mixed The data expected for the form. * @throws Exception if there is an error in the form event. * @since 1.6 */ protected function preprocessForm(JForm $form, $data, $group = 'user') { parent::preprocessForm($form, $data, $group); } public function send() { $app = JFactory::getApplication(); $data = $app->input->post->get('jform', array(), 'array'); $user = JFactory::getUser(); $access = new JAccess; $db = $this->getDbo(); $mode = array_key_exists('mode', $data) ? (int) $data['mode'] : 0; $subject = array_key_exists('subject', $data) ? $data['subject'] : ''; $grp = array_key_exists('group', $data) ? (int) $data['group'] : 0; $recurse = array_key_exists('recurse', $data) ? (int) $data['recurse'] : 0; $bcc = array_key_exists('bcc', $data) ? (int) $data['bcc'] : 0; $disabled = array_key_exists('disabled', $data) ? (int) $data['disabled'] : 0; $message_body = array_key_exists('message', $data) ? $data['message'] : ''; // automatically removes html formatting if (!$mode) { $message_body = JFilterInput::getInstance()->clean($message_body, 'string'); } // Check for a message body and subject if (!$message_body || !$subject) { $app->setUserState('com_users.display.mail.data', $data); $this->setError(JText::_('COM_USERS_MAIL_PLEASE_FILL_IN_THE_FORM_CORRECTLY')); return false; } // get users in the group out of the acl $to = $access->getUsersByGroup($grp, $recurse); // Get all users email and group except for senders $query = $db->getQuery(true) ->select('email') ->from('#__users') ->where('id != '.(int) $user->get('id')); if ($grp !== 0) { if (empty($to)) { $query->where('0'); } else { $query->where('id IN (' . implode(',', $to) . ')'); } } if ($disabled == 0){ $query->where("block = 0"); } $db->setQuery($query); $rows = $db->loadColumn(); // Check to see if there are any users in this group before we continue if (!count($rows)) { $app->setUserState('com_users.display.mail.data', $data); if (in_array($user->id, $to)) { $this->setError(JText::_('COM_USERS_MAIL_ONLY_YOU_COULD_BE_FOUND_IN_THIS_GROUP')); } else { $this->setError(JText::_('COM_USERS_MAIL_NO_USERS_COULD_BE_FOUND_IN_THIS_GROUP')); } return false; } // Get the Mailer $mailer = JFactory::getMailer(); $params = JComponentHelper::getParams('com_users'); // Build email message format. $mailer->setSender(array($app->getCfg('mailfrom'), $app->getCfg('fromname'))); $mailer->setSubject($params->get('mailSubjectPrefix') . stripslashes($subject)); $mailer->setBody($message_body . $params->get('mailBodySuffix')); $mailer->IsHTML($mode); // Add recipients if ($bcc) { $mailer->addBCC($rows); $mailer->addRecipient($app->getCfg('mailfrom')); } else { $mailer->addRecipient($rows); } // Send the Mail $rs = $mailer->Send(); // Check for an error if ($rs instanceof Exception) { $app->setUserState('com_users.display.mail.data', $data); $this->setError($rs->getError()); return false; } elseif (empty($rs)) { $app->setUserState('com_users.display.mail.data', $data); $this->setError(JText::_('COM_USERS_MAIL_THE_MAIL_COULD_NOT_BE_SENT')); return false; } else { // Fill the data (specially for the 'mode', 'group' and 'bcc': they could not exist in the array // when the box is not checked and in this case, the default value would be used instead of the '0' // one) $data['mode'] = $mode; $data['subject'] = $subject; $data['group'] = $grp; $data['recurse'] = $recurse; $data['bcc'] = $bcc; $data['message'] = $message_body; $app->setUserState('com_users.display.mail.data', array()); $app->enqueueMessage(JText::plural('COM_USERS_MAIL_EMAIL_SENT_TO_N_USERS', count($rows)), 'message'); return true; } } } components/com_users/models/group.php000066600000016600150771655450014106 0ustar00loadForm('com_users.group', 'group', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * @since 1.6 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_users.edit.group.data', array()); if (empty($data)) { $data = $this->getItem(); } $this->preprocessData('com_users.group', $data); return $data; } /** * Override preprocessForm to load the user plugin group instead of content. * * @param object A form object. * @param mixed The data expected for the form. * @throws Exception if there is an error in the form event. * @since 1.6 */ protected function preprocessForm(JForm $form, $data, $groups = '') { $obj = is_array($data) ? JArrayHelper::toObject($data, 'JObject') : $data; if (isset($obj->parent_id) && $obj->parent_id == 0 && $obj->id > 0) { $form->setFieldAttribute('parent_id', 'type', 'hidden'); $form->setFieldAttribute('parent_id', 'hidden', 'true'); } parent::preprocessForm($form, $data, 'user'); } /** * Method to save the form data. * * @param array The form data. * @return boolean True on success. * @since 1.6 */ public function save($data) { // Include the content plugins for events. JPluginHelper::importPlugin('user'); // Check the super admin permissions for group // We get the parent group permissions and then check the group permissions manually // We have to calculate the group permissions manually because we haven't saved the group yet $parentSuperAdmin = JAccess::checkGroup($data['parent_id'], 'core.admin'); // Get core.admin rules from the root asset $rules = JAccess::getAssetRules('root.1')->getData('core.admin'); // Get the value for the current group (will be true (allowed), false (denied), or null (inherit) $groupSuperAdmin = $rules['core.admin']->allow($data['id']); // We only need to change the $groupSuperAdmin if the parent is true or false. Otherwise, the value set in the rule takes effect. if ($parentSuperAdmin === false) { // If parent is false (Denied), effective value will always be false $groupSuperAdmin = false; } elseif ($parentSuperAdmin === true) { // If parent is true (allowed), group is true unless explicitly set to false $groupSuperAdmin = ($groupSuperAdmin === false) ? false : true; } // Check for non-super admin trying to save with super admin group $iAmSuperAdmin = JFactory::getUser()->authorise('core.admin'); if ((!$iAmSuperAdmin) && ($groupSuperAdmin)) { try { throw new Exception(JText::_('JLIB_USER_ERROR_NOT_SUPERADMIN')); } catch (Exception $e) { $this->setError($e->getMessage()); return false; } } // Check for super-admin changing self to be non-super-admin // First, are we a super admin> if ($iAmSuperAdmin) { // Next, are we a member of the current group? $myGroups = JAccess::getGroupsByUser(JFactory::getUser()->get('id'), false); if (in_array($data['id'], $myGroups)) { // Now, would we have super admin permissions without the current group? $otherGroups = array_diff($myGroups, array($data['id'])); $otherSuperAdmin = false; foreach ($otherGroups as $otherGroup) { $otherSuperAdmin = ($otherSuperAdmin) ? $otherSuperAdmin : JAccess::checkGroup($otherGroup, 'core.admin'); } // If we would not otherwise have super admin permissions // and the current group does not have super admin permissions, throw an exception if ((!$otherSuperAdmin) && (!$groupSuperAdmin)) { try { throw new Exception(JText::_('JLIB_USER_ERROR_CANNOT_DEMOTE_SELF')); } catch (Exception $e) { $this->setError($e->getMessage()); return false; } } } } // Proceed with the save return parent::save($data); } /** * Method to delete rows. * * @param array An array of item ids. * @return boolean Returns true on success, false on failure. * @since 1.6 */ public function delete(&$pks) { // Typecast variable. $pks = (array) $pks; $user = JFactory::getUser(); $groups = JAccess::getGroupsByUser($user->get('id')); // Get a row instance. $table = $this->getTable(); // Load plugins. JPluginHelper::importPlugin('user'); $dispatcher = JEventDispatcher::getInstance(); // Check if I am a Super Admin $iAmSuperAdmin = $user->authorise('core.admin'); // do not allow to delete groups to which the current user belongs foreach ($pks as $pk) { if (in_array($pk, $groups)) { JError::raiseWarning(403, JText::_('COM_USERS_DELETE_ERROR_INVALID_GROUP')); return false; } } // Iterate the items to delete each one. foreach ($pks as $i => $pk) { if ($table->load($pk)) { // Access checks. $allow = $user->authorise('core.edit.state', 'com_users'); // Don't allow non-super-admin to delete a super admin $allow = (!$iAmSuperAdmin && JAccess::checkGroup($pk, 'core.admin')) ? false : $allow; if ($allow) { // Fire the onUserBeforeDeleteGroup event. $dispatcher->trigger('onUserBeforeDeleteGroup', array($table->getProperties())); if (!$table->delete($pk)) { $this->setError($table->getError()); return false; } else { // Trigger the onUserAfterDeleteGroup event. $dispatcher->trigger('onUserAfterDeleteGroup', array($table->getProperties(), true, $this->getError())); } } else { // Prune items that you can't change. unset($pks[$i]); JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); } } else { $this->setError($table->getError()); return false; } } return true; } } components/com_users/models/users.php.backup000066600000025074150771655450015364 0ustar00input->get('layout', 'default', 'cmd')) { $this->context .= '.' . $layout; } // Load the filter state. $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $active = $this->getUserStateFromRequest($this->context . '.filter.active', 'filter_active'); $this->setState('filter.active', $active); $state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state'); $this->setState('filter.state', $state); $groupId = $this->getUserStateFromRequest($this->context . '.filter.group', 'filter_group_id', null, 'int'); $this->setState('filter.group_id', $groupId); $range = $this->getUserStateFromRequest($this->context . '.filter.range', 'filter_range'); $this->setState('filter.range', $range); $groups = json_decode(base64_decode($app->input->get('groups', '', 'BASE64'))); if (isset($groups)) { JArrayHelper::toInteger($groups); } $this->setState('filter.groups', $groups); $excluded = json_decode(base64_decode($app->input->get('excluded', '', 'BASE64'))); if (isset($excluded)) { JArrayHelper::toInteger($excluded); } $this->setState('filter.excluded', $excluded); // Load the parameters. $params = JComponentHelper::getParams('com_users'); $this->setState('params', $params); // List state information. parent::populateState('a.name', 'asc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. * * @return string A store id. * * @since 1.6 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.active'); $id .= ':' . $this->getState('filter.state'); $id .= ':' . $this->getState('filter.group_id'); $id .= ':' . $this->getState('filter.range'); return parent::getStoreId($id); } /** * Gets the list of users and adds expensive joins to the result set. * * @return mixed An array of data items on success, false on failure. * * @since 1.6 */ public function getItems() { // Get a storage key. $store = $this->getStoreId(); // Try to load the data from internal storage. if (empty($this->cache[$store])) { $groups = $this->getState('filter.groups'); $groupId = $this->getState('filter.group_id'); if (isset($groups) && (empty($groups) || $groupId && !in_array($groupId, $groups))) { $items = array(); } else { $items = parent::getItems(); } // Bail out on an error or empty list. if (empty($items)) { $this->cache[$store] = $items; return $items; } // Joining the groups with the main query is a performance hog. // Find the information only on the result set. // First pass: get list of the user id's and reset the counts. $userIds = array(); foreach ($items as $item) { $userIds[] = (int) $item->id; $item->group_count = 0; $item->group_names = ''; $item->note_count = 0; } // Get the counts from the database only for the users in the list. $db = $this->getDbo(); $query = $db->getQuery(true); // Join over the group mapping table. $query->select('map.user_id, COUNT(map.group_id) AS group_count') ->from('#__user_usergroup_map AS map') ->where('map.user_id IN (' . implode(',', $userIds) . ')') ->group('map.user_id') // Join over the user groups table. ->join('LEFT', '#__usergroups AS g2 ON g2.id = map.group_id'); $db->setQuery($query); // Load the counts into an array indexed on the user id field. try { $userGroups = $db->loadObjectList('user_id'); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } $query->clear() ->select('n.user_id, COUNT(n.id) As note_count') ->from('#__user_notes AS n') ->where('n.user_id IN (' . implode(',', $userIds) . ')') ->where('n.state >= 0') ->group('n.user_id'); $db->setQuery($query); // Load the counts into an array indexed on the aro.value field (the user id). try { $userNotes = $db->loadObjectList('user_id'); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } // Second pass: collect the group counts into the master items array. foreach ($items as &$item) { if (isset($userGroups[$item->id])) { $item->group_count = $userGroups[$item->id]->group_count; //Group_concat in other databases is not supported $item->group_names = $this->_getUserDisplayedGroups($item->id); } if (isset($userNotes[$item->id])) { $item->note_count = $userNotes[$item->id]->note_count; } } // Add the items to the internal cache. $this->cache[$store] = $items; } return $this->cache[$store]; } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery * * @since 1.6 */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.*' ) ); $query->from($db->quoteName('#__users') . ' AS a'); // If the model is set to check item state, add to the query. $state = $this->getState('filter.state'); if (is_numeric($state)) { $query->where('a.block = ' . (int) $state); } // If the model is set to check the activated state, add to the query. $active = $this->getState('filter.active'); if (is_numeric($active)) { if ($active == '0') { $query->where('a.activation = ' . $db->quote('')); } elseif ($active == '1') { $query->where($query->length('a.activation') . ' = 32'); } } // Filter the items over the group id if set. $groupId = $this->getState('filter.group_id'); $groups = $this->getState('filter.groups'); if ($groupId || isset($groups)) { $query->join('LEFT', '#__user_usergroup_map AS map2 ON map2.user_id = a.id') ->group($db->quoteName(array('a.id', 'a.name', 'a.username', 'a.password', 'a.block', 'a.sendEmail', 'a.registerDate', 'a.lastvisitDate', 'a.activation', 'a.params', 'a.email'))); if ($groupId) { $query->where('map2.group_id = ' . (int) $groupId); } if (isset($groups)) { $query->where('map2.group_id IN (' . implode(',', $groups) . ')'); } } // Filter the items over the search string if set. if ($this->getState('filter.search') !== '') { // Escape the search token. $token = $db->quote('%' . $db->escape($this->getState('filter.search')) . '%'); // Compile the different search clauses. $searches = array(); $searches[] = 'a.name LIKE ' . $token; $searches[] = 'a.username LIKE ' . $token; $searches[] = 'a.email LIKE ' . $token; // Add the clauses to the query. $query->where('(' . implode(' OR ', $searches) . ')'); } // Add filter for registration ranges select list $range = $this->getState('filter.range'); // Apply the range filter. if ($range = $this->getState('filter.range')) { // Get UTC for now. $dNow = new JDate; $dStart = clone $dNow; switch ($range) { case 'past_week': $dStart->modify('-7 day'); break; case 'past_1month': $dStart->modify('-1 month'); break; case 'past_3month': $dStart->modify('-3 month'); break; case 'past_6month': $dStart->modify('-6 month'); break; case 'post_year': case 'past_year': $dStart->modify('-1 year'); break; case 'today': // Ranges that need to align with local 'days' need special treatment. $app = JFactory::getApplication(); $offset = $app->getCfg('offset'); // Reset the start time to be the beginning of today, local time. $dStart = new JDate('now', $offset); $dStart->setTime(0, 0, 0); // Now change the timezone back to UTC. $tz = new DateTimeZone('GMT'); $dStart->setTimezone($tz); break; } if ($range == 'post_year') { $query->where( 'a.registerDate < ' . $db->quote($dStart->format('Y-m-d H:i:s')) ); } else { $query->where( 'a.registerDate >= ' . $db->quote($dStart->format('Y-m-d H:i:s')) . ' AND a.registerDate <=' . $db->quote($dNow->format('Y-m-d H:i:s')) ); } } // Filter by excluded users $excluded = $this->getState('filter.excluded'); if (!empty($excluded)) { $query->where('id NOT IN (' . implode(',', $excluded) . ')'); } // Add the list ordering clause. $query->order($db->escape($this->getState('list.ordering', 'a.name')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); return $query; } //sqlsrv change function _getUserDisplayedGroups($user_id) { $db = JFactory::getDbo(); $query = "SELECT title FROM " . $db->quoteName('#__usergroups') . " ug left join " . $db->quoteName('#__user_usergroup_map') . " map on (ug.id = map.group_id)" . " WHERE map.user_id=" . $user_id; $db->setQuery($query); $result = $db->loadColumn(); return implode("\n", $result); } } components/com_users/models/notes.php000066600000012735150771655450014107 0ustar00getDbo(); $query = $db->getQuery(true); $section = $this->getState('filter.category_id'); // Select the required fields from the table. $query->select( $this->getState('list.select', 'a.id, a.subject, a.checked_out, a.checked_out_time,' . 'a.catid, a.created_time, a.review_time,' . 'a.state, a.publish_up, a.publish_down' ) ); $query->from('#__user_notes AS a'); // Join over the category $query->select('c.title AS category_title, c.params AS category_params') ->join('LEFT', '#__categories AS c ON c.id = a.catid'); // Join over the users for the note user. $query->select('u.name AS user_name') ->join('LEFT', '#__users AS u ON u.id = a.user_id'); // Join over the users for the checked out user. $query->select('uc.name AS editor') ->join('LEFT', '#__users AS uc ON uc.id = a.checked_out'); // Filter by search in title $search = $this->getState('filter.search'); if (!empty($search)) { if (stripos($search, 'id:') === 0) { $query->where('a.id = ' . (int) substr($search, 3)); } elseif (stripos($search, 'uid:') === 0) { $query->where('a.user_id = ' . (int) substr($search, 4)); } else { $search = $db->quote('%' . $db->escape($search, true) . '%'); $query->where('((a.subject LIKE ' . $search . ') OR (u.name LIKE ' . $search . ') OR (u.username LIKE ' . $search . '))'); } } // Filter by published state $published = $this->getState('filter.state'); if (is_numeric($published)) { $query->where('a.state = '.(int) $published); } elseif ($published === '') { $query->where('(a.state IN (0, 1))'); } // Filter by a single or group of categories. $categoryId = (int) $this->getState('filter.category_id'); if ($categoryId) { if (is_scalar($section)) { $query->where('a.catid = ' . $categoryId); } } // Filter by a single user. $userId = (int) $this->getState('filter.user_id'); if ($userId) { // Add the body and where filter. $query->select('a.body') ->where('a.user_id = ' . $userId); } // Add the list ordering clause. $orderCol = $this->state->get('list.ordering'); $orderDirn = $this->state->get('list.direction'); $query->order($db->escape($orderCol . ' ' . $orderDirn)); return $query; } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. * * @return string A store id. * * @since 2.5 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.state'); $id .= ':' . $this->getState('filter.category_id'); return parent::getStoreId($id); } /** * Gets a user object if the user filter is set. * * @return JUser The JUser object * * @since 2.5 */ public function getUser() { $user = new JUser; // Filter by search in title $search = JFactory::getApplication()->input->get('u_id', 0, 'int'); if ($search != 0) { $user->load((int) $search); } return $user; } /** * Method to auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @return void * * @since 1.6 */ protected function populateState($ordering = null, $direction = null) { $app = JFactory::getApplication(); $input = $app->input; // Adjust the context to support modal layouts. if ($layout = $input->get('layout')) { $this->context .= '.' . $layout; } $value = $app->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $value); $published = $this->getUserStateFromRequest($this->context.'.filter.state', 'filter_published', '', 'string'); $this->setState('filter.state', $published); $section = $app->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id'); $this->setState('filter.category_id', $section); $userId = $input->get('u_id', 0, 'int'); $this->setState('filter.user_id', $userId); parent::populateState('a.review_time', 'DESC'); } } components/com_users/models/index.html000066600000000037150771655450014233 0ustar00 components/com_users/models/fields/groupparent.php000066600000004207150771655450016566 0ustar00getQuery(true) ->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level') ->from('#__usergroups AS a') ->join('LEFT', $db->quoteName('#__usergroups') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt'); // Prevent parenting to children of this item. if ($id = $this->form->getValue('id')) { $query->join('LEFT', $db->quoteName('#__usergroups') . ' AS p ON p.id = ' . (int) $id) ->where('NOT(a.lft >= p.lft AND a.rgt <= p.rgt)'); } $query->group('a.id, a.title, a.lft, a.rgt') ->order('a.lft ASC'); // Get the options. $db->setQuery($query); try { $options = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage()); } // Pad the option text with spaces using depth level as a multiplier. for ($i = 0, $n = count($options); $i < $n; $i++) { // Show groups only if user is super admin or group is not super admin if ($user->authorise('core.admin') || (!JAccess::checkGroup($options[$i]->value, 'core.admin'))) { $options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->text; } else { unset($options[$i]); } } // Merge any additional options in the XML definition. $options = array_merge(parent::getOptions(), $options); return $options; } } components/com_users/models/fields/index.html000066600000000037150771655450015501 0ustar00 components/com_users/models/forms/filter_users.xml000066600000005456150771655450016626 0ustar00
    components/com_users/models/forms/group.xml000066600000001252150771655450015242 0ustar00
    components/com_users/models/forms/note.xml000066600000005055150771655450015060 0ustar00
    components/com_users/models/forms/mail.xml000066600000002615150771655450015034 0ustar00
    components/com_users/models/forms/index.html000066600000000037150771655450015361 0ustar00 components/com_users/models/forms/user.xml.bak000066600000012275150771655450015627 0ustar00
    components/com_users/models/forms/level.xml000066600000001022150771655450015210 0ustar00
    components/com_users/models/forms/user.xml000066600000012673150771655450015075 0ustar00
    components/com_users/models/users.php000066600000025626150771655450014123 0ustar00input->get('layout', 'default', 'cmd')) { $this->context .= '.' . $layout; } // Load the filter state. $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $active = $this->getUserStateFromRequest($this->context . '.filter.active', 'filter_active'); $this->setState('filter.active', $active); $state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state'); $this->setState('filter.state', $state); $groupId = $this->getUserStateFromRequest($this->context . '.filter.group', 'filter_group_id', null, 'int'); $this->setState('filter.group_id', $groupId); $range = $this->getUserStateFromRequest($this->context . '.filter.range', 'filter_range'); $this->setState('filter.range', $range); $groups = json_decode(base64_decode($app->input->get('groups', '', 'BASE64'))); if (isset($groups)) { JArrayHelper::toInteger($groups); } $this->setState('filter.groups', $groups); $excluded = json_decode(base64_decode($app->input->get('excluded', '', 'BASE64'))); if (isset($excluded)) { JArrayHelper::toInteger($excluded); } $this->setState('filter.excluded', $excluded); // Load the parameters. $params = JComponentHelper::getParams('com_users'); $this->setState('params', $params); // List state information. parent::populateState('a.name', 'asc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. * * @return string A store id. * * @since 1.6 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.active'); $id .= ':' . $this->getState('filter.state'); $id .= ':' . $this->getState('filter.group_id'); $id .= ':' . $this->getState('filter.range'); return parent::getStoreId($id); } /** * Gets the list of users and adds expensive joins to the result set. * * @return mixed An array of data items on success, false on failure. * * @since 1.6 */ public function getItems() { // Get a storage key. $store = $this->getStoreId(); // Try to load the data from internal storage. if (empty($this->cache[$store])) { $groups = $this->getState('filter.groups'); $groupId = $this->getState('filter.group_id'); if (isset($groups) && (empty($groups) || $groupId && !in_array($groupId, $groups))) { $items = array(); } else { $items = parent::getItems(); } // Bail out on an error or empty list. if (empty($items)) { $this->cache[$store] = $items; return $items; } // Joining the groups with the main query is a performance hog. // Find the information only on the result set. // First pass: get list of the user id's and reset the counts. $userIds = array(); foreach ($items as $item) { $userIds[] = (int) $item->id; $item->group_count = 0; $item->group_names = ''; $item->note_count = 0; } // Get the counts from the database only for the users in the list. $db = $this->getDbo(); $query = $db->getQuery(true); // Join over the group mapping table. $query->select('map.user_id, COUNT(map.group_id) AS group_count') ->from('#__user_usergroup_map AS map') ->where('map.user_id IN (' . implode(',', $userIds) . ')') ->group('map.user_id') // Join over the user groups table. ->join('LEFT', '#__usergroups AS g2 ON g2.id = map.group_id'); $db->setQuery($query); // Load the counts into an array indexed on the user id field. try { $userGroups = $db->loadObjectList('user_id'); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } $query->clear() ->select('n.user_id, COUNT(n.id) As note_count') ->from('#__user_notes AS n') ->where('n.user_id IN (' . implode(',', $userIds) . ')') ->where('n.state >= 0') ->group('n.user_id'); $db->setQuery($query); // Load the counts into an array indexed on the aro.value field (the user id). try { $userNotes = $db->loadObjectList('user_id'); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } // Second pass: collect the group counts into the master items array. foreach ($items as &$item) { if (isset($userGroups[$item->id])) { $item->group_count = $userGroups[$item->id]->group_count; // Group_concat in other databases is not supported $item->group_names = $this->_getUserDisplayedGroups($item->id); } if (isset($userNotes[$item->id])) { $item->note_count = $userNotes[$item->id]->note_count; } } // Add the items to the internal cache. $this->cache[$store] = $items; } return $this->cache[$store]; } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery * * @since 1.6 */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.*' ) ); $query->from($db->quoteName('#__users') . ' AS a'); // If the model is set to check item state, add to the query. $state = $this->getState('filter.state'); if (is_numeric($state)) { $query->where('a.block = ' . (int) $state); } // If the model is set to check the activated state, add to the query. $active = $this->getState('filter.active'); if (is_numeric($active)) { if ($active == '0') { $query->where('a.activation = ' . $db->quote('')); } elseif ($active == '1') { $query->where($query->length('a.activation') . ' = 32'); } } // Filter the items over the group id if set. $groupId = $this->getState('filter.group_id'); $groups = $this->getState('filter.groups'); if ($groupId || isset($groups)) { $query->join('LEFT', '#__user_usergroup_map AS map2 ON map2.user_id = a.id') ->group($db->quoteName(array('a.id', 'a.name', 'a.username', 'a.password', 'a.block', 'a.sendEmail', 'a.registerDate', 'a.lastvisitDate', 'a.activation', 'a.params', 'a.email'))); if ($groupId) { $query->where('map2.group_id = ' . (int) $groupId); } if (isset($groups)) { $query->where('map2.group_id IN (' . implode(',', $groups) . ')'); } } // Filter the items over the search string if set. if ($this->getState('filter.search') !== '' && $this->getState('filter.search') !== null) { // Escape the search token. $token = $db->quote('%' . $db->escape($this->getState('filter.search')) . '%'); // Compile the different search clauses. $searches = array(); $searches[] = 'a.name LIKE ' . $token; $searches[] = 'a.username LIKE ' . $token; $searches[] = 'a.email LIKE ' . $token; // Add the clauses to the query. $query->where('(' . implode(' OR ', $searches) . ')'); } // Add filter for registration ranges select list $range = $this->getState('filter.range'); // Apply the range filter. if ($range) { // Get UTC for now. $dNow = new JDate; $dStart = clone $dNow; switch ($range) { case 'past_week': $dStart->modify('-7 day'); break; case 'past_1month': $dStart->modify('-1 month'); break; case 'past_3month': $dStart->modify('-3 month'); break; case 'past_6month': $dStart->modify('-6 month'); break; case 'post_year': case 'past_year': $dStart->modify('-1 year'); break; case 'today': // Ranges that need to align with local 'days' need special treatment. $app = JFactory::getApplication(); $offset = $app->getCfg('offset'); // Reset the start time to be the beginning of today, local time. $dStart = new JDate('now', $offset); $dStart->setTime(0, 0, 0); // Now change the timezone back to UTC. $tz = new DateTimeZone('GMT'); $dStart->setTimezone($tz); break; } if ($range == 'post_year') { $query->where( 'a.registerDate < ' . $db->quote($dStart->format('Y-m-d H:i:s')) ); } else { $query->where( 'a.registerDate >= ' . $db->quote($dStart->format('Y-m-d H:i:s')) . ' AND a.registerDate <=' . $db->quote($dNow->format('Y-m-d H:i:s')) ); } } // Filter by excluded users $excluded = $this->getState('filter.excluded'); if (!empty($excluded)) { $query->where('id NOT IN (' . implode(',', $excluded) . ')'); } // Add the list ordering clause. $query->order($db->escape($this->getState('list.ordering', 'a.name')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); return $query; } /** * SQL server change * * @param integer $user_id User identifier * * @return string Groups titles imploded :$ */ function _getUserDisplayedGroups($user_id) { $db = JFactory::getDbo(); $query = "SELECT title FROM " . $db->quoteName('#__usergroups') . " ug left join " . $db->quoteName('#__user_usergroup_map') . " map on (ug.id = map.group_id)" . " WHERE map.user_id=" . (int) $user_id; $db->setQuery($query); $result = $db->loadColumn(); return implode("\n", $result); } } components/com_users/models/user.php000066600000075061150771655450013736 0ustar00tags = new JHelperTags; $result->tags->getTagIds($result->id, 'com_users.user'); // Get the dispatcher and load the users plugins. $dispatcher = JEventDispatcher::getInstance(); JPluginHelper::importPlugin('user'); // Trigger the data preparation event. $dispatcher->trigger('onContentPrepareData', array('com_users.user', $result)); return $result; } /** * Method to get the record form. * * @param array $data An optional array of data for the form to interogate. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return mixed A JForm object on success, false on failure * * @since 1.6 */ public function getForm($data = array(), $loadData = true) { $plugin = JPluginHelper::getPlugin('user', 'joomla'); $pluginParams = new JRegistry($plugin->params); // Get the form. $form = $this->loadForm('com_users.user', 'user', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } // Passwords fields are required when mail to user is set to No in joomla user plugin $userId = $form->getValue('id'); if ($userId === 0 && $pluginParams->get('mail_to_user') === "0") { $form->setFieldAttribute('password', 'required', 'true'); $form->setFieldAttribute('password2', 'required', 'true'); } // If the user needs to change their password, mark the password fields as required if (JFactory::getUser()->requireReset) { $form->setFieldAttribute('password', 'required', 'true'); $form->setFieldAttribute('password2', 'required', 'true'); } // The user should not be able to set the requireReset value on their own account if ((int) $userId === (int) JFactory::getUser()->id) { $form->removeField('requireReset'); } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * * @since 1.6 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_users.edit.user.data', array()); if (empty($data)) { $data = $this->getItem(); } JPluginHelper::importPlugin('user'); $this->preprocessData('com_users.profile', $data); return $data; } /** * Override JModelAdmin::preprocessForm to ensure the correct plugin group is loaded. * * @param JForm $form A JForm object. * @param mixed $data The data expected for the form. * @param string $group The name of the plugin group to import (defaults to "content"). * * @return void * * @since 1.6 * @throws Exception if there is an error in the form event. */ protected function preprocessForm(JForm $form, $data, $group = 'user') { parent::preprocessForm($form, $data, $group); } /** * Method to save the form data. * * @param array $data The form data. * * @return boolean True on success. * * @since 1.6 */ public function save($data) { $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('user.id'); $user = JUser::getInstance($pk); $my = JFactory::getUser(); if ($data['block'] && $pk == $my->id && !$my->block) { $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF')); return false; } // Make sure that we are not removing ourself from Super Admin group $iAmSuperAdmin = $my->authorise('core.admin'); if ($iAmSuperAdmin && $my->get('id') == $pk) { // Check that at least one of our new groups is Super Admin $stillSuperAdmin = false; $myNewGroups = $data['groups']; foreach ($myNewGroups as $group) { $stillSuperAdmin = ($stillSuperAdmin) ? ($stillSuperAdmin) : JAccess::checkGroup($group, 'core.admin'); } if (!$stillSuperAdmin) { $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_DEMOTE_SELF')); return false; } } // Handle the two factor authentication setup if (array_key_exists('twofactor', $data)) { $twoFactorMethod = $data['twofactor']['method']; // Get the current One Time Password (two factor auth) configuration $otpConfig = $this->getOtpConfig($pk); if ($twoFactorMethod != 'none') { // Run the plugins FOFPlatform::getInstance()->importPlugin('twofactorauth'); $otpConfigReplies = FOFPlatform::getInstance()->runPlugins('onUserTwofactorApplyConfiguration', array($twoFactorMethod)); // Look for a valid reply foreach ($otpConfigReplies as $reply) { if (!is_object($reply) || empty($reply->method) || ($reply->method != $twoFactorMethod)) { continue; } $otpConfig->method = $reply->method; $otpConfig->config = $reply->config; break; } // Save OTP configuration. $this->setOtpConfig($pk, $otpConfig); // Generate one time emergency passwords if required (depleted or not set) if (empty($otpConfig->otep)) { $oteps = $this->generateOteps($pk); } } else { $otpConfig->method = 'none'; $otpConfig->config = array(); $this->setOtpConfig($pk, $otpConfig); } // Unset the raw data unset($data['twofactor']); // Reload the user record with the updated OTP configuration $user->load($pk); } // Bind the data. if (!$user->bind($data)) { $this->setError($user->getError()); return false; } // Store the data. if (!$user->save()) { $this->setError($user->getError()); return false; } $this->setState('user.id', $user->id); return true; } /** * Method to delete rows. * * @param array &$pks An array of item ids. * * @return boolean Returns true on success, false on failure. * * @since 1.6 */ public function delete(&$pks) { $user = JFactory::getUser(); $table = $this->getTable(); $pks = (array) $pks; // Check if I am a Super Admin $iAmSuperAdmin = $user->authorise('core.admin'); // Trigger the onUserBeforeSave event. JPluginHelper::importPlugin('user'); $dispatcher = JEventDispatcher::getInstance(); if (in_array($user->id, $pks)) { $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_DELETE_SELF')); return false; } // Iterate the items to delete each one. foreach ($pks as $i => $pk) { if ($table->load($pk)) { // Access checks. $allow = $user->authorise('core.delete', 'com_users'); // Don't allow non-super-admin to delete a super admin $allow = (!$iAmSuperAdmin && JAccess::check($pk, 'core.admin')) ? false : $allow; if ($allow) { // Get users data for the users to delete. $user_to_delete = JFactory::getUser($pk); // Fire the onUserBeforeDelete event. $dispatcher->trigger('onUserBeforeDelete', array($table->getProperties())); if (!$table->delete($pk)) { $this->setError($table->getError()); return false; } else { // Trigger the onUserAfterDelete event. $dispatcher->trigger('onUserAfterDelete', array($user_to_delete->getProperties(), true, $this->getError())); } } else { // Prune items that you can't change. unset($pks[$i]); JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); } } else { $this->setError($table->getError()); return false; } } return true; } /** * Method to block user records. * * @param array &$pks The ids of the items to publish. * @param integer $value The value of the published state * * @return boolean True on success. * * @since 1.6 */ public function block(&$pks, $value = 1) { $app = JFactory::getApplication(); $dispatcher = JEventDispatcher::getInstance(); $user = JFactory::getUser(); // Check if I am a Super Admin $iAmSuperAdmin = $user->authorise('core.admin'); $table = $this->getTable(); $pks = (array) $pks; JPluginHelper::importPlugin('user'); // Access checks. foreach ($pks as $i => $pk) { if ($value == 1 && $pk == $user->get('id')) { // Cannot block yourself. unset($pks[$i]); JError::raiseWarning(403, JText::_('COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF')); } elseif ($table->load($pk)) { $old = $table->getProperties(); $allow = $user->authorise('core.edit.state', 'com_users'); // Don't allow non-super-admin to delete a super admin $allow = (!$iAmSuperAdmin && JAccess::check($pk, 'core.admin')) ? false : $allow; // Prepare the logout options. $options = array( 'clientid' => 0 ); if ($allow) { // Skip changing of same state if ($table->block == $value) { unset($pks[$i]); continue; } $table->block = (int) $value; // If unblocking, also change password reset count to zero to unblock reset if ($table->block === 0) { $table->resetCount = 0; } // Allow an exception to be thrown. try { if (!$table->check()) { $this->setError($table->getError()); return false; } // Trigger the onUserBeforeSave event. $result = $dispatcher->trigger('onUserBeforeSave', array($old, false, $table->getProperties())); if (in_array(false, $result, true)) { // Plugin will have to raise its own error or throw an exception. return false; } // Store the table. if (!$table->store()) { $this->setError($table->getError()); return false; } // Trigger the onAftereStoreUser event $dispatcher->trigger('onUserAfterSave', array($table->getProperties(), false, true, null)); } catch (Exception $e) { $this->setError($e->getMessage()); return false; } // Log the user out. if ($value) { $app->logout($table->id, $options); } } else { // Prune items that you can't change. unset($pks[$i]); JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); } } } return true; } /** * Method to activate user records. * * @param array &$pks The ids of the items to activate. * * @return boolean True on success. * * @since 1.6 */ public function activate(&$pks) { $dispatcher = JEventDispatcher::getInstance(); $user = JFactory::getUser(); // Check if I am a Super Admin $iAmSuperAdmin = $user->authorise('core.admin'); $table = $this->getTable(); $pks = (array) $pks; JPluginHelper::importPlugin('user'); // Access checks. foreach ($pks as $i => $pk) { if ($table->load($pk)) { $old = $table->getProperties(); $allow = $user->authorise('core.edit.state', 'com_users'); // Don't allow non-super-admin to delete a super admin $allow = (!$iAmSuperAdmin && JAccess::check($pk, 'core.admin')) ? false : $allow; if (empty($table->activation)) { // Ignore activated accounts. unset($pks[$i]); } elseif ($allow) { $table->block = 0; $table->activation = ''; // Allow an exception to be thrown. try { if (!$table->check()) { $this->setError($table->getError()); return false; } // Trigger the onUserBeforeSave event. $result = $dispatcher->trigger('onUserBeforeSave', array($old, false, $table->getProperties())); if (in_array(false, $result, true)) { // Plugin will have to raise it's own error or throw an exception. return false; } // Store the table. if (!$table->store()) { $this->setError($table->getError()); return false; } // Fire the onAftereStoreUser event $dispatcher->trigger('onUserAfterSave', array($table->getProperties(), false, true, null)); } catch (Exception $e) { $this->setError($e->getMessage()); return false; } } else { // Prune items that you can't change. unset($pks[$i]); JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); } } } return true; } /** * Method to perform batch operations on an item or a set of items. * * @param array $commands An array of commands to perform. * @param array $pks An array of item ids. * @param array $contexts An array of item contexts. * * @return boolean Returns true on success, false on failure. * * @since 2.5 */ public function batch($commands, $pks, $contexts) { // Sanitize user ids. $pks = array_unique($pks); JArrayHelper::toInteger($pks); // Remove any values of zero. if (array_search(0, $pks, true)) { unset($pks[array_search(0, $pks, true)]); } if (empty($pks)) { $this->setError(JText::_('COM_USERS_USERS_NO_ITEM_SELECTED')); return false; } $done = false; if (!empty($commands['group_id'])) { $cmd = JArrayHelper::getValue($commands, 'group_action', 'add'); if (!$this->batchUser((int) $commands['group_id'], $pks, $cmd)) { return false; } $done = true; } if (!empty($commands['reset_id'])) { if (!$this->batchReset($pks, $commands['reset_id'])) { return false; } $done = true; } if (!$done) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); return false; } // Clear the cache $this->cleanCache(); return true; } /** * Batch flag users as being required to reset their passwords * * @param array $user_ids An array of user IDs on which to operate * @param string $action The action to perform * * @return boolean True on success, false on failure * * @since 3.2 */ public function batchReset($user_ids, $action) { // Set the action to perform if ($action === 'yes') { $value = 1; } else { $value = 0; } // Prune out the current user if they are in the supplied user ID array $user_ids = array_diff($user_ids, array(JFactory::getUser()->id)); // Get the DB object $db = $this->getDbo(); JArrayHelper::toInteger($user_ids); $query = $db->getQuery(true); // Update the reset flag $query->update($db->quoteName('#__users')) ->set($db->quoteName('requireReset') . ' = ' . $value) ->where($db->quoteName('id') . ' IN (' . implode(',', $user_ids) . ')'); $db->setQuery($query); try { $db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } return true; } /** * Perform batch operations * * @param integer $group_id The group ID which assignments are being edited * @param array $user_ids An array of user IDs on which to operate * @param string $action The action to perform * * @return boolean True on success, false on failure * * @since 1.6 */ public function batchUser($group_id, $user_ids, $action) { // Get the DB object $db = $this->getDbo(); JArrayHelper::toInteger($user_ids); // Non-super admin cannot work with super-admin group if ((!JFactory::getUser()->get('isRoot') && JAccess::checkGroup($group_id, 'core.admin')) || $group_id < 1) { $this->setError(JText::_('COM_USERS_ERROR_INVALID_GROUP')); return false; } switch ($action) { // Sets users to a selected group case 'set': $doDelete = 'all'; $doAssign = true; break; // Remove users from a selected group case 'del': $doDelete = 'group'; break; // Add users to a selected group case 'add': default: $doAssign = true; break; } // Remove the users from the group if requested. if (isset($doDelete)) { $query = $db->getQuery(true); // Remove users from the group $query->delete($db->quoteName('#__user_usergroup_map')) ->where($db->quoteName('user_id') . ' IN (' . implode(',', $user_ids) . ')'); // Only remove users from selected group if ($doDelete == 'group') { $query->where($db->quoteName('group_id') . ' = ' . (int) $group_id); } $db->setQuery($query); try { $db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } } // Assign the users to the group if requested. if (isset($doAssign)) { $query = $db->getQuery(true); // First, we need to check if the user is already assigned to a group $query->select($db->quoteName('user_id')) ->from($db->quoteName('#__user_usergroup_map')) ->where($db->quoteName('group_id') . ' = ' . (int) $group_id); $db->setQuery($query); $users = $db->loadColumn(); // Build the values clause for the assignment query. $query->clear(); $groups = false; foreach ($user_ids as $id) { if (!in_array($id, $users)) { $query->values($id . ',' . $group_id); $groups = true; } } // If we have no users to process, throw an error to notify the user if (!$groups) { $this->setError(JText::_('COM_USERS_ERROR_NO_ADDITIONS')); return false; } $query->insert($db->quoteName('#__user_usergroup_map')) ->columns(array($db->quoteName('user_id'), $db->quoteName('group_id'))); $db->setQuery($query); try { $db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } } return true; } /** * Gets the available groups. * * @return array An array of groups * * @since 1.6 */ public function getGroups() { $user = JFactory::getUser(); if ($user->authorise('core.edit', 'com_users') && $user->authorise('core.manage', 'com_users')) { $model = JModelLegacy::getInstance('Groups', 'UsersModel', array('ignore_request' => true)); return $model->getItems(); } else { return null; } } /** * Gets the groups this object is assigned to * * @param integer $userId The user ID to retrieve the groups for * * @return array An array of assigned groups * * @since 1.6 */ public function getAssignedGroups($userId = null) { $userId = (!empty($userId)) ? $userId : (int) $this->getState('user.id'); if (empty($userId)) { $result = array(); $groupsIDs = $this->getForm()->getValue('groups'); if (!empty($groupsIDs)) { $result = $groupsIDs; } else { $config = JComponentHelper::getParams('com_users'); if ($groupId = $config->get('new_usertype')) { $result[] = $groupId; } } } else { $result = JUserHelper::getUserGroups($userId); } return $result; } /** * Returns the one time password (OTP) – a.k.a. two factor authentication – * configuration for a particular user. * * @param integer $user_id The numeric ID of the user * * @return stdClass An object holding the OTP configuration for this user * * @since 3.2 */ public function getOtpConfig($user_id = null) { $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); // Initialise $otpConfig = (object) array( 'method' => 'none', 'config' => array(), 'otep' => array() ); /** * Get the raw data, without going through JUser (required in order to * be able to modify the user record before logging in the user). */ $db = $this->getDbo(); $query = $db->getQuery(true) ->select('*') ->from($db->qn('#__users')) ->where($db->qn('id') . ' = ' . $db->q($user_id)); $db->setQuery($query); $item = $db->loadObject(); // Make sure this user does have OTP enabled if (empty($item->otpKey)) { return $otpConfig; } // Get the encrypted data list($method, $encryptedConfig) = explode(':', $item->otpKey, 2); $encryptedOtep = $item->otep; // Create an encryptor class $key = $this->getOtpConfigEncryptionKey(); $aes = new FOFEncryptAes($key, 256); // Decrypt the data $decryptedConfig = $aes->decryptString($encryptedConfig); $decryptedOtep = $aes->decryptString($encryptedOtep); // Remove the null padding added during encryption $decryptedConfig = rtrim($decryptedConfig, "\0"); $decryptedOtep = rtrim($decryptedOtep, "\0"); // Update the configuration object $otpConfig->method = $method; $otpConfig->config = @json_decode($decryptedConfig); $otpConfig->otep = @json_decode($decryptedOtep); /* * If the decryption failed for any reason we essentially disable the * two-factor authentication. This prevents impossible to log in sites * if the site admin changes the site secret for any reason. */ if (is_null($otpConfig->config)) { $otpConfig->config = array(); } if (is_object($otpConfig->config)) { $otpConfig->config = (array) $otpConfig->config; } if (is_null($otpConfig->otep)) { $otpConfig->otep = array(); } if (is_object($otpConfig->otep)) { $otpConfig->otep = (array) $otpConfig->otep; } // Return the configuration object return $otpConfig; } /** * Sets the one time password (OTP) – a.k.a. two factor authentication – * configuration for a particular user. The $otpConfig object is the same as * the one returned by the getOtpConfig method. * * @param integer $user_id The numeric ID of the user * @param stdClass $otpConfig The OTP configuration object * * @return boolean True on success * * @since 3.2 */ public function setOtpConfig($user_id, $otpConfig) { $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); $updates = (object) array( 'id' => $user_id, 'otpKey' => '', 'otep' => '' ); // Create an encryptor class $key = $this->getOtpConfigEncryptionKey(); $aes = new FOFEncryptAes($key, 256); // Create the encrypted option strings if (!empty($otpConfig->method) && ($otpConfig->method != 'none')) { $decryptedConfig = json_encode($otpConfig->config); $decryptedOtep = json_encode($otpConfig->otep); $updates->otpKey = $otpConfig->method . ':' . $aes->encryptString($decryptedConfig); $updates->otep = $aes->encryptString($decryptedOtep); } $db = $this->getDbo(); $result = $db->updateObject('#__users', $updates, 'id'); return $result; } /** * Gets the symmetric encryption key for the OTP configuration data. It * currently returns the site's secret. * * @return string The encryption key * * @since 3.2 */ public function getOtpConfigEncryptionKey() { return JFactory::getConfig()->get('secret'); } /** * Gets the configuration forms for all two-factor authentication methods * in an array. * * @param integer $user_id The user ID to load the forms for (optional) * * @return array * * @since 3.2 */ public function getTwofactorform($user_id = null) { $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); $otpConfig = $this->getOtpConfig($user_id); FOFPlatform::getInstance()->importPlugin('twofactorauth'); return FOFPlatform::getInstance()->runPlugins('onUserTwofactorShowConfiguration', array($otpConfig, $user_id)); } /** * Generates a new set of One Time Emergency Passwords (OTEPs) for a given user. * * @param integer $user_id The user ID * @param integer $count How many OTEPs to generate? Default: 10 * * @return array The generated OTEPs * * @since 3.2 */ public function generateOteps($user_id, $count = 10) { $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); // Initialise $oteps = array(); // Get the OTP configuration for the user $otpConfig = $this->getOtpConfig($user_id); // If two factor authentication is not enabled, abort if (empty($otpConfig->method) || ($otpConfig->method == 'none')) { return $oteps; } $salt = "0123456789"; $base = strlen($salt); $length = 16; for ($i = 0; $i < $count; $i++) { $makepass = ''; $random = JCrypt::genRandomBytes($length + 1); $shift = ord($random[0]); for ($j = 1; $j <= $length; ++$j) { $makepass .= $salt[($shift + ord($random[$j])) % $base]; $shift += ord($random[$j]); } $oteps[] = $makepass; } $otpConfig->otep = $oteps; // Save the now modified OTP configuration $this->setOtpConfig($user_id, $otpConfig); return $oteps; } /** * Checks if the provided secret key is a valid two factor authentication * secret key. If not, it will check it against the list of one time * emergency passwords (OTEPs). If it's a valid OTEP it will also remove it * from the user's list of OTEPs. * * This method will return true in the following conditions: * - The two factor authentication is not enabled * - You have provided a valid secret key for * - You have provided a valid OTEP * * You can define the following options in the $options array: * otp_config The OTP (one time password, a.k.a. two factor auth) * configuration object. If not set we'll load it automatically. * warn_if_not_req Issue a warning if you are checking a secret key against * a user account which doesn't have any two factor * authentication method enabled. * warn_irq_msg The string to use for the warn_if_not_req warning * * @param integer $user_id The user's numeric ID * @param string $secretkey The secret key you want to check * @param array $options Options; see above * * @return boolean True if it's a valid secret key for this user. * * @since 3.2 */ public function isValidSecretKey($user_id, $secretkey, $options = array()) { // Load the user's OTP (one time password, a.k.a. two factor auth) configuration if (!array_key_exists('otp_config', $options)) { $otpConfig = $this->getOtpConfig($user_id); $options['otp_config'] = $otpConfig; } else { $otpConfig = $options['otp_config']; } // Check if the user has enabled two factor authentication if (empty($otpConfig->method) || ($otpConfig->method == 'none')) { // Load language $lang = JFactory::getLanguage(); $extension = 'com_users'; $source = JPATH_ADMINISTRATOR . '/components/' . $extension; $lang->load($extension, JPATH_ADMINISTRATOR, null, false, true) || $lang->load($extension, $source, null, false, true); $warn = true; $warnMessage = JText::_('COM_USERS_ERROR_SECRET_CODE_WITHOUT_TFA'); if (array_key_exists('warn_if_not_req', $options)) { $warn = $options['warn_if_not_req']; } if (array_key_exists('warn_irq_msg', $options)) { $warnMessage = $options['warn_irq_msg']; } // Warn the user if he's using a secret code but he has not // enabled two factor auth in his account. if (!empty($secretkey) && $warn) { try { $app = JFactory::getApplication(); $app->enqueueMessage($warnMessage, 'warning'); } catch (Exception $exc) { // This happens when we are in CLI mode. In this case // no warning is issued return true; } } return true; } $credentials = array( 'secretkey' => $secretkey, ); // Load the Joomla! RAD layer if (!defined('FOF_INCLUDED')) { include_once JPATH_LIBRARIES . '/fof/include.php'; } // Try to validate the OTP FOFPlatform::getInstance()->importPlugin('twofactorauth'); $otpAuthReplies = FOFPlatform::getInstance()->runPlugins('onUserTwofactorAuthenticate', array($credentials, $options)); $check = false; /* * This looks like noob code but DO NOT TOUCH IT and do not convert * to in_array(). During testing in_array() inexplicably returned * null when the OTEP begins with a zero! o_O */ if (!empty($otpAuthReplies)) { foreach ($otpAuthReplies as $authReply) { $check = $check || $authReply; } } // Fall back to one time emergency passwords if (!$check) { $check = $this->isValidOtep($user_id, $secretkey, $otpConfig); } return $check; } /** * Checks if the supplied string is a valid one time emergency password * (OTEP) for this user. If it is it will be automatically removed from the * user's list of OTEPs. * * @param integer $user_id The user ID against which you are checking * @param string $otep The string you want to test for validity * @param object $otpConfig Optional; the two factor authentication configuration (automatically fetched if not set) * * @return boolean True if it's a valid OTEP or if two factor auth is not * enabled in this user's account. * * @since 3.2 */ public function isValidOtep($user_id, $otep, $otpConfig = null) { if (is_null($otpConfig)) { $otpConfig = $this->getOtpConfig($user_id); } // Did the user use an OTEP instead? if (empty($otpConfig->otep)) { if (empty($otpConfig->method) || ($otpConfig->method == 'none')) { // Two factor authentication is not enabled on this account. // Any string is assumed to be a valid OTEP. return true; } else { /** * Two factor authentication enabled and no OTEPs defined. The * user has used them all up. Therefore anything he enters is * an invalid OTEP. */ return false; } } // Clean up the OTEP (remove dashes, spaces and other funny stuff // our beloved users may have unwittingly stuffed in it) $otep = filter_var($otep, FILTER_SANITIZE_NUMBER_INT); $otep = str_replace('-', '', $otep); $check = false; // Did we find a valid OTEP? if (in_array($otep, $otpConfig->otep)) { // Remove the OTEP from the array $otpConfig->otep = array_diff($otpConfig->otep, array($otep)); $this->setOtpConfig($user_id, $otpConfig); // Return true; the OTEP was a valid one $check = true; } return $check; } } components/com_users/models/debuguser.php000066600000013607150771655450014743 0ustar00getState('filter.component'); return UsersHelperDebug::getDebugActions($component); } /** * Override getItems method. * * @return array * @since 1.6 */ public function getItems() { $userId = $this->getState('filter.user_id'); if (($assets = parent::getItems()) && $userId) { $actions = $this->getDebugActions(); foreach ($assets as &$asset) { $asset->checks = array(); foreach ($actions as $action) { $name = $action[0]; $level = $action[1]; // Check that we check this action for the level of the asset. if ($level === null || $level >= $asset->level) { // We need to test this action. $asset->checks[$name] = JAccess::check($userId, $name, $asset->name); } else { // We ignore this action. $asset->checks[$name] = 'skip'; } } } } return $assets; } /** * Method to auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @return void * @since 1.6 */ protected function populateState($ordering = null, $direction = null) { $app = JFactory::getApplication('administrator'); // Adjust the context to support modal layouts. $layout = $app->input->get('layout', 'default'); if ($layout) { $this->context .= '.' . $layout; } // Load the filter state. $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $value = $this->getUserStateFromRequest($this->context . '.filter.user_id', 'user_id', 0, 'int'); $this->setState('filter.user_id', $value); $levelStart = $this->getUserStateFromRequest($this->context . '.filter.level_start', 'filter_level_start', 0, 'int'); $this->setState('filter.level_start', $levelStart); $value = $this->getUserStateFromRequest($this->context . '.filter.level_end', 'filter_level_end', 0, 'int'); if ($value > 0 && $value < $levelStart) { $value = $levelStart; } $this->setState('filter.level_end', $value); $component = $this->getUserStateFromRequest($this->context . '.filter.component', 'filter_component'); $this->setState('filter.component', $component); // Load the parameters. $params = JComponentHelper::getParams('com_users'); $this->setState('params', $params); // List state information. parent::populateState('a.lft', 'asc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string $id A prefix for the store id. * * @return string A store id. * @since 1.6 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.user_id'); $id .= ':' . $this->getState('filter.level_start'); $id .= ':' . $this->getState('filter.level_end'); $id .= ':' . $this->getState('filter.component'); return parent::getStoreId($id); } /** * Get the user being debugged. * * @return JUser * @since 1.6 */ public function getUser() { $userId = $this->getState('filter.user_id'); return JFactory::getUser($userId); } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery * @since 1.6 */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.id, a.name, a.title, a.level, a.lft, a.rgt' ) ); $query->from($db->quoteName('#__assets') . ' AS a'); // Filter the items over the group id if set. if ($groupId = $this->getState('filter.group_id')) { $query->join('LEFT', '#__user_usergroup_map AS map2 ON map2.user_id = a.id') ->where('map2.group_id = ' . (int) $groupId); } // Filter the items over the search string if set. if ($this->getState('filter.search')) { // Escape the search token. $token = $db->quote('%' . $db->escape($this->getState('filter.search')) . '%'); // Compile the different search clauses. $searches = array(); $searches[] = 'a.name LIKE ' . $token; $searches[] = 'a.title LIKE ' . $token; // Add the clauses to the query. $query->where('(' . implode(' OR ', $searches) . ')'); } // Filter on the start and end levels. $levelStart = (int) $this->getState('filter.level_start'); $levelEnd = (int) $this->getState('filter.level_end'); if ($levelEnd > 0 && $levelEnd < $levelStart) { $levelEnd = $levelStart; } if ($levelStart > 0) { $query->where('a.level >= ' . $levelStart); } if ($levelEnd > 0) { $query->where('a.level <= ' . $levelEnd); } // Filter the items over the component if set. if ($this->getState('filter.component')) { $component = $this->getState('filter.component'); $query->where('(a.name = ' . $db->quote($component) . ' OR a.name LIKE ' . $db->quote($component . '.%') . ')'); } // Add the list ordering clause. $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); return $query; } } components/com_users/models/note.php000066600000010247150771655450013720 0ustar00loadForm('com_users.note', 'note', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } return $form; } /** * Method to get a single record. * * @param integer $pk The id of the primary key. * * @return mixed Object on success, false on failure. * * @since 2.5 */ public function getItem($pk = null) { $result = parent::getItem($pk); // Get the dispatcher and load the users plugins. $dispatcher = JEventDispatcher::getInstance(); JPluginHelper::importPlugin('user'); // Trigger the data preparation event. $dispatcher->trigger('onContentPrepareData', array('com_users.note', $result)); return $result; } /** * Method to get a table object, load it if necessary. * * @param string $name The table name. Optional. * @param string $prefix The class prefix. Optional. * @param array $options Configuration array for model. Optional. * * @return JTable The table object * * @since 2.5 */ public function getTable($name = 'Note', $prefix = 'UsersTable', $options = array()) { return JTable::getInstance($name, $prefix, $options); } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * * @since 1.6 */ protected function loadFormData() { // Get the application $app = JFactory::getApplication(); // Check the session for previously entered form data. $data = $app->getUserState('com_users.edit.note.data', array()); if (empty($data)) { $data = $this->getItem(); // Prime some default values. if ($this->getState('note.id') == 0) { $data->set('catid', $app->input->get('catid', $app->getUserState('com_users.notes.filter.category_id'), 'int')); } $userId = $app->input->get('u_id', 0, 'int'); if ($userId != 0) { $data->user_id = $userId; } } $this->preprocessData('com_users.note', $data); return $data; } /** * Method to auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @return void * * @since 2.5 */ protected function populateState() { parent::populateState(); $userId = JFactory::getApplication()->input->get('u_id', 0, 'int'); $this->setState('note.user_id', $userId); } /** * Method to save the form data. * * @param array $data The form data. * * @return boolean True on success. * * @since 2.5 */ /*public function save($data) { $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('note.id'); $table = $this->getTable(); $isNew = empty($pk); if (!$table->bind($data)) { $this->setError($table->getError()); return false; } // JTableCategory doesn't bind the params, so we need to do that by hand. if (isset($data['params']) && is_array($data['params'])) { $registry = new JRegistry(); $registry->loadArray($data['params']); $table->params = $registry->toString(); // This will give us INI format. } if (!$table->check()) { $this->setError($table->getError()); return false; } if (!$table->store()) { $this->setError($table->getError()); return false; } $this->setState('note.id', $table->id); return true; }*/ } components/com_media/layouts/index.html000066600000000037150771655450014366 0ustar00 components/com_media/layouts/toolbar/deletemedia.php000066600000000746150771655450017015 0ustar00 components/com_media/layouts/toolbar/index.html000066600000000037150771655450016030 0ustar00 components/com_media/layouts/toolbar/uploadmedia.php000066600000001001150771655450017020 0ustar00 components/com_media/layouts/toolbar/newfolder.php000066600000000770150771655450016535 0ustar00 components/com_media/views/images/view.html.php000066600000002446150771655450015727 0ustar00isRTL()) { JHtml::_('stylesheet', 'media/popup-imagemanager_rtl.css', array(), true); } /* * Display form for FTP credentials? * Don't set them here, as there are other functions called before this one if there is any file write operation */ $ftp = !JClientHelper::hasCredentials('ftp'); $this->session = JFactory::getSession(); $this->config = $config; $this->state = $this->get('state'); $this->folderList = $this->get('folderList'); $this->require_ftp = $ftp; parent::display($tpl); } } components/com_media/views/images/tmpl/default.php000066600000014763150771655450016417 0ustar00 false)); $user = JFactory::getUser(); $input = JFactory::getApplication()->input; ?>
    folderList; ?>
    state->get('field.id')):?>
    state->get('field.id')):?>
    authorise('core.create', 'com_media')) : ?>

    config->get('upload_maxsize') == '0' ? JText::_('COM_MEDIA_UPLOAD_FILES_NOLIMIT') : JText::sprintf('COM_MEDIA_UPLOAD_FILES', $this->config->get('upload_maxsize')); ?>

    components/com_media/views/images/tmpl/index.html000066600000000037150771655450016244 0ustar00 components/com_media/views/images/index.html000066600000000037150771655450015270 0ustar00 components/com_media/views/medialist/view.html.php000066600000004335150771655450016434 0ustar00isAdmin()) { return $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); } // Do not allow cache $app->allowCache(false); JHtml::_('behavior.framework', true); JFactory::getDocument()->addScriptDeclaration(" window.addEvent('domready', function() { window.parent.document.updateUploader(); $$('a.img-preview').each(function(el) { el.addEvent('click', function(e) { window.top.document.preview.fromElement(el); return false; }); }); });"); $images = $this->get('images'); $documents = $this->get('documents'); $folders = $this->get('folders'); $state = $this->get('state'); // Check for invalid folder name if (empty($state->folder)) { $dirname = JRequest::getVar('folder', '', '', 'string'); if (!empty($dirname)) { $dirname = htmlspecialchars($dirname, ENT_COMPAT, 'UTF-8'); JError::raiseWarning(100, JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_BROWSE_FOLDER_WARNDIRNAME', $dirname)); } } $this->baseURL = JUri::root(); $this->images = &$images; $this->documents = &$documents; $this->folders = &$folders; $this->state = &$state; parent::display($tpl); } function setFolder($index = 0) { if (isset($this->folders[$index])) { $this->_tmp_folder = &$this->folders[$index]; } else { $this->_tmp_folder = new JObject; } } function setImage($index = 0) { if (isset($this->images[$index])) { $this->_tmp_img = &$this->images[$index]; } else { $this->_tmp_img = new JObject; } } function setDoc($index = 0) { if (isset($this->documents[$index])) { $this->_tmp_doc = &$this->documents[$index]; } else { $this->_tmp_doc = new JObject; } } } components/com_media/views/medialist/tmpl/thumbs_img.php000066600000003673150771655450017635 0ustar00trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_img, &$params)); ?>
  • authorise('core.delete', 'com_media')):?> ×
  • trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_img, &$params)); ?> components/com_media/views/medialist/tmpl/default.php000066600000000423150771655450017111 0ustar00
  • authorise('core.delete', 'com_media')):?> ×
  • components/com_media/views/medialist/tmpl/index.html000066600000000037150771655450016752 0ustar00 components/com_media/views/medialist/tmpl/thumbs_up.php000066600000001557150771655450017504 0ustar00
  •  
    ..
  • components/com_media/views/medialist/tmpl/details_folder.php000066600000003004150771655450020443 0ustar00 _tmp_folder->name; ?>     authorise('core.delete', 'com_media')):?> components/com_media/views/medialist/tmpl/details.php000066600000003260150771655450017114 0ustar00
    authorise('core.delete', 'com_media')):?> loadTemplate('up'); ?> folders); $i < $n; $i++) : $this->setFolder($i); echo $this->loadTemplate('folder'); endfor; ?> documents); $i < $n; $i++) : $this->setDoc($i); echo $this->loadTemplate('doc'); endfor; ?> images); $i < $n; $i++) : $this->setImage($i); echo $this->loadTemplate('img'); endfor; ?>
    components/com_media/views/medialist/tmpl/details_img.php000066600000004152150771655450017751 0ustar00trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_img, &$params)); ?> _tmp_img->path_relative, JText::sprintf('COM_MEDIA_IMAGE_TITLE', $this->_tmp_img->title, JHtml::_('number.bytes', $this->_tmp_img->size)), array('width' => $this->_tmp_img->width_16, 'height' => $this->_tmp_img->height_16)); ?> escape($this->_tmp_img->title); ?> _tmp_img->width, $this->_tmp_img->height); ?> _tmp_img->size); ?> authorise('core.delete', 'com_media')):?> trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_img, &$params)); ?> components/com_media/views/medialist/tmpl/details_doc.php000066600000003515150771655450017744 0ustar00trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_doc, &$params)); ?> _tmp_doc->icon_16, $this->_tmp_doc->title, null, true, true) ? JHtml::_('image', $this->_tmp_doc->icon_16, $this->_tmp_doc->title, array('width' => 16, 'height' => 16), true) : JHtml::_('image', 'media/con_info.png', $this->_tmp_doc->title, array('width' => 16, 'height' => 16), true);?> _tmp_doc->title; ?>   _tmp_doc->size); ?> authorise('core.delete', 'com_media')):?> trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_doc, &$params)); ?> components/com_media/views/medialist/tmpl/thumbs.php000066600000002222150771655450016766 0ustar00
      loadTemplate('up'); ?> folders); $i < $n; $i++) : $this->setFolder($i); echo $this->loadTemplate('folder'); endfor; ?> documents); $i < $n; $i++) : $this->setDoc($i); echo $this->loadTemplate('doc'); endfor; ?> images); $i < $n; $i++) : $this->setImage($i); echo $this->loadTemplate('img'); endfor; ?>
    components/com_media/views/medialist/tmpl/thumbs_doc.php000066600000003416150771655450017621 0ustar00trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_doc, &$params)); ?>
  • authorise('core.delete', 'com_media')):?> ×
    _tmp_doc->name, 10, false); ?>
  • trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_doc, &$params)); ?> components/com_media/views/medialist/tmpl/details_up.php000066600000001546150771655450017625 0ustar00 ..     authorise('core.delete', 'com_media')):?>   components/com_media/views/medialist/index.html000066600000000037150771655450015776 0ustar00 components/com_media/views/index.html000066600000000037150771655450014023 0ustar00 components/com_media/views/media/view.html.php000066600000010317150771655450015535 0ustar00isAdmin()) { return $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); } $lang = JFactory::getLanguage(); $style = $app->getUserStateFromRequest('media.list.layout', 'layout', 'thumbs', 'word'); $document = JFactory::getDocument(); JHtml::_('behavior.framework', true); JHtml::_('script', 'media/mediamanager.js', true, true); /* JHtml::_('stylesheet', 'media/mediamanager.css', array(), true); if ($lang->isRTL()) : JHtml::_('stylesheet', 'media/mediamanager_rtl.css', array(), true); endif; */ JHtml::_('behavior.modal'); $document->addScriptDeclaration(" window.addEvent('domready', function() { document.preview = SqueezeBox; });"); // JHtml::_('script', 'system/mootree.js', true, true, false, false); JHtml::_('stylesheet', 'system/mootree.css', array(), true); if ($lang->isRTL()) : JHtml::_('stylesheet', 'media/mootree_rtl.css', array(), true); endif; if (DIRECTORY_SEPARATOR == '\\') { $base = str_replace(DIRECTORY_SEPARATOR, "\\\\", COM_MEDIA_BASE); } else { $base = COM_MEDIA_BASE; } $js = " var basepath = '".$base."'; var viewstyle = '".$style."'; "; $document->addScriptDeclaration($js); /* * Display form for FTP credentials? * Don't set them here, as there are other functions called before this one if there is any file write operation */ $ftp = !JClientHelper::hasCredentials('ftp'); $session = JFactory::getSession(); $state = $this->get('state'); $this->session = $session; $this->config = &$config; $this->state = &$state; $this->require_ftp = $ftp; $this->folders_id = ' id="media-tree"'; $this->folders = $this->get('folderTree'); // Set the toolbar $this->addToolbar(); parent::display($tpl); echo JHtml::_('behavior.keepalive'); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { // Get the toolbar object instance $bar = JToolBar::getInstance('toolbar'); $user = JFactory::getUser(); // The toolbar functions depend on Bootstrap JS JHtml::_('bootstrap.framework'); // Set the titlebar text JToolbarHelper::title(JText::_('COM_MEDIA'), 'images mediamanager'); // Add a upload button if ($user->authorise('core.create', 'com_media')) { // Instantiate a new JLayoutFile instance and render the layout $layout = new JLayoutFile('toolbar.uploadmedia'); $bar->appendButton('Custom', $layout->render(array()), 'upload'); JToolbarHelper::divider(); } // Add a create folder button if ($user->authorise('core.create', 'com_media')) { // Instantiate a new JLayoutFile instance and render the layout $layout = new JLayoutFile('toolbar.newfolder'); $bar->appendButton('Custom', $layout->render(array()), 'upload'); JToolbarHelper::divider(); } // Add a delete button if ($user->authorise('core.delete', 'com_media')) { // Instantiate a new JLayoutFile instance and render the layout $layout = new JLayoutFile('toolbar.deletemedia'); $bar->appendButton('Custom', $layout->render(array()), 'upload'); JToolbarHelper::divider(); } // Add a preferences button if ($user->authorise('core.admin', 'com_media')) { JToolbarHelper::preferences('com_media'); JToolbarHelper::divider(); } JToolbarHelper::help('JHELP_CONTENT_MEDIA_MANAGER'); } function getFolderLevel($folder) { $this->folders_id = null; $txt = null; if (isset($folder['children']) && count($folder['children'])) { $tmp = $this->folders; $this->folders = $folder; $txt = $this->loadTemplate('folders'); $this->folders = $tmp; } return $txt; } } components/com_media/views/media/tmpl/default.php000066600000011025150771655450016215 0ustar00input; ?>
    loadTemplate('navigation'); ?> authorise('core.create', 'com_media')) and $this->require_ftp) : ?>
    authorise('core.create', 'com_media')):?>

    config->get('upload_maxsize') == '0' ? JText::_('COM_MEDIA_UPLOAD_FILES_NOLIMIT') : JText::sprintf('COM_MEDIA_UPLOAD_FILES', $this->config->get('upload_maxsize')); ?>

    components/com_media/views/media/tmpl/default_folders.php000066600000002133150771655450017733 0ustar00folders['data']->relative); ?> components/com_media/views/media/tmpl/index.html000066600000000037150771655450016056 0ustar00 components/com_media/views/media/tmpl/default_navigation.php000066600000001565150771655450020444 0ustar00getUserStateFromRequest('media.list.layout', 'layout', 'thumbs', 'word'); ?> components/com_media/views/media/index.html000066600000000037150771655450015102 0ustar00 components/com_media/views/imageslist/view.html.php000066600000002770150771655450016623 0ustar00allowCache(false); $lang = JFactory::getLanguage(); JHtml::_('stylesheet', 'media/popup-imagelist.css', array(), true); if ($lang->isRTL()) { JHtml::_('stylesheet', 'media/popup-imagelist_rtl.css', array(), true); } $document = JFactory::getDocument(); $document->addScriptDeclaration("var ImageManager = window.parent.ImageManager;"); $images = $this->get('images'); $folders = $this->get('folders'); $state = $this->get('state'); $this->baseURL = COM_MEDIA_BASEURL; $this->images = &$images; $this->folders = &$folders; $this->state = &$state; parent::display($tpl); } function setFolder($index = 0) { if (isset($this->folders[$index])) { $this->_tmp_folder = &$this->folders[$index]; } else { $this->_tmp_folder = new JObject; } } function setImage($index = 0) { if (isset($this->images[$index])) { $this->_tmp_img = &$this->images[$index]; } else { $this->_tmp_img = new JObject; } } } components/com_media/views/imageslist/tmpl/default.php000066600000001461150771655450017302 0ustar00 images) > 0 || count($this->folders) > 0) { ?>
      folders); $i < $n; $i++) : $this->setFolder($i); echo $this->loadTemplate('folder'); endfor; ?> images); $i < $n; $i++) : $this->setImage($i); echo $this->loadTemplate('image'); endfor; ?>
    components/com_media/views/imageslist/tmpl/index.html000066600000000037150771655450017140 0ustar00 components/com_media/views/imageslist/tmpl/default_image.php000066600000002323150771655450020442 0ustar00trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_img, &$params)); ?>
  • baseURL . '/' . $this->_tmp_img->path_relative, JText::sprintf('COM_MEDIA_IMAGE_TITLE', $this->_tmp_img->title, JHtml::_('number.bytes', $this->_tmp_img->size)), array('width' => $this->_tmp_img->width_60, 'height' => $this->_tmp_img->height_60)); ?>
    _tmp_img->name, 10, false); ?>
  • trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_img, &$params)); ?> components/com_media/views/imageslist/tmpl/default_folder.php000066600000001501150771655450020630 0ustar00input; ?>
  • _tmp_folder->name, 10, false); ?>
  • components/com_media/views/imageslist/index.html000066600000000037150771655450016164 0ustar00 components/com_media/media.xml000066600000002504150771655450012473 0ustar00 com_media Joomla! Project April 2006 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_MEDIA_XML_DESCRIPTION controller.php index.html media.php helpers language/en-GB.com_media.ini config.xml controller.php index.html media.php controllers helpers layouts models views language/en-GB.com_media.ini language/en-GB.com_media.sys.ini components/com_media/index.html000066600000000037150771655450012666 0ustar00 components/com_media/config.xml000066600000005516150771655450012667 0ustar00
    components/com_media/controller.php000066600000004175150771655450013574 0ustar00input->get('view', 'media'); switch ($vName) { case 'images': $vLayout = $this->input->get('layout', 'default', 'string'); $mName = 'manager'; break; case 'imagesList': $mName = 'list'; $vLayout = $this->input->get('layout', 'default', 'string'); break; case 'mediaList': $app = JFactory::getApplication(); $mName = 'list'; $vLayout = $app->getUserStateFromRequest('media.list.layout', 'layout', 'thumbs', 'word'); break; case 'media': default: $vName = 'media'; $vLayout = $this->input->get('layout', 'default', 'string'); $mName = 'manager'; break; } $document = JFactory::getDocument(); $vType = $document->getType(); // Get/Create the view $view = $this->getView($vName, $vType); $view->addTemplatePath(JPATH_COMPONENT_ADMINISTRATOR.'/views/'.strtolower($vName).'/tmpl'); // Get/Create the model if ($model = $this->getModel($mName)) { // Push the model into the view (as default) $view->setModel($model, true); } // Set the layout $view->setLayout($vLayout); // Display the view $view->display(); return $this; } public function ftpValidate() { // Set FTP credentials, if given JClientHelper::setCredentialsFromRequest('ftp'); } } components/com_media/controllers/file.json.php000066600000011231150771655450015635 0ustar00 '0', 'error' => JText::_('JINVALID_TOKEN') ); echo json_encode($response); return; } // Get the user $user = JFactory::getUser(); JLog::addLogger(array('text_file' => 'upload.error.php'), JLog::ALL, array('upload')); // Get some data from the request $file = $this->input->files->get('Filedata', '', 'array'); $folder = $this->input->get('folder', '', 'path'); if ( $_SERVER['CONTENT_LENGTH'] > ($params->get('upload_maxsize', 0) * 1024 * 1024) || $_SERVER['CONTENT_LENGTH'] > (int) (ini_get('upload_max_filesize')) * 1024 * 1024 || $_SERVER['CONTENT_LENGTH'] > (int) (ini_get('post_max_size')) * 1024 * 1024 || $_SERVER['CONTENT_LENGTH'] > (int) (ini_get('memory_limit')) * 1024 * 1024 ) { $response = array( 'status' => '0', 'error' => JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE') ); echo json_encode($response); return; } // Set FTP credentials, if given JClientHelper::setCredentialsFromRequest('ftp'); // Make the filename safe $file['name'] = JFile::makeSafe($file['name']); if (isset($file['name'])) { // The request is valid $err = null; $filepath = JPath::clean(COM_MEDIA_BASE . '/' . $folder . '/' . strtolower($file['name'])); if (!MediaHelper::canUpload($file, $err)) { JLog::add('Invalid: ' . $filepath . ': ' . $err, JLog::INFO, 'upload'); $response = array( 'status' => '0', 'error' => JText::_($err) ); echo json_encode($response); return; } // Trigger the onContentBeforeSave event. JPluginHelper::importPlugin('content'); $dispatcher = JEventDispatcher::getInstance(); $object_file = new JObject($file); $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 (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', 'error' => JText::_('COM_MEDIA_ERROR_FILE_EXISTS') ); 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') ); 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; } else { // 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; } } else { $response = array( 'status' => '0', 'error' => JText::_('COM_MEDIA_ERROR_BAD_REQUEST') ); echo json_encode($response); return; } } } components/com_media/controllers/index.html000066600000000037150771655450015234 0ustar00 components/com_media/controllers/file.php.backup000066600000017662150771655450016147 0ustar00input->files->get('Filedata', '', 'array'); $return = $this->input->post->get('return-url', null, 'base64'); $this->folder = $this->input->get('folder', '', 'path'); // Set the redirect if ($return) { $this->setRedirect(base64_decode($return) . '&folder=' . $this->folder); } // Authorize the user if (!$this->authoriseUser('create')) { return false; } if ( $_SERVER['CONTENT_LENGTH'] > ($params->get('upload_maxsize', 0) * 1024 * 1024) || $_SERVER['CONTENT_LENGTH'] > (int) (ini_get('upload_max_filesize')) * 1024 * 1024 || $_SERVER['CONTENT_LENGTH'] > (int) (ini_get('post_max_size')) * 1024 * 1024 || (($_SERVER['CONTENT_LENGTH'] > (int) (ini_get('memory_limit')) * 1024 * 1024) && ((int) (ini_get('memory_limit')) != -1)) ) { JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE')); return false; } // Perform basic checks on file info before attempting anything foreach ($files as &$file) { $file['name'] = JFile::makeSafe($file['name']); $file['filepath'] = JPath::clean(implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $this->folder, $file['name']))); if ($file['error'] == 1) { JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE')); return false; } if ($file['size'] > ($params->get('upload_maxsize', 0) * 1024 * 1024)) { JError::raiseNotice(100, JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE')); return false; } if (JFile::exists($file['filepath'])) { // A file with this name already exists JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_FILE_EXISTS')); return false; } if (!isset($file['name'])) { // No filename (after the name was cleaned by JFile::makeSafe) $this->setRedirect('index.php', JText::_('COM_MEDIA_INVALID_REQUEST'), 'error'); return false; } } // Set FTP credentials, if given JClientHelper::setCredentialsFromRequest('ftp'); JPluginHelper::importPlugin('content'); $dispatcher = JEventDispatcher::getInstance(); foreach ($files as &$file) { // The request is valid $err = null; if (!MediaHelper::canUpload($file, $err)) { // The file can't be upload JError::raiseNotice(100, JText::_($err)); return false; } // Trigger the onContentBeforeSave event. $object_file = new JObject($file); $result = $dispatcher->trigger('onContentBeforeSave', array('com_media.file', &$object_file)); if (in_array(false, $result, true)) { // There are some errors in the plugins JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_SAVE', count($errors = $object_file->getErrors()), implode('
    ', $errors))); return false; } if (!JFile::upload($object_file->tmp_name, $object_file->filepath)) { // Error in upload JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE')); return false; } else { // Trigger the onContentAfterSave event. $dispatcher->trigger('onContentAfterSave', array('com_media.file', &$object_file, true)); $this->setMessage(JText::sprintf('COM_MEDIA_UPLOAD_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); } } return true; } /** * Check that the user is authorized to perform this action * * @param string $action - the action to be peformed (create or delete) * * @return boolean * * @since 1.6 */ protected function authoriseUser($action) { if (!JFactory::getUser()->authorise('core.' . strtolower($action), 'com_media')) { // User is not authorised JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_' . strtoupper($action) . '_NOT_PERMITTED')); return false; } return true; } /** * Deletes paths from the current path * * @return boolean * * @since 1.5 */ public function delete() { JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); // Get some data from the request $tmpl = $this->input->get('tmpl'); $paths = $this->input->get('rm', array(), 'array'); $folder = $this->input->get('folder', '', 'path'); $redirect = 'index.php?option=com_media&folder=' . $folder; if ($tmpl == 'component') { // We are inside the iframe $redirect .= '&view=mediaList&tmpl=component'; } $this->setRedirect($redirect); // Nothing to delete if (empty($paths)) { return true; } // Authorize the user if (!$this->authoriseUser('delete')) { return false; } // Set FTP credentials, if given JClientHelper::setCredentialsFromRequest('ftp'); JPluginHelper::importPlugin('content'); $dispatcher = JEventDispatcher::getInstance(); $ret = true; foreach ($paths as $path) { if ($path !== JFile::makeSafe($path)) { // filename is not safe $filename = htmlspecialchars($path, ENT_COMPAT, 'UTF-8'); JError::raiseWarning(100, JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_DELETE_FILE_WARNFILENAME', substr($filename, strlen(COM_MEDIA_BASE)))); continue; } $fullPath = JPath::clean(implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $folder, $path))); $object_file = new JObject(array('filepath' => $fullPath)); if (is_file($object_file->filepath)) { // Trigger the onContentBeforeDelete event. $result = $dispatcher->trigger('onContentBeforeDelete', array('com_media.file', &$object_file)); if (in_array(false, $result, true)) { // There are some errors in the plugins JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_DELETE', count($errors = $object_file->getErrors()), implode('
    ', $errors))); continue; } $ret &= JFile::delete($object_file->filepath); // Trigger the onContentAfterDelete event. $dispatcher->trigger('onContentAfterDelete', array('com_media.file', &$object_file)); $this->setMessage(JText::sprintf('COM_MEDIA_DELETE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); } elseif (is_dir($object_file->filepath)) { $contents = JFolder::files($object_file->filepath, '.', true, false, array('.svn', 'CVS', '.DS_Store', '__MACOSX', 'index.html')); if (empty($contents)) { // Trigger the onContentBeforeDelete event. $result = $dispatcher->trigger('onContentBeforeDelete', array('com_media.folder', &$object_file)); if (in_array(false, $result, true)) { // There are some errors in the plugins JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_DELETE', count($errors = $object_file->getErrors()), implode('
    ', $errors))); continue; } $ret &= JFolder::delete($object_file->filepath); // Trigger the onContentAfterDelete event. $dispatcher->trigger('onContentAfterDelete', array('com_media.folder', &$object_file)); $this->setMessage(JText::sprintf('COM_MEDIA_DELETE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); } else { // This makes no sense... JError::raiseWarning(100, JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_DELETE_FOLDER_NOT_EMPTY', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); } } } return $ret; } } components/com_media/controllers/file.php000066600000020030150771655450014662 0ustar00input->files->get('Filedata', '', 'array'); $return = $this->input->post->get('return-url', null, 'base64'); $this->folder = $this->input->get('folder', '', 'path'); // Set the redirect if ($return) { $this->setRedirect(base64_decode($return) . '&folder=' . $this->folder); } // Authorize the user if (!$this->authoriseUser('create')) { return false; } if (($params->get('upload_maxsize', 0) * 1024 * 1024) != 0) { if ( $_SERVER['CONTENT_LENGTH'] > ($params->get('upload_maxsize', 0) * 1024 * 1024) || $_SERVER['CONTENT_LENGTH'] > (int) (ini_get('upload_max_filesize')) * 1024 * 1024 || $_SERVER['CONTENT_LENGTH'] > (int) (ini_get('post_max_size')) * 1024 * 1024 || (($_SERVER['CONTENT_LENGTH'] > (int) (ini_get('memory_limit')) * 1024 * 1024) && ((int) (ini_get('memory_limit')) != -1)) ) { JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE')); return false; } } // Perform basic checks on file info before attempting anything foreach ($files as &$file) { $file['name'] = JFile::makeSafe($file['name']); $file['filepath'] = JPath::clean(implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $this->folder, $file['name']))); if ($file['error'] == 1) { JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE')); return false; } if (($params->get('upload_maxsize', 0) * 1024 * 1024) != 0 && $file['size'] > ($params->get('upload_maxsize', 0) * 1024 * 1024)) { JError::raiseNotice(100, JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE')); return false; } if (JFile::exists($file['filepath'])) { // A file with this name already exists JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_FILE_EXISTS')); return false; } if (!isset($file['name'])) { // No filename (after the name was cleaned by JFile::makeSafe) $this->setRedirect('index.php', JText::_('COM_MEDIA_INVALID_REQUEST'), 'error'); return false; } } // Set FTP credentials, if given JClientHelper::setCredentialsFromRequest('ftp'); JPluginHelper::importPlugin('content'); $dispatcher = JEventDispatcher::getInstance(); foreach ($files as &$file) { // The request is valid $err = null; if (!MediaHelper::canUpload($file, $err)) { // The file can't be uploaded return false; } // Trigger the onContentBeforeSave event. $object_file = new JObject($file); $result = $dispatcher->trigger('onContentBeforeSave', array('com_media.file', &$object_file, true)); if (in_array(false, $result, true)) { // There are some errors in the plugins JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_SAVE', count($errors = $object_file->getErrors()), implode('
    ', $errors))); return false; } if (!JFile::upload($object_file->tmp_name, $object_file->filepath)) { // Error in upload JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE')); return false; } else { // Trigger the onContentAfterSave event. $dispatcher->trigger('onContentAfterSave', array('com_media.file', &$object_file, true)); $this->setMessage(JText::sprintf('COM_MEDIA_UPLOAD_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); } } return true; } /** * Check that the user is authorized to perform this action * * @param string $action - the action to be peformed (create or delete) * * @return boolean * * @since 1.6 */ protected function authoriseUser($action) { if (!JFactory::getUser()->authorise('core.' . strtolower($action), 'com_media')) { // User is not authorised JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_' . strtoupper($action) . '_NOT_PERMITTED')); return false; } return true; } /** * Deletes paths from the current path * * @return boolean * * @since 1.5 */ public function delete() { JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); // Get some data from the request $tmpl = $this->input->get('tmpl'); $paths = $this->input->get('rm', array(), 'array'); $folder = $this->input->get('folder', '', 'path'); $redirect = 'index.php?option=com_media&folder=' . $folder; if ($tmpl == 'component') { // We are inside the iframe $redirect .= '&view=mediaList&tmpl=component'; } $this->setRedirect($redirect); // Nothing to delete if (empty($paths)) { return true; } // Authorize the user if (!$this->authoriseUser('delete')) { return false; } // Set FTP credentials, if given JClientHelper::setCredentialsFromRequest('ftp'); JPluginHelper::importPlugin('content'); $dispatcher = JEventDispatcher::getInstance(); $ret = true; foreach ($paths as $path) { if ($path !== JFile::makeSafe($path)) { // filename is not safe $filename = htmlspecialchars($path, ENT_COMPAT, 'UTF-8'); JError::raiseWarning(100, JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_DELETE_FILE_WARNFILENAME', substr($filename, strlen(COM_MEDIA_BASE)))); continue; } $fullPath = JPath::clean(implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $folder, $path))); $object_file = new JObject(array('filepath' => $fullPath)); if (is_file($object_file->filepath)) { // Trigger the onContentBeforeDelete event. $result = $dispatcher->trigger('onContentBeforeDelete', array('com_media.file', &$object_file)); if (in_array(false, $result, true)) { // There are some errors in the plugins JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_DELETE', count($errors = $object_file->getErrors()), implode('
    ', $errors))); continue; } $ret &= JFile::delete($object_file->filepath); // Trigger the onContentAfterDelete event. $dispatcher->trigger('onContentAfterDelete', array('com_media.file', &$object_file)); $this->setMessage(JText::sprintf('COM_MEDIA_DELETE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); } elseif (is_dir($object_file->filepath)) { $contents = JFolder::files($object_file->filepath, '.', true, false, array('.svn', 'CVS', '.DS_Store', '__MACOSX', 'index.html')); if (empty($contents)) { // Trigger the onContentBeforeDelete event. $result = $dispatcher->trigger('onContentBeforeDelete', array('com_media.folder', &$object_file)); if (in_array(false, $result, true)) { // There are some errors in the plugins JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_DELETE', count($errors = $object_file->getErrors()), implode('
    ', $errors))); continue; } $ret &= JFolder::delete($object_file->filepath); // Trigger the onContentAfterDelete event. $dispatcher->trigger('onContentAfterDelete', array('com_media.folder', &$object_file)); $this->setMessage(JText::sprintf('COM_MEDIA_DELETE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); } else { // This makes no sense... JError::raiseWarning(100, JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_DELETE_FOLDER_NOT_EMPTY', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); } } } return $ret; } } components/com_media/controllers/folder.php000066600000015071150771655450015227 0ustar00input->get('tmpl'); $paths = $this->input->get('rm', array(), 'array'); $folder = $this->input->get('folder', '', 'path'); $redirect = 'index.php?option=com_media&folder=' . $folder; if ($tmpl == 'component') { // We are inside the iframe $redirect .= '&view=mediaList&tmpl=component'; } $this->setRedirect($redirect); // Just return if there's nothing to do if (empty($paths)) { return true; } if (!$user->authorise('core.delete', 'com_media')) { // User is not authorised to delete JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); return false; } // Set FTP credentials, if given JClientHelper::setCredentialsFromRequest('ftp'); $ret = true; JPluginHelper::importPlugin('content'); $dispatcher = JEventDispatcher::getInstance(); if (count($paths)) { foreach ($paths as $path) { if ($path !== JFile::makeSafe($path)) { $dirname = htmlspecialchars($path, ENT_COMPAT, 'UTF-8'); JError::raiseWarning(100, JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_DELETE_FOLDER_WARNDIRNAME', substr($dirname, strlen(COM_MEDIA_BASE)))); continue; } $fullPath = JPath::clean(implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $folder, $path))); $object_file = new JObject(array('filepath' => $fullPath)); if (is_file($object_file->filepath)) { // Trigger the onContentBeforeDelete event. $result = $dispatcher->trigger('onContentBeforeDelete', array('com_media.file', &$object_file)); if (in_array(false, $result, true)) { // There are some errors in the plugins JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_DELETE', count($errors = $object_file->getErrors()), implode('
    ', $errors))); continue; } $ret &= JFile::delete($object_file->filepath); // Trigger the onContentAfterDelete event. $dispatcher->trigger('onContentAfterDelete', array('com_media.file', &$object_file)); $this->setMessage(JText::sprintf('COM_MEDIA_DELETE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); } elseif (is_dir($object_file->filepath)) { $contents = JFolder::files($object_file->filepath, '.', true, false, array('.svn', 'CVS', '.DS_Store', '__MACOSX', 'index.html')); if (empty($contents)) { // Trigger the onContentBeforeDelete event. $result = $dispatcher->trigger('onContentBeforeDelete', array('com_media.folder', &$object_file)); if (in_array(false, $result, true)) { // There are some errors in the plugins JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_DELETE', count($errors = $object_file->getErrors()), implode('
    ', $errors))); continue; } $ret &= !JFolder::delete($object_file->filepath); // Trigger the onContentAfterDelete event. $dispatcher->trigger('onContentAfterDelete', array('com_media.folder', &$object_file)); $this->setMessage(JText::sprintf('COM_MEDIA_DELETE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); } else { // This makes no sense... JError::raiseWarning(100, JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_DELETE_FOLDER_NOT_EMPTY', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); } } } } return $ret; } /** * Create a folder * * @return boolean * * @since 1.5 */ public function create() { // Check for request forgeries JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); $user = JFactory::getUser(); $folder = $this->input->get('foldername', ''); $folderCheck = (string) $this->input->get('foldername', null, 'raw'); $parent = $this->input->get('folderbase', '', 'path'); $this->setRedirect('index.php?option=com_media&folder=' . $parent . '&tmpl=' . $this->input->get('tmpl', 'index')); if (strlen($folder) > 0) { if (!$user->authorise('core.create', 'com_media')) { // User is not authorised to create JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_CREATE_NOT_PERMITTED')); return false; } // Set FTP credentials, if given JClientHelper::setCredentialsFromRequest('ftp'); $this->input->set('folder', $parent); if (($folderCheck !== null) && ($folder !== $folderCheck)) { $this->setMessage(JText::_('COM_MEDIA_ERROR_UNABLE_TO_CREATE_FOLDER_WARNDIRNAME')); return false; } $path = JPath::clean(COM_MEDIA_BASE . '/' . $parent . '/' . $folder); if (!is_dir($path) && !is_file($path)) { // Trigger the onContentBeforeSave event. $object_file = new JObject(array('filepath' => $path)); JPluginHelper::importPlugin('content'); $dispatcher = JEventDispatcher::getInstance(); $result = $dispatcher->trigger('onContentBeforeSave', array('com_media.folder', &$object_file, true)); if (in_array(false, $result, true)) { // There are some errors in the plugins JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_SAVE', count($errors = $object_file->getErrors()), implode('
    ', $errors))); return false; } if (JFolder::create($object_file->filepath)) { $data = "\n\n\n"; JFile::write($object_file->filepath . "/index.html", $data); // Trigger the onContentAfterSave event. $dispatcher->trigger('onContentAfterSave', array('com_media.folder', &$object_file, true)); $this->setMessage(JText::sprintf('COM_MEDIA_CREATE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); } } $this->input->set('folder', ($parent) ? $parent . '/' . $folder : $folder); } else { // File name is of zero length (null). JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_UNABLE_TO_CREATE_FOLDER_WARNDIRNAME')); return false; } return true; } } components/com_media/access.xml000066600000001002150771655450012645 0ustar00
    components/com_media/helpers/index.html000066600000000037150771655450014330 0ustar00 components/com_media/helpers/media.php000066600000006667150771655450014142 0ustar00isImage($fileName); } /** * Gets the file extension for the purpose of using an icon. * * @param string $fileName The filename * * @return string File extension * * @since 1.5 * @deprecated 4.0 Use JHelperMedia::getTypeIcon instead */ public static function getTypeIcon($fileName) { JLog::add('MediaHelper::getTypeIcon() is deprecated. Use JHelperMedia::getTypeIcon() instead.', JLog::WARNING, 'deprecated'); $mediaHelper = new JHelperMedia; return $mediaHelper->getTypeIcon($fileName); } /** * Checks if the file can be uploaded * * @param array File information * @param string An error message to be returned * * @return boolean * * @since 1.5 * @deprecated 4.0 Use JHelperMedia::canUpload instead */ public static function canUpload($file, $err = '') { JLog::add('MediaHelper::canUpload() is deprecated. Use JHelperMedia::canUpload() instead.', JLog::WARNING, 'deprecated'); $mediaHelper = new JHelperMedia; return $mediaHelper->canUpload($file, 'com_media'); } /** * Method to parse a file size * * @param integer $size The file size in bytes * * @return string The converted file size * * @since 1.6 * @deprecated 4.0 Use JHtmlNumber::bytes() instead */ public static function parseSize($size) { JLog::add('MediaHelper::parseSize() is deprecated. Use JHtmlNumber::bytes() instead.', JLog::WARNING, 'deprecated'); return JHtml::_('number.bytes', $size); } /** * Calculate the size of a resized image * * @param integer $width Image width * @param integer $height Image height * @param integer $target Target size * * @return array The new width and height * * @since 3.2 * @deprecated 4.0 Use JHelperMedia::imageResize instead */ public static function imageResize($width, $height, $target) { JLog::add('MediaHelper::countFiles() is deprecated. Use JHelperMedia::countFiles() instead.', JLog::WARNING, 'deprecated'); $mediaHelper = new JHelperMedia; return $mediaHelper->imageResize($width, $height, $target); } /** * Counts the files and directories in a directory that are not php or html files. * * @param string $dir Directory name * * @return array The number of files and directories in the given directory * * @since 1.5 * @deprecated 4.0 Use JHelperMedia::countFiles instead */ public static function countFiles($dir) { JLog::add('MediaHelper::countFiles() is deprecated. Use JHelperMedia::countFiles() instead.', JLog::WARNING, 'deprecated'); $mediaHelper = new JHelperMedia; return $mediaHelper->countFiles($dir); } } components/com_media/models/index.html000066600000000037150771655450014151 0ustar00 components/com_media/models/list.php000066600000010722150771655450013642 0ustar00input; $folder = $input->get('folder', '', 'path'); $this->setState('folder', $folder); $parent = str_replace("\\", "/", dirname($folder)); $parent = ($parent == '.') ? null : $parent; $this->setState('parent', $parent); $set = true; } return parent::getState($property, $default); } public function getImages() { $list = $this->getList(); return $list['images']; } public function getFolders() { $list = $this->getList(); return $list['folders']; } public function getDocuments() { $list = $this->getList(); return $list['docs']; } /** * Build imagelist * * @param string $listFolder The image directory to display * @since 1.5 */ public function getList() { static $list; // Only process the list once per request if (is_array($list)) { return $list; } // Get current path from request $current = $this->getState('folder'); // If undefined, set to empty if ($current == 'undefined') { $current = ''; } if (strlen($current) > 0) { $basePath = COM_MEDIA_BASE.'/'.$current; } else { $basePath = COM_MEDIA_BASE; } $mediaBase = str_replace(DIRECTORY_SEPARATOR, '/', COM_MEDIA_BASE.'/'); $images = array (); $folders = array (); $docs = array (); $fileList = false; $folderList = false; if (file_exists($basePath)) { // Get the list of files and folders from the given folder $fileList = JFolder::files($basePath); $folderList = JFolder::folders($basePath); } // Iterate over the files if they exist if ($fileList !== false) { foreach ($fileList as $file) { if (is_file($basePath.'/'.$file) && substr($file, 0, 1) != '.' && strtolower($file) !== 'index.html') { $tmp = new JObject; $tmp->name = $file; $tmp->title = $file; $tmp->path = str_replace(DIRECTORY_SEPARATOR, '/', JPath::clean($basePath . '/' . $file)); $tmp->path_relative = str_replace($mediaBase, '', $tmp->path); $tmp->size = filesize($tmp->path); $ext = strtolower(JFile::getExt($file)); switch ($ext) { // Image case 'jpg': case 'png': case 'gif': case 'xcf': case 'odg': case 'bmp': case 'jpeg': case 'ico': $info = @getimagesize($tmp->path); $tmp->width = @$info[0]; $tmp->height = @$info[1]; $tmp->type = @$info[2]; $tmp->mime = @$info['mime']; if (($info[0] > 60) || ($info[1] > 60)) { $dimensions = MediaHelper::imageResize($info[0], $info[1], 60); $tmp->width_60 = $dimensions[0]; $tmp->height_60 = $dimensions[1]; } else { $tmp->width_60 = $tmp->width; $tmp->height_60 = $tmp->height; } if (($info[0] > 16) || ($info[1] > 16)) { $dimensions = MediaHelper::imageResize($info[0], $info[1], 16); $tmp->width_16 = $dimensions[0]; $tmp->height_16 = $dimensions[1]; } else { $tmp->width_16 = $tmp->width; $tmp->height_16 = $tmp->height; } $images[] = $tmp; break; // Non-image document default: $tmp->icon_32 = "media/mime-icon-32/".$ext.".png"; $tmp->icon_16 = "media/mime-icon-16/".$ext.".png"; $docs[] = $tmp; break; } } } } // Iterate over the folders if they exist if ($folderList !== false) { foreach ($folderList as $folder) { $tmp = new JObject; $tmp->name = basename($folder); $tmp->path = str_replace(DIRECTORY_SEPARATOR, '/', JPath::clean($basePath . '/' . $folder)); $tmp->path_relative = str_replace($mediaBase, '', $tmp->path); $count = MediaHelper::countFiles($tmp->path); $tmp->files = $count[0]; $tmp->folders = $count[1]; $folders[] = $tmp; } } $list = array('folders' => $folders, 'docs' => $docs, 'images' => $images); return $list; } } components/com_media/models/forms/index.html000066600000000037150771655450015277 0ustar00 components/com_media/models/manager.php000066600000007774150771655450014316 0ustar00input; $folder = $input->get('folder', '', 'path'); $this->setState('folder', $folder); $fieldid = $input->get('fieldid', ''); $this->setState('field.id', $fieldid); $parent = str_replace("\\", "/", dirname($folder)); $parent = ($parent == '.') ? null : $parent; $this->setState('parent', $parent); $set = true; } return parent::getState($property, $default); } /** * Image Manager Popup * * @param string $listFolder The image directory to display * @since 1.5 */ function getFolderList($base = null) { // Get some paths from the request if (empty($base)) { $base = COM_MEDIA_BASE; } //corrections for windows paths $base = str_replace(DIRECTORY_SEPARATOR, '/', $base); $com_media_base_uni = str_replace(DIRECTORY_SEPARATOR, '/', COM_MEDIA_BASE); // Get the list of folders jimport('joomla.filesystem.folder'); $folders = JFolder::folders($base, '.', true, true); $document = JFactory::getDocument(); $document->setTitle(JText::_('COM_MEDIA_INSERT_IMAGE')); // Build the array of select options for the folder list $options[] = JHtml::_('select.option', "", "/"); foreach ($folders as $folder) { $folder = str_replace($com_media_base_uni, "", str_replace(DIRECTORY_SEPARATOR, '/', $folder)); $value = substr($folder, 1); $text = str_replace(DIRECTORY_SEPARATOR, "/", $folder); $options[] = JHtml::_('select.option', $value, $text); } // Sort the folder list array if (is_array($options)) { sort($options); } // Get asset and author id (use integer filter) $input = JFactory::getApplication()->input; $asset = $input->get('asset', 0, 'integer'); // For new items the asset is a string. JAccess always checks type first // so both string and integer are supported. if ($asset == 0) { $asset = $input->get('asset', 0, 'string'); } $author = $input->get('author', 0, 'integer'); // Create the drop-down folder select list $list = JHtml::_('select.genericlist', $options, 'folderlist', 'size="1" onchange="ImageManager.setFolder(this.options[this.selectedIndex].value, '.$asset.', '.$author.')" ', 'value', 'text', $base); return $list; } function getFolderTree($base = null) { // Get some paths from the request if (empty($base)) { $base = COM_MEDIA_BASE; } $mediaBase = str_replace(DIRECTORY_SEPARATOR, '/', COM_MEDIA_BASE.'/'); // Get the list of folders jimport('joomla.filesystem.folder'); $folders = JFolder::folders($base, '.', true, true); $tree = array(); foreach ($folders as $folder) { $folder = str_replace(DIRECTORY_SEPARATOR, '/', $folder); $name = substr($folder, strrpos($folder, '/') + 1); $relative = str_replace($mediaBase, '', $folder); $absolute = $folder; $path = explode('/', $relative); $node = (object) array('name' => $name, 'relative' => $relative, 'absolute' => $absolute); $tmp = &$tree; for ($i = 0, $n = count($path); $i < $n; $i++) { if (!isset($tmp['children'])) { $tmp['children'] = array(); } if ($i == $n - 1) { // We need to place the node $tmp['children'][$relative] = array('data' => $node, 'children' => array()); break; } if (array_key_exists($key = implode('/', array_slice($path, 0, $i + 1)), $tmp['children'])) { $tmp = &$tmp['children'][$key]; } } } $tree['data'] = (object) array('name' => JText::_('COM_MEDIA_MEDIA'), 'relative' => '', 'absolute' => $base); return $tree; } } components/com_media/media.php000066600000002752150771655450012467 0ustar00input; $user = JFactory::getUser(); $asset = $input->get('asset'); $author = $input->get('author'); // Access check. if (!$user->authorise('core.manage', 'com_media') && (!$asset or ( !$user->authorise('core.edit', $asset) && !$user->authorise('core.create', $asset) && count($user->getAuthorisedCategories($asset, 'core.create')) == 0) && !($user->id == $author && $user->authorise('core.edit.own', $asset)))) { return JError::raiseWarning(403, JText::_('JERROR_ALERTNOAUTHOR')); } $params = JComponentHelper::getParams('com_media'); // Load the helper class require_once JPATH_COMPONENT_ADMINISTRATOR . '/helpers/media.php'; // Set the path definitions $popup_upload = $input->get('pop_up', null); $path = 'file_path'; $view = $input->get('view'); if (substr(strtolower($view), 0, 6) == 'images' || $popup_upload == 1) { $path = 'image_path'; } define('COM_MEDIA_BASE', JPATH_ROOT . '/' . $params->get($path, 'images')); define('COM_MEDIA_BASEURL', JUri::root() . $params->get($path, 'images')); $controller = JControllerLegacy::getInstance('Media', array('base_path' => JPATH_COMPONENT_ADMINISTRATOR)); $controller->execute($input->get('task')); $controller->redirect(); components/com_modules/layouts/index.html000066600000000037150771655450014757 0ustar00 components/com_modules/layouts/toolbar/cancelselect.php000066600000000751150771655450017565 0ustar00 components/com_modules/layouts/toolbar/newmodule.php000066600000001026150771655450017133 0ustar00 components/com_modules/layouts/toolbar/index.html000066600000000037150771655450016421 0ustar00 components/com_modules/views/module/view.html.php000066600000005323150771655450016335 0ustar00form = $this->get('Form'); $this->item = $this->get('Item'); $this->state = $this->get('State'); $this->canDo = JHelperContent::getActions('com_modules', 'module', $this->item->id); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { JFactory::getApplication()->input->set('hidemainmenu', true); $user = JFactory::getUser(); $isNew = ($this->item->id == 0); $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); $canDo = $this->canDo; JToolbarHelper::title(JText::sprintf('COM_MODULES_MANAGER_MODULE', JText::_($this->item->module)), 'cube module'); // For new records, check the create permission. if ($isNew && $canDo->get('core.create')) { JToolbarHelper::apply('module.apply'); JToolbarHelper::save('module.save'); JToolbarHelper::save2new('module.save2new'); JToolbarHelper::cancel('module.cancel'); } else { // Can't save the record if it's checked out. if (!$checkedOut) { // Since it's an existing record, check the edit permission. if ($canDo->get('core.edit')) { JToolbarHelper::apply('module.apply'); JToolbarHelper::save('module.save'); // We can save this record, but check the create permission to see if we can return to make a new one. if ($canDo->get('core.create')) { JToolbarHelper::save2new('module.save2new'); } } } // If checked out, we can still save if ($canDo->get('core.create')) { JToolbarHelper::save2copy('module.save2copy'); } JToolbarHelper::cancel('module.cancel', 'JTOOLBAR_CLOSE'); } // Get the help information for the menu item. $lang = JFactory::getLanguage(); $help = $this->get('Help'); if ($lang->hasKey($help->url)) { $debug = $lang->setDebug(false); $url = JText::_($help->url); $lang->setDebug($debug); } else { $url = null; } JToolbarHelper::help($help->key, false, $url); } } components/com_modules/views/module/tmpl/edit.php000066600000013132150771655450016316 0ustar00item->module) || isset($this->item->xml->customContent); $hasContentFieldName = "content"; // For a later improvement if ($hasContent) { $hasContentFieldName = "content"; } // Get Params Fieldsets $this->fieldsets = $this->form->getFieldsets('params'); $script = "Joomla.submitbutton = function(task) { if (task == 'module.cancel' || document.formvalidator.isValid(document.id('module-form'))) {"; if ($hasContent) { $script .= $this->form->getField($hasContentFieldName)->save(); } $script .= " Joomla.submitform(task, document.getElementById('module-form')); if (self != top) { window.top.setTimeout('window.parent.SqueezeBox.close()', 1000); } } };"; JFactory::getDocument()->addScriptDeclaration($script); ?>
    'general')); ?>
    item->xml) : ?> item->xml->description) : ?>

    item->xml) { echo ($text = (string) $this->item->xml->name) ? JText::_($text) : $this->item->module; } else { echo JText::_('COM_MODULES_ERR_XML'); } ?>

    item->client_id == 0 ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); ?>
    item->xml->description); $this->fieldset = 'description'; $long_description = JLayoutHelper::render('joomla.edit.fieldset', $this); if(!$long_description) { $truncated = JHtmlString::truncate($short_description, 550, true, false); if(strlen($truncated) > 500) { $long_description = $short_description; $short_description = JHtmlString::truncate($truncated, 250); if($short_description == $long_description) { $long_description = ''; } } } ?>

    form->getInput($hasContentFieldName); } $this->fieldset = 'basic'; $html = JLayoutHelper::render('joomla.edit.fieldset', $this); echo $html ? '
    ' . $html : ''; ?>
    form->getControlGroup('showtitle'); ?>
    form->getLabel('position'); ?>
    loadTemplate('positions'); ?>
    fields = array( 'published', 'publish_up', 'publish_down', 'access', 'ordering', 'language', 'note' ); ?>
    item->client_id == 0) : ?> loadTemplate('assignment'); ?> canDo->get('core.admin')) : ?> form->getInput('rules'); ?> fieldsets = array(); $this->ignore_fieldsets = array('basic', 'description'); echo JLayoutHelper::render('joomla.edit.params', $this); ?> form->getInput('module'); ?> form->getInput('client_id'); ?>
    components/com_modules/views/module/tmpl/index.html000066600000000037150771655450016655 0ustar00 components/com_modules/views/module/tmpl/edit_positions.php000066600000002224150771655450020425 0ustar00item->client_id; $state = 1; $selectedPosition = $this->item->position; $positions = JHtml::_('modules.positions', $clientId, $state, $selectedPosition); // Add custom position to options $customGroupText = JText::_('COM_MODULES_CUSTOM_POSITION'); // Build field $attr = array( 'id' => 'jform_position', 'list.select' => $this->item->position, 'list.attr' => 'class="chzn-custom-value input-xlarge" ' . 'data-custom_group_text="' . $customGroupText . '" ' . 'data-no_results_text="' . JText::_('COM_MODULES_ADD_CUSTOM_POSITION') . '" ' . 'data-placeholder="' . JText::_('COM_MODULES_TYPE_OR_SELECT_POSITION') . '" ' ); echo JHtml::_('select.groupedlist', $positions, 'jform[position]', $attr); components/com_modules/views/module/tmpl/edit_assignment.php000066600000012542150771655450020552 0ustar00addScriptDeclaration($script); ?>
    components/com_modules/views/module/tmpl/modal.php000066600000001336150771655450016470 0ustar00
    setLayout('edit'); echo $this->loadTemplate(); components/com_modules/views/module/tmpl/edit_options.php000066600000002464150771655450020077 0ustar00 'collapse0')); $fieldSets = $this->form->getFieldsets('params'); $i = 0; foreach ($fieldSets as $name => $fieldSet) : $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_MODULES_'.$name.'_FIELDSET_LABEL'; $class = isset($fieldSet->class) && !empty($fieldSet->class) ? $fieldSet->class : ''; echo JHtml::_('bootstrap.addSlide', 'moduleOptions', JText::_($label), 'collapse' . $i++, $class); if (isset($fieldSet->description) && trim($fieldSet->description)) : echo '

    '.$this->escape(JText::_($fieldSet->description)).'

    '; endif; ?> form->getFieldset($name) as $field) : ?>
    label; ?>
    input; ?>
    components/com_modules/views/index.html000066600000000037150771655450014414 0ustar00 components/com_modules/views/modules/view.html.php000066600000013147150771655450016523 0ustar00items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } // Check if there are no matching items if (!count($this->items)){ JFactory::getApplication()->enqueueMessage( JText::_('COM_MODULES_MSG_MANAGE_NO_MODULES'), 'warning' ); } $this->addToolbar(); // Include the component HTML helpers. JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 1.6 */ protected function addToolbar() { $state = $this->get('State'); $canDo = JHelperContent::getActions('com_modules'); $user = JFactory::getUser(); // Get the toolbar object instance $bar = JToolBar::getInstance('toolbar'); JToolbarHelper::title(JText::_('COM_MODULES_MANAGER_MODULES'), 'cube module'); if ($canDo->get('core.create')) { // Instantiate a new JLayoutFile instance and render the layout $layout = new JLayoutFile('toolbar.newmodule'); $bar->appendButton('Custom', $layout->render(array()), 'new'); } if ($canDo->get('core.edit')) { JToolbarHelper::editList('module.edit'); } if ($canDo->get('core.create')) { JToolbarHelper::custom('modules.duplicate', 'copy.png', 'copy_f2.png', 'JTOOLBAR_DUPLICATE', true); } if ($canDo->get('core.edit.state')) { JToolbarHelper::publish('modules.publish', 'JTOOLBAR_PUBLISH', true); JToolbarHelper::unpublish('modules.unpublish', 'JTOOLBAR_UNPUBLISH', true); JToolbarHelper::checkin('modules.checkin'); } if ($state->get('filter.state') == -2 && $canDo->get('core.delete')) { JToolbarHelper::deleteList('', 'modules.delete', 'JTOOLBAR_EMPTY_TRASH'); } elseif ($canDo->get('core.edit.state')) { JToolbarHelper::trash('modules.trash'); } // Add a batch button if ($user->authorise('core.create', 'com_modules') && $user->authorise('core.edit', 'com_modules') && $user->authorise('core.edit.state', 'com_modules')) { JHtml::_('bootstrap.modal', 'collapseModal'); $title = JText::_('JTOOLBAR_BATCH'); // Instantiate a new JLayoutFile instance and render the batch button $layout = new JLayoutFile('joomla.toolbar.batch'); $dhtml = $layout->render(array('title' => $title)); $bar->appendButton('Custom', $dhtml, 'batch'); } if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_modules'); } JToolbarHelper::help('JHELP_EXTENSIONS_MODULE_MANAGER'); JHtmlSidebar::addEntry( JText::_('JSITE'), 'index.php?option=com_modules&filter_client_id=0', $this->state->get('filter.client_id') == 0 ); JHtmlSidebar::addEntry( JText::_('JADMINISTRATOR'), 'index.php?option=com_modules&filter_client_id=1', $this->state->get('filter.client_id') == 1 ); JHtmlSidebar::setAction('index.php?option=com_modules'); JHtmlSidebar::addFilter( // @todo we need a label for this '', 'filter_client_id', JHtml::_('select.options', ModulesHelper::getClientOptions(), 'value', 'text', $this->state->get('filter.client_id')), false ); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_PUBLISHED'), 'filter_state', JHtml::_('select.options', ModulesHelper::getStateOptions(), 'value', 'text', $this->state->get('filter.state')) ); JHtmlSidebar::addFilter( JText::_('COM_MODULES_OPTION_SELECT_POSITION'), 'filter_position', JHtml::_('select.options', ModulesHelper::getPositions($this->state->get('filter.client_id')), 'value', 'text', $this->state->get('filter.position')) ); JHtmlSidebar::addFilter( JText::_('COM_MODULES_OPTION_SELECT_MODULE'), 'filter_module', JHtml::_('select.options', ModulesHelper::getModules($this->state->get('filter.client_id')), 'value', 'text', $this->state->get('filter.module')) ); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_ACCESS'), 'filter_access', JHtml::_('select.options', JHtml::_('access.assetgroups'), 'value', 'text', $this->state->get('filter.access')) ); JHtmlSidebar::addFilter( JText::_('JOPTION_SELECT_LANGUAGE'), 'filter_language', JHtml::_('select.options', JHtml::_('contentlanguage.existing', true, true), 'value', 'text', $this->state->get('filter.language')) ); $this->sidebar = JHtmlSidebar::render(); } /** * Returns an array of fields the table can be sorted by * * @return array Array containing the field name to sort by as the key and display text as value * * @since 3.0 */ protected function getSortFields() { return array( 'ordering' => JText::_('JGRID_HEADING_ORDERING'), 'a.published' => JText::_('JSTATUS'), 'a.title' => JText::_('JGLOBAL_TITLE'), 'position' => JText::_('COM_MODULES_HEADING_POSITION'), 'name' => JText::_('COM_MODULES_HEADING_MODULE'), 'pages' => JText::_('COM_MODULES_HEADING_PAGES'), 'a.access' => JText::_('JGRID_HEADING_ACCESS'), 'language_title' => JText::_('JGRID_HEADING_LANGUAGE'), 'a.id' => JText::_('JGRID_HEADING_ID') ); } } components/com_modules/views/modules/tmpl/default.php000066600000023563150771655450017211 0ustar00state->get('filter.client_id') ? 'administrator' : 'site'; $user = JFactory::getUser(); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $trashed = $this->state->get('filter.published') == -2 ? true : false; $canOrder = $user->authorise('core.edit.state', 'com_modules'); $saveOrder = $listOrder == 'ordering'; if ($saveOrder) { $saveOrderingUrl = 'index.php?option=com_modules&task=modules.saveOrderAjax&tmpl=component'; JHtml::_('sortablelist.sortable', 'articleList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); } $sortFields = $this->getSortFields(); ?>
    sidebar)) : ?>
    sidebar; ?>
    pagination->getLimitBox(); ?>
    items as $i => $item) : $ordering = ($listOrder == 'ordering'); $canCreate = $user->authorise('core.create', 'com_modules'); $canEdit = $user->authorise('core.edit', 'com_modules.module.'.$item->id); $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id')|| $item->checked_out == 0; $canChange = $user->authorise('core.edit.state', 'com_modules.module.'.$item->id) && $canCheckin; ?>
    ', 'ordering', $listDirn, $listOrder, null, 'asc', 'JGRID_HEADING_ORDERING'); ?>
    pagination->getListFooter(); ?>
    id); ?>
    published, $i, $canChange, 'cb'); ?> escape($item->title)); ?>
    checked_out) : ?> editor, $item->checked_out_time, 'modules.', $canCheckin); ?> escape($item->title); ?> escape($item->title); ?> note)) : ?>
    escape($item->note));?>
    position) : ?> position; ?> name;?> pages; ?> escape($item->access_level); ?> language == ''):?> language == '*'):?> language_title ? $this->escape($item->language_title) : JText::_('JUNDEFINED'); ?> id; ?>
    loadTemplate('batch'); ?>
    components/com_modules/views/modules/tmpl/index.html000066600000000037150771655450017040 0ustar00 components/com_modules/views/modules/tmpl/default_batch.php000066600000005370150771655450020346 0ustar00state->get('filter.client_id'); $published = $this->state->get('filter.published'); $positions = JHtml::_('modules.positions', $clientId, $published); $positions['']['items'][] = ModulesHelper::createOption('nochange', JText::_('COM_MODULES_BATCH_POSITION_NOCHANGE')); $positions['']['items'][] = ModulesHelper::createOption('noposition', JText::_('COM_MODULES_BATCH_POSITION_NOPOSITION')); // Add custom position to options $customGroupText = JText::_('COM_MODULES_CUSTOM_POSITION'); // Build field $attr = array( 'id' => 'batch-position-id', 'list.attr' => 'class="chzn-custom-value input-xlarge" ' . 'data-custom_group_text="' . $customGroupText . '" ' . 'data-no_results_text="' . JText::_('COM_MODULES_ADD_CUSTOM_POSITION') . '" ' . 'data-placeholder="' . JText::_('COM_MODULES_TYPE_OR_SELECT_POSITION') . '" ' ); ?> components/com_modules/views/modules/index.html000066600000000037150771655450016064 0ustar00 components/com_modules/views/select/view.html.php000066600000002533150771655450016327 0ustar00get('State'); $items = $this->get('Items'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } $this->state = &$state; $this->items = &$items; $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @since 3.0 */ protected function addToolbar() { // Add page title JToolbarHelper::title(JText::_('COM_MODULES_MANAGER_MODULES'), 'cube module'); // Get the toolbar object instance $bar = JToolBar::getInstance('toolbar'); // Instantiate a new JLayoutFile instance and render the layout $layout = new JLayoutFile('toolbar.cancelselect'); $bar->appendButton('Custom', $layout->render(array()), 'new'); } } components/com_modules/views/select/tmpl/default.php000066600000002762150771655450017016 0ustar00

      items as &$item) : ?> extension_id; $name = $this->escape($item->name); $desc = JHTML::_('string.truncate', ($this->escape($item->desc)), 200); $short_desc = JHTML::_('string.truncate', ($this->escape($item->desc)), 90); ?> direction != "rtl") : ?>
    components/com_modules/views/select/tmpl/index.html000066600000000037150771655450016647 0ustar00 components/com_modules/views/select/index.html000066600000000037150771655450015673 0ustar00 components/com_modules/views/positions/view.html.php000066600000001534150771655450017077 0ustar00items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } parent::display($tpl); } } components/com_modules/views/positions/tmpl/index.html000066600000000037150771655450017417 0ustar00 components/com_modules/views/positions/tmpl/modal.php000066600000010052150771655450017225 0ustar00input->getCmd('function', 'jSelectPosition'); $lang = JFactory::getLanguage(); $ordering = $this->escape($this->state->get('list.ordering')); $direction = $this->escape($this->state->get('list.direction')); $clientId = $this->state->get('filter.client_id'); $state = $this->state->get('filter.state'); $template = $this->state->get('filter.template'); $type = $this->state->get('filter.type'); ?>
    items as $value => $templates) : ?>
    pagination->getListFooter(); ?>
    escape($value); ?>
      $label):?>
    • hasKey($label) ? JText::sprintf('COM_MODULES_MODULE_TEMPLATE_POSITION', JText::_($template), JText::_($label)) : JText::_($template);?>
    components/com_modules/views/positions/index.html000066600000000037150771655450016443 0ustar00 components/com_modules/views/preview/view.html.php000066600000001176150771655450016533 0ustar00get('editor'); $this->editor = JEditor::getInstance($editor); parent::display($tpl); } } components/com_modules/views/preview/tmpl/default.php000066600000001270150771655450017211 0ustar00
    components/com_modules/views/preview/tmpl/index.html000066600000000037150771655450017051 0ustar00 components/com_modules/views/preview/index.html000066600000000037150771655450016075 0ustar00 components/com_modules/index.html000066600000000037150771655450013257 0ustar00 components/com_modules/config.xml000066600000000542150771655450013252 0ustar00
    components/com_modules/controller.php000066600000002322150771655450014155 0ustar00input->get('view', 'modules')); $view = $this->input->get('view', 'modules'); $layout = $this->input->get('layout', 'default'); $id = $this->input->getInt('id'); return parent::display(); } } components/com_modules/controllers/index.html000066600000000037150771655450015625 0ustar00 components/com_modules/controllers/modules.php000066600000003211150771655450016006 0ustar00input->post->get('cid', array(), 'array'); JArrayHelper::toInteger($pks); try { if (empty($pks)) { throw new Exception(JText::_('COM_MODULES_ERROR_NO_MODULES_SELECTED')); } $model = $this->getModel(); $model->duplicate($pks); $this->setMessage(JText::plural('COM_MODULES_N_MODULES_DUPLICATED', count($pks))); } catch (Exception $e) { JError::raiseWarning(500, $e->getMessage()); } $this->setRedirect('index.php?option=com_modules&view=modules'); } /** * Method to get a model object, loading it if required. * * @param string $name The model name. Optional. * @param string $prefix The class prefix. Optional. * @param array $config Configuration array for model. Optional. * * @return object The model. * * @since 1.6 */ public function getModel($name = 'Module', $prefix = 'ModulesModel', $config = array('ignore_request' => true)) { $model = parent::getModel($name, $prefix, $config); return $model; } } components/com_modules/controllers/module.php000066600000010613150771655450015627 0ustar00input->get('eid', 0, 'int'); if (empty($extensionId)) { $this->setRedirect(JRoute::_('index.php?option='.$this->option.'&view='.$this->view_item.'&layout=edit', false)); return JError::raiseWarning(500, JText::_('COM_MODULES_ERROR_INVALID_EXTENSION')); } $app->setUserState('com_modules.add.module.extension_id', $extensionId); $app->setUserState('com_modules.add.module.params', null); // Parameters could be coming in for a new item, so let's set them. $params = $app->input->get('params', array(), 'array'); $app->setUserState('com_modules.add.module.params', $params); } /** * Override parent cancel method to reset the add module state. * * @param string $key The name of the primary key of the URL variable. * * @return boolean True if access level checks pass, false otherwise. * * @since 1.6 */ public function cancel($key = null) { $app = JFactory::getApplication(); $result = parent::cancel(); $app->setUserState('com_modules.add.module.extension_id', null); $app->setUserState('com_modules.add.module.params', null); return $result; } /** * Override parent allowSave method. * * @param array $data An array of input data. * @param string $key The name of the key for the primary key. * * @return boolean * * @since 1.6 */ protected function allowSave($data, $key = 'id') { // use custom position if selected if (isset($data['custom_position'])) { if (empty($data['position'])) { $data['position'] = $data['custom_position']; } unset($data['custom_position']); } return parent::allowSave($data, $key); } /** * Method override to check if you can edit an existing record. * * @param array $data An array of input data. * @param string $key The name of the key for the primary key. * * @return boolean * * @since 3.2 */ protected function allowEdit($data = array(), $key = 'id') { // Initialise variables. $recordId = (int) isset($data[$key]) ? $data[$key] : 0; $user = JFactory::getUser(); $userId = $user->get('id'); // Check general edit permission first. if ($user->authorise('core.edit', 'com_modules.module.' . $recordId)) { return true; } // Since there is no asset tracking, revert to the component permissions. return parent::allowEdit($data, $key); } /** * Method to run batch operations. * * @param string $model The model * * @return boolean True on success. * * @since 1.7 */ public function batch($model = null) { JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Set the model $model = $this->getModel('Module', '', array()); // Preset the redirect $this->setRedirect(JRoute::_('index.php?option=com_modules&view=modules'.$this->getRedirectToListAppend(), false)); return parent::batch($model); } /** * Function that allows child controller access to model data after the data has been saved. * * @param JModelLegacy $model The data model object. * @param array $validData The validated data. * * @return void * * @since 1.6 */ protected function postSaveHook(JModelLegacy $model, $validData = array()) { $app = JFactory::getApplication(); $task = $this->getTask(); switch ($task) { case 'save2new': $app->setUserState('com_modules.add.module.extension_id', $model->getState('module.extension_id')); break; default: $app->setUserState('com_modules.add.module.extension_id', null); break; } $app->setUserState('com_modules.add.module.params', null); } } components/com_modules/modules.xml000066600000002042150771655450013452 0ustar00 com_modules Joomla! Project April 2006 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_MODULES_XML_DESCRIPTION config.xml controller.php index.html modules.php controllers helpers models views language/en-GB.com_modules.ini language/en-GB.com_modules.sys.ini components/com_modules/modules.php000066600000001132150771655450013440 0ustar00authorise('core.manage', 'com_modules')) { return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR')); } $controller = JControllerLegacy::getInstance('Modules'); $controller->execute(JFactory::getApplication()->input->get('task')); $controller->redirect(); components/com_modules/access.xml000066600000002037150771655450013247 0ustar00
    components/com_modules/helpers/html/index.html000066600000000037150771655450015665 0ustar00 components/com_modules/helpers/html/modules.php000066600000013675150771655450016065 0ustar00element, $template->name); } return $options; } /** * Builds an array of template type options * * @return array */ public static function types() { $options = array(); $options[] = JHtml::_('select.option', 'user', 'COM_MODULES_OPTION_POSITION_USER_DEFINED'); $options[] = JHtml::_('select.option', 'template', 'COM_MODULES_OPTION_POSITION_TEMPLATE_DEFINED'); return $options; } /** * Builds an array of template state options * * @return array */ public static function templateStates() { $options = array(); $options[] = JHtml::_('select.option', '1', 'JENABLED'); $options[] = JHtml::_('select.option', '0', 'JDISABLED'); return $options; } /** * Returns a published state on a grid * * @param integer $value The state value. * @param integer $i The row index * @param boolean $enabled An optional setting for access control on the action. * @param string $checkbox An optional prefix for checkboxes. * * @return string The Html code * * @see JHtmlJGrid::state * @since 1.7.1 */ public static function state($value, $i, $enabled = true, $checkbox = 'cb') { $states = array( 1 => array( 'unpublish', 'COM_MODULES_EXTENSION_PUBLISHED_ENABLED', 'COM_MODULES_HTML_UNPUBLISH_ENABLED', 'COM_MODULES_EXTENSION_PUBLISHED_ENABLED', true, 'publish', 'publish' ), 0 => array( 'publish', 'COM_MODULES_EXTENSION_UNPUBLISHED_ENABLED', 'COM_MODULES_HTML_PUBLISH_ENABLED', 'COM_MODULES_EXTENSION_UNPUBLISHED_ENABLED', true, 'unpublish', 'unpublish' ), -1 => array( 'unpublish', 'COM_MODULES_EXTENSION_PUBLISHED_DISABLED', 'COM_MODULES_HTML_UNPUBLISH_DISABLED', 'COM_MODULES_EXTENSION_PUBLISHED_DISABLED', true, 'warning', 'warning' ), -2 => array( 'publish', 'COM_MODULES_EXTENSION_UNPUBLISHED_DISABLED', 'COM_MODULES_HTML_PUBLISH_DISABLED', 'COM_MODULES_EXTENSION_UNPUBLISHED_DISABLED', true, 'unpublish', 'unpublish' ), ); return JHtml::_('jgrid.state', $states, $value, $i, 'modules.', $enabled, true, $checkbox); } /** * Display a batch widget for the module position selector. * * @param integer $clientId The client ID. * @param integer $state The state of the module (enabled, unenabled, trashed). * @param string $selectedPosition The currently selected position for the module. * * @return string The necessary positions for the widget. * * @since 2.5 */ public static function positions($clientId, $state = 1, $selectedPosition = '') { require_once JPATH_ADMINISTRATOR . '/components/com_templates/helpers/templates.php'; $templates = array_keys(ModulesHelper::getTemplates($clientId, $state)); $templateGroups = array(); // Add an empty value to be able to deselect a module position $option = ModulesHelper::createOption(); $templateGroups[''] = ModulesHelper::createOptionGroup('', array($option)); // Add positions from templates $isTemplatePosition = false; foreach ($templates as $template) { $options = array(); $positions = TemplatesHelper::getPositions($clientId, $template); if (is_array($positions)) foreach ($positions as $position) { $text = ModulesHelper::getTranslatedModulePosition($clientId, $template, $position) . ' [' . $position . ']'; $options[] = ModulesHelper::createOption($position, $text); if (!$isTemplatePosition && $selectedPosition === $position) { $isTemplatePosition = true; } } $templateGroups[$template] = ModulesHelper::createOptionGroup(ucfirst($template), $options); } // Add custom position to options $customGroupText = JText::_('COM_MODULES_CUSTOM_POSITION'); $editPositions = true; $customPositions = ModulesHelper::getPositions($clientId, $editPositions); $templateGroups[$customGroupText] = ModulesHelper::createOptionGroup($customGroupText, $customPositions); return $templateGroups; } public static function batchOptions() { // Create the copy/move options. $options = array( JHtml::_('select.option', 'c', JText::_('JLIB_HTML_BATCH_COPY')), JHtml::_('select.option', 'm', JText::_('JLIB_HTML_BATCH_MOVE')) ); echo JHtml::_('select.radiolist', $options, 'batch[move_copy]', '', 'value', 'text', 'm'); } /** * Method to get the field options. * * @param integer $clientId The client ID * * @return array The field option objects. * * @since 2.5 */ public static function positionList($clientId = 0) { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('DISTINCT(position) as value') ->select('position as text') ->from($db->quoteName('#__modules')) ->where($db->quoteName('client_id') . ' = ' . (int) $clientId) ->order('position'); // Get the options. $db->setQuery($query); try { $options = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage()); } // Pop the first item off the array if it's blank if (count($options)) { if (strlen($options[0]->text) < 1) { array_shift($options); } } return $options; } } components/com_modules/helpers/xml.php000066600000002161150771655450014235 0ustar00 $row) { if ($row->module == '') { $rows[$i]->name = 'custom'; $rows[$i]->module = 'custom'; $rows[$i]->descrip = 'Custom created module, using Module Manager New function'; } else { $data = JInstaller::parseXMLInstallFile($row->path . '/' . $row->file); if ($data['type'] == 'module') { $rows[$i]->name = $data['name']; $rows[$i]->descrip = $data['description']; } } } } } components/com_modules/helpers/index.html000066600000000037150771655450014721 0ustar00 components/com_modules/helpers/modules.php000066600000020442150771655450015107 0ustar00getQuery(true) ->select('DISTINCT(position)') ->from('#__modules') ->where($db->quoteName('client_id') . ' = ' . (int) $clientId) ->order('position'); $db->setQuery($query); try { $positions = $db->loadColumn(); $positions = is_array($positions) ? $positions : array(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage()); return; } // Build the list $options = array(); foreach ($positions as $position) { if (!$position && !$editPositions) { $options[] = JHtml::_('select.option', 'none', ':: ' . JText::_('JNONE') . ' ::'); } else { $options[] = JHtml::_('select.option', $position, $position); } } return $options; } /** * Return a list of templates * * @param integer $clientId Client ID * @param string $state State * @param string $template Template name * * @return array List of templates */ public static function getTemplates($clientId = 0, $state = '', $template = '') { $db = JFactory::getDbo(); // Get the database object and a new query object. $query = $db->getQuery(true); // Build the query. $query->select('element, name, enabled') ->from('#__extensions') ->where('client_id = ' . (int) $clientId) ->where('type = ' . $db->quote('template')); if ($state != '') { $query->where('enabled = ' . $db->quote($state)); } if ($template != '') { $query->where('element = ' . $db->quote($template)); } // Set the query and load the templates. $db->setQuery($query); $templates = $db->loadObjectList('element'); return $templates; } /** * Get a list of the unique modules installed in the client application. * * @param int $clientId The client id. * * @return array Array of unique modules */ public static function getModules($clientId) { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('element AS value, name AS text') ->from('#__extensions as e') ->where('e.client_id = ' . (int) $clientId) ->where('type = ' . $db->quote('module')) ->join('LEFT', '#__modules as m ON m.module=e.element AND m.client_id=e.client_id') ->where('m.module IS NOT NULL') ->group('element,name'); $db->setQuery($query); $modules = $db->loadObjectList(); $lang = JFactory::getLanguage(); foreach ($modules as $i => $module) { $extension = $module->value; $path = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; $source = $path . "/modules/$extension"; $lang->load("$extension.sys", $path, null, false, true) || $lang->load("$extension.sys", $source, null, false, true); $modules[$i]->text = JText::_($module->text); } JArrayHelper::sortObjects($modules, 'text', 1, true, true); return $modules; } /** * Get a list of the assignment options for modules to menus. * * @param int $clientId The client id. * * @return array */ public static function getAssignmentOptions($clientId) { $options = array(); $options[] = JHtml::_('select.option', '0', 'COM_MODULES_OPTION_MENU_ALL'); $options[] = JHtml::_('select.option', '-', 'COM_MODULES_OPTION_MENU_NONE'); if ($clientId == 0) { $options[] = JHtml::_('select.option', '1', 'COM_MODULES_OPTION_MENU_INCLUDE'); $options[] = JHtml::_('select.option', '-1', 'COM_MODULES_OPTION_MENU_EXCLUDE'); } return $options; } /** * Return a translated module position name * * @param string $template Template name * @param string $position Position name * * @return string Return a translated position name * * @since 3.0 */ public static function getTranslatedModulePosition($clientId, $template, $position) { // Template translation $lang = JFactory::getLanguage(); $path = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; $lang->load('tpl_'.$template.'.sys', $path, null, false, false) || $lang->load('tpl_'.$template.'.sys', $path.'/templates/'.$template, null, false, false) || $lang->load('tpl_'.$template.'.sys', $path, $lang->getDefault(), false, false) || $lang->load('tpl_'.$template.'.sys', $path.'/templates/'.$template, $lang->getDefault(), false, false); $langKey = strtoupper('TPL_' . $template . '_POSITION_' . $position); $text = JText::_($langKey); // Avoid untranslated strings if (!self::isTranslatedText($langKey, $text)) { // Modules component translation $langKey = strtoupper('COM_MODULES_POSITION_' . $position); $text = JText::_($langKey); // Avoid untranslated strings if (!self::isTranslatedText($langKey, $text)) { // Try to humanize the position name $text = ucfirst(preg_replace('/^' . $template . '\-/', '', $position)); $text = ucwords(str_replace(array('-', '_'), ' ', $text)); } } return $text; } /** * Check if the string was translated * * @param string $langKey Language file text key * @param string $text The "translated" text to be checked * * @return boolean Return true for translated text * * @since 3.0 */ public static function isTranslatedText($langKey, $text) { return $text !== $langKey; } /** * Create and return a new Option * * @param string $value The option value [optional] * @param string $text The option text [optional] * * @return object The option as an object (stdClass instance) * * @since 3.0 */ public static function createOption($value = '', $text = '') { if (empty($text)) { $text = $value; } $option = new stdClass; $option->value = $value; $option->text = $text; return $option; } /** * Create and return a new Option Group * * @param string $label Value and label for group [optional] * @param array $options Array of options to insert into group [optional] * * @return array Return the new group as an array * * @since 3.0 */ public static function createOptionGroup($label = '', $options = array()) { $group = array(); $group['value'] = $label; $group['text'] = $label; $group['items'] = $options; return $group; } } components/com_modules/models/index.html000066600000000037150771655450014542 0ustar00 components/com_modules/models/select.php000066600000007643150771655450014547 0ustar00getUserState('com_modules.modules.filter.client_id', 0); $this->setState('filter.client_id', (int) $clientId); // Load the parameters. $params = JComponentHelper::getParams('com_modules'); $this->setState('params', $params); // Manually set limits to get all modules. $this->setState('list.limit', 0); $this->setState('list.start', 0); $this->setState('list.ordering', 'a.name'); $this->setState('list.direction', 'ASC'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string A prefix for the store id. * * @return string A store id. */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.client_id'); return parent::getStoreId($id); } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.extension_id, a.name, a.element AS module' ) ); $query->from($db->quoteName('#__extensions') . ' AS a'); // Filter by module $query->where('a.type = ' . $db->quote('module')); // Filter by client. $clientId = $this->getState('filter.client_id'); $query->where('a.client_id = ' . (int) $clientId); // Filter by enabled $query->where('a.enabled = 1'); // Add the list ordering clause. $query->order($db->escape($this->getState('list.ordering', 'a.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); //echo nl2br(str_replace('#__','jos_',$query)); return $query; } /** * Method to get a list of items. * * @return mixed An array of objects on success, false on failure. */ public function getItems() { // Get the list of items from the database. $items = parent::getItems(); $client = JApplicationHelper::getClientInfo($this->getState('filter.client_id', 0)); $lang = JFactory::getLanguage(); // Loop through the results to add the XML metadata, // and load language support. foreach ($items as &$item) { $path = JPath::clean($client->path . '/modules/' . $item->module . '/' . $item->module . '.xml'); if (file_exists($path)) { $item->xml = simplexml_load_file($path); } else { $item->xml = null; } // 1.5 Format; Core files or language packs then // 1.6 3PD Extension Support $lang->load($item->module . '.sys', $client->path, null, false, true) || $lang->load($item->module . '.sys', $client->path . '/modules/' . $item->module, null, false, true); $item->name = JText::_($item->name); if (isset($item->xml) && $text = trim($item->xml->description)) { $item->desc = JText::_($text); } else { $item->desc = JText::_('COM_MODULES_NODESCRIPTION'); } } $items = JArrayHelper::sortObjects($items, 'name', 1, true, true); // TODO: Use the cached XML from the extensions table? return $items; } } components/com_modules/models/forms/module.xml000066600000006052150771655450015705 0ustar00
    components/com_modules/models/forms/index.html000066600000000037150771655450015670 0ustar00 components/com_modules/models/forms/advanced.xml000066600000001772150771655450016171 0ustar00
    components/com_modules/models/modules.php000066600000022474150771655450014737 0ustar00getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $accessId = $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', null, 'int'); $this->setState('filter.access', $accessId); $state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string'); $this->setState('filter.state', $state); $position = $this->getUserStateFromRequest($this->context . '.filter.position', 'filter_position', '', 'string'); $this->setState('filter.position', $position); $module = $this->getUserStateFromRequest($this->context . '.filter.module', 'filter_module', '', 'string'); $this->setState('filter.module', $module); $clientId = $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', 0, 'int', false); $previousId = $app->getUserState($this->context . '.filter.client_id_previous', null); if ($previousId != $clientId || $previousId === null) { $this->getUserStateFromRequest($this->context . '.filter.client_id_previous', 'filter_client_id_previous', 0, 'int', true); $app->setUserState($this->context . '.filter.client_id_previous', $clientId); } $this->setState('filter.client_id', $clientId); $language = $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', ''); $this->setState('filter.language', $language); // Load the parameters. $params = JComponentHelper::getParams('com_modules'); $this->setState('params', $params); // List state information. parent::populateState('position', 'asc'); } /** * Method to get a store id based on model configuration state. * * This is necessary because the model is used by the component and * different modules that might need different sets of data or different * ordering requirements. * * @param string A prefix for the store id. * * @return string A store id. */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.access'); $id .= ':' . $this->getState('filter.state'); $id .= ':' . $this->getState('filter.position'); $id .= ':' . $this->getState('filter.module'); $id .= ':' . $this->getState('filter.client_id'); $id .= ':' . $this->getState('filter.language'); return parent::getStoreId($id); } /** * Returns an object list * * @param string The query * @param int Offset * @param int The number of records * @return array */ protected function _getList($query, $limitstart = 0, $limit = 0) { $ordering = $this->getState('list.ordering', 'ordering'); if (in_array($ordering, array('pages', 'name'))) { $this->_db->setQuery($query); $result = $this->_db->loadObjectList(); $this->translate($result); JArrayHelper::sortObjects($result, $ordering, $this->getState('list.direction') == 'desc' ? -1 : 1, true, true); $total = count($result); $this->cache[$this->getStoreId('getTotal')] = $total; if ($total < $limitstart) { $limitstart = 0; $this->setState('list.start', 0); } return array_slice($result, $limitstart, $limit ? $limit : null); } else { if ($ordering == 'ordering') { $query->order('a.position ASC'); $ordering = 'a.ordering'; } if ($ordering == 'language_title') { $ordering = 'l.title'; } $query->order($this->_db->quoteName($ordering) . ' ' . $this->getState('list.direction')); if ($ordering == 'position') { $query->order('a.ordering ASC'); } $result = parent::_getList($query, $limitstart, $limit); $this->translate($result); return $result; } } /** * Translate a list of objects * * @param array The array of objects * @return array The array of translated objects */ protected function translate(&$items) { $lang = JFactory::getLanguage(); $client = $this->getState('filter.client_id') ? 'administrator' : 'site'; foreach ($items as $item) { $extension = $item->module; $source = constant('JPATH_' . strtoupper($client)) . "/modules/$extension"; $lang->load("$extension.sys", constant('JPATH_' . strtoupper($client)), null, false, true) || $lang->load("$extension.sys", $source, null, false, true); $item->name = JText::_($item->name); if (is_null($item->pages)) { $item->pages = JText::_('JNONE'); } elseif ($item->pages < 0) { $item->pages = JText::_('COM_MODULES_ASSIGNED_VARIES_EXCEPT'); } elseif ($item->pages > 0) { $item->pages = JText::_('COM_MODULES_ASSIGNED_VARIES_ONLY'); } else { $item->pages = JText::_('JALL'); } } } /** * Build an SQL query to load the list data. * * @return JDatabaseQuery */ protected function getListQuery() { // Create a new query object. $db = $this->getDbo(); $query = $db->getQuery(true); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.id, a.title, a.note, a.position, a.module, a.language,' . 'a.checked_out, a.checked_out_time, a.published+2*(e.enabled-1) as published, a.access, a.ordering, a.publish_up, a.publish_down' ) ); $query->from($db->quoteName('#__modules') . ' AS a'); // Join over the language $query->select('l.title AS language_title') ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); // Join over the users for the checked out user. $query->select('uc.name AS editor') ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); // Join over the asset groups. $query->select('ag.title AS access_level') ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); // Join over the module menus $query->select('MIN(mm.menuid) AS pages') ->join('LEFT', '#__modules_menu AS mm ON mm.moduleid = a.id'); // Join over the extensions $query->select('e.name AS name') ->join('LEFT', '#__extensions AS e ON e.element = a.module') ->group( 'a.id, a.title, a.note, a.position, a.module, a.language,a.checked_out,' . 'a.checked_out_time, a.published, a.access, a.ordering,l.title, uc.name, ag.title, e.name,' . 'l.lang_code, uc.id, ag.id, mm.moduleid, e.element, a.publish_up, a.publish_down,e.enabled' ); // Filter by access level. if ($access = $this->getState('filter.access')) { $query->where('a.access = ' . (int) $access); } // Filter by published state $state = $this->getState('filter.state'); if (is_numeric($state)) { $query->where('a.published = ' . (int) $state); } elseif ($state === '') { $query->where('(a.published IN (0, 1))'); } // Filter by position $position = $this->getState('filter.position'); if ($position && $position != 'none') { $query->where('a.position = ' . $db->quote($position)); } elseif ($position == 'none') { $query->where('a.position = ' . $db->quote('')); } // Filter by module $module = $this->getState('filter.module'); if ($module) { $query->where('a.module = ' . $db->quote($module)); } // Filter by client. $clientId = $this->getState('filter.client_id'); if (is_numeric($clientId)) { $query->where('a.client_id = ' . (int) $clientId . ' AND e.client_id =' . (int) $clientId); } // Filter by search in title $search = $this->getState('filter.search'); if (!empty($search)) { if (stripos($search, 'id:') === 0) { $query->where('a.id = ' . (int) substr($search, 3)); } else { $search = $db->quote('%' . $db->escape($search, true) . '%'); $query->where('(' . 'a.title LIKE ' . $search . ' OR a.note LIKE ' . $search . ')'); } } // Filter on the language. if ($language = $this->getState('filter.language')) { $query->where('a.language = ' . $db->quote($language)); } //echo nl2br(str_replace('#__','jos_',$query)); return $query; } } components/com_modules/models/positions.php000066600000013460150771655450015311 0ustar00getUserStateFromRequest($this->context.'.filter.search', 'filter_search'); $this->setState('filter.search', $search); $state = $this->getUserStateFromRequest($this->context.'.filter.state', 'filter_state', '', 'string'); $this->setState('filter.state', $state); $clientId = $app->input->getInt('client_id', 0); $this->setState('filter.client_id', $clientId); $template = $this->getUserStateFromRequest($this->context.'.filter.template', 'filter_template', '', 'string'); $this->setState('filter.template', $template); $type = $this->getUserStateFromRequest($this->context.'.filter.type', 'filter_type', '', 'string'); $this->setState('filter.type', $type); // Load the parameters. $params = JComponentHelper::getParams('com_modules'); $this->setState('params', $params); // List state information. parent::populateState('value', 'asc'); } /** * Method to get an array of data items. * * @return mixed An array of data items on success, false on failure. * @since 1.6 */ public function getItems() { if (!isset($this->items)) { $lang = JFactory::getLanguage(); $search = $this->getState('filter.search'); $state = $this->getState('filter.state'); $clientId = $this->getState('filter.client_id'); $filter_template = $this->getState('filter.template'); $type = $this->getState('filter.type'); $ordering = $this->getState('list.ordering'); $direction = $this->getState('list.direction'); $limitstart = $this->getState('list.start'); $limit = $this->getState('list.limit'); $client = JApplicationHelper::getClientInfo($clientId); if ($type != 'template') { // Get the database object and a new query object. $query = $this->_db->getQuery(true) ->select('DISTINCT(position) as value') ->from('#__modules') ->where($this->_db->quoteName('client_id').' = '.(int) $clientId); if ($search) { $query->where('position LIKE '.$this->_db->quote('%'.$this->_db->escape($search, true).'%')); } $this->_db->setQuery($query); try { $positions = $this->_db->loadObjectList('value'); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } foreach ($positions as $value => $position) { $positions[$value] = array(); } } else { $positions = array(); } // Load the positions from the installed templates. foreach (ModulesHelper::getTemplates($clientId) as $template) { $path = JPath::clean($client->path.'/templates/'.$template->element.'/templateDetails.xml'); if (file_exists($path)) { $xml = simplexml_load_file($path); if (isset($xml->positions[0])) { $lang->load('tpl_'.$template->element.'.sys', $client->path, null, false, true) || $lang->load('tpl_'.$template->element.'.sys', $client->path.'/templates/'.$template->element, null, false, true); foreach ($xml->positions[0] as $position) { $value = (string) $position['value']; $label = (string) $position; if (!$value) { $value = $label; $label = preg_replace('/[^a-zA-Z0-9_\-]/', '_', 'TPL_'.$template->element.'_POSITION_'.$value); $altlabel = preg_replace('/[^a-zA-Z0-9_\-]/', '_', 'COM_MODULES_POSITION_'.$value); if (!$lang->hasKey($label) && $lang->hasKey($altlabel)) { $label = $altlabel; } } if ($type == 'user' || ($state != '' && $state != $template->enabled)) { unset($positions[$value]); } elseif (preg_match(chr(1) . $search . chr(1) . 'i', $value) && ($filter_template == '' || $filter_template == $template->element)) { if (!isset($positions[$value])) { $positions[$value] = array(); } $positions[$value][$template->name] = $label; } } } } } $this->total = count($positions); if ($limitstart >= $this->total) { $limitstart = $limitstart < $limit ? 0 : $limitstart - $limit; $this->setState('list.start', $limitstart); } if ($ordering == 'value') { if ($direction == 'asc') { ksort($positions); } else { krsort($positions); } } else { if ($direction == 'asc') { asort($positions); } else { arsort($positions); } } $this->items = array_slice($positions, $limitstart, $limit ? $limit : null); } return $this->items; } /** * Method to get the total number of items. * * @return int The total number of items. * @since 1.6 */ public function getTotal() { if (!isset($this->total)) { $this->getItems(); } return $this->total; } } components/com_modules/models/module.php000066600000063334150771655450014554 0ustar00input->getInt('id'); if (!$pk) { if ($extensionId = (int) $app->getUserState('com_modules.add.module.extension_id')) { $this->setState('extension.id', $extensionId); } } $this->setState('module.id', $pk); // Load the parameters. $params = JComponentHelper::getParams('com_modules'); $this->setState('params', $params); } /** * Method to perform batch operations on a set of modules. * * @param array $commands An array of commands to perform. * @param array $pks An array of item ids. * @param array $contexts An array of item contexts. * * @return boolean Returns true on success, false on failure. * * @since 1.7 */ public function batch($commands, $pks, $contexts) { // Sanitize user ids. $pks = array_unique($pks); JArrayHelper::toInteger($pks); // Remove any values of zero. if (array_search(0, $pks, true)) { unset($pks[array_search(0, $pks, true)]); } if (empty($pks)) { $this->setError(JText::_('JGLOBAL_NO_ITEM_SELECTED')); return false; } $done = false; if (!empty($commands['position_id'])) { $cmd = JArrayHelper::getValue($commands, 'move_copy', 'c'); if (!empty($commands['position_id'])) { if ($cmd == 'c') { $result = $this->batchCopy($commands['position_id'], $pks, $contexts); if (is_array($result)) { $pks = $result; } else { return false; } } elseif ($cmd == 'm' && !$this->batchMove($commands['position_id'], $pks, $contexts)) { return false; } $done = true; } } if (!empty($commands['assetgroup_id'])) { if (!$this->batchAccess($commands['assetgroup_id'], $pks, $contexts)) { return false; } $done = true; } if (!empty($commands['language_id'])) { if (!$this->batchLanguage($commands['language_id'], $pks, $contexts)) { return false; } $done = true; } if (!$done) { $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); return false; } // Clear the cache $this->cleanCache(); return true; } /** * Batch copy modules to a new position or current. * * @param integer $value The new value matching a module position. * @param array $pks An array of row IDs. * @param array $contexts An array of item contexts. * * @return boolean True if successful, false otherwise and internal error is set. * * @since 2.5 */ protected function batchCopy($value, $pks, $contexts) { // Set the variables $user = JFactory::getUser(); $table = $this->getTable(); $newIds = array(); $i = 0; foreach ($pks as $pk) { if ($user->authorise('core.create', 'com_modules')) { $table->reset(); $table->load($pk); // Set the new position if ($value == 'noposition') { $position = ''; } elseif ($value == 'nochange') { $position = $table->position; } else { $position = $value; } $table->position = $position; // Alter the title if necessary $data = $this->generateNewTitle(0, $table->title, $table->position); $table->title = $data['0']; // Reset the ID because we are making a copy $table->id = 0; // Unpublish the new module $table->published = 0; if (!$table->store()) { $this->setError($table->getError()); return false; } // Get the new item ID $newId = $table->get('id'); // Add the new ID to the array $newIds[$i] = $newId; $i++; // Now we need to handle the module assignments $db = $this->getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('menuid')) ->from($db->quoteName('#__modules_menu')) ->where($db->quoteName('moduleid') . ' = ' . $pk); $db->setQuery($query); $menus = $db->loadColumn(); // Insert the new records into the table foreach ($menus as $menu) { $query->clear() ->insert($db->quoteName('#__modules_menu')) ->columns(array($db->quoteName('moduleid'), $db->quoteName('menuid'))) ->values($newId . ', ' . $menu); $db->setQuery($query); $db->execute(); } } else { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); return false; } } // Clean the cache $this->cleanCache(); return $newIds; } /** * Batch move modules to a new position or current. * * @param integer $value The new value matching a module position. * @param array $pks An array of row IDs. * @param array $contexts An array of item contexts. * * @return boolean True if successful, false otherwise and internal error is set. * * @since 2.5 */ protected function batchMove($value, $pks, $contexts) { // Set the variables $user = JFactory::getUser(); $table = $this->getTable(); foreach ($pks as $pk) { if ($user->authorise('core.edit', 'com_modules')) { $table->reset(); $table->load($pk); // Set the new position if ($value == 'noposition') { $position = ''; } elseif ($value == 'nochange') { $position = $table->position; } else { $position = $value; } $table->position = $position; // Alter the title if necessary $data = $this->generateNewTitle(0, $table->title, $table->position); $table->title = $data['0']; // Unpublish the moved module $table->published = 0; if (!$table->store()) { $this->setError($table->getError()); return false; } } else { $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); return false; } } // Clean the cache $this->cleanCache(); return true; } /** * Method to test whether a record can have its state edited. * * @param object $record A record object. * * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. * @since 3.2 */ protected function canEditState($record) { $user = JFactory::getUser(); // Check for existing module. if (!empty($record->id)) { return $user->authorise('core.edit.state', 'com_modules.module.' . (int) $record->id); } // Default to component settings if module not known. else { return parent::canEditState('com_modules'); } } /** * Method to delete rows. * * @param array &$pks An array of item ids. * * @return boolean Returns true on success, false on failure. * * @since 1.6 * @throws Exception */ public function delete(&$pks) { $pks = (array) $pks; $user = JFactory::getUser(); $table = $this->getTable(); // Iterate the items to delete each one. foreach ($pks as $pk) { if ($table->load($pk)) { // Access checks. if (!$user->authorise('core.delete', 'com_modules.module.'.(int) $pk) || $table->published != -2) { JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); return; } if (!$table->delete($pk)) { throw new Exception($table->getError()); } else { // Delete the menu assignments $db = $this->getDbo(); $query = $db->getQuery(true) ->delete('#__modules_menu') ->where('moduleid=' . (int) $pk); $db->setQuery($query); $db->execute(); } // Clear module cache parent::cleanCache($table->module, $table->client_id); } else { throw new Exception($table->getError()); } } // Clear modules cache $this->cleanCache(); return true; } /** * Method to duplicate modules. * * @param array &$pks An array of primary key IDs. * * @return boolean True if successful. * * @since 1.6 * @throws Exception */ public function duplicate(&$pks) { $user = JFactory::getUser(); $db = $this->getDbo(); // Access checks. if (!$user->authorise('core.create', 'com_modules')) { throw new Exception(JText::_('JERROR_CORE_CREATE_NOT_PERMITTED')); } $table = $this->getTable(); foreach ($pks as $pk) { if ($table->load($pk, true)) { // Reset the id to create a new record. $table->id = 0; // Alter the title. $m = null; if (preg_match('#\((\d+)\)$#', $table->title, $m)) { $table->title = preg_replace('#\(\d+\)$#', '(' . ($m[1] + 1) . ')', $table->title); } else { $table->title .= ' (2)'; } // Unpublish duplicate module $table->published = 0; if (!$table->check() || !$table->store()) { throw new Exception($table->getError()); } $query = $db->getQuery(true) ->select($db->quoteName('menuid')) ->from($db->quoteName('#__modules_menu')) ->where($db->quoteName('moduleid') . ' = ' . (int) $pk); $this->_db->setQuery($query); $rows = $this->_db->loadColumn(); foreach ($rows as $menuid) { $tuples[] = (int) $table->id . ',' . (int) $menuid; } } else { throw new Exception($table->getError()); } } if (!empty($tuples)) { // Module-Menu Mapping: Do it in one query $query = $db->getQuery(true) ->insert($db->quoteName('#__modules_menu')) ->columns($db->quoteName(array('moduleid', 'menuid'))) ->values($tuples); $this->_db->setQuery($query); try { $this->_db->execute(); } catch (RuntimeException $e) { return JError::raiseWarning(500, $e->getMessage()); } } // Clear modules cache $this->cleanCache(); return true; } /** * Method to change the title. * * @param integer $category_id The id of the category. Not used here. * @param string $title The title. * @param string $position The position. * * @return array Contains the modified title. * * @since 2.5 */ protected function generateNewTitle($category_id, $title, $position) { // Alter the title & alias $table = $this->getTable(); while ($table->load(array('position' => $position, 'title' => $title))) { $title = JString::increment($title); } return array($title); } /** * Method to get the client object * * @return void * * @since 1.6 */ public function &getClient() { return $this->_client; } /** * Method to get the record form. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return JForm A JForm object on success, false on failure * * @since 1.6 */ public function getForm($data = array(), $loadData = true) { // The folder and element vars are passed when saving the form. if (empty($data)) { $item = $this->getItem(); $clientId = $item->client_id; $module = $item->module; $id = $item->id; } else { $clientId = JArrayHelper::getValue($data, 'client_id'); $module = JArrayHelper::getValue($data, 'module'); $id = JArrayHelper::getValue($data, 'id'); } // These variables are used to add data from the plugin XML files. $this->setState('item.client_id', $clientId); $this->setState('item.module', $module); // Get the form. $form = $this->loadForm('com_modules.module', 'module', array('control' => 'jform', 'load_data' => $loadData)); if (empty($form)) { return false; } $form->setFieldAttribute('position', 'client', $this->getState('item.client_id') == 0 ? 'site' : 'administrator'); $user = JFactory::getUser(); // Check for existing module // Modify the form based on Edit State access controls. if ($id != 0 && (!$user->authorise('core.edit.state', 'com_modules.module.'.(int) $id)) || ($id == 0 && !$user->authorise('core.edit.state', 'com_modules')) ) { // Disable fields for display. $form->setFieldAttribute('ordering', 'disabled', 'true'); $form->setFieldAttribute('published', 'disabled', 'true'); $form->setFieldAttribute('publish_up', 'disabled', 'true'); $form->setFieldAttribute('publish_down', 'disabled', 'true'); // Disable fields while saving. // The controller has already verified this is a record you can edit. $form->setFieldAttribute('ordering', 'filter', 'unset'); $form->setFieldAttribute('published', 'filter', 'unset'); $form->setFieldAttribute('publish_up', 'filter', 'unset'); $form->setFieldAttribute('publish_down', 'filter', 'unset'); } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * * @since 1.6 */ protected function loadFormData() { $app = JFactory::getApplication(); // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState('com_modules.edit.module.data', array()); if (empty($data)) { $data = $this->getItem(); // This allows us to inject parameter settings into a new module. $params = $app->getUserState('com_modules.add.module.params'); if (is_array($params)) { $data->set('params', $params); } } $this->preprocessData('com_modules.module', $data); return $data; } /** * Method to get a single record. * * @param integer $pk The id of the primary key. * * @return mixed Object on success, false on failure. * * @since 1.6 */ public function getItem($pk = null) { $pk = (!empty($pk)) ? (int) $pk : (int) $this->getState('module.id'); $db = $this->getDbo(); if (!isset($this->_cache[$pk])) { $false = false; // Get a row instance. $table = $this->getTable(); // Attempt to load the row. $return = $table->load($pk); // Check for a table object error. if ($return === false && $error = $table->getError()) { $this->setError($error); return $false; } // Check if we are creating a new extension. if (empty($pk)) { if ($extensionId = (int) $this->getState('extension.id')) { $query = $db->getQuery(true) ->select('element, client_id') ->from('#__extensions') ->where('extension_id = ' . $extensionId) ->where('type = ' . $db->quote('module')); $db->setQuery($query); try { $extension = $db->loadObject(); } catch (RuntimeException $e) { $this->setError($e->getMessage); return false; } if (empty($extension)) { $this->setError('COM_MODULES_ERROR_CANNOT_FIND_MODULE'); return false; } // Extension found, prime some module values. $table->module = $extension->element; $table->client_id = $extension->client_id; } else { $app = JFactory::getApplication(); $app->redirect(JRoute::_('index.php?option=com_modules&view=modules', false)); return false; } } // Convert to the JObject before adding other data. $properties = $table->getProperties(1); $this->_cache[$pk] = JArrayHelper::toObject($properties, 'JObject'); // Convert the params field to an array. $registry = new JRegistry; $registry->loadString($table->params); $this->_cache[$pk]->params = $registry->toArray(); // Determine the page assignment mode. $query = $db->getQuery(true) ->select($db->quoteName('menuid')) ->from($db->quoteName('#__modules_menu')) ->where($db->quoteName('moduleid') . ' = ' . (int) $pk); $db->setQuery($query); $assigned = $db->loadColumn(); if (empty($pk)) { // If this is a new module, assign to all pages. $assignment = 0; } elseif (empty($assigned)) { // For an existing module it is assigned to none. $assignment = '-'; } else { if ($assigned[0] > 0) { $assignment = 1; } elseif ($assigned[0] < 0) { $assignment = -1; } else { $assignment = 0; } } $this->_cache[$pk]->assigned = $assigned; $this->_cache[$pk]->assignment = $assignment; // Get the module XML. $client = JApplicationHelper::getClientInfo($table->client_id); $path = JPath::clean($client->path . '/modules/' . $table->module . '/' . $table->module . '.xml'); if (file_exists($path)) { $this->_cache[$pk]->xml = simplexml_load_file($path); } else { $this->_cache[$pk]->xml = null; } } return $this->_cache[$pk]; } /** * Get the necessary data to load an item help screen. * * @return object An object with key, url, and local properties for loading the item help screen. * * @since 1.6 */ public function getHelp() { return (object) array('key' => $this->helpKey, 'url' => $this->helpURL); } /** * Returns a reference to the a Table object, always creating it. * * @param string $type The table type to instantiate * @param string $prefix A prefix for the table class name. Optional. * @param array $config Configuration array for model. Optional. * * @return JTable A database object * * @since 1.6 */ public function getTable($type = 'Module', $prefix = 'JTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } /** * Prepare and sanitise the table prior to saving. * * @param JTable $table The database object * * @return void * * @since 1.6 */ protected function prepareTable($table) { $table->title = htmlspecialchars_decode($table->title, ENT_QUOTES); $table->position = trim($table->position); } /** * Method to preprocess the form * * @param JForm $form A form object. * @param mixed $data The data expected for the form. * @param string $group The name of the plugin group to import (defaults to "content"). * * @return void * * @since 1.6 * @throws Exception if there is an error loading the form. */ protected function preprocessForm(JForm $form, $data, $group = 'content') { jimport('joomla.filesystem.path'); $lang = JFactory::getLanguage(); $clientId = $this->getState('item.client_id'); $module = $this->getState('item.module'); $client = JApplicationHelper::getClientInfo($clientId); $formFile = JPath::clean($client->path . '/modules/' . $module . '/' . $module . '.xml'); // Load the core and/or local language file(s). $lang->load($module, $client->path, null, false, true) || $lang->load($module, $client->path . '/modules/' . $module, null, false, true); if (file_exists($formFile)) { // Get the module form. if (!$form->loadFile($formFile, false, '//config')) { throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); } // Attempt to load the xml file. if (!$xml = simplexml_load_file($formFile)) { throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); } // Get the help data from the XML file if present. $help = $xml->xpath('/extension/help'); if (!empty($help)) { $helpKey = trim((string) $help[0]['key']); $helpURL = trim((string) $help[0]['url']); $this->helpKey = $helpKey ? $helpKey : $this->helpKey; $this->helpURL = $helpURL ? $helpURL : $this->helpURL; } } // Load the default advanced params JForm::addFormPath(JPATH_ADMINISTRATOR . '/components/com_modules/models/forms'); $form->loadFile('advanced', false); // Trigger the default form events. parent::preprocessForm($form, $data, $group); } /** * Loads ContentHelper for filters before validating data. * * @param object $form The form to validate against. * @param array $data The data to validate. * @param string $group The name of the group(defaults to null). * * @return mixed Array of filtered data if valid, false otherwise. * * @since 1.1 */ public function validate($form, $data, $group = null) { require_once JPATH_ADMINISTRATOR . '/components/com_content/helpers/content.php'; return parent::validate($form, $data, $group); } /** * Method to save the form data. * * @param array $data The form data. * * @return boolean True on success. * * @since 1.6 */ public function save($data) { $dispatcher = JEventDispatcher::getInstance(); $input = JFactory::getApplication()->input; $table = $this->getTable(); $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('module.id'); $isNew = true; // Include the content modules for the onSave events. JPluginHelper::importPlugin('extension'); // Load the row if saving an existing record. if ($pk > 0) { $table->load($pk); $isNew = false; } // Alter the title and published state for Save as Copy if ($input->get('task') == 'save2copy') { $orig_data = $input->post->get('jform', array(), 'array'); $orig_table = clone($this->getTable()); $orig_table->load((int) $orig_data['id']); if ($data['title'] == $orig_table->title) { $data['title'] .= ' ' . JText::_('JGLOBAL_COPY'); $data['published'] = 0; } } // Bind the data. if (!$table->bind($data)) { $this->setError($table->getError()); return false; } // Prepare the row for saving $this->prepareTable($table); // Check the data. if (!$table->check()) { $this->setError($table->getError()); return false; } // Trigger the onExtensionBeforeSave event. $result = $dispatcher->trigger('onExtensionBeforeSave', array('com_modules.module', &$table, $isNew)); if (in_array(false, $result, true)) { $this->setError($table->getError()); return false; } // Store the data. if (!$table->store()) { $this->setError($table->getError()); return false; } // Process the menu link mappings. $assignment = isset($data['assignment']) ? $data['assignment'] : 0; // Delete old module to menu item associations $db = $this->getDbo(); $query = $db->getQuery(true) ->delete('#__modules_menu') ->where('moduleid = ' . (int) $table->id); $db->setQuery($query); try { $db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } // If the assignment is numeric, then something is selected (otherwise it's none). if (is_numeric($assignment)) { // Variable is numeric, but could be a string. $assignment = (int) $assignment; // Logic check: if no module excluded then convert to display on all. if ($assignment == -1 && empty($data['assigned'])) { $assignment = 0; } // Check needed to stop a module being assigned to `All` // and other menu items resulting in a module being displayed twice. if ($assignment === 0) { // Assign new module to `all` menu item associations. $query->clear() ->insert('#__modules_menu') ->columns(array($db->quoteName('moduleid'), $db->quoteName('menuid'))) ->values((int) $table->id . ', 0'); $db->setQuery($query); try { $db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } } elseif (!empty($data['assigned'])) { // Get the sign of the number. $sign = $assignment < 0 ? -1 : 1; // Preprocess the assigned array. $tuples = array(); foreach ($data['assigned'] as &$pk) { $tuples[] = '(' . (int) $table->id . ',' . (int) $pk * $sign . ')'; } $this->_db->setQuery( 'INSERT INTO #__modules_menu (moduleid, menuid) VALUES ' . implode(',', $tuples) ); try { $db->execute(); } catch (RuntimeException $e) { $this->setError($e->getMessage()); return false; } } } // Trigger the onExtensionAfterSave event. $dispatcher->trigger('onExtensionAfterSave', array('com_modules.module', &$table, $isNew)); // Compute the extension id of this module in case the controller wants it. $query = $db->getQuery(true) ->select('extension_id') ->from('#__extensions AS e') ->join('LEFT', '#__modules AS m ON e.element = m.module') ->where('m.id = ' . (int) $table->id); $db->setQuery($query); try { $extensionId = $db->loadResult(); } catch (RuntimeException $e) { JError::raiseWarning(500, $e->getMessage()); return false; } $this->setState('module.extension_id', $extensionId); $this->setState('module.id', $table->id); // Clear modules cache $this->cleanCache(); // Clean module cache parent::cleanCache($table->module, $table->client_id); return true; } /** * A protected method to get a set of ordering conditions. * * @param object $table A record object. * * @return array An array of conditions to add to add to ordering queries. * * @since 1.6 */ protected function getReorderConditions($table) { $condition = array(); $condition[] = 'client_id = ' . (int) $table->client_id; $condition[] = 'position = ' . $this->_db->quote($table->position); return $condition; } /** * Custom clean cache method for different clients * * @param string $group The name of the plugin group to import (defaults to null). * @param integer $client_id The client ID. [optional] * * @return void * * @since 1.6 */ protected function cleanCache($group = null, $client_id = 0) { parent::cleanCache('com_modules', $this->getClient()); } } components/com_jce/licence.txt000066600000043254150771655450012526 0ustar00 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. components/com_jce/elements/blockformats.php000066600000005635150771655450015377 0ustar00 'Paragraph', 'div' => 'Div', 'h1' => 'Heading1', 'h2' => 'Heading2', 'h3' => 'Heading3', 'h4' => 'Heading4', 'h5' => 'Heading5', 'h6' => 'Heading6', 'blockquote' => 'Blockquote', 'address' => 'Address', 'code' => 'Code', 'pre' => 'Preformatted', 'samp' => 'Sample', 'span' => 'Span', 'section' => 'Section', 'article' => 'Article', 'aside' => 'Aside', 'figure' => 'Figure', 'dt' => 'Definition Term', 'dd' => 'Definition List'); /** * Element type * * @access protected * @var string */ var $_name = 'Blockformats'; /** * array_insert function from http://www.php.net/manual/en/function.array-splice.php#56794 * @param array $array * @param integer $position * @param array $insert_array */ protected static function array_insert(&$array, $position, $insert_array) { $first_array = array_splice($array, 0, $position); $array = array_merge($first_array, $insert_array, $array); } public function fetchElement($name, $value, &$node, $control_name) { if (empty($value)) { $data = array_keys(self::$formats); $value = array(); } else { $value = is_array($value) ? $value : explode(",", $value); $data = array_unique(array_merge($value, array_keys(self::$formats))); } $output = array(); $output[] = '
    '; $output[] = '
      '; // create default font structure foreach ($data as $format) { if (array_key_exists($format, self::$formats) === false) { continue; } if (empty($value) || in_array($format, $value)) { $output[] = '
    • ' . self::$formats[$format] . '
    • '; } else { $output[] = '
    • ' . self::$formats[$format] . '
    • '; } } $output[] = '
    '; $output[] = ''; $output[] = '
    '; return implode("\n", $output); } } ?>components/com_jce/elements/radio.php000066600000004157150771655450014005 0ustar00children() as $option) { $val = (string) $option->attributes()->value; $text = (string) $option; $options[] = JHtml::_('select.option', $val, $text); } $attribs = array(); // pattern data attribute for editable select input box if ((string) $node->attributes()->parent) { $prefix = preg_replace(array('#^params#', '#([^\w]+)#'), '', $control_name); $items = array(); foreach(explode(';', (string) $node->attributes()->parent) as $item) { $items[] = $prefix . $item; } $attribs[] = 'data-parent="' . implode(';', $items) . '"'; } return JHtml::_('select.radiolist', $options, $control_name . '[' . $name . ']', implode(' ', $attribs), 'value', 'text', $value, $control_name . $name, true); } } components/com_jce/elements/fonts.php000066600000006356150771655450014043 0ustar00 'andale mono,times', 'Arial' => 'arial,helvetica,sans-serif', 'Arial Black' => 'arial black,avant garde', 'Book Antiqua' => 'book antiqua,palatino', 'Comic Sans MS' => 'comic sans ms,sans-serif', 'Courier New' => 'courier new,courier', 'Georgia' => 'georgia,palatino', 'Helvetica' => 'helvetica', 'Impact' => 'impact,chicago', 'Symbol' => 'symbol', 'Tahoma' => 'tahoma,arial,helvetica,sans-serif', 'Terminal' => 'terminal,monaco', 'Times New Roman' => 'times new roman,times', 'Trebuchet MS' => 'trebuchet ms,geneva', 'Verdana' => 'verdana,geneva', 'Webdings' => 'webdings', 'Wingdings' => 'wingdings,zapf dingbats'); /** * Element type * * @access protected * @var string */ var $_name = 'Fonts'; public function fetchElement($name, $value, &$node, $control_name) { $default = self::$fonts; if (empty($value)) { $data = self::$fonts; } else { $data = json_decode($value, true); } $output = array(); $output[] = '
    '; $output[] = '
      '; foreach($data as $title => $fonts) { if (in_array($title, array_keys(self::$fonts))) { $output[] = '
    • ' . $title . '
    • '; unset($default[$title]); } else { $output[] = '
    • ×
    • '; } } foreach($default as $title => $fonts) { $output[] = '
    • ' . $title . '
    • '; } $output[] = '
    • ×
    • '; $output[] = '
    '; $output[] = '' . WFText::_('WF_PARAM_FONTS_NEW') . '+'; $output[] = ''; $output[] = '
    '; return implode("\n", $output); } } ?>components/com_jce/elements/extension.php000066600000002747150771655450014726 0ustar00attributes()->class ? 'class="' . (string) $node->attributes()->class . ' text_area"' : 'class="text_area"' ); $control = $control_name . '[' . $name . ']'; return ''; } } ?>components/com_jce/elements/browser.php000066600000006377150771655450014400 0ustar00attributes() as $k => $v) { if ($v != '') { $attributes[$k] = (string) $v; } } /* * Required to avoid a cycle of encoding & * html_entity_decode was used in place of htmlspecialchars_decode because * htmlspecialchars_decode is not compatible with PHP 4 */ $value = htmlspecialchars(html_entity_decode($value, ENT_QUOTES), ENT_QUOTES); $attributes['class'] = ((string) $node->attributes()->class ? (string) $node->attributes()->class . ' text_area' : 'text_area' ); $control = $control_name . '[' . $name . ']'; $html = ''; $attributes['value'] = $value; $attributes['type'] = 'text'; $attributes['name'] = $control; $attributes['id'] = preg_replace('#[^a-z0-9_-]#i', '', $control_name . $name); // pattern data attribute for editable select input box if ((string) $node->attributes()->parent) { $prefix = preg_replace(array('#^params#', '#([^\w]+)#'), '', $control_name); $items = array(); foreach(explode(';', (string) $node->attributes()->parent) as $item) { $items[] = $prefix . $item; } $attributes['data-parent'] = implode(';', $items); } $filter = isset($attributes['data-filter']) ? $attributes['data-filter'] : ''; $html .= ' $v) { if (!in_array($k, array('default', 'label', 'description'))) { $html .= ' ' . $k . ' = "' . $v . '"'; } } $html .= ' />'; $component = WFExtensionHelper::getComponent(); // get params definitions $params = new WFParameter($component->params, '', 'preferences'); $width = (int) $params->get('browser_width', 780); $height = (int) $params->get('browser_height', 560); wfimport('admin.models.model'); $model = new WFModel(); $link = $model->getBrowserLink($attributes['id'], $filter); $html .= ''; return $html; } } ?>components/com_jce/elements/index.html000066600000000054150771655450014163 0ustar00components/com_jce/elements/list.php000066600000010133150771655450013651 0ustar00attributes()->class) { $attribs[] = 'class="' . $class . '"'; } else { $attribs[] = 'class="inputbox"'; } foreach ($node->children() as $option) { $val = (string) $option->attributes()->value; $text = (string) $option; $disabled = (string) $option->attributes()->disabled ? true : false; $text = is_numeric($text) ? $text : WFText::_($text); if (is_array($value)) { $key = array_search($val, $value); if ($key !== false) { $options[$key] = JHTML::_('select.option', $val, $text, 'value', 'text', $disabled); } } else { $options[] = JHTML::_('select.option', $val, $text, 'value', 'text', $disabled); } // create temp values $values[] = $val; } // re-sort options by key ksort($options); // method to append additional values to options array if (is_array($value)) { $diff = array_diff($values, $value); foreach ($node->children() as $option) { $val = (string) $option->attributes()->value; $text = (string) $option; $text = strpos($text, 'WF_') === false ? $text : WFText::_($text); if (in_array($val, $diff)) { $options[] = JHTML::_('select.option', $val, $text); } } } // revert to default values if ($value === '') { $value = (string) $node->attributes()->defaults; } // editable lists if (strpos($class, 'editable') !== false) { // pattern data attribute for editable select input box if ((string) $node->attributes()->pattern) { $attribs[] = 'data-pattern="' . (string) $node->attributes()->pattern . '"'; } $value = strpos($value, 'WF_') === false ? $value : WFText::_($value); // editable lists - add value to list if (!in_array($value, $values) && !(string) $node->attributes()->multiple) { $options[] = JHTML::_('select.option', $value, $value); } } // pattern data attribute for editable select input box if ((string) $node->attributes()->parent) { $prefix = preg_replace(array('#^params#', '#([^\w]+)#'), '', $control_name); $items = array(); foreach(explode(';', (string) $node->attributes()->parent) as $item) { $items[] = $prefix . $item; } $attribs[] = 'data-parent="' . implode(';', $items) . '"'; } // multiple lists if ((string) $node->attributes()->multiple) { $attribs[] = 'multiple="multiple"'; $ctrl .= '[]'; $value = !is_array($value) ? preg_split('#[|,]#', $value) : $value; } return JHTML::_('select.genericlist', $options, $ctrl, implode(' ', $attribs), 'value', 'text', $value, $control_name . $name); } } ?> components/com_jce/elements/filelist.php000066600000004743150771655450014523 0ustar00attributes()->directory; $filter = (string) $node->attributes()->filter; $exclude = (string) $node->attributes()->exclude; $stripExt = (string) $node->attributes()->stripext; $files = JFolder::files($path, $filter); $options = array(); if (!(string) $node->attributes()->hide_none) { $options[] = JHtml::_('select.option', '-1', JText::_('JOPTION_DO_NOT_USE')); } if (!(string) $node->attributes()->hide_default) { $options[] = JHtml::_('select.option', '', JText::_('JOPTION_USE_DEFAULT')); } if (is_array($files)) { foreach ($files as $file) { if ($exclude) { if (preg_match(chr(1) . $exclude . chr(1), $file)) { continue; } } if ($stripExt) { $file = JFile::stripExt($file); } $options[] = JHtml::_('select.option', $file, $file); } } return JHtml::_('select.genericlist', $options, $control_name . '[' . $name . ']', array('id' => 'param' . $name, 'list.attr' => 'class="inputbox"', 'list.select' => (string)$value)); } } components/com_jce/elements/password.php000066600000003062150771655450014543 0ustar00attributes()->size ? 'size="' . (string) $node->attributes()->size . '"' : ''); $class = ((string) $node->attributes()->class ? 'class="' . (string) $node->attributes()->class . '"' : 'class="text_area"'); return ''; } } components/com_jce/elements/text.php000066600000010444150771655450013667 0ustar00attributes() as $k => $v) { if ($k === 'parent') { continue; } if ($v != '') { $attributes[$k] = (string) $v; } } $class = (string) $node->attributes()->class; if (strpos($name, 'max_size') !== false || strpos($class, 'upload_size') !== false) { $uploadsize = intval($this->getUploadValue()); $attributes['max'] = $uploadsize; } /* * Required to avoid a cycle of encoding & * html_entity_decode was used in place of htmlspecialchars_decode because * htmlspecialchars_decode is not compatible with PHP 4 */ $value = htmlspecialchars(html_entity_decode($value, ENT_QUOTES), ENT_QUOTES); $attributes['class'] = ($class ? $class . ' text_area' : 'text_area' ); $control = $control_name . '[' . $name . ']'; $html = ''; $attributes['value'] = $value; $attributes['type'] = 'text'; $attributes['name'] = $control; $attributes['id'] = preg_replace('#[^a-z0-9_-]#i', '', $control_name . $name); // pattern data attribute for editable select input box if ((string) $node->attributes()->parent) { $prefix = preg_replace(array('#^params#', '#([^\w]+)#'), '', $control_name); $items = array(); foreach(explode(';', (string) $node->attributes()->parent) as $item) { $items[] = $prefix . $item; } $attributes['data-parent'] = implode(';', $items); } $html .= ' $v) { if (!in_array($k, array('default', 'label', 'description'))) { $html .= ' ' . $k . ' = "' . $v . '"'; } } $html .= ' />'; if (strpos($name, 'max_size') !== false) { $html .= $this->uploadSize(); } return $html; } function uploadSize() { return ' ' . WFText::_('WF_SERVER_UPLOAD_SIZE') . ' : ' . $this->getUploadValue(); } function getUploadValue() { $upload = trim(ini_get('upload_max_filesize')); $post = trim(ini_get('post_max_size')); $upload = $this->convertValue($upload); $post = $this->convertValue($post); if (intval($upload) <= intval($post)) { return $upload; } return $post; } function convertValue($value) { $unit = 'KB'; // GB if ($value > 1073741824) $unit = 'GB'; // MB if ($value > 1048576) $unit = 'MB'; // Convert to bytes switch (strtolower($value{strlen($value) - 1})) { case 'g': $value *= 1073741824; break; case 'm': $value *= 1048576; break; case 'k': $value *= 1024; break; } // Convert to unit value switch (strtolower($unit{0})) { case 'g': $value /= 1073741824; break; case 'm': $value /= 1048576; break; case 'k': $value /= 1024; break; } return preg_replace('/[^0-9]/', '', $value) . ' ' . $unit; } } ?>components/com_jce/elements/spacer.php000066600000003346150771655450014163 0ustar00 '' ); foreach ($attributes as $k => $v) { $av = (string) $node->attributes()->$k; if ($av || $v) { $v = !$av ? $v : $av; $attribs .= ' ' . $k . '="' . $v . '"'; } } // pattern data attribute for editable select input box if ((string) $node->attributes()->parent) { $attribs .= 'data-parent="' . preg_replace(array('#^params#', '#([^\w]+)#'), '', $control_name) . (string) $node->attributes()->parent . '"'; } $rows = (string) $node->attributes()->rows; $cols = (string) $node->attributes()->cols; $class = ((string) $node->attributes()->class ? 'class="' . (string) $node->attributes()->class . '"' : 'class="text_area"' ); // convert
    tags so they are not visible when editing $value = str_replace('
    ', "\n", $value); return ''; } } ?>components/com_jce/elements/folderlist.php000066600000004365150771655450015057 0ustar00attributes()->directory; $filter = (string) $node->attributes()->filter; $exclude = (string) $node->attributes()->exclude; $folders = JFolder::folders($path, $filter); $options = array(); foreach ($folders as $folder) { if ($exclude) { if (preg_match(chr(1) . $exclude . chr(1), $folder)) { continue; } } $options[] = JHtml::_('select.option', $folder, $folder); } if (!(string) $node->attributes()->hide_none) { array_unshift($options, JHtml::_('select.option', '-1', JText::_('JOPTION_DO_NOT_USE'))); } if (!(string) $node->attributes()->hide_default) { array_unshift($options, JHtml::_('select.option', '', JText::_('JOPTION_USE_DEFAULT'))); } return JHtml::_('select.genericlist', $options, $control_name . '[' . $name . ']', array('id' => 'param' . $name, 'list.attr' => 'class="inputbox"', 'list.select' => (string) $value)); } } components/com_jce/elements/styleformat.php000066600000015427150771655450015262 0ustar00 '', 'element' => '', 'selector' => '', 'classes' => '', 'styles' => ''); // pass to items $items = json_decode($value, true); /* Convert legacy styles */ $theme_advanced_styles = $wf->getParam('editor.theme_advanced_styles', ''); if (!empty($theme_advanced_styles)) { foreach(explode(',', $theme_advanced_styles) as $styles) { $style = json_decode("{" . preg_replace('#([^=]+)=([^=]+)#', '"title":"$1","classes":"$2"', $styles) . "}", true); if ($style) { $items[] = $style; } } } // create default array if no items if (empty($items)) { $items = array($default); $value = array(); } // store element options $this->elements = $this->getElementOptions(); $html = '
    attributes()->parent) { $prefix = preg_replace(array('#^params#', '#([^\w]+)#'), '', $control_name); $parents = array(); foreach(explode(';', (string) $node->attributes()->parent) as $item) { $parents[] = $prefix . $item; } $html .= ' data-parent="' . implode(';', $parents) . '"'; } $html .= '>'; $output[] = $html; foreach ($items as $item) { $elements = array('
    '); foreach ($default as $k => $v) { if (array_key_exists($k, $item)) { $v = $item[$k]; } $elements[] = '
    ' . $this->getField($k, $v) . '
    '; } // handle $elements[] = ' '; // delete button $elements[] = '×'; // collapse $elements[] = ''; $elements[] = '
    '; $output[] = implode('', $elements); } $output[] = '' . WFText::_('WF_STYLEFORMAT_NEW') . '+'; // hidden field $output[] = ''; if (!empty($theme_advanced_styles)) { $output[] = ''; } $output[] = '
    '; return implode("\n", $output); } protected function getElementOptions() { // create elements list $options = array( JHTML::_('select.option', '', WFText::_('WF_OPTION_SELECTED_ELEMENT')) ); $options[] = JHTML::_('select.option', '', WFText::_('WF_OPTION_SECTION_ELEMENTS')); foreach ($this->sections as $item) { $options[] = JHTML::_('select.option', $item, $item); } $options[] = JHTML::_('select.option', ''); $options[] = JHTML::_('select.option', '', WFText::_('WF_OPTION_GROUPING_ELEMENTS')); foreach ($this->grouping as $item) { $options[] = JHTML::_('select.option', $item, $item); } $options[] = JHTML::_('select.option', ''); $options[] = JHTML::_('select.option', '', WFText::_('WF_OPTION_TEXT_LEVEL_ELEMENTS')); foreach ($this->textlevel as $item) { $options[] = JHTML::_('select.option', $item, $item); } $options[] = JHTML::_('select.option', ''); return $options; } protected function getField($key, $value) { $item = array(); if ($key !== "title") { $item[] = ''; } switch ($key) { case 'inline': case 'block': case 'element': $class = ""; // make element editable /*if ($key === "element") { $class = ' class="editable"'; }*/ $item[] = JHTML::_('select.genericlist', $this->elements, null, 'data-key="' . $key . '"' . $class, 'value', 'text', $value); break; case 'title': $item[] = ''; break; case 'styles': case 'attributes': case 'selector': case 'classes': $item[] = ''; break; } if ($key !== "title") { $item[] = '' . WFText::_('WF_STYLEFORMAT_' . strtoupper($key) . '_DESC') . ''; } return implode('', $item); } } ?>components/com_jce/classes/language.php000066600000027116150771655450014313 0ustar00setProperties($config); } /** * Parse an INI formatted string and convert it into an array. * * @param string $data INI formatted string to convert. * @param bool $process_sections A boolean setting to process sections. * @param array $sections An array of sections to include. * @param mixed $filter A regular expression to filter sections by. * * @return array Data array. * * @since 2.4 * * Based on JRegistryFormatINI::stringToObject * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ protected static function ini_to_array($data, $process_sections = false, $sections = array(), $filter = '') { // Check the memory cache for already processed strings. $hash = md5($data . ':' . (int) $process_sections . ':' . serialize($sections) . ':' . $filter); if (isset(self::$cache[$hash])) { return self::$cache[$hash]; } // If no lines present just return the array. if (empty($data)) { return array(); } $array = array(); $section = false; $lines = explode("\n", $data); // Process the lines. foreach ($lines as $line) { // Trim any unnecessary whitespace. $line = trim($line); // Ignore empty lines and comments. if (empty($line) || ($line{0} == ';')) { continue; } if ($process_sections) { $length = strlen($line); // If we are processing sections and the line is a section add the object and continue. if (($line[0] == '[') && ($line[$length - 1] == ']')) { $section = substr($line, 1, $length - 2); // filter section by regular expression if ($filter) { if (preg_match('#' . $filter . '#', $section)) { continue; } } // allow all sections if (empty($sections)) { $array[$section] = array(); } else { if (in_array($section, $sections)) { $array[$section] = array(); } } continue; } } elseif ($line{0} == '[') { continue; } // Check that an equal sign exists and is not the first character of the line. if (!strpos($line, '=')) { // Maybe throw exception? continue; } // Get the key and value for the line. list ($key, $value) = explode('=', $line, 2); // Validate the key. if (preg_match('/[^A-Z0-9_]/i', $key)) { // Maybe throw exception? continue; } // If the value is quoted then we assume it is a string. $length = strlen($value); if ($length && ($value[0] == '"') && ($value[$length - 1] == '"')) { // Strip the quotes and Convert the new line characters. $value = stripcslashes(substr($value, 1, ($length - 2))); $value = str_replace(array("\n", "\r"), array('\n', '\r'), $value); } else { // If the value is not quoted, we assume it is not a string. // If the value is 'false' assume boolean false. if ($value == 'false') { $value = false; } // If the value is 'true' assume boolean true. elseif ($value == 'true') { $value = true; } // If the value is numeric than it is either a float or int. elseif (is_numeric($value)) { // If there is a period then we assume a float. if (strpos($value, '.') !== false) { $value = (float) $value; } else { $value = (int) $value; } } } // If a section is set add the key/value to the section, otherwise top level. if ($section) { $array[$section][$key] = $value; } else { $array[$key] = $value; } } // Cache the string self::$cache[$hash] = $array; return $array; } protected static function filterSections($ini, $sections = array(), $filter = '') { if ($ini && is_array($ini)) { if (!empty($sections)) { $ini = array_intersect_key($ini, array_flip($sections)); } // filter keys by regular expression if ($filter) { foreach (array_keys($ini) as $key) { if (preg_match('#' . $filter . '#', $key)) { unset($ini[$key]); } } } } return $ini; } protected static function processLanguageINI($files, $sections = array(), $filter = '') { $data = array(); foreach ((array) $files as $file) { $ini = false; $content = @file_get_contents($file); if ($content && is_string($content)) { if (function_exists('parse_ini_string')) { $ini = @parse_ini_string($content, true); // filter $ini = self::filterSections($ini, $sections, $filter); } else { $ini = self::ini_to_array($content, true, $sections, $filter); } } // merge with data array if ($ini && is_array($ini)) { $data = array_merge($data, $ini); } } $output = ''; if (!empty($data)) { $x = 0; foreach ($data as $key => $strings) { if (is_array($strings)) { $output .= '"' . strtolower($key) . '":{'; $i = 0; foreach ($strings as $k => $v) { if (is_numeric($v)) { $v = (float) $v; } else { $v = '"' . $v . '"'; } // key to lowercase $k = strtolower($k); // get position of the section name in the key if any $pos = strpos($k, $key . '_'); // remove the section name if ($pos === 0) { $k = substr($k, strlen($key) + 1); } // hex colours to uppercase and remove marker if (strpos($k, 'hex_') !== false) { $k = strtoupper(str_replace('hex_', '', $k)); } // create key/value pair as JSON string $output .= '"' . $k . '":' . $v . ','; $i++; } // remove last comma $output = rtrim(trim($output), ','); $output .= "},"; $x++; } } // remove last comma $output = rtrim(trim($output), ','); } return $output; } private function getFilter() { switch ($this->get('mode')) { case 'editor': return '(dlg|_dlg)$'; break; case 'plugin': return ''; break; } } public function load($files = array()) { // get the language file $language = JFactory::getLanguage(); // get language tag $tag = $language->getTag(); // base language path $path = JPATH_SITE . '/language/' . $tag; // if no file set if (empty($files)) { // Add English language $files[] = JPATH_SITE . '/language/en-GB/en-GB.com_jce.ini'; // non-english language if ($tag != 'en-GB') { if (is_dir($path)) { $file = $path . '/' . $tag . '.com_jce.ini'; if (is_file($file)) { $files[] = $file; } else { $tag = 'en-GB'; } } else { $tag = 'en-GB'; } } $plugins = $this->get('plugins'); if (!empty($plugins)) { foreach ($plugins as $plugin) { // add English file $ini = JPATH_SITE . '/language/en-GB/en-GB.com_jce_' . $plugin . '.ini'; if (is_file($ini)) { $files[] = $ini; } // non-english language if ($tag != 'en-GB') { $ini = JPATH_SITE . '/language/' . $tag . '/' . $tag . '.com_jce_' . $plugin . '.ini'; if (is_file($ini)) { $files[] = $ini; } } } } } // shorten the tag, eg: en-GB -> en $tag = substr($tag, 0, strpos($tag, '-')); $sections = $this->get('sections'); $filter = $this->getFilter(); $data = self::processLanguageINI($files, $sections, $filter); // clean data $data = rtrim(trim($data), ','); return 'tinyMCE.addI18n({"' . $tag . '":{' . $data . '}});'; } public function output($data) { if ($data) { ob_start(); header("Content-type: application/javascript; charset: UTF-8"); header("Vary: Accept-Encoding"); // expires after 2 days $expires = 60 * 60 * 24 * 2; header("Cache-Control: maxage=" . $expires); // Handle proxies header("Expires: " . gmdate("D, d M Y H:i:s", time() + $expires) . " GMT"); // get content hash $hash = md5($data); // set etag header header("ETag: \"{$hash}\""); echo $data; exit(ob_get_clean()); } exit(); } } ?>components/com_jce/classes/error.php000066600000001421150771655450013650 0ustar00getMessage(), "\n"; } } // suppress E_STRICT warnings set_error_handler(array('WFError', 'errorHandler'), E_ALL | E_STRICT); // suppress uncaught exceptions set_exception_handler(array('WFError', 'exceptionHandler')); ?>components/com_jce/classes/parameter.php000066600000043353150771655450014511 0ustar00control = $config['control']; } // Set base path. $this->addElementPath(dirname(dirname(__FILE__)) . '/elements'); /* if ($data = trim($data)) { $this->loadString($data); } */ if ($path) { $this->loadSetupFile($path); } //$this->_raw = $data; $this->data = new StdClass(); if ($data) { if (!is_object($data)) { $data = json_decode($data); } if ($keys) { if (!is_array($keys)) { $keys = explode('.', $keys); } $this->key = $keys; foreach ($keys as $key) { $data = isset($data->$key) ? $data->$key : $data; } } $this->bindData($this->data, $data); } } /** * Loads an XML setup file and parses it. * * @param string $path A path to the XML setup file. * * @return object * @since 2.2.5 */ public function loadSetupFile($path) { $result = false; if ($path) { $controls = explode(':', $this->control); if ($xml = WFXMLElement::load($path)) { $params = $xml; // move through tree foreach ($controls as $control) { $params = $params->$control; } foreach ($params as $param) { $this->setXML($param); $result = true; } } } else { $result = true; } return $result; } /** * Sets the XML object from custom XML files. * * @param JSimpleXMLElement &$xml An XML object. * * @return void * @since 2.2.5 */ public function setXML(&$xml) { if (is_object($xml)) { if ($group = (string) $xml->attributes()->group) { $this->xml[$group] = $xml; } else { $this->xml['_default'] = $xml; } if ($dir = (string) $xml->attributes()->addpath) { $this->addElementPath(JPATH_ROOT . $dir); } } } /** * Add a directory where JParameter should search for element types. * * You may either pass a string or an array of directories. * * JParameter will be searching for a element type in the same * order you added them. If the parameter type cannot be found in * the custom folders, it will look in * JParameter/types. * * @param mixed $path Directory (string) or directories (array) to search. * * @return void * @since 2.2.5 */ public function addElementPath($paths) { // Just force path to array. settype($paths, 'array'); // Loop through the path directories. foreach ($paths as $dir) { // No surrounding spaces allowed! $dir = trim($dir); // Add trailing separators as needed. if (substr($dir, -1) != DIRECTORY_SEPARATOR) { // Directory $dir .= DIRECTORY_SEPARATOR; } // Add to the top of the search dirs. array_unshift($this->elementPath, $dir); } } /** * Loads an element type. * * @param string $type The element type. * @param boolean $new False (default) to reuse parameter elements; true to load the parameter element type again. * * @return object * @since 2.2.5 */ public function loadElement($type, $new = false) { $signature = md5($type); if ((isset($this->elements[$signature]) && !($this->elements[$signature] instanceof __PHP_Incomplete_Class)) && $new === false) { return $this->elements[$signature]; } $elementClass = 'WFElement' . $type; if (!class_exists($elementClass)) { if (isset($this->elementPath)) { $dirs = $this->elementPath; } else { $dirs = array(); } $file = JFilterInput::getInstance()->clean(str_replace('_', '/', $type) . '.php', 'path'); jimport('joomla.filesystem.path'); if ($elementFile = JPath::find($dirs, $file)) { include_once $elementFile; } else { $false = false; return $false; } } if (!class_exists($elementClass)) { $false = false; return $false; } $this->elements[$signature] = new $elementClass($this); return $this->elements[$signature]; } /** * Bind data to the parameter. * * @param mixed $data An array or object. * @param string $group An optional group that the data should bind to. The default group is used if not supplied. * * @return boolean True if the data was successfully bound, false otherwise. */ public function bind($data) { if (is_array($data)) { return $this->bindData($this->data, $data); } else if (is_object($data)) { return $this->bindData($this->data, $data); } else { return $this->bindData($this->data, json_decode($data)); } } /** * Method to recursively bind data to a parent object. * * @param object $parent The parent object on which to attach the data values. * @param mixed $data An array or object of data to bind to the parent object. * * @return void * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved. */ protected function bindData(&$parent, $data) { // Ensure the input data is an array. if (is_object($data)) { $data = get_object_vars($data); } else { $data = (array) $data; } foreach ($data as $k => $v) { if (self::is_assoc($v) || is_object($v)) { $parent->$k = new stdClass(); $this->bindData($parent->$k, $v); } else { $parent->$k = $v; } } } /** * Return the number of parameters in a group. * * @param string $group An optional group. The default group is used if not supplied. * * @return mixed False if no params exist or integer number of parameters that exist. * @since 2.2.5 */ public function getNumParams($group = '_default') { if (!isset($this->xml[$group]) || !count($this->xml[$group]->children())) { return false; } else { return count($this->xml[$group]->children()); } } /** * Get the number of params in each group. * * @return array Array of all group names as key and parameters count as value. * @since 2.2.5 */ public function getGroups() { $results = array(); if (is_array($this->xml)) { foreach ($this->xml as $name => $group) { $results[] = $name;//$this->getNumParams($name); } } return $results; } public function getAll($name = '') { $results = array(); if ($name) { $groups = (array) $name; } else { $groups = $this->getGroups(); } foreach ($groups as $group) { if (!isset($this->xml[$group])) { return null; } $data = new StdClass(); foreach ($this->xml[$group]->children() as $param) { $key = (string) $param->attributes()->name; $value = $this->get($key, (string) $param->attributes()->default); $data->$key = $value; } $results[$group] = $data; } if ($name) { return $results[$name]; } return $results; } private function isEmpty($value) { return (is_string($value) && $value == "") || (is_array($value) && empty($value)); } /** * Get a parameter value. * * @param string Registry path (e.g. editor.width) * @param string Optional default value, returned if the internal value is null. * @return mixed Value of entry or null * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved. */ public function get($path, $default = '', $allowempty = true) { // set default value as result $result = $default; // Explode the registry path into an array $nodes = is_array($path) ? $path : explode('.', $path); // Initialize the current node to be the registry root. $node = $this->data; $found = false; // Traverse the registry to find the correct node for the result. foreach ($nodes as $n) { if (isset($node->$n)) { $node = $node->$n; $found = true; } else { $found = false; break; } } if ($found) { $result = $node; if ($allowempty === false) { if (self::isEmpty($result)) { $result = $default; } } } // convert to float if numeric if (is_numeric($result)) { $result = (float) $result; } return $result; } /** * Render all parameters * * @access public * @param string The name of the control, or the default text area if a setup file is not found * @return array Array of all parameters, each as array Any array of the label, the form element and the tooltip * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved. */ public function getParams($name = 'params', $group = '_default', $exclude = array()) { if (!isset($this->xml[$group])) { return false; } $results = array(); $parent = (string) $this->xml[$group]->attributes()->parent; foreach ($this->xml[$group]->children() as $param) { if (!empty($exclude) && in_array((string) $param->attributes()->name, $exclude)) { continue; } $results[] = $this->getParam($param, $name, $group, $parent); $parameters = (string) $param->attributes()->parameters; // get sub-parameters if ($parameters) { jimport('joomla.filesystem.folder'); // load manifest files for extensions $files = JFolder::files(JPATH_SITE . '/' . $parameters, '\.xml$', false, true); // get the base key for the parameter $keys = explode('.', (string) $param->attributes()->name); foreach ($files as $file) { $key = $keys[0] . '.' . basename($file, '.xml'); $results[] = new WFParameter($this->data, $file, $key); } } } return $results; } /** * Render a parameter type * * @param object A param tag node * @param string The control name * @return array Any array of the label, the form element and the tooltip * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved. */ public function getParam(&$node, $control_name = 'params', $group = '_default', $parent = '') { //get the type of the parameter $type = (string) $node->attributes()->type; $element = $this->loadElement($type); // error happened if ($element === false) { $result = array(); $result[0] = (string) $node->attributes()->name; $result[1] = WFText::_('Element not defined for type') . ' = ' . $type; $result[5] = $result[0]; return $result; } $key = (string) $node->attributes()->name; if ((string) $node->attributes()->group) { $key = (string) $node->attributes()->group . '.' . $key; } // get value $value = $this->get($key, (string) $node->attributes()->default); // get value if value is object or has parent if (is_object($value) || $parent) { $group = $parent ? $parent . '.' . $group : $group; $value = $this->get($group . '.' . (string) $node->attributes()->name, (string) $node->attributes()->default); } return $element->render($node, $value, $control_name); } private function cleanAttribute($matches) { return $matches[1] . '="' . preg_replace('#([^\w]+)#i', '', $matches[2]) . '"'; } public function render($name = 'params', $group = '_default', $exclude = array()) { $params = $this->getParams($name, $group, $exclude); $html = ''; if (!empty($params)) { $html .= '
      '; foreach ($params as $item) { //if (is_a($item, 'WFParameter')) { if ($item instanceof WFParameter) { foreach ($item->getGroups() as $group) { $label = $group; $class = ''; $parent = ''; $xml = $item->xml[$group]; if ((string) $xml->attributes()->parent) { $parent = '[' . (string) $xml->attributes()->parent . '][' . $group . ']'; $label = (string) $xml->attributes()->parent . '_' . $group; } $html .= '
      '; $html .= $item->render($name . $parent, $group); $html .= '
      '; } } else { $label = preg_replace_callback('#(for|id)="([^"]+)"#', array($this, 'cleanAttribute'), $item[0]); $element = preg_replace_callback('#(id)="([^"]+)"#', array($this, 'cleanAttribute'), $item[1]); $html .= '
    • ' . $label . $element; } } $html .= '
    '; } return $html; } /** * Check if a parent attribute is set. If it is, this parameter groups is included by the parent */ public function hasParent() { foreach ($this->xml as $name => $group) { if ((string) $group->attributes()->parent) { return true; } } return false; } /* * http://www.php.net/manual/en/function.array-merge-recursive.php#92195 */ public static function mergeParams(array &$array1, array &$array2, $toObject = true) { $merged = $array1; foreach ($array2 as $key => &$value) { if (is_array($value) && self::is_assoc($value) && isset($merged[$key]) && is_array($merged[$key])) { $merged[$key] = self::mergeParams($merged[$key], $value); } else { $merged[$key] = $value; } } if ($toObject) { return self::array_to_object($merged); } return $merged; } /** * Method to determine if an array is an associative array. * * @param array An array to test. * @return boolean True if the array is an associative array. * @link http://www.php.net/manual/en/function.is-array.php#98305 */ private static function is_assoc($array) { return (is_array($array) && (count($array) == 0 || 0 !== count(array_diff_key($array, array_keys(array_keys($array)))))); } /** * Convert an associate array to an object * @param array Associative array */ private static function array_to_object($array) { $object = new StdClass(); foreach ($array as $key => $value) { $object->$key = is_array($value) && self::is_assoc($value) ? self::array_to_object($value) : $value; } return $object; } /** * Get Parameter data * @param boolean $toString Return as JSON string * @return object or string */ public function getData($toString = false) { if ($toString) { return json_encode($this->data); } return $this->data; } } components/com_jce/classes/packer.php000066600000023640150771655450013773 0ustar00setProperties($config); } public function setFiles($files = array()) { $this->files = $files; } public function getFiles() { return $this->files; } public function setText($text = '') { $this->text = $text; } public function setContentStart($start = '') { $this->start = $start; } public function getContentStart() { return $this->start; } public function setContentEnd($end = '') { $this->end = $end; } public function getContentEnd() { return $this->end; } public function setType($type) { $this->type = $type; } public function getType() { return $this->type; } /** * Get encoding * @copyright Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved. */ private static function getEncoding() { if (!isset($_SERVER['HTTP_ACCEPT_ENCODING'])) { return false; } $encoding = false; if (false !== strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) { $encoding = 'gzip'; } if (false !== strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip')) { $encoding = 'x-gzip'; } return $encoding; } public function pack($minify = true, $gzip = false) { $type = $this->getType(); ob_start(); // Headers if ($type == 'javascript') { header("Content-type: application/javascript; charset: UTF-8"); } if ($type == 'css') { header("Content-type: text/css; charset: UTF-8"); } // encoding header("Vary: Accept-Encoding"); // expires after 48 hours $expires = 60 * 60 * 24 * 2; header("Cache-Control: maxage=" . $expires); // Handle proxies header("Expires: " . gmdate("D, d M Y H:i:s", time() + $expires) . " GMT"); $files = $this->getFiles(); $encoding = self::getEncoding(); $zlib = function_exists('ini_get') && extension_loaded('zlib') && ini_get('zlib.output_compression'); $gzip = $gzip && !empty($encoding) && !$zlib && function_exists('gzencode'); $content = $this->getContentStart(); if (empty($files)) { $content .= $this->getText(); } else { foreach ($files as $file) { $content .= $this->getText($file, $minify); } } if ($this->getType() == 'css') { // move external import rules to top foreach (array_unique(self::$imports) as $import) { if (strpos($import, '//') !== false) { $content = '@import url("' . $import . '");' . $content; } } } $content .= $this->getContentEnd(); // get content hash $hash = md5($content); // set etag header header("ETag: \"{$hash}\""); // Generate GZIP'd content if ($gzip) { header("Content-Encoding: " . $encoding); $content = gzencode($content, 4, FORCE_GZIP); } // stream to client echo $content; exit(ob_get_clean()); } protected function jsmin($data) { // remove header comments return preg_replace('#^\/\*[\s\S]+?\*\/#', '', $data); } /** * Simple CSS Minifier * https://github.com/GaryJones/Simple-PHP-CSS-Minification * @param $data Data string to minify */ protected function cssmin($css) { // Normalize whitespace //$css = preg_replace('/\s+/', ' ', $css); // Remove comment blocks, everything between /* and */, unless // preserved with /*! ... */ //$css = preg_replace('/\/\*[^\!](.*?)\*\//', '', $css); // Remove space after , : ; { } //$css = preg_replace('/(,|:|;|\{|}) /', '$1', $css); // Remove space before , ; { } //$css = preg_replace('/ (,|;|\{|})/', '$1', $css); // Strips leading 0 on decimal values (converts 0.5px into .5px) //$css = preg_replace('/(:| )0\.([0-9]+)(%|em|ex|px|in|cm|mm|pt|pc)/i', '${1}.${2}${3}', $css); // Strips units if value is 0 (converts 0px to 0) //$css = preg_replace('/(:| )(\.?)0(%|em|ex|px|in|cm|mm|pt|pc)/i', '${1}0', $css); // Converts all zeros value into short-hand //$css = preg_replace('/0 0 0 0/', '0', $css); // Shortern 6-character hex color codes to 3-character where possible //$css = preg_replace('/#([a-f0-9])\\1([a-f0-9])\\2([a-f0-9])\\3/i', '#\1\2\3', $css); require_once(dirname(__FILE__) . '/cssmin.php'); $min = new CSSmin(); $css = $min->run($css); return trim($css); } /** * Import CSS from a file * @param file File path where data comes from * @param $data Data from file */ protected function importCss($data, $file) { if (preg_match_all(self::IMPORT_RX, $data, $matches)) { $data = ''; foreach ($matches[1] as $match) { // clean up url $match = str_replace(array('url', '"', "'", '(', ')'), '', $match); // trim $match = trim($match); if ($match) { // external url, skip it if (strpos($match, '//') !== false) { // add to imports list self::$imports[] = $match; continue; } // url has a query, remove if (strpos($match, '?') !== false) { $match = substr($match, 0, strpos($match, '?')); } if (strpos($match, '&') !== false) { $match = substr($match, 0, strpos($match, '&')); } // get full path $path = realpath($this->get('_cssbase') . '/' . $match); // already import, don't repeat! if (in_array($path, self::$imports)) { continue; } // get data $data .= $this->getText($path); } } return $data; } return ''; } protected function compileLess($string, $path) { require_once(WF_ADMINISTRATOR . '/classes/lessc.inc.php'); $less = new lessc; // add file directory $less->addImportDir($path); // add joomla media folder $less->addImportDir(JPATH_SITE . 'media'); try { return $less->compile($string); } catch (Exception $e) { return "/* LESS file could not be compiled due to error - " . $e->getMessage() . " */"; } } protected function getText($file = null, $minify = true) { if ($file && is_file($file)) { $text = file_get_contents($file); if ($text) { // process css files if ($this->getType() == 'css') { // compile less files if (preg_match('#\.less$#', $file)) { $text = $this->compileLess($text, dirname($file)); } if ($minify) { // minify $text = $this->cssmin($text, $file); } // add to imports list self::$imports[] = $file; if (strpos($text, '@import') !== false) { // store the base path of the current file $this->set('_cssbase', dirname($file)); // process import rules $text = $this->importCss($text, $file) . preg_replace(self::IMPORT_RX, '', $text); } // store the base path of the current file $this->set('_imgbase', dirname($file)); // process urls $text = preg_replace_callback('#url\s?\([\'"]?([^\'"\))]+)[\'"]?\)#', array('WFPacker', 'processPaths'), $text); } // make sure text ends in a semi-colon; if ($this->getType() == 'javascript') { $text = rtrim(trim($text), ';') . ';'; if ($minify) { $text = $this->jsmin($text); } } return $text; } } return $this->text; } protected function processPaths($data) { if (isset($data[1])) { if (strpos($data[1], '//') === false) { $path = str_replace(JPATH_SITE, '', realpath($this->get('_imgbase') . '/' . $data[1])); if ($path) { return "url('" . JURI::root(true) . str_replace('\\', '/', $path) . "')"; } return "url('" . $data[1] . "')"; } return $data[1]; } return ""; } } ?>components/com_jce/classes/xml.php000066600000003160150771655450013321 0ustar00message); } } return $xml; } }components/com_jce/classes/view.php000066600000005121150771655450013472 0ustar00_getTab(); $end = $document->_getLineEnd(); $model = new WFModel(); foreach ($this->stylesheets as $style) { if (strpos($style, '?version=') === false || strpos($style, '?etag=') === false) { $style .= '?' . md5(basename($style) . $model->getVersion()); } $document->addCustomTag($tab . '' . $end); } foreach ($this->scripts as $script) { if (strpos($script, '?version=') === false || strpos($script, '?etag=') === false) { $script .= '?' . md5(basename($script) . $model->getVersion()); } $document->addCustomTag($tab . '' . $end); } $head = array(); foreach ($this->javascript as $script) { $head[] = $tab . '' . $end; } foreach ($this->styles as $style) { $head[] = $tab . '' . $end; } if (!empty($head)) { $document->addCustomTag(implode('', $head)); } parent::display($tpl); } public function addScript($url) { $this->scripts[] = $url; } public function addStyleSheet($url) { $this->stylesheets[] = $url; } public function addScriptDeclaration($text) { $this->javascript[] = $text; } public function addStyleDeclaration($text) { $this->styles[] = $text; } } ?> components/com_jce/classes/index.html000066600000000054150771655450014004 0ustar00components/com_jce/classes/model.php000066600000000470150771655450013622 0ustar00components/com_jce/classes/text.php000066600000003261150771655450013507 0ustar00_($string); if ($translated == $string) { if ($default) { return $default; } if (strpos($string, 'WF_') !== false) { $view = JRequest::getWord('view', ''); // remove prefix $translated = preg_replace(array('#^(WF_)#', '#(LABEL|OPTION|FILEGROUP|' . strtoupper($view) . ')_#', '#_(DESC|TITLE)#'), '', $string); $translated = ucwords(strtolower(str_replace('_', ' ', $translated))); } } return $translated; } /** * Translate a string with variables * @param string $string * @copyright Copyright (c) 2005 - 2007 Open Source Matters. All rights reserved. */ public static function sprintf($string) { $language = JFactory::getLanguage(); $args = func_get_args(); if (count($args) > 0) { $args[0] = $language->_($args[0]); return call_user_func_array('sprintf', $args); } return ''; } }components/com_jce/classes/element.php000066600000007107150771655450014157 0ustar00_parent = $parent; } /** * Get the element name * * @return string type of the parameter */ public function getName() { return $this->_name; } /** * Method to render an xml element * * @param string &$xmlElement Name of the element * @param string $value Value of the element * @param string $control_name Name of the control * * @return array Attributes of an element */ public function render(&$xmlElement, $value, $control_name = 'params') { $name = (string) $xmlElement->attributes()->name; $label = (string) $xmlElement->attributes()->label; $descr = (string) $xmlElement->attributes()->description; //make sure we have a valid label $label = $label ? $label : $name; $result[0] = $this->fetchTooltip($label, $descr, $xmlElement, $control_name, $name); $result[1] = $this->fetchElement($name, $value, $xmlElement, $control_name); $result[2] = $descr; $result[3] = $label; $result[4] = $value; $result[5] = $name; return $result; } /** * Method to get a tool tip from an XML element * * @param string $label Label attribute for the element * @param string $description Description attribute for the element * @param JXMLElement &$xmlElement The element object * @param string $control_name Control name * @param string $name Name attribut * * @return string */ public function fetchTooltip($label, $description, &$xmlElement, $control_name = '', $name = '') { $output = ''; return $output; } /** * Fetch an element * * @param string $name Name attribute of the element * @param string $value Value attribute of the element * @param JXMLElement &$xmlElement Element object * @param string $control_name Control name of the element * * @return void */ public function fetchElement($name, $value, &$xmlElement, $control_name) { } } components/com_jce/classes/installer.php000066600000020627150771655450014525 0ustar00installer = $installer; } /** * Returns the global Installer object, only creating it * if it doesn't already exist. * * @return object An installer object */ public static function getInstance() { static $instance; if (!isset($instance)) { $instance = new WFInstaller; } return $instance; } /** * Set an installer adapter by name * * @access public * @param string $name Adapter name * @param object $adapter Installer adapter object * @return boolean True if successful */ public function setAdapter($name, $adapter = null) { if (!is_object($adapter)) { $adapter = $this->getAdapter($name); } $this->_adapters[$name] = $adapter; return true; } /** * Get a JCE installer adapter * @param string $name adapter name eg: plugin. * @return $adapter instance */ public function getAdapter($type) { // Try to load the adapter object require_once(dirname(dirname(__FILE__)) . '/adapters/' . strtolower($type) . '.php'); $class = 'WFInstaller' . ucfirst($type); if (!class_exists($class)) { return false; } $adapter = new $class($this); // set parent as JInstaller instance $adapter->parent = $this->installer; return $adapter; } public function install($path) { if ($path && JFolder::exists($path)) { $this->installer->setPath('source', $path); } else { $this->installer->abort(JText::_('JLIB_INSTALLER_ABORT_NOINSTALLPATH')); return false; } if (!$this->setupInstall()) { $this->installer->abort(JText::_('JLIB_INSTALLER_ABORT_DETECTMANIFEST')); return false; } // Load the adapter(s) for the install manifest $type = (string) $this->installer->manifest->attributes()->type; if ($type == 'extension') { $type = 'plugin'; } if (is_object($this->_adapters[$type])) { // Add the languages from the package itself if (method_exists($this->_adapters[$type], 'loadLanguage')) { $this->_adapters[$type]->loadLanguage($path); } // Run the install $ret = $this->_adapters[$type]->install(); $this->set('name', $this->installer->get('name')); $this->set('version', $this->installer->get('version')); $this->set('message', $this->installer->get('description')); $this->set('extension.message', $this->installer->get('extension.message')); return $ret; } } /** * Package uninstallation method * * @param string $type Package type * @param mixed $identifier Package identifier for adapter * * @return boolean True if successful */ public function uninstall($type, $identifier) { if (!isset($this->_adapters[$type]) || !is_object($this->_adapters[$type])) { if (!$this->setAdapter($type)) { // We failed to get the right adapter return false; } } if (is_object($this->_adapters[$type])) { // Run the uninstall return $this->_adapters[$type]->uninstall($identifier); } return false; } /** * Prepare for installation: this method sets the installation directory, finds * and checks the installation file and verifies the installation type. * * @return boolean True on success */ public function setupInstall() { // We need to find the installation manifest file if (!$this->findManifest()) { return false; } // Load the adapter(s) for the install manifest $type = (string) $this->installer->manifest->attributes()->type; if ($type == 'extension') { $type = 'plugin'; } // Lazy load the adapter if (!isset($this->_adapters[$type]) || !is_object($this->_adapters[$type])) { $adapter = $this->getAdapter($type); if (!$adapter) { return false; } if (!$this->setAdapter($type, $adapter)) { return false; } } return true; } public function getManifest() { if (!is_object($this->installer->manifest)) { $this->findManifest(); } return $this->installer->manifest; } /** * Tries to find the package manifest file * * @return boolean True on success, False on error */ public function findManifest() { jimport('joomla.filesystem.folder'); // Get an array of all the XML files from the installation directory $xmlfiles = JFolder::files($this->installer->getPath('source'), '.xml$', 1, true); // If at least one XML file exists if (!empty($xmlfiles)) { foreach ($xmlfiles as $file) { // Is it a valid Joomla installation manifest file? $manifest = $this->isManifest($file); if (!is_null($manifest)) { // If the root method attribute is set to upgrade, allow file overwrite if ((string) $manifest->attributes()->method == 'upgrade') { if (method_exists($this->installer, 'setUpgrade')) { $this->installer->setUpgrade(true); } $this->installer->setOverwrite(true); } // If the overwrite option is set, allow file overwriting if ((string) $manifest->attributes()->overwrite == 'true') { $this->installer->setOverwrite(true); } // Set the manifest object and path $this->installer->manifest = $manifest; $this->installer->setPath('manifest', $file); // Set the installation source path to that of the manifest file $this->installer->setPath('source', dirname($file)); return true; } } // None of the XML files found were valid install files JError::raiseWarning(JText::_('WF_INSTALLER_MANIFEST_INVALID')); return false; } else { // No XML files were found in the install folder JError::raiseWarning(JText::_('WF_INSTALLER_MANIFEST_LOAD_ERROR')); return false; } } /** * Is the XML file a valid Joomla installation manifest file. * * @param string $file An xmlfile path to check * * @return mixed A SimpleXMLElement, or null if the file failed to parse */ public function isManifest($file) { $xml = simplexml_load_file($file); // If we cannot load the XML file return null if (!$xml) { return null; } // Check for a valid XML root tag. if ($xml->getName() != 'extension' && $xml->getName() != 'install') { return null; } // Valid manifest file return the object return $xml; } } ?>components/com_jce/classes/controller.php000066600000000533150771655450014705 0ustar00components/com_jce/classes/lessc.inc.php000066600000251671150771655450014416 0ustar00 * Licensed under MIT or GPLv3, see LICENSE */ /** * The less compiler and parser. * * Converting LESS to CSS is a three stage process. The incoming file is parsed * by `lessc_parser` into a syntax tree, then it is compiled into another tree * representing the CSS structure by `lessc`. The CSS tree is fed into a * formatter, like `lessc_formatter` which then outputs CSS as a string. * * During the first compile, all values are *reduced*, which means that their * types are brought to the lowest form before being dump as strings. This * handles math equations, variable dereferences, and the like. * * The `parse` function of `lessc` is the entry point. * * In summary: * * The `lessc` class creates an intstance of the parser, feeds it LESS code, * then transforms the resulting tree to a CSS tree. This class also holds the * evaluation context, such as all available mixins and variables at any given * time. * * The `lessc_parser` class is only concerned with parsing its input. * * The `lessc_formatter` takes a CSS tree, and dumps it to a formatted string, * handling things like indentation. */ class lessc { static public $VERSION = "v0.3.9"; static protected $TRUE = array("keyword", "true"); static protected $FALSE = array("keyword", "false"); protected $libFunctions = array(); protected $registeredVars = array(); protected $preserveComments = false; public $vPrefix = '@'; // prefix of abstract properties public $mPrefix = '$'; // prefix of abstract blocks public $parentSelector = '&'; public $importDisabled = false; public $importDir = ''; protected $numberPrecision = null; // set to the parser that generated the current line when compiling // so we know how to create error messages protected $sourceParser = null; protected $sourceLoc = null; static public $defaultValue = array("keyword", ""); static protected $nextImportId = 0; // uniquely identify imports // attempts to find the path of an import url, returns null for css files protected function findImport($url) { foreach ((array)$this->importDir as $dir) { $full = $dir.(substr($dir, -1) != '/' ? '/' : '').$url; if ($this->fileExists($file = $full.'.less') || $this->fileExists($file = $full)) { return $file; } } return null; } protected function fileExists($name) { return is_file($name); } static public function compressList($items, $delim) { if (!isset($items[1]) && isset($items[0])) return $items[0]; else return array('list', $delim, $items); } static public function preg_quote($what) { return preg_quote($what, '/'); } protected function tryImport($importPath, $parentBlock, $out) { if ($importPath[0] == "function" && $importPath[1] == "url") { $importPath = $this->flattenList($importPath[2]); } $str = $this->coerceString($importPath); if ($str === null) return false; $url = $this->compileValue($this->lib_e($str)); // don't import if it ends in css if (substr_compare($url, '.css', -4, 4) === 0) return false; $realPath = $this->findImport($url); if ($realPath === null) return false; if ($this->importDisabled) { return array(false, "/* import disabled */"); } $this->addParsedFile($realPath); $parser = $this->makeParser($realPath); $root = $parser->parse(file_get_contents($realPath)); // set the parents of all the block props foreach ($root->props as $prop) { if ($prop[0] == "block") { $prop[1]->parent = $parentBlock; } } // copy mixins into scope, set their parents // bring blocks from import into current block // TODO: need to mark the source parser these came from this file foreach ($root->children as $childName => $child) { if (isset($parentBlock->children[$childName])) { $parentBlock->children[$childName] = array_merge( $parentBlock->children[$childName], $child); } else { $parentBlock->children[$childName] = $child; } } $pi = pathinfo($realPath); $dir = $pi["dirname"]; list($top, $bottom) = $this->sortProps($root->props, true); $this->compileImportedProps($top, $parentBlock, $out, $parser, $dir); return array(true, $bottom, $parser, $dir); } protected function compileImportedProps($props, $block, $out, $sourceParser, $importDir) { $oldSourceParser = $this->sourceParser; $oldImport = $this->importDir; // TODO: this is because the importDir api is stupid $this->importDir = (array)$this->importDir; array_unshift($this->importDir, $importDir); foreach ($props as $prop) { $this->compileProp($prop, $block, $out); } $this->importDir = $oldImport; $this->sourceParser = $oldSourceParser; } /** * Recursively compiles a block. * * A block is analogous to a CSS block in most cases. A single LESS document * is encapsulated in a block when parsed, but it does not have parent tags * so all of it's children appear on the root level when compiled. * * Blocks are made up of props and children. * * Props are property instructions, array tuples which describe an action * to be taken, eg. write a property, set a variable, mixin a block. * * The children of a block are just all the blocks that are defined within. * This is used to look up mixins when performing a mixin. * * Compiling the block involves pushing a fresh environment on the stack, * and iterating through the props, compiling each one. * * See lessc::compileProp() * */ protected function compileBlock($block) { switch ($block->type) { case "root": $this->compileRoot($block); break; case null: $this->compileCSSBlock($block); break; case "media": $this->compileMedia($block); break; case "directive": $name = "@" . $block->name; if (!empty($block->value)) { $name .= " " . $this->compileValue($this->reduce($block->value)); } $this->compileNestedBlock($block, array($name)); break; default: $this->throwError("unknown block type: $block->type\n"); } } protected function compileCSSBlock($block) { $env = $this->pushEnv(); $selectors = $this->compileSelectors($block->tags); $env->selectors = $this->multiplySelectors($selectors); $out = $this->makeOutputBlock(null, $env->selectors); $this->scope->children[] = $out; $this->compileProps($block, $out); $block->scope = $env; // mixins carry scope with them! $this->popEnv(); } protected function compileMedia($media) { $env = $this->pushEnv($media); $parentScope = $this->mediaParent($this->scope); $query = $this->compileMediaQuery($this->multiplyMedia($env)); $this->scope = $this->makeOutputBlock($media->type, array($query)); $parentScope->children[] = $this->scope; $this->compileProps($media, $this->scope); if (count($this->scope->lines) > 0) { $orphanSelelectors = $this->findClosestSelectors(); if (!is_null($orphanSelelectors)) { $orphan = $this->makeOutputBlock(null, $orphanSelelectors); $orphan->lines = $this->scope->lines; array_unshift($this->scope->children, $orphan); $this->scope->lines = array(); } } $this->scope = $this->scope->parent; $this->popEnv(); } protected function mediaParent($scope) { while (!empty($scope->parent)) { if (!empty($scope->type) && $scope->type != "media") { break; } $scope = $scope->parent; } return $scope; } protected function compileNestedBlock($block, $selectors) { $this->pushEnv($block); $this->scope = $this->makeOutputBlock($block->type, $selectors); $this->scope->parent->children[] = $this->scope; $this->compileProps($block, $this->scope); $this->scope = $this->scope->parent; $this->popEnv(); } protected function compileRoot($root) { $this->pushEnv(); $this->scope = $this->makeOutputBlock($root->type); $this->compileProps($root, $this->scope); $this->popEnv(); } protected function compileProps($block, $out) { foreach ($this->sortProps($block->props) as $prop) { $this->compileProp($prop, $block, $out); } } protected function sortProps($props, $split = false) { $vars = array(); $imports = array(); $other = array(); foreach ($props as $prop) { switch ($prop[0]) { case "assign": if (isset($prop[1][0]) && $prop[1][0] == $this->vPrefix) { $vars[] = $prop; } else { $other[] = $prop; } break; case "import": $id = self::$nextImportId++; $prop[] = $id; $imports[] = $prop; $other[] = array("import_mixin", $id); break; default: $other[] = $prop; } } if ($split) { return array(array_merge($vars, $imports), $other); } else { return array_merge($vars, $imports, $other); } } protected function compileMediaQuery($queries) { $compiledQueries = array(); foreach ($queries as $query) { $parts = array(); foreach ($query as $q) { switch ($q[0]) { case "mediaType": $parts[] = implode(" ", array_slice($q, 1)); break; case "mediaExp": if (isset($q[2])) { $parts[] = "($q[1]: " . $this->compileValue($this->reduce($q[2])) . ")"; } else { $parts[] = "($q[1])"; } break; case "variable": $parts[] = $this->compileValue($this->reduce($q)); break; } } if (count($parts) > 0) { $compiledQueries[] = implode(" and ", $parts); } } $out = "@media"; if (!empty($parts)) { $out .= " " . implode($this->formatter->selectorSeparator, $compiledQueries); } return $out; } protected function multiplyMedia($env, $childQueries = null) { if (is_null($env) || !empty($env->block->type) && $env->block->type != "media") { return $childQueries; } // plain old block, skip if (empty($env->block->type)) { return $this->multiplyMedia($env->parent, $childQueries); } $out = array(); $queries = $env->block->queries; if (is_null($childQueries)) { $out = $queries; } else { foreach ($queries as $parent) { foreach ($childQueries as $child) { $out[] = array_merge($parent, $child); } } } return $this->multiplyMedia($env->parent, $out); } protected function expandParentSelectors(&$tag, $replace) { $parts = explode("$&$", $tag); $count = 0; foreach ($parts as &$part) { $part = str_replace($this->parentSelector, $replace, $part, $c); $count += $c; } $tag = implode($this->parentSelector, $parts); return $count; } protected function findClosestSelectors() { $env = $this->env; $selectors = null; while ($env !== null) { if (isset($env->selectors)) { $selectors = $env->selectors; break; } $env = $env->parent; } return $selectors; } // multiply $selectors against the nearest selectors in env protected function multiplySelectors($selectors) { // find parent selectors $parentSelectors = $this->findClosestSelectors(); if (is_null($parentSelectors)) { // kill parent reference in top level selector foreach ($selectors as &$s) { $this->expandParentSelectors($s, ""); } return $selectors; } $out = array(); foreach ($parentSelectors as $parent) { foreach ($selectors as $child) { $count = $this->expandParentSelectors($child, $parent); // don't prepend the parent tag if & was used if ($count > 0) { $out[] = trim($child); } else { $out[] = trim($parent . ' ' . $child); } } } return $out; } // reduces selector expressions protected function compileSelectors($selectors) { $out = array(); foreach ($selectors as $s) { if (is_array($s)) { list(, $value) = $s; $out[] = trim($this->compileValue($this->reduce($value))); } else { $out[] = $s; } } return $out; } protected function eq($left, $right) { return $left == $right; } protected function patternMatch($block, $callingArgs) { // match the guards if it has them // any one of the groups must have all its guards pass for a match if (!empty($block->guards)) { $groupPassed = false; foreach ($block->guards as $guardGroup) { foreach ($guardGroup as $guard) { $this->pushEnv(); $this->zipSetArgs($block->args, $callingArgs); $negate = false; if ($guard[0] == "negate") { $guard = $guard[1]; $negate = true; } $passed = $this->reduce($guard) == self::$TRUE; if ($negate) $passed = !$passed; $this->popEnv(); if ($passed) { $groupPassed = true; } else { $groupPassed = false; break; } } if ($groupPassed) break; } if (!$groupPassed) { return false; } } $numCalling = count($callingArgs); if (empty($block->args)) { return $block->isVararg || $numCalling == 0; } $i = -1; // no args // try to match by arity or by argument literal foreach ($block->args as $i => $arg) { switch ($arg[0]) { case "lit": if (empty($callingArgs[$i]) || !$this->eq($arg[1], $callingArgs[$i])) { return false; } break; case "arg": // no arg and no default value if (!isset($callingArgs[$i]) && !isset($arg[2])) { return false; } break; case "rest": $i--; // rest can be empty break 2; } } if ($block->isVararg) { return true; // not having enough is handled above } else { $numMatched = $i + 1; // greater than becuase default values always match return $numMatched >= $numCalling; } } protected function patternMatchAll($blocks, $callingArgs) { $matches = null; foreach ($blocks as $block) { if ($this->patternMatch($block, $callingArgs)) { $matches[] = $block; } } return $matches; } // attempt to find blocks matched by path and args protected function findBlocks($searchIn, $path, $args, $seen=array()) { if ($searchIn == null) return null; if (isset($seen[$searchIn->id])) return null; $seen[$searchIn->id] = true; $name = $path[0]; if (isset($searchIn->children[$name])) { $blocks = $searchIn->children[$name]; if (count($path) == 1) { $matches = $this->patternMatchAll($blocks, $args); if (!empty($matches)) { // This will return all blocks that match in the closest // scope that has any matching block, like lessjs return $matches; } } else { $matches = array(); foreach ($blocks as $subBlock) { $subMatches = $this->findBlocks($subBlock, array_slice($path, 1), $args, $seen); if (!is_null($subMatches)) { foreach ($subMatches as $sm) { $matches[] = $sm; } } } return count($matches) > 0 ? $matches : null; } } if ($searchIn->parent === $searchIn) return null; return $this->findBlocks($searchIn->parent, $path, $args, $seen); } // sets all argument names in $args to either the default value // or the one passed in through $values protected function zipSetArgs($args, $values) { $i = 0; $assignedValues = array(); foreach ($args as $a) { if ($a[0] == "arg") { if ($i < count($values) && !is_null($values[$i])) { $value = $values[$i]; } elseif (isset($a[2])) { $value = $a[2]; } else $value = null; $value = $this->reduce($value); $this->set($a[1], $value); $assignedValues[] = $value; } $i++; } // check for a rest $last = end($args); if ($last[0] == "rest") { $rest = array_slice($values, count($args) - 1); $this->set($last[1], $this->reduce(array("list", " ", $rest))); } $this->env->arguments = $assignedValues; } // compile a prop and update $lines or $blocks appropriately protected function compileProp($prop, $block, $out) { // set error position context $this->sourceLoc = isset($prop[-1]) ? $prop[-1] : -1; switch ($prop[0]) { case 'assign': list(, $name, $value) = $prop; if ($name[0] == $this->vPrefix) { $this->set($name, $value); } else { $out->lines[] = $this->formatter->property($name, $this->compileValue($this->reduce($value))); } break; case 'block': list(, $child) = $prop; $this->compileBlock($child); break; case 'mixin': list(, $path, $args, $suffix) = $prop; $args = array_map(array($this, "reduce"), (array)$args); $mixins = $this->findBlocks($block, $path, $args); if ($mixins === null) { // fwrite(STDERR,"failed to find block: ".implode(" > ", $path)."\n"); break; // throw error here?? } foreach ($mixins as $mixin) { $haveScope = false; if (isset($mixin->parent->scope)) { $haveScope = true; $mixinParentEnv = $this->pushEnv(); $mixinParentEnv->storeParent = $mixin->parent->scope; } $haveArgs = false; if (isset($mixin->args)) { $haveArgs = true; $this->pushEnv(); $this->zipSetArgs($mixin->args, $args); } $oldParent = $mixin->parent; if ($mixin != $block) $mixin->parent = $block; foreach ($this->sortProps($mixin->props) as $subProp) { if ($suffix !== null && $subProp[0] == "assign" && is_string($subProp[1]) && $subProp[1]{0} != $this->vPrefix) { $subProp[2] = array( 'list', ' ', array($subProp[2], array('keyword', $suffix)) ); } $this->compileProp($subProp, $mixin, $out); } $mixin->parent = $oldParent; if ($haveArgs) $this->popEnv(); if ($haveScope) $this->popEnv(); } break; case 'raw': $out->lines[] = $prop[1]; break; case "directive": list(, $name, $value) = $prop; $out->lines[] = "@$name " . $this->compileValue($this->reduce($value)).';'; break; case "comment": $out->lines[] = $prop[1]; break; case "import"; list(, $importPath, $importId) = $prop; $importPath = $this->reduce($importPath); if (!isset($this->env->imports)) { $this->env->imports = array(); } $result = $this->tryImport($importPath, $block, $out); $this->env->imports[$importId] = $result === false ? array(false, "@import " . $this->compileValue($importPath).";") : $result; break; case "import_mixin": list(,$importId) = $prop; $import = $this->env->imports[$importId]; if ($import[0] === false) { $out->lines[] = $import[1]; } else { list(, $bottom, $parser, $importDir) = $import; $this->compileImportedProps($bottom, $block, $out, $parser, $importDir); } break; default: $this->throwError("unknown op: {$prop[0]}\n"); } } /** * Compiles a primitive value into a CSS property value. * * Values in lessphp are typed by being wrapped in arrays, their format is * typically: * * array(type, contents [, additional_contents]*) * * The input is expected to be reduced. This function will not work on * things like expressions and variables. */ protected function compileValue($value) { switch ($value[0]) { case 'list': // [1] - delimiter // [2] - array of values return implode($value[1], array_map(array($this, 'compileValue'), $value[2])); case 'raw_color': if (!empty($this->formatter->compressColors)) { return $this->compileValue($this->coerceColor($value)); } return $value[1]; case 'keyword': // [1] - the keyword return $value[1]; case 'number': list(, $num, $unit) = $value; // [1] - the number // [2] - the unit if ($this->numberPrecision !== null) { $num = round($num, $this->numberPrecision); } return $num . $unit; case 'string': // [1] - contents of string (includes quotes) list(, $delim, $content) = $value; foreach ($content as &$part) { if (is_array($part)) { $part = $this->compileValue($part); } } return $delim . implode($content) . $delim; case 'color': // [1] - red component (either number or a %) // [2] - green component // [3] - blue component // [4] - optional alpha component list(, $r, $g, $b) = $value; $r = round($r); $g = round($g); $b = round($b); if (count($value) == 5 && $value[4] != 1) { // rgba return 'rgba('.$r.','.$g.','.$b.','.$value[4].')'; } $h = sprintf("#%02x%02x%02x", $r, $g, $b); if (!empty($this->formatter->compressColors)) { // Converting hex color to short notation (e.g. #003399 to #039) if ($h[1] === $h[2] && $h[3] === $h[4] && $h[5] === $h[6]) { $h = '#' . $h[1] . $h[3] . $h[5]; } } return $h; case 'function': list(, $name, $args) = $value; return $name.'('.$this->compileValue($args).')'; default: // assumed to be unit $this->throwError("unknown value type: $value[0]"); } } protected function lib_isnumber($value) { return $this->toBool($value[0] == "number"); } protected function lib_isstring($value) { return $this->toBool($value[0] == "string"); } protected function lib_iscolor($value) { return $this->toBool($this->coerceColor($value)); } protected function lib_iskeyword($value) { return $this->toBool($value[0] == "keyword"); } protected function lib_ispixel($value) { return $this->toBool($value[0] == "number" && $value[2] == "px"); } protected function lib_ispercentage($value) { return $this->toBool($value[0] == "number" && $value[2] == "%"); } protected function lib_isem($value) { return $this->toBool($value[0] == "number" && $value[2] == "em"); } protected function lib_isrem($value) { return $this->toBool($value[0] == "number" && $value[2] == "rem"); } protected function lib_rgbahex($color) { $color = $this->coerceColor($color); if (is_null($color)) $this->throwError("color expected for rgbahex"); return sprintf("#%02x%02x%02x%02x", isset($color[4]) ? $color[4]*255 : 255, $color[1],$color[2], $color[3]); } protected function lib_argb($color){ return $this->lib_rgbahex($color); } // utility func to unquote a string protected function lib_e($arg) { switch ($arg[0]) { case "list": $items = $arg[2]; if (isset($items[0])) { return $this->lib_e($items[0]); } return self::$defaultValue; case "string": $arg[1] = ""; return $arg; case "keyword": return $arg; default: return array("keyword", $this->compileValue($arg)); } } protected function lib__sprintf($args) { if ($args[0] != "list") return $args; $values = $args[2]; $string = array_shift($values); $template = $this->compileValue($this->lib_e($string)); $i = 0; if (preg_match_all('/%[dsa]/', $template, $m)) { foreach ($m[0] as $match) { $val = isset($values[$i]) ? $this->reduce($values[$i]) : array('keyword', ''); // lessjs compat, renders fully expanded color, not raw color if ($color = $this->coerceColor($val)) { $val = $color; } $i++; $rep = $this->compileValue($this->lib_e($val)); $template = preg_replace('/'.self::preg_quote($match).'/', $rep, $template, 1); } } $d = $string[0] == "string" ? $string[1] : '"'; return array("string", $d, array($template)); } protected function lib_floor($arg) { $value = $this->assertNumber($arg); return array("number", floor($value), $arg[2]); } protected function lib_ceil($arg) { $value = $this->assertNumber($arg); return array("number", ceil($value), $arg[2]); } protected function lib_round($arg) { $value = $this->assertNumber($arg); return array("number", round($value), $arg[2]); } protected function lib_unit($arg) { if ($arg[0] == "list") { list($number, $newUnit) = $arg[2]; return array("number", $this->assertNumber($number), $this->compileValue($this->lib_e($newUnit))); } else { return array("number", $this->assertNumber($arg), ""); } } /** * Helper function to get arguments for color manipulation functions. * takes a list that contains a color like thing and a percentage */ protected function colorArgs($args) { if ($args[0] != 'list' || count($args[2]) < 2) { return array(array('color', 0, 0, 0), 0); } list($color, $delta) = $args[2]; $color = $this->assertColor($color); $delta = floatval($delta[1]); return array($color, $delta); } protected function lib_darken($args) { list($color, $delta) = $this->colorArgs($args); $hsl = $this->toHSL($color); $hsl[3] = $this->clamp($hsl[3] - $delta, 100); return $this->toRGB($hsl); } protected function lib_lighten($args) { list($color, $delta) = $this->colorArgs($args); $hsl = $this->toHSL($color); $hsl[3] = $this->clamp($hsl[3] + $delta, 100); return $this->toRGB($hsl); } protected function lib_saturate($args) { list($color, $delta) = $this->colorArgs($args); $hsl = $this->toHSL($color); $hsl[2] = $this->clamp($hsl[2] + $delta, 100); return $this->toRGB($hsl); } protected function lib_desaturate($args) { list($color, $delta) = $this->colorArgs($args); $hsl = $this->toHSL($color); $hsl[2] = $this->clamp($hsl[2] - $delta, 100); return $this->toRGB($hsl); } protected function lib_spin($args) { list($color, $delta) = $this->colorArgs($args); $hsl = $this->toHSL($color); $hsl[1] = $hsl[1] + $delta % 360; if ($hsl[1] < 0) $hsl[1] += 360; return $this->toRGB($hsl); } protected function lib_fadeout($args) { list($color, $delta) = $this->colorArgs($args); $color[4] = $this->clamp((isset($color[4]) ? $color[4] : 1) - $delta/100); return $color; } protected function lib_fadein($args) { list($color, $delta) = $this->colorArgs($args); $color[4] = $this->clamp((isset($color[4]) ? $color[4] : 1) + $delta/100); return $color; } protected function lib_hue($color) { $hsl = $this->toHSL($this->assertColor($color)); return round($hsl[1]); } protected function lib_saturation($color) { $hsl = $this->toHSL($this->assertColor($color)); return round($hsl[2]); } protected function lib_lightness($color) { $hsl = $this->toHSL($this->assertColor($color)); return round($hsl[3]); } // get the alpha of a color // defaults to 1 for non-colors or colors without an alpha protected function lib_alpha($value) { if (!is_null($color = $this->coerceColor($value))) { return isset($color[4]) ? $color[4] : 1; } } // set the alpha of the color protected function lib_fade($args) { list($color, $alpha) = $this->colorArgs($args); $color[4] = $this->clamp($alpha / 100.0); return $color; } protected function lib_percentage($arg) { $num = $this->assertNumber($arg); return array("number", $num*100, "%"); } // mixes two colors by weight // mix(@color1, @color2, @weight); // http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#mix-instance_method protected function lib_mix($args) { if ($args[0] != "list" || count($args[2]) < 3) $this->throwError("mix expects (color1, color2, weight)"); list($first, $second, $weight) = $args[2]; $first = $this->assertColor($first); $second = $this->assertColor($second); $first_a = $this->lib_alpha($first); $second_a = $this->lib_alpha($second); $weight = $weight[1] / 100.0; $w = $weight * 2 - 1; $a = $first_a - $second_a; $w1 = (($w * $a == -1 ? $w : ($w + $a)/(1 + $w * $a)) + 1) / 2.0; $w2 = 1.0 - $w1; $new = array('color', $w1 * $first[1] + $w2 * $second[1], $w1 * $first[2] + $w2 * $second[2], $w1 * $first[3] + $w2 * $second[3], ); if ($first_a != 1.0 || $second_a != 1.0) { $new[] = $first_a * $weight + $second_a * ($weight - 1); } return $this->fixColor($new); } protected function lib_contrast($args) { if ($args[0] != 'list' || count($args[2]) < 3) { return array(array('color', 0, 0, 0), 0); } list($inputColor, $darkColor, $lightColor) = $args[2]; $inputColor = $this->assertColor($inputColor); $darkColor = $this->assertColor($darkColor); $lightColor = $this->assertColor($lightColor); $hsl = $this->toHSL($inputColor); if ($hsl[3] > 50) { return $darkColor; } return $lightColor; } protected function assertColor($value, $error = "expected color value") { $color = $this->coerceColor($value); if (is_null($color)) $this->throwError($error); return $color; } protected function assertNumber($value, $error = "expecting number") { if ($value[0] == "number") return $value[1]; $this->throwError($error); } protected function toHSL($color) { if ($color[0] == 'hsl') return $color; $r = $color[1] / 255; $g = $color[2] / 255; $b = $color[3] / 255; $min = min($r, $g, $b); $max = max($r, $g, $b); $L = ($min + $max) / 2; if ($min == $max) { $S = $H = 0; } else { if ($L < 0.5) $S = ($max - $min)/($max + $min); else $S = ($max - $min)/(2.0 - $max - $min); if ($r == $max) $H = ($g - $b)/($max - $min); elseif ($g == $max) $H = 2.0 + ($b - $r)/($max - $min); elseif ($b == $max) $H = 4.0 + ($r - $g)/($max - $min); } $out = array('hsl', ($H < 0 ? $H + 6 : $H)*60, $S*100, $L*100, ); if (count($color) > 4) $out[] = $color[4]; // copy alpha return $out; } protected function toRGB_helper($comp, $temp1, $temp2) { if ($comp < 0) $comp += 1.0; elseif ($comp > 1) $comp -= 1.0; if (6 * $comp < 1) return $temp1 + ($temp2 - $temp1) * 6 * $comp; if (2 * $comp < 1) return $temp2; if (3 * $comp < 2) return $temp1 + ($temp2 - $temp1)*((2/3) - $comp) * 6; return $temp1; } /** * Converts a hsl array into a color value in rgb. * Expects H to be in range of 0 to 360, S and L in 0 to 100 */ protected function toRGB($color) { if ($color[0] == 'color') return $color; $H = $color[1] / 360; $S = $color[2] / 100; $L = $color[3] / 100; if ($S == 0) { $r = $g = $b = $L; } else { $temp2 = $L < 0.5 ? $L*(1.0 + $S) : $L + $S - $L * $S; $temp1 = 2.0 * $L - $temp2; $r = $this->toRGB_helper($H + 1/3, $temp1, $temp2); $g = $this->toRGB_helper($H, $temp1, $temp2); $b = $this->toRGB_helper($H - 1/3, $temp1, $temp2); } // $out = array('color', round($r*255), round($g*255), round($b*255)); $out = array('color', $r*255, $g*255, $b*255); if (count($color) > 4) $out[] = $color[4]; // copy alpha return $out; } protected function clamp($v, $max = 1, $min = 0) { return min($max, max($min, $v)); } /** * Convert the rgb, rgba, hsl color literals of function type * as returned by the parser into values of color type. */ protected function funcToColor($func) { $fname = $func[1]; if ($func[2][0] != 'list') return false; // need a list of arguments $rawComponents = $func[2][2]; if ($fname == 'hsl' || $fname == 'hsla') { $hsl = array('hsl'); $i = 0; foreach ($rawComponents as $c) { $val = $this->reduce($c); $val = isset($val[1]) ? floatval($val[1]) : 0; if ($i == 0) $clamp = 360; elseif ($i < 3) $clamp = 100; else $clamp = 1; $hsl[] = $this->clamp($val, $clamp); $i++; } while (count($hsl) < 4) $hsl[] = 0; return $this->toRGB($hsl); } elseif ($fname == 'rgb' || $fname == 'rgba') { $components = array(); $i = 1; foreach ($rawComponents as $c) { $c = $this->reduce($c); if ($i < 4) { if ($c[0] == "number" && $c[2] == "%") { $components[] = 255 * ($c[1] / 100); } else { $components[] = floatval($c[1]); } } elseif ($i == 4) { if ($c[0] == "number" && $c[2] == "%") { $components[] = 1.0 * ($c[1] / 100); } else { $components[] = floatval($c[1]); } } else break; $i++; } while (count($components) < 3) $components[] = 0; array_unshift($components, 'color'); return $this->fixColor($components); } return false; } protected function reduce($value, $forExpression = false) { switch ($value[0]) { case "interpolate": $reduced = $this->reduce($value[1]); $var = $this->compileValue($reduced); $res = $this->reduce(array("variable", $this->vPrefix . $var)); if (empty($value[2])) $res = $this->lib_e($res); return $res; case "variable": $key = $value[1]; if (is_array($key)) { $key = $this->reduce($key); $key = $this->vPrefix . $this->compileValue($this->lib_e($key)); } $seen =& $this->env->seenNames; if (!empty($seen[$key])) { $this->throwError("infinite loop detected: $key"); } $seen[$key] = true; $out = $this->reduce($this->get($key, self::$defaultValue)); $seen[$key] = false; return $out; case "list": foreach ($value[2] as &$item) { $item = $this->reduce($item, $forExpression); } return $value; case "expression": return $this->evaluate($value); case "string": foreach ($value[2] as &$part) { if (is_array($part)) { $strip = $part[0] == "variable"; $part = $this->reduce($part); if ($strip) $part = $this->lib_e($part); } } return $value; case "escape": list(,$inner) = $value; return $this->lib_e($this->reduce($inner)); case "function": $color = $this->funcToColor($value); if ($color) return $color; list(, $name, $args) = $value; if ($name == "%") $name = "_sprintf"; $f = isset($this->libFunctions[$name]) ? $this->libFunctions[$name] : array($this, 'lib_'.$name); if (is_callable($f)) { if ($args[0] == 'list') $args = self::compressList($args[2], $args[1]); $ret = call_user_func($f, $this->reduce($args, true), $this); if (is_null($ret)) { return array("string", "", array( $name, "(", $args, ")" )); } // convert to a typed value if the result is a php primitive if (is_numeric($ret)) $ret = array('number', $ret, ""); elseif (!is_array($ret)) $ret = array('keyword', $ret); return $ret; } // plain function, reduce args $value[2] = $this->reduce($value[2]); return $value; case "unary": list(, $op, $exp) = $value; $exp = $this->reduce($exp); if ($exp[0] == "number") { switch ($op) { case "+": return $exp; case "-": $exp[1] *= -1; return $exp; } } return array("string", "", array($op, $exp)); } if ($forExpression) { switch ($value[0]) { case "keyword": if ($color = $this->coerceColor($value)) { return $color; } break; case "raw_color": return $this->coerceColor($value); } } return $value; } // coerce a value for use in color operation protected function coerceColor($value) { switch($value[0]) { case 'color': return $value; case 'raw_color': $c = array("color", 0, 0, 0); $colorStr = substr($value[1], 1); $num = hexdec($colorStr); $width = strlen($colorStr) == 3 ? 16 : 256; for ($i = 3; $i > 0; $i--) { // 3 2 1 $t = $num % $width; $num /= $width; $c[$i] = $t * (256/$width) + $t * floor(16/$width); } return $c; case 'keyword': $name = $value[1]; if (isset(self::$cssColors[$name])) { $rgba = explode(',', self::$cssColors[$name]); if(isset($rgba[3])) return array('color', $rgba[0], $rgba[1], $rgba[2], $rgba[3]); return array('color', $rgba[0], $rgba[1], $rgba[2]); } return null; } } // make something string like into a string protected function coerceString($value) { switch ($value[0]) { case "string": return $value; case "keyword": return array("string", "", array($value[1])); } return null; } // turn list of length 1 into value type protected function flattenList($value) { if ($value[0] == "list" && count($value[2]) == 1) { return $this->flattenList($value[2][0]); } return $value; } protected function toBool($a) { if ($a) return self::$TRUE; else return self::$FALSE; } // evaluate an expression protected function evaluate($exp) { list(, $op, $left, $right, $whiteBefore, $whiteAfter) = $exp; $left = $this->reduce($left, true); $right = $this->reduce($right, true); if ($leftColor = $this->coerceColor($left)) { $left = $leftColor; } if ($rightColor = $this->coerceColor($right)) { $right = $rightColor; } $ltype = $left[0]; $rtype = $right[0]; // operators that work on all types if ($op == "and") { return $this->toBool($left == self::$TRUE && $right == self::$TRUE); } if ($op == "=") { return $this->toBool($this->eq($left, $right) ); } if ($op == "+" && !is_null($str = $this->stringConcatenate($left, $right))) { return $str; } // type based operators $fname = "op_${ltype}_${rtype}"; if (is_callable(array($this, $fname))) { $out = $this->$fname($op, $left, $right); if (!is_null($out)) return $out; } // make the expression look it did before being parsed $paddedOp = $op; if ($whiteBefore) $paddedOp = " " . $paddedOp; if ($whiteAfter) $paddedOp .= " "; return array("string", "", array($left, $paddedOp, $right)); } protected function stringConcatenate($left, $right) { if ($strLeft = $this->coerceString($left)) { if ($right[0] == "string") { $right[1] = ""; } $strLeft[2][] = $right; return $strLeft; } if ($strRight = $this->coerceString($right)) { array_unshift($strRight[2], $left); return $strRight; } } // make sure a color's components don't go out of bounds protected function fixColor($c) { foreach (range(1, 3) as $i) { if ($c[$i] < 0) $c[$i] = 0; if ($c[$i] > 255) $c[$i] = 255; } return $c; } protected function op_number_color($op, $lft, $rgt) { if ($op == '+' || $op == '*') { return $this->op_color_number($op, $rgt, $lft); } } protected function op_color_number($op, $lft, $rgt) { if ($rgt[0] == '%') $rgt[1] /= 100; return $this->op_color_color($op, $lft, array_fill(1, count($lft) - 1, $rgt[1])); } protected function op_color_color($op, $left, $right) { $out = array('color'); $max = count($left) > count($right) ? count($left) : count($right); foreach (range(1, $max - 1) as $i) { $lval = isset($left[$i]) ? $left[$i] : 0; $rval = isset($right[$i]) ? $right[$i] : 0; switch ($op) { case '+': $out[] = $lval + $rval; break; case '-': $out[] = $lval - $rval; break; case '*': $out[] = $lval * $rval; break; case '%': $out[] = $lval % $rval; break; case '/': if ($rval == 0) $this->throwError("evaluate error: can't divide by zero"); $out[] = $lval / $rval; break; default: $this->throwError('evaluate error: color op number failed on op '.$op); } } return $this->fixColor($out); } function lib_red($color){ $color = $this->coerceColor($color); if (is_null($color)) { $this->throwError('color expected for red()'); } return $color[1]; } function lib_green($color){ $color = $this->coerceColor($color); if (is_null($color)) { $this->throwError('color expected for green()'); } return $color[2]; } function lib_blue($color){ $color = $this->coerceColor($color); if (is_null($color)) { $this->throwError('color expected for blue()'); } return $color[3]; } // operator on two numbers protected function op_number_number($op, $left, $right) { $unit = empty($left[2]) ? $right[2] : $left[2]; $value = 0; switch ($op) { case '+': $value = $left[1] + $right[1]; break; case '*': $value = $left[1] * $right[1]; break; case '-': $value = $left[1] - $right[1]; break; case '%': $value = $left[1] % $right[1]; break; case '/': if ($right[1] == 0) $this->throwError('parse error: divide by zero'); $value = $left[1] / $right[1]; break; case '<': return $this->toBool($left[1] < $right[1]); case '>': return $this->toBool($left[1] > $right[1]); case '>=': return $this->toBool($left[1] >= $right[1]); case '=<': return $this->toBool($left[1] <= $right[1]); default: $this->throwError('parse error: unknown number operator: '.$op); } return array("number", $value, $unit); } /* environment functions */ protected function makeOutputBlock($type, $selectors = null) { $b = new stdclass; $b->lines = array(); $b->children = array(); $b->selectors = $selectors; $b->type = $type; $b->parent = $this->scope; return $b; } // the state of execution protected function pushEnv($block = null) { $e = new stdclass; $e->parent = $this->env; $e->store = array(); $e->block = $block; $this->env = $e; return $e; } // pop something off the stack protected function popEnv() { $old = $this->env; $this->env = $this->env->parent; return $old; } // set something in the current env protected function set($name, $value) { $this->env->store[$name] = $value; } // get the highest occurrence entry for a name protected function get($name, $default=null) { $current = $this->env; $isArguments = $name == $this->vPrefix . 'arguments'; while ($current) { if ($isArguments && isset($current->arguments)) { return array('list', ' ', $current->arguments); } if (isset($current->store[$name])) return $current->store[$name]; else { $current = isset($current->storeParent) ? $current->storeParent : $current->parent; } } return $default; } // inject array of unparsed strings into environment as variables protected function injectVariables($args) { $this->pushEnv(); $parser = new lessc_parser($this, __METHOD__); foreach ($args as $name => $strValue) { if ($name{0} != '@') $name = '@'.$name; $parser->count = 0; $parser->buffer = (string)$strValue; if (!$parser->propertyValue($value)) { throw new Exception("failed to parse passed in variable $name: $strValue"); } $this->set($name, $value); } } /** * Initialize any static state, can initialize parser for a file * $opts isn't used yet */ public function __construct($fname = null) { if ($fname !== null) { // used for deprecated parse method $this->_parseFile = $fname; } } public function compile($string, $name = null) { $locale = setlocale(LC_NUMERIC, 0); setlocale(LC_NUMERIC, "C"); $this->parser = $this->makeParser($name); $root = $this->parser->parse($string); $this->env = null; $this->scope = null; $this->formatter = $this->newFormatter(); if (!empty($this->registeredVars)) { $this->injectVariables($this->registeredVars); } $this->sourceParser = $this->parser; // used for error messages $this->compileBlock($root); ob_start(); $this->formatter->block($this->scope); $out = ob_get_clean(); setlocale(LC_NUMERIC, $locale); return $out; } public function compileFile($fname, $outFname = null) { if (!is_readable($fname)) { throw new Exception('load error: failed to find '.$fname); } $pi = pathinfo($fname); $oldImport = $this->importDir; $this->importDir = (array)$this->importDir; $this->importDir[] = $pi['dirname'].'/'; $this->allParsedFiles = array(); $this->addParsedFile($fname); $out = $this->compile(file_get_contents($fname), $fname); $this->importDir = $oldImport; if ($outFname !== null) { return file_put_contents($outFname, $out); } return $out; } // compile only if changed input has changed or output doesn't exist public function checkedCompile($in, $out) { if (!is_file($out) || filemtime($in) > filemtime($out)) { $this->compileFile($in, $out); return true; } return false; } /** * Execute lessphp on a .less file or a lessphp cache structure * * The lessphp cache structure contains information about a specific * less file having been parsed. It can be used as a hint for future * calls to determine whether or not a rebuild is required. * * The cache structure contains two important keys that may be used * externally: * * compiled: The final compiled CSS * updated: The time (in seconds) the CSS was last compiled * * The cache structure is a plain-ol' PHP associative array and can * be serialized and unserialized without a hitch. * * @param mixed $in Input * @param bool $force Force rebuild? * @return array lessphp cache structure */ public function cachedCompile($in, $force = false) { // assume no root $root = null; if (is_string($in)) { $root = $in; } elseif (is_array($in) and isset($in['root'])) { if ($force or ! isset($in['files'])) { // If we are forcing a recompile or if for some reason the // structure does not contain any file information we should // specify the root to trigger a rebuild. $root = $in['root']; } elseif (isset($in['files']) and is_array($in['files'])) { foreach ($in['files'] as $fname => $ftime ) { if (!file_exists($fname) or filemtime($fname) > $ftime) { // One of the files we knew about previously has changed // so we should look at our incoming root again. $root = $in['root']; break; } } } } else { // TODO: Throw an exception? We got neither a string nor something // that looks like a compatible lessphp cache structure. return null; } if ($root !== null) { // If we have a root value which means we should rebuild. $out = array(); $out['root'] = $root; $out['compiled'] = $this->compileFile($root); $out['files'] = $this->allParsedFiles(); $out['updated'] = time(); return $out; } else { // No changes, pass back the structure // we were given initially. return $in; } } // parse and compile buffer // This is deprecated public function parse($str = null, $initialVariables = null) { if (is_array($str)) { $initialVariables = $str; $str = null; } $oldVars = $this->registeredVars; if ($initialVariables !== null) { $this->setVariables($initialVariables); } if ($str == null) { if (empty($this->_parseFile)) { throw new exception("nothing to parse"); } $out = $this->compileFile($this->_parseFile); } else { $out = $this->compile($str); } $this->registeredVars = $oldVars; return $out; } protected function makeParser($name) { $parser = new lessc_parser($this, $name); $parser->writeComments = $this->preserveComments; return $parser; } public function setFormatter($name) { $this->formatterName = $name; } protected function newFormatter() { $className = "lessc_formatter_lessjs"; if (!empty($this->formatterName)) { if (!is_string($this->formatterName)) return $this->formatterName; $className = "lessc_formatter_$this->formatterName"; } return new $className; } public function setPreserveComments($preserve) { $this->preserveComments = $preserve; } public function registerFunction($name, $func) { $this->libFunctions[$name] = $func; } public function unregisterFunction($name) { unset($this->libFunctions[$name]); } public function setVariables($variables) { $this->registeredVars = array_merge($this->registeredVars, $variables); } public function unsetVariable($name) { unset($this->registeredVars[$name]); } public function setImportDir($dirs) { $this->importDir = (array)$dirs; } public function addImportDir($dir) { $this->importDir = (array)$this->importDir; $this->importDir[] = $dir; } public function allParsedFiles() { return $this->allParsedFiles; } protected function addParsedFile($file) { $this->allParsedFiles[realpath($file)] = filemtime($file); } /** * Uses the current value of $this->count to show line and line number */ protected function throwError($msg = null) { if ($this->sourceLoc >= 0) { $this->sourceParser->throwError($msg, $this->sourceLoc); } throw new exception($msg); } // compile file $in to file $out if $in is newer than $out // returns true when it compiles, false otherwise public static function ccompile($in, $out, $less = null) { if ($less === null) { $less = new self; } return $less->checkedCompile($in, $out); } public static function cexecute($in, $force = false, $less = null) { if ($less === null) { $less = new self; } return $less->cachedCompile($in, $force); } static protected $cssColors = array( 'aliceblue' => '240,248,255', 'antiquewhite' => '250,235,215', 'aqua' => '0,255,255', 'aquamarine' => '127,255,212', 'azure' => '240,255,255', 'beige' => '245,245,220', 'bisque' => '255,228,196', 'black' => '0,0,0', 'blanchedalmond' => '255,235,205', 'blue' => '0,0,255', 'blueviolet' => '138,43,226', 'brown' => '165,42,42', 'burlywood' => '222,184,135', 'cadetblue' => '95,158,160', 'chartreuse' => '127,255,0', 'chocolate' => '210,105,30', 'coral' => '255,127,80', 'cornflowerblue' => '100,149,237', 'cornsilk' => '255,248,220', 'crimson' => '220,20,60', 'cyan' => '0,255,255', 'darkblue' => '0,0,139', 'darkcyan' => '0,139,139', 'darkgoldenrod' => '184,134,11', 'darkgray' => '169,169,169', 'darkgreen' => '0,100,0', 'darkgrey' => '169,169,169', 'darkkhaki' => '189,183,107', 'darkmagenta' => '139,0,139', 'darkolivegreen' => '85,107,47', 'darkorange' => '255,140,0', 'darkorchid' => '153,50,204', 'darkred' => '139,0,0', 'darksalmon' => '233,150,122', 'darkseagreen' => '143,188,143', 'darkslateblue' => '72,61,139', 'darkslategray' => '47,79,79', 'darkslategrey' => '47,79,79', 'darkturquoise' => '0,206,209', 'darkviolet' => '148,0,211', 'deeppink' => '255,20,147', 'deepskyblue' => '0,191,255', 'dimgray' => '105,105,105', 'dimgrey' => '105,105,105', 'dodgerblue' => '30,144,255', 'firebrick' => '178,34,34', 'floralwhite' => '255,250,240', 'forestgreen' => '34,139,34', 'fuchsia' => '255,0,255', 'gainsboro' => '220,220,220', 'ghostwhite' => '248,248,255', 'gold' => '255,215,0', 'goldenrod' => '218,165,32', 'gray' => '128,128,128', 'green' => '0,128,0', 'greenyellow' => '173,255,47', 'grey' => '128,128,128', 'honeydew' => '240,255,240', 'hotpink' => '255,105,180', 'indianred' => '205,92,92', 'indigo' => '75,0,130', 'ivory' => '255,255,240', 'khaki' => '240,230,140', 'lavender' => '230,230,250', 'lavenderblush' => '255,240,245', 'lawngreen' => '124,252,0', 'lemonchiffon' => '255,250,205', 'lightblue' => '173,216,230', 'lightcoral' => '240,128,128', 'lightcyan' => '224,255,255', 'lightgoldenrodyellow' => '250,250,210', 'lightgray' => '211,211,211', 'lightgreen' => '144,238,144', 'lightgrey' => '211,211,211', 'lightpink' => '255,182,193', 'lightsalmon' => '255,160,122', 'lightseagreen' => '32,178,170', 'lightskyblue' => '135,206,250', 'lightslategray' => '119,136,153', 'lightslategrey' => '119,136,153', 'lightsteelblue' => '176,196,222', 'lightyellow' => '255,255,224', 'lime' => '0,255,0', 'limegreen' => '50,205,50', 'linen' => '250,240,230', 'magenta' => '255,0,255', 'maroon' => '128,0,0', 'mediumaquamarine' => '102,205,170', 'mediumblue' => '0,0,205', 'mediumorchid' => '186,85,211', 'mediumpurple' => '147,112,219', 'mediumseagreen' => '60,179,113', 'mediumslateblue' => '123,104,238', 'mediumspringgreen' => '0,250,154', 'mediumturquoise' => '72,209,204', 'mediumvioletred' => '199,21,133', 'midnightblue' => '25,25,112', 'mintcream' => '245,255,250', 'mistyrose' => '255,228,225', 'moccasin' => '255,228,181', 'navajowhite' => '255,222,173', 'navy' => '0,0,128', 'oldlace' => '253,245,230', 'olive' => '128,128,0', 'olivedrab' => '107,142,35', 'orange' => '255,165,0', 'orangered' => '255,69,0', 'orchid' => '218,112,214', 'palegoldenrod' => '238,232,170', 'palegreen' => '152,251,152', 'paleturquoise' => '175,238,238', 'palevioletred' => '219,112,147', 'papayawhip' => '255,239,213', 'peachpuff' => '255,218,185', 'peru' => '205,133,63', 'pink' => '255,192,203', 'plum' => '221,160,221', 'powderblue' => '176,224,230', 'purple' => '128,0,128', 'red' => '255,0,0', 'rosybrown' => '188,143,143', 'royalblue' => '65,105,225', 'saddlebrown' => '139,69,19', 'salmon' => '250,128,114', 'sandybrown' => '244,164,96', 'seagreen' => '46,139,87', 'seashell' => '255,245,238', 'sienna' => '160,82,45', 'silver' => '192,192,192', 'skyblue' => '135,206,235', 'slateblue' => '106,90,205', 'slategray' => '112,128,144', 'slategrey' => '112,128,144', 'snow' => '255,250,250', 'springgreen' => '0,255,127', 'steelblue' => '70,130,180', 'tan' => '210,180,140', 'teal' => '0,128,128', 'thistle' => '216,191,216', 'tomato' => '255,99,71', 'transparent' => '0,0,0,0', 'turquoise' => '64,224,208', 'violet' => '238,130,238', 'wheat' => '245,222,179', 'white' => '255,255,255', 'whitesmoke' => '245,245,245', 'yellow' => '255,255,0', 'yellowgreen' => '154,205,50' ); } // responsible for taking a string of LESS code and converting it into a // syntax tree class lessc_parser { static protected $nextBlockId = 0; // used to uniquely identify blocks static protected $precedence = array( '=<' => 0, '>=' => 0, '=' => 0, '<' => 0, '>' => 0, '+' => 1, '-' => 1, '*' => 2, '/' => 2, '%' => 2, ); static protected $whitePattern; static protected $commentMulti; static protected $commentSingle = "//"; static protected $commentMultiLeft = "/*"; static protected $commentMultiRight = "*/"; // regex string to match any of the operators static protected $operatorString; // these properties will supress division unless it's inside parenthases static protected $supressDivisionProps = array('/border-radius$/i', '/^font$/i'); protected $blockDirectives = array("font-face", "keyframes", "page", "-moz-document"); protected $lineDirectives = array("charset"); /** * if we are in parens we can be more liberal with whitespace around * operators because it must evaluate to a single value and thus is less * ambiguous. * * Consider: * property1: 10 -5; // is two numbers, 10 and -5 * property2: (10 -5); // should evaluate to 5 */ protected $inParens = false; // caches preg escaped literals static protected $literalCache = array(); public function __construct($lessc, $sourceName = null) { $this->eatWhiteDefault = true; // reference to less needed for vPrefix, mPrefix, and parentSelector $this->lessc = $lessc; $this->sourceName = $sourceName; // name used for error messages $this->writeComments = false; if (!self::$operatorString) { self::$operatorString = '('.implode('|', array_map(array('lessc', 'preg_quote'), array_keys(self::$precedence))).')'; $commentSingle = lessc::preg_quote(self::$commentSingle); $commentMultiLeft = lessc::preg_quote(self::$commentMultiLeft); $commentMultiRight = lessc::preg_quote(self::$commentMultiRight); self::$commentMulti = $commentMultiLeft.'.*?'.$commentMultiRight; self::$whitePattern = '/'.$commentSingle.'[^\n]*\s*|('.self::$commentMulti.')\s*|\s+/Ais'; } } public function parse($buffer) { $this->count = 0; $this->line = 1; $this->env = null; // block stack $this->buffer = $this->writeComments ? $buffer : $this->removeComments($buffer); $this->pushSpecialBlock("root"); $this->eatWhiteDefault = true; $this->seenComments = array(); // trim whitespace on head // if (preg_match('/^\s+/', $this->buffer, $m)) { // $this->line += substr_count($m[0], "\n"); // $this->buffer = ltrim($this->buffer); // } $this->whitespace(); // parse the entire file $lastCount = $this->count; while (false !== $this->parseChunk()); if ($this->count != strlen($this->buffer)) $this->throwError(); // TODO report where the block was opened if (!is_null($this->env->parent)) throw new exception('parse error: unclosed block'); return $this->env; } /** * Parse a single chunk off the head of the buffer and append it to the * current parse environment. * Returns false when the buffer is empty, or when there is an error. * * This function is called repeatedly until the entire document is * parsed. * * This parser is most similar to a recursive descent parser. Single * functions represent discrete grammatical rules for the language, and * they are able to capture the text that represents those rules. * * Consider the function lessc::keyword(). (all parse functions are * structured the same) * * The function takes a single reference argument. When calling the * function it will attempt to match a keyword on the head of the buffer. * If it is successful, it will place the keyword in the referenced * argument, advance the position in the buffer, and return true. If it * fails then it won't advance the buffer and it will return false. * * All of these parse functions are powered by lessc::match(), which behaves * the same way, but takes a literal regular expression. Sometimes it is * more convenient to use match instead of creating a new function. * * Because of the format of the functions, to parse an entire string of * grammatical rules, you can chain them together using &&. * * But, if some of the rules in the chain succeed before one fails, then * the buffer position will be left at an invalid state. In order to * avoid this, lessc::seek() is used to remember and set buffer positions. * * Before parsing a chain, use $s = $this->seek() to remember the current * position into $s. Then if a chain fails, use $this->seek($s) to * go back where we started. */ protected function parseChunk() { if (empty($this->buffer)) return false; $s = $this->seek(); // setting a property if ($this->keyword($key) && $this->assign() && $this->propertyValue($value, $key) && $this->end()) { $this->append(array('assign', $key, $value), $s); return true; } else { $this->seek($s); } // look for special css blocks if ($this->literal('@', false)) { $this->count--; // media if ($this->literal('@media')) { if (($this->mediaQueryList($mediaQueries) || true) && $this->literal('{')) { $media = $this->pushSpecialBlock("media"); $media->queries = is_null($mediaQueries) ? array() : $mediaQueries; return true; } else { $this->seek($s); return false; } } if ($this->literal("@", false) && $this->keyword($dirName)) { if ($this->isDirective($dirName, $this->blockDirectives)) { if (($this->openString("{", $dirValue, null, array(";")) || true) && $this->literal("{")) { $dir = $this->pushSpecialBlock("directive"); $dir->name = $dirName; if (isset($dirValue)) $dir->value = $dirValue; return true; } } elseif ($this->isDirective($dirName, $this->lineDirectives)) { if ($this->propertyValue($dirValue) && $this->end()) { $this->append(array("directive", $dirName, $dirValue)); return true; } } } $this->seek($s); } // setting a variable if ($this->variable($var) && $this->assign() && $this->propertyValue($value) && $this->end()) { $this->append(array('assign', $var, $value), $s); return true; } else { $this->seek($s); } if ($this->import($importValue)) { $this->append($importValue, $s); return true; } // opening parametric mixin if ($this->tag($tag, true) && $this->argumentDef($args, $isVararg) && ($this->guards($guards) || true) && $this->literal('{')) { $block = $this->pushBlock($this->fixTags(array($tag))); $block->args = $args; $block->isVararg = $isVararg; if (!empty($guards)) $block->guards = $guards; return true; } else { $this->seek($s); } // opening a simple block if ($this->tags($tags) && $this->literal('{')) { $tags = $this->fixTags($tags); $this->pushBlock($tags); return true; } else { $this->seek($s); } // closing a block if ($this->literal('}', false)) { try { $block = $this->pop(); } catch (exception $e) { $this->seek($s); $this->throwError($e->getMessage()); } $hidden = false; if (is_null($block->type)) { $hidden = true; if (!isset($block->args)) { foreach ($block->tags as $tag) { if (!is_string($tag) || $tag{0} != $this->lessc->mPrefix) { $hidden = false; break; } } } foreach ($block->tags as $tag) { if (is_string($tag)) { $this->env->children[$tag][] = $block; } } } if (!$hidden) { $this->append(array('block', $block), $s); } // this is done here so comments aren't bundled into he block that // was just closed $this->whitespace(); return true; } // mixin if ($this->mixinTags($tags) && ($this->argumentValues($argv) || true) && ($this->keyword($suffix) || true) && $this->end()) { $tags = $this->fixTags($tags); $this->append(array('mixin', $tags, $argv, $suffix), $s); return true; } else { $this->seek($s); } // spare ; if ($this->literal(';')) return true; return false; // got nothing, throw error } protected function isDirective($dirname, $directives) { // TODO: cache pattern in parser $pattern = implode("|", array_map(array("lessc", "preg_quote"), $directives)); $pattern = '/^(-[a-z-]+-)?(' . $pattern . ')$/i'; return preg_match($pattern, $dirname); } protected function fixTags($tags) { // move @ tags out of variable namespace foreach ($tags as &$tag) { if ($tag{0} == $this->lessc->vPrefix) $tag[0] = $this->lessc->mPrefix; } return $tags; } // a list of expressions protected function expressionList(&$exps) { $values = array(); while ($this->expression($exp)) { $values[] = $exp; } if (count($values) == 0) return false; $exps = lessc::compressList($values, ' '); return true; } /** * Attempt to consume an expression. * @link http://en.wikipedia.org/wiki/Operator-precedence_parser#Pseudo-code */ protected function expression(&$out) { if ($this->value($lhs)) { $out = $this->expHelper($lhs, 0); // look for / shorthand if (!empty($this->env->supressedDivision)) { unset($this->env->supressedDivision); $s = $this->seek(); if ($this->literal("/") && $this->value($rhs)) { $out = array("list", "", array($out, array("keyword", "/"), $rhs)); } else { $this->seek($s); } } return true; } return false; } /** * recursively parse infix equation with $lhs at precedence $minP */ protected function expHelper($lhs, $minP) { $this->inExp = true; $ss = $this->seek(); while (true) { $whiteBefore = isset($this->buffer[$this->count - 1]) && ctype_space($this->buffer[$this->count - 1]); // If there is whitespace before the operator, then we require // whitespace after the operator for it to be an expression $needWhite = $whiteBefore && !$this->inParens; if ($this->match(self::$operatorString.($needWhite ? '\s' : ''), $m) && self::$precedence[$m[1]] >= $minP) { if (!$this->inParens && isset($this->env->currentProperty) && $m[1] == "/" && empty($this->env->supressedDivision)) { foreach (self::$supressDivisionProps as $pattern) { if (preg_match($pattern, $this->env->currentProperty)) { $this->env->supressedDivision = true; break 2; } } } $whiteAfter = isset($this->buffer[$this->count - 1]) && ctype_space($this->buffer[$this->count - 1]); if (!$this->value($rhs)) break; // peek for next operator to see what to do with rhs if ($this->peek(self::$operatorString, $next) && self::$precedence[$next[1]] > self::$precedence[$m[1]]) { $rhs = $this->expHelper($rhs, self::$precedence[$next[1]]); } $lhs = array('expression', $m[1], $lhs, $rhs, $whiteBefore, $whiteAfter); $ss = $this->seek(); continue; } break; } $this->seek($ss); return $lhs; } // consume a list of values for a property public function propertyValue(&$value, $keyName = null) { $values = array(); if ($keyName !== null) $this->env->currentProperty = $keyName; $s = null; while ($this->expressionList($v)) { $values[] = $v; $s = $this->seek(); if (!$this->literal(',')) break; } if ($s) $this->seek($s); if ($keyName !== null) unset($this->env->currentProperty); if (count($values) == 0) return false; $value = lessc::compressList($values, ', '); return true; } protected function parenValue(&$out) { $s = $this->seek(); // speed shortcut if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "(") { return false; } $inParens = $this->inParens; if ($this->literal("(") && ($this->inParens = true) && $this->expression($exp) && $this->literal(")")) { $out = $exp; $this->inParens = $inParens; return true; } else { $this->inParens = $inParens; $this->seek($s); } return false; } // a single value protected function value(&$value) { $s = $this->seek(); // speed shortcut if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "-") { // negation if ($this->literal("-", false) && (($this->variable($inner) && $inner = array("variable", $inner)) || $this->unit($inner) || $this->parenValue($inner))) { $value = array("unary", "-", $inner); return true; } else { $this->seek($s); } } if ($this->parenValue($value)) return true; if ($this->unit($value)) return true; if ($this->color($value)) return true; if ($this->func($value)) return true; if ($this->string($value)) return true; if ($this->keyword($word)) { $value = array('keyword', $word); return true; } // try a variable if ($this->variable($var)) { $value = array('variable', $var); return true; } // unquote string (should this work on any type? if ($this->literal("~") && $this->string($str)) { $value = array("escape", $str); return true; } else { $this->seek($s); } // css hack: \0 if ($this->literal('\\') && $this->match('([0-9]+)', $m)) { $value = array('keyword', '\\'.$m[1]); return true; } else { $this->seek($s); } return false; } // an import statement protected function import(&$out) { $s = $this->seek(); if (!$this->literal('@import')) return false; // @import "something.css" media; // @import url("something.css") media; // @import url(something.css) media; if ($this->propertyValue($value)) { $out = array("import", $value); return true; } } protected function mediaQueryList(&$out) { if ($this->genericList($list, "mediaQuery", ",", false)) { $out = $list[2]; return true; } return false; } protected function mediaQuery(&$out) { $s = $this->seek(); $expressions = null; $parts = array(); if (($this->literal("only") && ($only = true) || $this->literal("not") && ($not = true) || true) && $this->keyword($mediaType)) { $prop = array("mediaType"); if (isset($only)) $prop[] = "only"; if (isset($not)) $prop[] = "not"; $prop[] = $mediaType; $parts[] = $prop; } else { $this->seek($s); } if (!empty($mediaType) && !$this->literal("and")) { // ~ } else { $this->genericList($expressions, "mediaExpression", "and", false); if (is_array($expressions)) $parts = array_merge($parts, $expressions[2]); } if (count($parts) == 0) { $this->seek($s); return false; } $out = $parts; return true; } protected function mediaExpression(&$out) { $s = $this->seek(); $value = null; if ($this->literal("(") && $this->keyword($feature) && ($this->literal(":") && $this->expression($value) || true) && $this->literal(")")) { $out = array("mediaExp", $feature); if ($value) $out[] = $value; return true; } elseif ($this->variable($variable)) { $out = array('variable', $variable); return true; } $this->seek($s); return false; } // an unbounded string stopped by $end protected function openString($end, &$out, $nestingOpen=null, $rejectStrs = null) { $oldWhite = $this->eatWhiteDefault; $this->eatWhiteDefault = false; $stop = array("'", '"', "@{", $end); $stop = array_map(array("lessc", "preg_quote"), $stop); // $stop[] = self::$commentMulti; if (!is_null($rejectStrs)) { $stop = array_merge($stop, $rejectStrs); } $patt = '(.*?)('.implode("|", $stop).')'; $nestingLevel = 0; $content = array(); while ($this->match($patt, $m, false)) { if (!empty($m[1])) { $content[] = $m[1]; if ($nestingOpen) { $nestingLevel += substr_count($m[1], $nestingOpen); } } $tok = $m[2]; $this->count-= strlen($tok); if ($tok == $end) { if ($nestingLevel == 0) { break; } else { $nestingLevel--; } } if (($tok == "'" || $tok == '"') && $this->string($str)) { $content[] = $str; continue; } if ($tok == "@{" && $this->interpolation($inter)) { $content[] = $inter; continue; } if (!empty($rejectStrs) && in_array($tok, $rejectStrs)) { $ount = null; break; } $content[] = $tok; $this->count+= strlen($tok); } $this->eatWhiteDefault = $oldWhite; if (count($content) == 0) return false; // trim the end if (is_string(end($content))) { $content[count($content) - 1] = rtrim(end($content)); } $out = array("string", "", $content); return true; } protected function string(&$out) { $s = $this->seek(); if ($this->literal('"', false)) { $delim = '"'; } elseif ($this->literal("'", false)) { $delim = "'"; } else { return false; } $content = array(); // look for either ending delim , escape, or string interpolation $patt = '([^\n]*?)(@\{|\\\\|' . lessc::preg_quote($delim).')'; $oldWhite = $this->eatWhiteDefault; $this->eatWhiteDefault = false; while ($this->match($patt, $m, false)) { $content[] = $m[1]; if ($m[2] == "@{") { $this->count -= strlen($m[2]); if ($this->interpolation($inter, false)) { $content[] = $inter; } else { $this->count += strlen($m[2]); $content[] = "@{"; // ignore it } } elseif ($m[2] == '\\') { $content[] = $m[2]; if ($this->literal($delim, false)) { $content[] = $delim; } } else { $this->count -= strlen($delim); break; // delim } } $this->eatWhiteDefault = $oldWhite; if ($this->literal($delim)) { $out = array("string", $delim, $content); return true; } $this->seek($s); return false; } protected function interpolation(&$out) { $oldWhite = $this->eatWhiteDefault; $this->eatWhiteDefault = true; $s = $this->seek(); if ($this->literal("@{") && $this->openString("}", $interp, null, array("'", '"', ";")) && $this->literal("}", false)) { $out = array("interpolate", $interp); $this->eatWhiteDefault = $oldWhite; if ($this->eatWhiteDefault) $this->whitespace(); return true; } $this->eatWhiteDefault = $oldWhite; $this->seek($s); return false; } protected function unit(&$unit) { // speed shortcut if (isset($this->buffer[$this->count])) { $char = $this->buffer[$this->count]; if (!ctype_digit($char) && $char != ".") return false; } if ($this->match('([0-9]+(?:\.[0-9]*)?|\.[0-9]+)([%a-zA-Z]+)?', $m)) { $unit = array("number", $m[1], empty($m[2]) ? "" : $m[2]); return true; } return false; } // a # color protected function color(&$out) { if ($this->match('(#(?:[0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{3}))', $m)) { if (strlen($m[1]) > 7) { $out = array("string", "", array($m[1])); } else { $out = array("raw_color", $m[1]); } return true; } return false; } // consume a list of property values delimited by ; and wrapped in () protected function argumentValues(&$args, $delim = ',') { $s = $this->seek(); if (!$this->literal('(')) return false; $values = array(); while (true) { if ($this->expressionList($value)) $values[] = $value; if (!$this->literal($delim)) break; else { if ($value == null) $values[] = null; $value = null; } } if (!$this->literal(')')) { $this->seek($s); return false; } $args = $values; return true; } // consume an argument definition list surrounded by () // each argument is a variable name with optional value // or at the end a ... or a variable named followed by ... protected function argumentDef(&$args, &$isVararg, $delim = ',') { $s = $this->seek(); if (!$this->literal('(')) return false; $values = array(); $isVararg = false; while (true) { if ($this->literal("...")) { $isVararg = true; break; } if ($this->variable($vname)) { $arg = array("arg", $vname); $ss = $this->seek(); if ($this->assign() && $this->expressionList($value)) { $arg[] = $value; } else { $this->seek($ss); if ($this->literal("...")) { $arg[0] = "rest"; $isVararg = true; } } $values[] = $arg; if ($isVararg) break; continue; } if ($this->value($literal)) { $values[] = array("lit", $literal); } if (!$this->literal($delim)) break; } if (!$this->literal(')')) { $this->seek($s); return false; } $args = $values; return true; } // consume a list of tags // this accepts a hanging delimiter protected function tags(&$tags, $simple = false, $delim = ',') { $tags = array(); while ($this->tag($tt, $simple)) { $tags[] = $tt; if (!$this->literal($delim)) break; } if (count($tags) == 0) return false; return true; } // list of tags of specifying mixin path // optionally separated by > (lazy, accepts extra >) protected function mixinTags(&$tags) { $s = $this->seek(); $tags = array(); while ($this->tag($tt, true)) { $tags[] = $tt; $this->literal(">"); } if (count($tags) == 0) return false; return true; } // a bracketed value (contained within in a tag definition) protected function tagBracket(&$value) { // speed shortcut if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "[") { return false; } $s = $this->seek(); if ($this->literal('[') && $this->to(']', $c, true) && $this->literal(']', false)) { $value = '['.$c.']'; // whitespace? if ($this->whitespace()) $value .= " "; // escape parent selector, (yuck) $value = str_replace($this->lessc->parentSelector, "$&$", $value); return true; } $this->seek($s); return false; } protected function tagExpression(&$value) { $s = $this->seek(); if ($this->literal("(") && $this->expression($exp) && $this->literal(")")) { $value = array('exp', $exp); return true; } $this->seek($s); return false; } // a space separated list of selectors protected function tag(&$tag, $simple = false) { if ($simple) $chars = '^@,:;{}\][>\(\) "\''; else $chars = '^@,;{}["\''; $s = $this->seek(); if (!$simple && $this->tagExpression($tag)) { return true; } $hasExpression = false; $parts = array(); while ($this->tagBracket($first)) $parts[] = $first; $oldWhite = $this->eatWhiteDefault; $this->eatWhiteDefault = false; while (true) { if ($this->match('(['.$chars.'0-9]['.$chars.']*)', $m)) { $parts[] = $m[1]; if ($simple) break; while ($this->tagBracket($brack)) { $parts[] = $brack; } continue; } if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "@") { if ($this->interpolation($interp)) { $hasExpression = true; $interp[2] = true; // don't unescape $parts[] = $interp; continue; } if ($this->literal("@")) { $parts[] = "@"; continue; } } if ($this->unit($unit)) { // for keyframes $parts[] = $unit[1]; $parts[] = $unit[2]; continue; } break; } $this->eatWhiteDefault = $oldWhite; if (!$parts) { $this->seek($s); return false; } if ($hasExpression) { $tag = array("exp", array("string", "", $parts)); } else { $tag = trim(implode($parts)); } $this->whitespace(); return true; } // a css function protected function func(&$func) { $s = $this->seek(); if ($this->match('(%|[\w\-_][\w\-_:\.]+|[\w_])', $m) && $this->literal('(')) { $fname = $m[1]; $sPreArgs = $this->seek(); $args = array(); while (true) { $ss = $this->seek(); // this ugly nonsense is for ie filter properties if ($this->keyword($name) && $this->literal('=') && $this->expressionList($value)) { $args[] = array("string", "", array($name, "=", $value)); } else { $this->seek($ss); if ($this->expressionList($value)) { $args[] = $value; } } if (!$this->literal(',')) break; } $args = array('list', ',', $args); if ($this->literal(')')) { $func = array('function', $fname, $args); return true; } elseif ($fname == 'url') { // couldn't parse and in url? treat as string $this->seek($sPreArgs); if ($this->openString(")", $string) && $this->literal(")")) { $func = array('function', $fname, $string); return true; } } } $this->seek($s); return false; } // consume a less variable protected function variable(&$name) { $s = $this->seek(); if ($this->literal($this->lessc->vPrefix, false) && ($this->variable($sub) || $this->keyword($name))) { if (!empty($sub)) { $name = array('variable', $sub); } else { $name = $this->lessc->vPrefix.$name; } return true; } $name = null; $this->seek($s); return false; } /** * Consume an assignment operator * Can optionally take a name that will be set to the current property name */ protected function assign($name = null) { if ($name) $this->currentProperty = $name; return $this->literal(':') || $this->literal('='); } // consume a keyword protected function keyword(&$word) { if ($this->match('([\w_\-\*!"][\w\-_"]*)', $m)) { $word = $m[1]; return true; } return false; } // consume an end of statement delimiter protected function end() { if ($this->literal(';')) { return true; } elseif ($this->count == strlen($this->buffer) || $this->buffer{$this->count} == '}') { // if there is end of file or a closing block next then we don't need a ; return true; } return false; } protected function guards(&$guards) { $s = $this->seek(); if (!$this->literal("when")) { $this->seek($s); return false; } $guards = array(); while ($this->guardGroup($g)) { $guards[] = $g; if (!$this->literal(",")) break; } if (count($guards) == 0) { $guards = null; $this->seek($s); return false; } return true; } // a bunch of guards that are and'd together // TODO rename to guardGroup protected function guardGroup(&$guardGroup) { $s = $this->seek(); $guardGroup = array(); while ($this->guard($guard)) { $guardGroup[] = $guard; if (!$this->literal("and")) break; } if (count($guardGroup) == 0) { $guardGroup = null; $this->seek($s); return false; } return true; } protected function guard(&$guard) { $s = $this->seek(); $negate = $this->literal("not"); if ($this->literal("(") && $this->expression($exp) && $this->literal(")")) { $guard = $exp; if ($negate) $guard = array("negate", $guard); return true; } $this->seek($s); return false; } /* raw parsing functions */ protected function literal($what, $eatWhitespace = null) { if ($eatWhitespace === null) $eatWhitespace = $this->eatWhiteDefault; // shortcut on single letter if (!isset($what[1]) && isset($this->buffer[$this->count])) { if ($this->buffer[$this->count] == $what) { if (!$eatWhitespace) { $this->count++; return true; } // goes below... } else { return false; } } if (!isset(self::$literalCache[$what])) { self::$literalCache[$what] = lessc::preg_quote($what); } return $this->match(self::$literalCache[$what], $m, $eatWhitespace); } protected function genericList(&$out, $parseItem, $delim="", $flatten=true) { $s = $this->seek(); $items = array(); while ($this->$parseItem($value)) { $items[] = $value; if ($delim) { if (!$this->literal($delim)) break; } } if (count($items) == 0) { $this->seek($s); return false; } if ($flatten && count($items) == 1) { $out = $items[0]; } else { $out = array("list", $delim, $items); } return true; } // advance counter to next occurrence of $what // $until - don't include $what in advance // $allowNewline, if string, will be used as valid char set protected function to($what, &$out, $until = false, $allowNewline = false) { if (is_string($allowNewline)) { $validChars = $allowNewline; } else { $validChars = $allowNewline ? "." : "[^\n]"; } if (!$this->match('('.$validChars.'*?)'.lessc::preg_quote($what), $m, !$until)) return false; if ($until) $this->count -= strlen($what); // give back $what $out = $m[1]; return true; } // try to match something on head of buffer protected function match($regex, &$out, $eatWhitespace = null) { if ($eatWhitespace === null) $eatWhitespace = $this->eatWhiteDefault; $r = '/'.$regex.($eatWhitespace && !$this->writeComments ? '\s*' : '').'/Ais'; if (preg_match($r, $this->buffer, $out, null, $this->count)) { $this->count += strlen($out[0]); if ($eatWhitespace && $this->writeComments) $this->whitespace(); return true; } return false; } // match some whitespace protected function whitespace() { if ($this->writeComments) { $gotWhite = false; while (preg_match(self::$whitePattern, $this->buffer, $m, null, $this->count)) { if (isset($m[1]) && empty($this->commentsSeen[$this->count])) { $this->append(array("comment", $m[1])); $this->commentsSeen[$this->count] = true; } $this->count += strlen($m[0]); $gotWhite = true; } return $gotWhite; } else { $this->match("", $m); return strlen($m[0]) > 0; } } // match something without consuming it protected function peek($regex, &$out = null, $from=null) { if (is_null($from)) $from = $this->count; $r = '/'.$regex.'/Ais'; $result = preg_match($r, $this->buffer, $out, null, $from); return $result; } // seek to a spot in the buffer or return where we are on no argument protected function seek($where = null) { if ($where === null) return $this->count; else $this->count = $where; return true; } /* misc functions */ public function throwError($msg = "parse error", $count = null) { $count = is_null($count) ? $this->count : $count; $line = $this->line + substr_count(substr($this->buffer, 0, $count), "\n"); if (!empty($this->sourceName)) { $loc = "$this->sourceName on line $line"; } else { $loc = "line: $line"; } // TODO this depends on $this->count if ($this->peek("(.*?)(\n|$)", $m, $count)) { throw new exception("$msg: failed at `$m[1]` $loc"); } else { throw new exception("$msg: $loc"); } } protected function pushBlock($selectors=null, $type=null) { $b = new stdclass; $b->parent = $this->env; $b->type = $type; $b->id = self::$nextBlockId++; $b->isVararg = false; // TODO: kill me from here $b->tags = $selectors; $b->props = array(); $b->children = array(); $this->env = $b; return $b; } // push a block that doesn't multiply tags protected function pushSpecialBlock($type) { return $this->pushBlock(null, $type); } // append a property to the current block protected function append($prop, $pos = null) { if ($pos !== null) $prop[-1] = $pos; $this->env->props[] = $prop; } // pop something off the stack protected function pop() { $old = $this->env; $this->env = $this->env->parent; return $old; } // remove comments from $text // todo: make it work for all functions, not just url protected function removeComments($text) { $look = array( 'url(', '//', '/*', '"', "'" ); $out = ''; $min = null; while (true) { // find the next item foreach ($look as $token) { $pos = strpos($text, $token); if ($pos !== false) { if (!isset($min) || $pos < $min[1]) $min = array($token, $pos); } } if (is_null($min)) break; $count = $min[1]; $skip = 0; $newlines = 0; switch ($min[0]) { case 'url(': if (preg_match('/url\(.*?\)/', $text, $m, 0, $count)) $count += strlen($m[0]) - strlen($min[0]); break; case '"': case "'": if (preg_match('/'.$min[0].'.*?'.$min[0].'/', $text, $m, 0, $count)) $count += strlen($m[0]) - 1; break; case '//': $skip = strpos($text, "\n", $count); if ($skip === false) $skip = strlen($text) - $count; else $skip -= $count; break; case '/*': if (preg_match('/\/\*.*?\*\//s', $text, $m, 0, $count)) { $skip = strlen($m[0]); $newlines = substr_count($m[0], "\n"); } break; } if ($skip == 0) $count += strlen($min[0]); $out .= substr($text, 0, $count).str_repeat("\n", $newlines); $text = substr($text, $count + $skip); $min = null; } return $out.$text; } } class lessc_formatter_classic { public $indentChar = " "; public $break = "\n"; public $open = " {"; public $close = "}"; public $selectorSeparator = ", "; public $assignSeparator = ":"; public $openSingle = " { "; public $closeSingle = " }"; public $disableSingle = false; public $breakSelectors = false; public $compressColors = false; public function __construct() { $this->indentLevel = 0; } public function indentStr($n = 0) { return str_repeat($this->indentChar, max($this->indentLevel + $n, 0)); } public function property($name, $value) { return $name . $this->assignSeparator . $value . ";"; } protected function isEmpty($block) { if (empty($block->lines)) { foreach ($block->children as $child) { if (!$this->isEmpty($child)) return false; } return true; } return false; } public function block($block) { if ($this->isEmpty($block)) return; $inner = $pre = $this->indentStr(); $isSingle = !$this->disableSingle && is_null($block->type) && count($block->lines) == 1; if (!empty($block->selectors)) { $this->indentLevel++; if ($this->breakSelectors) { $selectorSeparator = $this->selectorSeparator . $this->break . $pre; } else { $selectorSeparator = $this->selectorSeparator; } echo $pre . implode($selectorSeparator, $block->selectors); if ($isSingle) { echo $this->openSingle; $inner = ""; } else { echo $this->open . $this->break; $inner = $this->indentStr(); } } if (!empty($block->lines)) { $glue = $this->break.$inner; echo $inner . implode($glue, $block->lines); if (!$isSingle && !empty($block->children)) { echo $this->break; } } foreach ($block->children as $child) { $this->block($child); } if (!empty($block->selectors)) { if (!$isSingle && empty($block->children)) echo $this->break; if ($isSingle) { echo $this->closeSingle . $this->break; } else { echo $pre . $this->close . $this->break; } $this->indentLevel--; } } } class lessc_formatter_compressed extends lessc_formatter_classic { public $disableSingle = true; public $open = "{"; public $selectorSeparator = ","; public $assignSeparator = ":"; public $break = ""; public $compressColors = true; public function indentStr($n = 0) { return ""; } } class lessc_formatter_lessjs extends lessc_formatter_classic { public $disableSingle = true; public $breakSelectors = true; public $assignSeparator = ": "; public $selectorSeparator = ","; } components/com_jce/classes/cssmin.php000066600000075010150771655450014020 0ustar00memory_limit = 128 * 1048576; // 128MB in bytes $this->max_execution_time = 60; // 1 min $this->pcre_backtrack_limit = 1000 * 1000; $this->pcre_recursion_limit = 500 * 1000; $this->raise_php_limits = (bool) $raise_php_limits; } /** * Minify a string of CSS * @param string $css * @param int|bool $linebreak_pos * @return string */ public function run($css = '', $linebreak_pos = FALSE) { if (empty($css)) { return ''; } if ($this->raise_php_limits) { $this->do_raise_php_limits(); } $this->comments = array(); $this->preserved_tokens = array(); $start_index = 0; $length = strlen($css); $css = $this->extract_data_urls($css); // collect all comment blocks... while (($start_index = $this->index_of($css, '/*', $start_index)) >= 0) { $end_index = $this->index_of($css, '*/', $start_index + 2); if ($end_index < 0) { $end_index = $length; } $comment_found = $this->str_slice($css, $start_index + 2, $end_index); $this->comments[] = $comment_found; $comment_preserve_string = self::COMMENT . (count($this->comments) - 1) . '___'; $css = $this->str_slice($css, 0, $start_index + 2) . $comment_preserve_string . $this->str_slice($css, $end_index); // Set correct start_index: Fixes issue #2528130 $start_index = $end_index + 2 + strlen($comment_preserve_string) - strlen($comment_found); } // preserve strings so their content doesn't get accidentally minified $css = preg_replace_callback('/(?:"(?:[^\\\\"]|\\\\.|\\\\)*")|'."(?:'(?:[^\\\\']|\\\\.|\\\\)*')/S", array($this, 'replace_string'), $css); // Let's divide css code in chunks of 5.000 chars aprox. // Reason: PHP's PCRE functions like preg_replace have a "backtrack limit" // of 100.000 chars by default (php < 5.3.7) so if we're dealing with really // long strings and a (sub)pattern matches a number of chars greater than // the backtrack limit number (i.e. /(.*)/s) PCRE functions may fail silently // returning NULL and $css would be empty. $charset = ''; $charset_regexp = '/(@charset)( [^;]+;)/i'; $css_chunks = array(); $css_chunk_length = 5000; // aprox size, not exact $start_index = 0; $i = $css_chunk_length; // save initial iterations $l = strlen($css); // if the number of characters is 25000 or less, do not chunk if ($l <= $css_chunk_length) { $css_chunks[] = $css; } else { // chunk css code securely while ($i < $l) { $i += 50; // save iterations if ($l - $start_index <= $css_chunk_length || $i >= $l) { $css_chunks[] = $this->str_slice($css, $start_index); break; } if ($css[$i - 1] === '}' && $i - $start_index > $css_chunk_length) { // If there are two ending curly braces }} separated or not by spaces, // join them in the same chunk (i.e. @media blocks) $next_chunk = substr($css, $i); if (preg_match('/^\s*\}/', $next_chunk)) { $i = $i + $this->index_of($next_chunk, '}') + 1; } $css_chunks[] = $this->str_slice($css, $start_index, $i); $start_index = $i; } } } // Minify each chunk for ($i = 0, $n = count($css_chunks); $i < $n; $i++) { $css_chunks[$i] = $this->minify($css_chunks[$i], $linebreak_pos); // Keep the first @charset at-rule found if (empty($charset) && preg_match($charset_regexp, $css_chunks[$i], $matches)) { $charset = strtolower($matches[1]) . $matches[2]; } // Delete all @charset at-rules $css_chunks[$i] = preg_replace($charset_regexp, '', $css_chunks[$i]); } // Update the first chunk and push the charset to the top of the file. $css_chunks[0] = $charset . $css_chunks[0]; return implode('', $css_chunks); } /** * Sets the memory limit for this script * @param int|string $limit */ public function set_memory_limit($limit) { $this->memory_limit = $this->normalize_int($limit); } /** * Sets the maximum execution time for this script * @param int|string $seconds */ public function set_max_execution_time($seconds) { $this->max_execution_time = (int) $seconds; } /** * Sets the PCRE backtrack limit for this script * @param int $limit */ public function set_pcre_backtrack_limit($limit) { $this->pcre_backtrack_limit = (int) $limit; } /** * Sets the PCRE recursion limit for this script * @param int $limit */ public function set_pcre_recursion_limit($limit) { $this->pcre_recursion_limit = (int) $limit; } /** * Try to configure PHP to use at least the suggested minimum settings */ private function do_raise_php_limits() { $php_limits = array( 'memory_limit' => $this->memory_limit, 'max_execution_time' => $this->max_execution_time, 'pcre.backtrack_limit' => $this->pcre_backtrack_limit, 'pcre.recursion_limit' => $this->pcre_recursion_limit ); // If current settings are higher respect them. foreach ($php_limits as $name => $suggested) { $current = $this->normalize_int(ini_get($name)); // memory_limit exception: allow -1 for "no memory limit". if ($current > -1 && ($suggested == -1 || $current < $suggested)) { ini_set($name, $suggested); } } } /** * Does bulk of the minification * @param string $css * @param int|bool $linebreak_pos * @return string */ private function minify($css, $linebreak_pos) { // strings are safe, now wrestle the comments for ($i = 0, $max = count($this->comments); $i < $max; $i++) { $token = $this->comments[$i]; $placeholder = '/' . self::COMMENT . $i . '___/'; // ! in the first position of the comment means preserve // so push to the preserved tokens keeping the ! if (substr($token, 0, 1) === '!') { $this->preserved_tokens[] = $token; $token_tring = self::TOKEN . (count($this->preserved_tokens) - 1) . '___'; $css = preg_replace($placeholder, $token_tring, $css, 1); // Preserve new lines for /*! important comments $css = preg_replace('/\s*[\n\r\f]+\s*(\/\*'. $token_tring .')/S', self::NL.'$1', $css); $css = preg_replace('/('. $token_tring .'\*\/)\s*[\n\r\f]+\s*/', '$1'.self::NL, $css); continue; } // \ in the last position looks like hack for Mac/IE5 // shorten that to /*\*/ and the next one to /**/ if (substr($token, (strlen($token) - 1), 1) === '\\') { $this->preserved_tokens[] = '\\'; $css = preg_replace($placeholder, self::TOKEN . (count($this->preserved_tokens) - 1) . '___', $css, 1); $i = $i + 1; // attn: advancing the loop $this->preserved_tokens[] = ''; $css = preg_replace('/' . self::COMMENT . $i . '___/', self::TOKEN . (count($this->preserved_tokens) - 1) . '___', $css, 1); continue; } // keep empty comments after child selectors (IE7 hack) // e.g. html >/**/ body if (strlen($token) === 0) { $start_index = $this->index_of($css, $this->str_slice($placeholder, 1, -1)); if ($start_index > 2) { if (substr($css, $start_index - 3, 1) === '>') { $this->preserved_tokens[] = ''; $css = preg_replace($placeholder, self::TOKEN . (count($this->preserved_tokens) - 1) . '___', $css, 1); } } } // in all other cases kill the comment $css = preg_replace('/\/\*' . $this->str_slice($placeholder, 1, -1) . '\*\//', '', $css, 1); } // Normalize all whitespace strings to single spaces. Easier to work with that way. $css = preg_replace('/\s+/', ' ', $css); // Fix IE7 issue on matrix filters which browser accept whitespaces between Matrix parameters $css = preg_replace_callback('/\s*filter\:\s*progid:DXImageTransform\.Microsoft\.Matrix\(([^\)]+)\)/', array($this, 'preserve_old_IE_specific_matrix_definition'), $css); // Shorten & preserve calculations calc(...) since spaces are important $css = preg_replace_callback('/calc(\(((?:[^\(\)]+|(?1))*)\))/i', array($this, 'replace_calc'), $css); // Replace positive sign from numbers preceded by : or a white-space before the leading space is removed // +1.2em to 1.2em, +.8px to .8px, +2% to 2% $css = preg_replace('/((? -9.0 to -9 $css = preg_replace('/((?\+\(\)\]\~\=,])/', '$1', $css); // Restore spaces for !important $css = preg_replace('/\!important/i', ' !important', $css); // bring back the colon $css = preg_replace('/' . self::CLASSCOLON . '/', ':', $css); // retain space for special IE6 cases $css = preg_replace_callback('/\:first\-(line|letter)(\{|,)/i', array($this, 'lowercase_pseudo_first'), $css); // no space after the end of a preserved comment $css = preg_replace('/\*\/ /', '*/', $css); // lowercase some popular @directives $css = preg_replace_callback('/@(font-face|import|(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?keyframe|media|page|namespace)/i', array($this, 'lowercase_directives'), $css); // lowercase some more common pseudo-elements $css = preg_replace_callback('/:(active|after|before|checked|disabled|empty|enabled|first-(?:child|of-type)|focus|hover|last-(?:child|of-type)|link|only-(?:child|of-type)|root|:selection|target|visited)/i', array($this, 'lowercase_pseudo_elements'), $css); // lowercase some more common functions $css = preg_replace_callback('/:(lang|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|(?:-(?:moz|webkit)-)?any)\(/i', array($this, 'lowercase_common_functions'), $css); // lower case some common function that can be values // NOTE: rgb() isn't useful as we replace with #hex later, as well as and() is already done for us $css = preg_replace_callback('/([:,\( ]\s*)(attr|color-stop|from|rgba|to|url|(?:-(?:atsc|khtml|moz|ms|o|wap|webkit)-)?(?:calc|max|min|(?:repeating-)?(?:linear|radial)-gradient)|-webkit-gradient)/iS', array($this, 'lowercase_common_functions_values'), $css); // Put the space back in some cases, to support stuff like // @media screen and (-webkit-min-device-pixel-ratio:0){ $css = preg_replace('/\band\(/i', 'and (', $css); // Remove the spaces after the things that should not have spaces after them. $css = preg_replace('/([\!\{\}\:;\>\+\(\[\~\=,])\s+/S', '$1', $css); // remove unnecessary semicolons $css = preg_replace('/;+\}/', '}', $css); // Fix for issue: #2528146 // Restore semicolon if the last property is prefixed with a `*` (lte IE7 hack) // to avoid issues on Symbian S60 3.x browsers. $css = preg_replace('/(\*[a-z0-9\-]+\s*\:[^;\}]+)(\})/', '$1;$2', $css); // Replace 0 length units 0(px,em,%) with 0. $css = preg_replace('/(^|[^0-9])(?:0?\.)?0(?:em|ex|ch|rem|vw|vh|vm|vmin|cm|mm|in|px|pt|pc|%|deg|g?rad|m?s|k?hz)/iS', '${1}0', $css); // 0% step in a keyframe? restore the % unit $css = preg_replace_callback('/(@[a-z\-]*?keyframes[^\{]*?\{)(.*?\}\s*\})/iS', array($this, 'replace_keyframe_zero'), $css); // Replace 0 0; or 0 0 0; or 0 0 0 0; with 0. $css = preg_replace('/\:0(?: 0){1,3}(;|\}| \!)/', ':0$1', $css); // Fix for issue: #2528142 // Replace text-shadow:0; with text-shadow:0 0 0; $css = preg_replace('/(text-shadow\:0)(;|\}| \!)/i', '$1 0 0$2', $css); // Replace background-position:0; with background-position:0 0; // same for transform-origin // Changing -webkit-mask-position: 0 0 to just a single 0 will result in the second parameter defaulting to 50% (center) $css = preg_replace('/(background\-position|webkit-mask-position|(?:webkit|moz|o|ms|)\-?transform\-origin)\:0(;|\}| \!)/iS', '$1:0 0$2', $css); // Shorten colors from rgb(51,102,153) to #336699, rgb(100%,0%,0%) to #ff0000 (sRGB color space) // Shorten colors from hsl(0, 100%, 50%) to #ff0000 (sRGB color space) // This makes it more likely that it'll get further compressed in the next step. $css = preg_replace_callback('/rgb\s*\(\s*([0-9,\s\-\.\%]+)\s*\)(.{1})/i', array($this, 'rgb_to_hex'), $css); $css = preg_replace_callback('/hsl\s*\(\s*([0-9,\s\-\.\%]+)\s*\)(.{1})/i', array($this, 'hsl_to_hex'), $css); // Shorten colors from #AABBCC to #ABC or short color name. $css = $this->compress_hex_colors($css); // border: none to border:0, outline: none to outline:0 $css = preg_replace('/(border\-?(?:top|right|bottom|left|)|outline)\:none(;|\}| \!)/iS', '$1:0$2', $css); // shorter opacity IE filter $css = preg_replace('/progid\:DXImageTransform\.Microsoft\.Alpha\(Opacity\=/i', 'alpha(opacity=', $css); // Find a fraction that is used for Opera's -o-device-pixel-ratio query // Add token to add the "\" back in later $css = preg_replace('/\(([a-z\-]+):([0-9]+)\/([0-9]+)\)/i', '($1:$2'. self::QUERY_FRACTION .'$3)', $css); // Remove empty rules. $css = preg_replace('/[^\};\{\/]+\{\}/S', '', $css); // Add "/" back to fix Opera -o-device-pixel-ratio query $css = preg_replace('/'. self::QUERY_FRACTION .'/', '/', $css); // Replace multiple semi-colons in a row by a single one // See SF bug #1980989 $css = preg_replace('/;;+/', ';', $css); // Restore new lines for /*! important comments $css = preg_replace('/'. self::NL .'/', "\n", $css); // Lowercase all uppercase properties $css = preg_replace_callback('/(\{|\;)([A-Z\-]+)(\:)/', array($this, 'lowercase_properties'), $css); // Some source control tools don't like it when files containing lines longer // than, say 8000 characters, are checked in. The linebreak option is used in // that case to split long lines after a specific column. if ($linebreak_pos !== FALSE && (int) $linebreak_pos >= 0) { $linebreak_pos = (int) $linebreak_pos; $start_index = $i = 0; while ($i < strlen($css)) { $i++; if ($css[$i - 1] === '}' && $i - $start_index > $linebreak_pos) { $css = $this->str_slice($css, 0, $i) . "\n" . $this->str_slice($css, $i); $start_index = $i; } } } // restore preserved comments and strings in reverse order for ($i = count($this->preserved_tokens) - 1; $i >= 0; $i--) { $css = preg_replace('/' . self::TOKEN . $i . '___/', $this->preserved_tokens[$i], $css, 1); } // Trim the final string (for any leading or trailing white spaces) return trim($css); } /** * Utility method to replace all data urls with tokens before we start * compressing, to avoid performance issues running some of the subsequent * regexes against large strings chunks. * * @param string $css * @return string */ private function extract_data_urls($css) { // Leave data urls alone to increase parse performance. $max_index = strlen($css) - 1; $append_index = $index = $last_index = $offset = 0; $sb = array(); $pattern = '/url\(\s*(["\']?)data\:/i'; // Since we need to account for non-base64 data urls, we need to handle // ' and ) being part of the data string. Hence switching to indexOf, // to determine whether or not we have matching string terminators and // handling sb appends directly, instead of using matcher.append* methods. while (preg_match($pattern, $css, $m, 0, $offset)) { $index = $this->index_of($css, $m[0], $offset); $last_index = $index + strlen($m[0]); $start_index = $index + 4; // "url(".length() $end_index = $last_index - 1; $terminator = $m[1]; // ', " or empty (not quoted) $found_terminator = FALSE; if (strlen($terminator) === 0) { $terminator = ')'; } while ($found_terminator === FALSE && $end_index+1 <= $max_index) { $end_index = $this->index_of($css, $terminator, $end_index + 1); // endIndex == 0 doesn't really apply here if ($end_index > 0 && substr($css, $end_index - 1, 1) !== '\\') { $found_terminator = TRUE; if (')' != $terminator) { $end_index = $this->index_of($css, ')', $end_index); } } } // Enough searching, start moving stuff over to the buffer $sb[] = $this->str_slice($css, $append_index, $index); if ($found_terminator) { $token = $this->str_slice($css, $start_index, $end_index); $token = preg_replace('/\s+/', '', $token); $this->preserved_tokens[] = $token; $preserver = 'url(' . self::TOKEN . (count($this->preserved_tokens) - 1) . '___)'; $sb[] = $preserver; $append_index = $end_index + 1; } else { // No end terminator found, re-add the whole match. Should we throw/warn here? $sb[] = $this->str_slice($css, $index, $last_index); $append_index = $last_index; } $offset = $last_index; } $sb[] = $this->str_slice($css, $append_index); return implode('', $sb); } /** * Utility method to compress hex color values of the form #AABBCC to #ABC or short color name. * * DOES NOT compress CSS ID selectors which match the above pattern (which would break things). * e.g. #AddressForm { ... } * * DOES NOT compress IE filters, which have hex color values (which would break things). * e.g. filter: chroma(color="#FFFFFF"); * * DOES NOT compress invalid hex values. * e.g. background-color: #aabbccdd * * @param string $css * @return string */ private function compress_hex_colors($css) { // Look for hex colors inside { ... } (to avoid IDs) and which don't have a =, or a " in front of them (to avoid filters) $pattern = '/(\=\s*?["\']?)?#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])(\}|[^0-9a-f{][^{]*?\})/iS'; $_index = $index = $last_index = $offset = 0; $sb = array(); // See: http://ajaxmin.codeplex.com/wikipage?title=CSS%20Colors $short_safe = array( '#808080' => 'gray', '#008000' => 'green', '#800000' => 'maroon', '#000080' => 'navy', '#808000' => 'olive', '#ffa500' => 'orange', '#800080' => 'purple', '#c0c0c0' => 'silver', '#008080' => 'teal', '#f00' => 'red' ); while (preg_match($pattern, $css, $m, 0, $offset)) { $index = $this->index_of($css, $m[0], $offset); $last_index = $index + strlen($m[0]); $is_filter = $m[1] !== null && $m[1] !== ''; $sb[] = $this->str_slice($css, $_index, $index); if ($is_filter) { // Restore, maintain case, otherwise filter will break $sb[] = $m[1] . '#' . $m[2] . $m[3] . $m[4] . $m[5] . $m[6] . $m[7]; } else { if (strtolower($m[2]) == strtolower($m[3]) && strtolower($m[4]) == strtolower($m[5]) && strtolower($m[6]) == strtolower($m[7])) { // Compress. $hex = '#' . strtolower($m[3] . $m[5] . $m[7]); } else { // Non compressible color, restore but lower case. $hex = '#' . strtolower($m[2] . $m[3] . $m[4] . $m[5] . $m[6] . $m[7]); } // replace Hex colors to short safe color names $sb[] = array_key_exists($hex, $short_safe) ? $short_safe[$hex] : $hex; } $_index = $offset = $last_index - strlen($m[8]); } $sb[] = $this->str_slice($css, $_index); return implode('', $sb); } /* CALLBACKS * --------------------------------------------------------------------------------------------- */ private function replace_string($matches) { $match = $matches[0]; $quote = substr($match, 0, 1); // Must use addcslashes in PHP to avoid parsing of backslashes $match = addcslashes($this->str_slice($match, 1, -1), '\\'); // maybe the string contains a comment-like substring? // one, maybe more? put'em back then if (($pos = $this->index_of($match, self::COMMENT)) >= 0) { for ($i = 0, $max = count($this->comments); $i < $max; $i++) { $match = preg_replace('/' . self::COMMENT . $i . '___/', $this->comments[$i], $match, 1); } } // minify alpha opacity in filter strings $match = preg_replace('/progid\:DXImageTransform\.Microsoft\.Alpha\(Opacity\=/i', 'alpha(opacity=', $match); $this->preserved_tokens[] = $match; return $quote . self::TOKEN . (count($this->preserved_tokens) - 1) . '___' . $quote; } private function replace_colon($matches) { return preg_replace('/\:/', self::CLASSCOLON, $matches[0]); } private function replace_calc($matches) { $this->preserved_tokens[] = trim(preg_replace('/\s*([\*\/\(\),])\s*/', '$1', $matches[2])); return 'calc('. self::TOKEN . (count($this->preserved_tokens) - 1) . '___' . ')'; } private function preserve_old_IE_specific_matrix_definition($matches) { $this->preserved_tokens[] = $matches[1]; return 'filter:progid:DXImageTransform.Microsoft.Matrix(' . self::TOKEN . (count($this->preserved_tokens) - 1) . '___' . ')'; } private function replace_keyframe_zero($matches) { return $matches[1] . preg_replace('/0\s*,/', '0%,', preg_replace('/\s*0\s*\{/', '0%{', $matches[2])); } private function rgb_to_hex($matches) { // Support for percentage values rgb(100%, 0%, 45%); if ($this->index_of($matches[1], '%') >= 0){ $rgbcolors = explode(',', str_replace('%', '', $matches[1])); for ($i = 0; $i < count($rgbcolors); $i++) { $rgbcolors[$i] = $this->round_number(floatval($rgbcolors[$i]) * 2.55); } } else { $rgbcolors = explode(',', $matches[1]); } // Values outside the sRGB color space should be clipped (0-255) for ($i = 0; $i < count($rgbcolors); $i++) { $rgbcolors[$i] = $this->clamp_number(intval($rgbcolors[$i], 10), 0, 255); $rgbcolors[$i] = sprintf("%02x", $rgbcolors[$i]); } // Fix for issue #2528093 if (!preg_match('/[\s\,\);\}]/', $matches[2])){ $matches[2] = ' ' . $matches[2]; } return '#' . implode('', $rgbcolors) . $matches[2]; } private function hsl_to_hex($matches) { $values = explode(',', str_replace('%', '', $matches[1])); $h = floatval($values[0]); $s = floatval($values[1]); $l = floatval($values[2]); // Wrap and clamp, then fraction! $h = ((($h % 360) + 360) % 360) / 360; $s = $this->clamp_number($s, 0, 100) / 100; $l = $this->clamp_number($l, 0, 100) / 100; if ($s == 0) { $r = $g = $b = $this->round_number(255 * $l); } else { $v2 = $l < 0.5 ? $l * (1 + $s) : ($l + $s) - ($s * $l); $v1 = (2 * $l) - $v2; $r = $this->round_number(255 * $this->hue_to_rgb($v1, $v2, $h + (1/3))); $g = $this->round_number(255 * $this->hue_to_rgb($v1, $v2, $h)); $b = $this->round_number(255 * $this->hue_to_rgb($v1, $v2, $h - (1/3))); } return $this->rgb_to_hex(array('', $r.','.$g.','.$b, $matches[2])); } private function lowercase_pseudo_first($matches) { return ':first-'. strtolower($matches[1]) .' '. $matches[2]; } private function lowercase_directives($matches) { return '@'. strtolower($matches[1]); } private function lowercase_pseudo_elements($matches) { return ':'. strtolower($matches[1]); } private function lowercase_common_functions($matches) { return ':'. strtolower($matches[1]) .'('; } private function lowercase_common_functions_values($matches) { return $matches[1] . strtolower($matches[2]); } private function lowercase_properties($matches) { return $matches[1].strtolower($matches[2]).$matches[3]; } /* HELPERS * --------------------------------------------------------------------------------------------- */ private function hue_to_rgb($v1, $v2, $vh) { $vh = $vh < 0 ? $vh + 1 : ($vh > 1 ? $vh - 1 : $vh); if ($vh * 6 < 1) return $v1 + ($v2 - $v1) * 6 * $vh; if ($vh * 2 < 1) return $v2; if ($vh * 3 < 2) return $v1 + ($v2 - $v1) * ((2/3) - $vh) * 6; return $v1; } private function round_number($n) { return intval(floor(floatval($n) + 0.5), 10); } private function clamp_number($n, $min, $max) { return min(max($n, $min), $max); } /** * PHP port of Javascript's "indexOf" function for strings only * Author: Tubal Martin http://blog.margenn.com * * @param string $haystack * @param string $needle * @param int $offset index (optional) * @return int */ private function index_of($haystack, $needle, $offset = 0) { $index = strpos($haystack, $needle, $offset); return ($index !== FALSE) ? $index : -1; } /** * PHP port of Javascript's "slice" function for strings only * Author: Tubal Martin http://blog.margenn.com * Tests: http://margenn.com/tubal/str_slice/ * * @param string $str * @param int $start index * @param int|bool $end index (optional) * @return string */ private function str_slice($str, $start = 0, $end = FALSE) { if ($end !== FALSE && ($start < 0 || $end <= 0)) { $max = strlen($str); if ($start < 0) { if (($start = $max + $start) < 0) { return ''; } } if ($end < 0) { if (($end = $max + $end) < 0) { return ''; } } if ($end <= $start) { return ''; } } $slice = ($end === FALSE) ? substr($str, $start) : substr($str, $start, $end - $start); return ($slice === FALSE) ? '' : $slice; } /** * Convert strings like "64M" or "30" to int values * @param mixed $size * @return int */ private function normalize_int($size) { if (is_string($size)) { switch (substr($size, -1)) { case 'M': case 'm': return $size * 1048576; case 'K': case 'k': return $size * 1024; case 'G': case 'g': return $size * 1073741824; } } return (int) $size; } }components/com_jce/classes/encrypt.php000066600000045427150771655450014221 0ustar00 6 && $i%$Nk == 4) { $temp = self::SubWord($temp); } for ($t=0; $t<4; $t++) $w[$i][$t] = $w[$i-$Nk][$t] ^ $temp[$t]; } return $w; } protected static function SubWord($w) { // apply SBox to 4-byte word w for ($i=0; $i<4; $i++) $w[$i] = self::$Sbox[$w[$i]]; return $w; } protected static function RotWord($w) { // rotate 4-byte word w left by one byte $tmp = $w[0]; for ($i=0; $i<3; $i++) $w[$i] = $w[$i+1]; $w[3] = $tmp; return $w; } /* * Unsigned right shift function, since PHP has neither >>> operator nor unsigned ints * * @param a number to be shifted (32-bit integer) * @param b number of bits to shift a to the right (0..31) * @return a right-shifted and zero-filled by b bits */ protected static function urs($a, $b) { $a &= 0xffffffff; $b &= 0x1f; // (bounds check) if ($a&0x80000000 && $b>0) { // if left-most bit set $a = ($a>>1) & 0x7fffffff; // right-shift one bit & clear left-most bit $a = $a >> ($b-1); // remaining right-shifts } else { // otherwise $a = ($a>>$b); // use normal right-shift } return $a; } /** * Encrypt a text using AES encryption in Counter mode of operation * - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf * * Unicode multi-byte character safe * * @param plaintext source text to be encrypted * @param password the password to use to generate a key * @param nBits number of bits to be used in the key (128, 192, or 256) * @return encrypted text */ public static function AESEncryptCtr($plaintext, $password, $nBits) { $blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES if (!($nBits==128 || $nBits==192 || $nBits==256)) return ''; // standard allows 128/192/256 bit keys // note PHP (5) gives us plaintext and password in UTF8 encoding! // use AES itself to encrypt password to get cipher key (using plain password as source for // key expansion) - gives us well encrypted key $nBytes = $nBits/8; // no bytes in key $pwBytes = array(); for ($i=0; $i<$nBytes; $i++) $pwBytes[$i] = ord(substr($password,$i,1)) & 0xff; $key = self::Cipher($pwBytes, self::KeyExpansion($pwBytes)); $key = array_merge($key, array_slice($key, 0, $nBytes-16)); // expand key to 16/24/32 bytes long // initialise counter block (NIST SP800-38A �B.2): millisecond time-stamp for nonce in // 1st 8 bytes, block counter in 2nd 8 bytes $counterBlock = array(); $nonce = floor(microtime(true)*1000); // timestamp: milliseconds since 1-Jan-1970 $nonceSec = floor($nonce/1000); $nonceMs = $nonce%1000; // encode nonce with seconds in 1st 4 bytes, and (repeated) ms part filling 2nd 4 bytes for ($i=0; $i<4; $i++) $counterBlock[$i] = self::urs($nonceSec, $i*8) & 0xff; for ($i=0; $i<4; $i++) $counterBlock[$i+4] = $nonceMs & 0xff; // and convert it to a string to go on the front of the ciphertext $ctrTxt = ''; for ($i=0; $i<8; $i++) $ctrTxt .= chr($counterBlock[$i]); // generate key schedule - an expansion of the key into distinct Key Rounds for each round $keySchedule = self::KeyExpansion($key); $blockCount = ceil(strlen($plaintext)/$blockSize); $ciphertxt = array(); // ciphertext as array of strings for ($b=0; $b<$blockCount; $b++) { // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes) // done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB) for ($c=0; $c<4; $c++) $counterBlock[15-$c] = self::urs($b, $c*8) & 0xff; for ($c=0; $c<4; $c++) $counterBlock[15-$c-4] = self::urs($b/0x100000000, $c*8); $cipherCntr = self::Cipher($counterBlock, $keySchedule); // -- encrypt counter block -- // block size is reduced on final block $blockLength = $b<$blockCount-1 ? $blockSize : (strlen($plaintext)-1)%$blockSize+1; $cipherByte = array(); for ($i=0; $i<$blockLength; $i++) { // -- xor plaintext with ciphered counter byte-by-byte -- $cipherByte[$i] = $cipherCntr[$i] ^ ord(substr($plaintext, $b*$blockSize+$i, 1)); $cipherByte[$i] = chr($cipherByte[$i]); } $ciphertxt[$b] = implode('', $cipherByte); // escape troublesome characters in ciphertext } // implode is more efficient than repeated string concatenation $ciphertext = $ctrTxt . implode('', $ciphertxt); $ciphertext = base64_encode($ciphertext); return $ciphertext; } /** * Decrypt a text encrypted by AES in counter mode of operation * * @param ciphertext source text to be decrypted * @param password the password to use to generate a key * @param nBits number of bits to be used in the key (128, 192, or 256) * @return decrypted text */ public static function AESDecryptCtr($ciphertext, $password, $nBits) { $blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES if (!($nBits==128 || $nBits==192 || $nBits==256)) return ''; // standard allows 128/192/256 bit keys $ciphertext = base64_decode($ciphertext); // use AES to encrypt password (mirroring encrypt routine) $nBytes = $nBits/8; // no bytes in key $pwBytes = array(); for ($i=0; $i<$nBytes; $i++) $pwBytes[$i] = ord(substr($password,$i,1)) & 0xff; $key = self::Cipher($pwBytes, self::KeyExpansion($pwBytes)); $key = array_merge($key, array_slice($key, 0, $nBytes-16)); // expand key to 16/24/32 bytes long // recover nonce from 1st element of ciphertext $counterBlock = array(); $ctrTxt = substr($ciphertext, 0, 8); for ($i=0; $i<8; $i++) $counterBlock[$i] = ord(substr($ctrTxt,$i,1)); // generate key schedule $keySchedule = self::KeyExpansion($key); // separate ciphertext into blocks (skipping past initial 8 bytes) $nBlocks = ceil((strlen($ciphertext)-8) / $blockSize); $ct = array(); for ($b=0; $b<$nBlocks; $b++) $ct[$b] = substr($ciphertext, 8+$b*$blockSize, 16); $ciphertext = $ct; // ciphertext is now array of block-length strings // plaintext will get generated block-by-block into array of block-length strings $plaintxt = array(); for ($b=0; $b<$nBlocks; $b++) { // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes) for ($c=0; $c<4; $c++) $counterBlock[15-$c] = self::urs($b, $c*8) & 0xff; for ($c=0; $c<4; $c++) $counterBlock[15-$c-4] = self::urs(($b+1)/0x100000000-1, $c*8) & 0xff; $cipherCntr = self::Cipher($counterBlock, $keySchedule); // encrypt counter block $plaintxtByte = array(); for ($i=0; $i $data_size) { $plaintext = substr($plaintext, 0, $data_size); } return $plaintext; } }components/com_jce/controller/cpanel.php000066600000001347150771655450014516 0ustar00getModel('cpanel'); $feeds = $model->getFeeds(); exit(json_encode(array('feeds' => $feeds))); } } ?>components/com_jce/controller/index.html000066600000000054150771655450014532 0ustar00components/com_jce/controller/help.php000066600000001262150771655450014200 0ustar00components/com_jce/controller/installer.php000066600000005234150771655450015250 0ustar00registerTask('disable', 'enable'); $language = JFactory::getLanguage(); $language->load('com_installer', JPATH_ADMINISTRATOR); } /** * Install an extension * * @access public * @return void * @since 1.5 */ function install() { // Check for request forgeries JRequest::checkToken() or jexit('RESTRICTED'); $model = $this->getModel('installer'); if ($model->install()) { $cache = JFactory::getCache('mod_menu'); $cache->clean(); } $view = $this->getView(); $view->setModel($model, true); $view->display(); } /** * Remove (uninstall) an extension * * @static * @param array An array of identifiers * @return boolean True on success * @since 1.0 */ function remove() { // Check for request forgeries JRequest::checkToken() or jexit('RESTRICTED'); $model = $this->getModel('installer'); $items = array( 'plugin' => JRequest::getVar('pid', array(), '', 'array'), 'language' => JRequest::getVar('lid', array(), '', 'array'), 'related' => JRequest::getVar('rid', array(), '', 'array') ); // Uninstall the chosen extensions foreach ($items as $type => $ids) { if (count($ids)) { foreach ($ids as $id) { if ($id) { if ($model->remove($id, $type)) { $cache = JFactory::getCache('mod_menu'); $cache->clean(); } } } } } $view = $this->getView(); $view->setModel($model, true); $view->display(); } } ?>components/com_jce/controller/editor.php000066600000004746150771655450014550 0ustar00load('com_jce', JPATH_ADMINISTRATOR); $layout = JRequest::getCmd('layout'); $plugin = JRequest::getCmd('plugin'); if ($layout) { switch ($layout) { case 'editor': if ($task == 'pack' || $task == 'loadlanguages' || $task == 'compileless') { wfimport('admin.models.editor'); $model = new WFModelEditor(); switch($task) { case 'loadlanguages': $model->loadLanguages(); break; case 'pack': $model->pack(); break; case 'compileless': $model->compileLess(); break; } exit(); } break; case 'plugin': $file = basename(JRequest::getCmd('file', $plugin)); $path = WF_EDITOR_PLUGINS . '/' . $plugin; if (is_dir($path) && file_exists($path . '/' . $file . '.php')) { include_once($path . '/' . $file . '.php'); } else { throw new InvalidArgumentException('File ' . $file . ' not found!'); } break; } exit(); } else { throw new InvalidArgumentException('No Layout'); } } } ?>components/com_jce/controller/profiles.php000066600000040431150771655450015074 0ustar00registerTask('apply', 'save'); $this->registerTask('unpublish', 'publish'); $this->registerTask('enable', 'publish'); $this->registerTask('disable', 'publish'); $this->registerTask('orderup', 'order'); $this->registerTask('orderdown', 'order'); } public function remove() { // Check for request forgeries JRequest::checkToken() or die('RESTRICTED'); $db = JFactory::getDBO(); $user = JFactory::getUser(); $cid = JRequest::getVar('cid', array(0), 'post', 'array'); JArrayHelper::toInteger($cid, array(0)); if (count($cid) < 1) { JError::raiseError(500, WFText::_('WF_PROFILES_SELECT_ERROR')); } $cids = implode(',', $cid); $query = 'DELETE FROM #__wf_profiles' . ' WHERE id IN ( ' . $cids . ' )' ; $db->setQuery($query); if (!$db->query()) { JError::raiseError(500, $db->getErrorMsg()); } $msg = JText::sprintf('WF_PROFILES_DELETED', count($cid)); $this->setRedirect('index.php?option=com_jce&view=profiles', $msg); } public function copy() { // Check for request forgeries JRequest::checkToken() or die('RESTRICTED'); $db = JFactory::getDBO(); $user = JFactory::getUser(); $cid = JRequest::getVar('cid', array(0), 'post', 'array'); JArrayHelper::toInteger($cid, array(0)); $n = count($cid); if ($n == 0) { return JError::raiseWarning(500, WFText::_('WF_PROFILES_SELECT_ERROR')); } $row = JTable::getInstance('profiles', 'WFTable'); foreach ($cid as $id) { // load the row from the db table $row->load((int) $id); $row->name = JText::sprintf('WF_PROFILES_COPY_OF', $row->name); $row->id = 0; $row->published = 0; if (!$row->check()) { return JError::raiseWarning(500, $row->getError()); } if (!$row->store()) { return JError::raiseWarning(500, $row->getError()); } $row->checkin(); $row->reorder('ordering=' . $db->Quote($row->ordering)); } $msg = JText::sprintf('WF_PROFILES_COPIED', $n); $this->setRedirect('index.php?option=com_jce&view=profiles', $msg); } public function save() { // Check for request forgeries JRequest::checkToken() or die('RESTRICTED'); $db = JFactory::getDBO(); $filter = JFilterInput::getInstance(); $row = JTable::getInstance('profiles', 'WFTable'); $task = $this->getTask(); $post = JRequest::get('post', array()); $id = JRequest::getInt('id'); $result = array('error' => false); // load existing profile $row->load($id); // bind data but ignore params and usergroups $row->bind($post, array('params', 'usergroups')); // process values foreach ($post as $key => $value) { // don't process null values if (is_null($value)) { continue; } switch ($key) { case 'name': case 'description': $value = $filter->clean($value); break; case 'components': case 'device': $value = array_filter($value); $value = implode(',', $this->cleanInput($value)); break; case 'usergroups': $key = 'types'; $value = implode(',', $this->cleanInput($value, 'int')); break; case 'users': $value = implode(',', $this->cleanInput($value, 'int')); break; case 'area': if (empty($value) || count($value) == 2) { $value = 0; } else { $value = $value[0]; } break; case 'plugins': $value = preg_replace('#[^\w,]+#', '', $value); break; case 'rows': $value = preg_replace('#[^\w,;]+#', '', $value); break; case 'params': $json = array(); // get params $params = isset($row->params) ? $row->params : ''; // convert params to json data array $data = (array) json_decode($params, true); // assign editor data if (array_key_exists('editor', $value)) { $json['editor'] = $value['editor']; } // get plugins $plugins = explode(',', $row->plugins); // assign plugin data foreach ($plugins as $plugin) { // add plugin params to array if (array_key_exists($plugin, $value)) { $json[$plugin] = $value[$plugin]; } } // combine and encode as json string $value = json_encode(WFParameter::mergeParams($data, $json, false)); break; } $row->bind(array($key => $value)); } if (!$row->check()) { JError::raiseError(500, $db->getErrorMsg()); } if (!$row->store()) { JError::raiseError(500, $db->getErrorMsg()); } $row->checkin(); switch ($task) { case 'apply': $msg = JText::sprintf('WF_PROFILES_SAVED_CHANGES', $row->name); $this->setRedirect('index.php?option=com_jce&view=profiles&task=edit&cid[]=' . $row->id, $msg); break; case 'save': default: $msg = JText::sprintf('WF_PROFILES_SAVED', $row->name); $this->setRedirect('index.php?option=com_jce&view=profiles', $msg); break; } } /** * Generic publish method * @return */ public function publish() { // Check for request forgeries JRequest::checkToken() or die('Invalid Token'); $db = JFactory::getDBO(); $user = JFactory::getUser(); $cid = JRequest::getVar('cid', array(0), 'post', 'array'); JArrayHelper::toInteger($cid, array(0)); switch ($this->getTask()) { case 'publish': case 'enable': $publish = 1; break; case 'unpublish': case 'disable': $publish = 0; break; } $view = JRequest::getCmd('view'); if (count($cid) < 1) { $action = $publish ? WFText::_('WF_LABEL_PUBLISH') : WFText::_('WF_LABEL_UNPUBLISH'); JError::raiseError(500, JText::sprintf('WF_PROFILES_VIEW_SELECT', $view, $action)); } $cids = implode(',', $cid); $query = 'UPDATE #__wf_profiles SET published = ' . (int) $publish . ' WHERE id IN ( ' . $cids . ' )' . ' AND ( checked_out = 0 OR ( checked_out = ' . (int) $user->get('id') . ' ))' ; $db->setQuery($query); if (!$db->query()) { JError::raiseError(500, $db->getErrorMsg()); } if (count($cid) == 1) { $row = JTable::getInstance('profiles', 'WFTable'); $row->checkin($cid[0]); } $this->setRedirect('index.php?option=com_jce&view=profiles'); } public function order() { // Check for request forgeries JRequest::checkToken() or jexit('Invalid Token'); $db = JFactory::getDBO(); $cid = JRequest::getVar('cid', array(0), 'post', 'array'); JArrayHelper::toInteger($cid, array(0)); $uid = $cid[0]; $inc = ( $this->getTask() == 'orderup' ? -1 : 1 ); $row = JTable::getInstance('profiles', 'WFTable'); $row->load($uid); $row->move($inc); $this->setRedirect('index.php?option=com_jce&view=profiles'); } public function saveorder() { // Check for request forgeries JRequest::checkToken() or jexit('RESTRICTED'); $cid = JRequest::getVar('cid', array(0), 'post', 'array'); $order = JRequest::getVar('order', array(0), 'post', 'array'); if (!empty($cid)) { $model = $this->getModel('profiles', 'WFModel'); $result = $model->saveOrder($cid, $order); } // ajax request if (JRequest::getWord('tmpl') === 'component') { echo (int) $result; JFactory::getApplication()->close(); } $msg = WFText::_('WF_PROFILES_ORDERING_SAVED'); $this->setRedirect('index.php?option=com_jce&view=profiles', $msg); } public function cancelEdit() { // Check for request forgeries JRequest::checkToken() or die('RESTRICTED'); $view = JRequest::getCmd('view'); $db = JFactory::getDBO(); $row = JTable::getInstance($view, 'WFTable'); $row->bind(JRequest::get('post')); $row->checkin(); $this->setRedirect(JRoute::_('index.php?option=com_jce&view=' . $view, false)); } public function export() { wfimport('admin.helpers.encrypt'); $mainframe = JFactory::getApplication(); $db = JFactory::getDBO(); $tmp = $mainframe->getCfg('tmp_path'); $buffer = ''; $buffer .= "\n" . ''; $buffer .= "\n\t" . ''; $cid = JRequest::getVar('cid', array(0), 'post', 'array'); JArrayHelper::toInteger($cid, array(0)); if (count($cid) < 1) { JError::raiseError(500, WFText::_('WF_PROFILES_SELECT_ERROR')); } $cids = implode(',', $cid); $query = $db->getQuery(true); // check for name if (is_object($query)) { $query->select('*')->from('#__wf_profiles')->where('id IN (' . $cids . ')'); } else { $query = 'SELECT * FROM #__wf_profiles WHERE id IN (' . $cids . ')'; } $db->setQuery($query); $profiles = $db->loadObjectList(); foreach ($profiles as $profile) { // remove some stuff unset($profile->id); unset($profile->checked_out); unset($profile->checked_out_time); // set published to 0 $profile->published = 0; $buffer .= "\n\t\t"; $buffer .= ''; foreach ($profile as $key => $value) { if ($key == 'params') { $buffer .= "\n\t\t\t" . '<' . $key . '>'; if ($value) { // decrypt if necessary $value = WFEncryptHelper::decrypt($value); // check is valid json $valid = json_decode($value, false); // json is valid if (is_null($valid) === false) { // create array $params = explode("\n", $value); foreach ($params as $param) { if ($param !== '') { $buffer .= "\n\t\t\t\t" . '' . $param . ''; } } $buffer .= "\n\t\t\t\t"; } } $buffer .= ''; } else { $buffer .= "\n\t\t\t" . '<' . $key . '>' . $this->encodeData($value) . ''; } } $buffer .= "\n\t\t"; } $buffer .= "\n\t"; $buffer .= "\n"; // set_time_limit doesn't work in safe mode if (!ini_get('safe_mode')) { @set_time_limit(0); } $name = 'jce_profile_' . date('Y_m_d') . '.xml'; header("Pragma: public"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Expires: 0"); header("Content-Transfer-Encoding: binary"); header("Content-Type: text/xml"); header('Content-Disposition: attachment;' . ' filename="' . $name . '";' ); echo $buffer; exit(); } /** * Process XML restore file * @param object $xml * @return boolean */ public function import() { // Check for request forgeries JRequest::checkToken() or die('RESTRICTED'); $app = JFactory::getApplication(); $file = JRequest::getVar('import', '', 'files', 'array'); $input = JRequest::getVar('import_input'); $tmp = $app->getCfg('tmp_path'); $model = $this->getModel('profiles', 'WFModel'); $filter = JFilterInput::getInstance(); jimport('joomla.filesystem.file'); if (!is_array($file)) { $app->enqueueMessage(WFText::_('WF_PROFILES_UPLOAD_NOFILE'), 'error'); } else { // check for valid uploaded file if (is_uploaded_file($file['tmp_name']) && $file['name']) { // create destination path $destination = $tmp . '/' . $file['name']; if (JFile::upload($file['tmp_name'], $destination)) { // check it exists, was uploaded properly if (JFile::exists($destination)) { // process import $model->processImport($destination); } else { $app->enqueueMessage(WFText::_('WF_PROFILES_UPLOAD_FAILED'), 'error'); } } else { $app->enqueueMessage(WFText::_('WF_PROFILES_UPLOAD_FAILED'), 'error'); } } else { // clean input $input = $filter->clean($input, 'path'); // check for file input value instead if ($input) { // check file exists if (JFile::exists($input)) { // process import $model->processImport($input); } else { $app->enqueueMessage(WFText::_('WF_PROFILES_IMPORT_NOFILE'), 'error'); } } else { $app->enqueueMessage(WFText::_('WF_PROFILES_UPLOAD_FAILED'), 'error'); } } } $this->setRedirect('index.php?option=com_jce&view=profiles'); } /** * CDATA encode a parameter if it contains & < > characters, eg: * @param object $param * @return CDATA encoded parameter or parameter */ private function encodeData($data) { if (preg_match('/[<>&]/', $data)) { $data = ''; } $data = preg_replace('/"/', '\"', $data); return $data; } } ?>components/com_jce/controller/config.php000066600000004165150771655450014522 0ustar00registerTask('apply', 'save'); } public function save() { // Check for request forgeries JRequest::checkToken() or die('RESTRICTED'); $db = JFactory::getDBO(); $task = $this->getTask(); // get plugin $plugin = WFExtensionHelper::getPlugin(); // get params data $data = JRequest::getVar('params', '', 'POST', 'ARRAY'); // clean input data $data = $this->cleanInput($data); // store data $plugin->params = json_encode($data); // remove "id" if (isset($plugin->extension_id)) { unset($plugin->id); } if (!$plugin->check()) { JError::raiseError(500, $plugin->getError()); } if (!$plugin->store()) { JError::raiseError(500, $plugin->getError()); } $plugin->checkin(); $msg = JText::sprintf('WF_CONFIG_SAVED'); switch ($task) { case 'apply': $this->setRedirect('index.php?option=com_jce&view=config', $msg); break; case 'save': default: $this->setRedirect('index.php?option=com_jce&view=cpanel', $msg); break; } } } ?>components/com_jce/controller/preferences.php000066600000004170150771655450015552 0ustar00registerTask('apply', 'save'); } protected function filter($data) { $model = $this->getModel('preferences'); $form = $model->getForm(); if (is_a($form, 'JForm')) { return $form->filter($data); } return $data; } public function save() { // Check for request forgeries JRequest::checkToken() or die('RESTRICTED'); $db = JFactory::getDBO(); $post = JRequest::getVar('params', '', 'POST', 'ARRAY'); $registry = new JRegistry(); $registry->loadArray($post); // get params $component = WFExtensionHelper::getComponent(); // set preferences object $preferences = $registry->toObject(); if (isset($preferences->rules)) { $preferences->access = $preferences->rules; unset($preferences->rules); } // set params as JSON string $component->params = json_encode($preferences); if (!$component->check()) { JError::raiseError(500, $row->getError()); } if (!$component->store()) { JError::raiseError(500, $row->getError()); } $component->checkin(); $close = 0; if ($this->getTask() == 'save') { $close = 1; } $this->setRedirect('index.php?option=com_jce&view=preferences&tmpl=component&close=' . $close, WFText::_('WF_PREFERENCES_SAVED')); } } ?>components/com_jce/controller/updates.php000066600000003612150771655450014716 0ustar00getModel('updates'); $result = array(); switch ($step) { case 'check': $result = $model->check(); break; case 'download': $result = $model->download(); break; case 'install': $result = $model->install(); break; } ob_start(); // set output headers header('Content-Type: text/json;charset=UTF-8'); header('Content-Encoding: UTF-8'); header("Expires: Mon, 4 April 1984 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); if (!is_string($result)) { $result = json_encode($result); } echo $result; exit(ob_get_clean()); } } ?>components/com_jce/controller/mediabox.php000066600000003460150771655450015042 0ustar00registerTask('apply', 'save'); } public function save() { // Check for request forgeries JRequest::checkToken() or die('RESTRICTED'); $row = WFExtensionHelper::getPlugin(null, 'jcemediabox', 'system'); $task = $this->getTask(); // remove id for Joomla! 2.5+ if ($row->extension_id) { unset($row->id); } if (!$row->bind(JRequest::get('post'))) { JError::raiseError(500, $row->getError()); } if (!$row->check()) { JError::raiseError(500, $row->getError()); } if (!$row->store()) { JError::raiseError(500, $row->getError()); } $row->checkin(); $msg = JText::sprintf('WF_MEDIABOX_SAVED'); switch ($task) { case 'apply': $this->setRedirect('index.php?option=com_jce&view=mediabox', $msg); break; case 'save': default: $this->setRedirect('index.php?option=com_jce&view=cpanel', $msg); break; } } } ?>components/com_jce/controller/popup.php000066600000002056150771655450014415 0ustar00addViewPath(JPATH_COMPONENT . '/views'); $view = $this->getView('popup', $document->getType()); $view->assignRef('document', $document); $view->display(); } }components/com_jce/tables/index.html000066600000000054150771655450013621 0ustar00components/com_jce/tables/profiles.php000066600000006544150771655450014172 0ustar00params)) { $this->params = WFEncryptHelper::decrypt($this->params); } return $return; } /** * Overridden JTable::store to encrypt parameters * * @param boolean $updateNulls True to update fields even if they are null. * * @return boolean True on success. * * @since 2.4 */ public function store($updateNulls = false) { if ($this->id && $this->params) { $component = WFExtensionHelper::getComponent(); // get params definitions $params = new WFParameter($component->params, '', 'preferences'); if ($params->get('secureparams', 0)) { $this->params = WFEncryptHelper::encrypt($this->params); } } return parent::store($updateNulls); } } ?>components/com_jce/views/installer/view.html.php000066600000006344150771655450016142 0ustar00getModel(); $state = $model->getState(); $layout = JRequest::getWord('layout', 'install'); $plugins = ''; $extensions = ''; $languages = ''; JHtml::_('behavior.modal'); if (WFModel::authorize('uninstall')) { WFToolbarHelper::deleteList('', 'remove', 'WF_INSTALLER_UNINSTALL'); } WFToolbarHelper::updates(WFModelUpdates::canUpdate()); WFToolbarHelper::help('installer.about'); $options = array( 'extensions' => array('zip', 'tar', 'gz', 'gzip', 'tgz', 'tbz2', 'bz2', 'bzip2'), 'width' => 300, 'button' => 'install_button', 'task' => 'install', 'iframe' => false, 'labels' => array( 'browse' => WFText::_('WF_LABEL_BROWSE'), 'alert' => WFText::_('WF_INSTALLER_FILETYPE_ERROR') ) ); $this->addScript('components/com_jce/media/js/installer.js'); $this->addScript('components/com_jce/media/js/uploads.js'); $this->addScriptDeclaration('jQuery.jce.Installer.options = ' . json_encode($options) . ';'); // load styles $this->addStyleSheet(JURI::root(true) . '/administrator/components/com_jce/media/css/installer.css'); $state->set('install.directory', $app->getCfg('tmp_path')); $plugins = $model->getPlugins(); $extensions = $model->getExtensions(); $languages = $model->getLanguages(); $related = $model->getRelated(); $this->assign('plugins', $plugins); $this->assign('extensions', $extensions); $this->assign('languages', $languages); $this->assign('related', $related); $result = $state->get('install.result'); $this->assign('showMessage', count($result)); $this->assign('model', $model); $this->assign('state', $state); $ftp = JClientHelper::setCredentialsFromRequest('ftp'); $this->assign('ftp', $ftp); $this->setLayout($layout); parent::display($tpl); } function loadItem($index = 0) { $item = $this->items[$index]; $item->index = $index; $item->cbd = null; $item->style = null; $item->author_info = @$item->authorEmail . '
    ' . @$item->authorUrl; $this->assignRef('item', $item); } }components/com_jce/views/installer/tmpl/install_languages.php000066600000003346150771655450020674 0ustar00 languages as $language) : ?> style;?>>
     
    cbd;?>/> name; ?> version != '' ? $language->version : ' '; ?> creationdate != '' ? $language->creationdate : ' '; ?> author != '' ? $language->author : ' '; ?>
    components/com_jce/views/installer/tmpl/install_ftp.php000066600000002644150771655450017517 0ustar00
    ftp)): ?>
    ftp->message); ?>
    components/com_jce/views/installer/tmpl/install_related.php000066600000003534150771655450020345 0ustar00 related as $related) : ?>
     
    name); ?> version != '' ? $related->version : ' '; ?> creationdate != '' ? $related->creationdate : ' '; ?> author != '' ? $related->author : ' '; ?>
    components/com_jce/views/installer/tmpl/index.html000066600000000054150771655450016455 0ustar00components/com_jce/views/installer/tmpl/install_uninstall.php000066600000005364150771655450020741 0ustar00

    plugins)) : ?> loadTemplate('plugins'); ?>
    extensions)) : ?> loadTemplate('extensions'); ?>
    languages)) : ?> loadTemplate('languages'); ?>
    components/com_jce/views/installer/tmpl/install_extensions.php000066600000004265150771655450021126 0ustar00 extensions as $extension) : $disabled = $extension->core ? ' disabled="disabled"' : ''; ?>
     
    /> title); ?> type) . '_TITLE'); ?> version != '' ? $extension->version : ' '; ?> creationdate != '' ? $extension->creationdate : ' '; ?> author != '' ? $extension->author : ' '; ?>
    components/com_jce/views/installer/tmpl/install_install.php000066600000001740150771655450020370 0ustar00

    components/com_jce/views/installer/tmpl/install.php000066600000003216150771655450016642 0ustar00
    showMessage) : echo $this->loadTemplate('message'); endif; ?>
    ftp) : echo $this->loadTemplate('ftp'); endif; echo $this->loadTemplate('install'); ?>
    loadTemplate('uninstall'); ?>
    components/com_jce/views/installer/tmpl/install_plugins.php000066600000003534150771655450020406 0ustar00 plugins as $plugin) : ?>
     
    title); ?> version != '' ? $plugin->version : ' '; ?> creationdate != '' ? $plugin->creationdate : ' '; ?> author != '' ? $plugin->author : ' '; ?>
    components/com_jce/views/installer/tmpl/install_message.php000066600000001571150771655450020350 0ustar00state->get('result') ? 'success' : 'error'; ?> state->get('message')) :?>

    state->get('name'); ?>

    state->get('message'); ?>

    state->get('extension.message', ''); ?>
    components/com_jce/views/installer/index.html000066600000000054150771655450015501 0ustar00components/com_jce/views/users/view.html.php000066600000016575150771655450015315 0ustar00getModel(); $this->addScript('components/com_jce/media/js/users.js'); $filter_order = $app->getUserStateFromRequest("$option.$view.filter_order", 'filter_order', 'a.name', 'cmd'); $filter_order_Dir = $app->getUserStateFromRequest("$option.$view.filter_order_Dir", 'filter_order_Dir', '', 'word'); $filter_type = $app->getUserStateFromRequest("$option.$view.filter_type", 'filter_type', '', 'int'); $search = $app->getUserStateFromRequest("$option.$view.search", 'search', '', 'cmd'); $search = JString::strtolower($search); $limit = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->getCfg('list_limit'), 'int'); $limitstart = $app->getUserStateFromRequest("$option.$view.limitstart", 'limitstart', 0, 'int'); $where = array(); if (!empty($search)) { if (defined('JPATH_PLATFORM')) { $quoted = $db->quote('%' . $search . '%', false); } else { $quoted = $db->Quote('%' . $search . '%', false); } $where[] = 'a.username LIKE ' . $quoted . ' OR a.email LIKE ' . $quoted . ' OR a.name LIKE ' . $quoted; } if (defined('JPATH_PLATFORM')) { if ($filter_type) { $where[] = 'map.group_id = LOWER(' . $db->Quote($filter_type) . ') '; } } else { if ($filter_type) { $where[] = 'a.gid =' . (int) $filter_type; } // exclude any child group id's for this user $pgids = $acl->get_group_children($currentUser->get('gid'), 'ARO', 'RECURSE'); if (is_array($pgids) && count($pgids) > 0) { JArrayHelper::toInteger($pgids); $where[] = 'a.gid NOT IN (' . implode(',', $pgids) . ')'; } // Exclude ROOT, USERS, Super Administrator, Public Frontend, Public Backend $where[] = 'a.gid NOT IN (17,28,29,30)'; } // Only unblocked users $where[] = 'a.block = 0'; $orderby = array($filter_order, $filter_order_Dir); jimport('joomla.html.pagination'); if (defined('JPATH_PLATFORM')) { $query = $db->getQuery(true); $query->select('COUNT(a.id)')->from('#__users AS a')->join('LEFT', '#__user_usergroup_map AS map ON map.user_id = a.id'); if (count($where)) { $query->where($where); } $db->setQuery($query); $total = $db->loadResult(); $pagination = new JPagination($total, $limitstart, $limit); $query = $db->getQuery(true); $query->select('a.id, a.name, a.username, g.title AS groupname'); $query->from('#__users AS a'); $query->join('LEFT', '#__user_usergroup_map AS map ON map.user_id = a.id'); $query->join('LEFT', '#__usergroups AS g ON g.id = map.group_id'); if (count($where)) { $query->where($where); } $query->group('a.id, a.name, a.username, g.title'); $query->order(trim(implode(' ', $orderby))); } else { $query = 'SELECT COUNT(a.id)' . ' FROM #__users AS a' . $where ; $db->setQuery($query); $total = $db->loadResult(); $pagination = new JPagination($total, $limitstart, $limit); $query = 'SELECT a.id, a.name, a.username, g.name AS groupname' . ' FROM #__users AS a' . ' INNER JOIN #__core_acl_aro AS aro ON aro.value = a.id' . ' INNER JOIN #__core_acl_groups_aro_map AS gm ON gm.aro_id = aro.id' . ' INNER JOIN #__core_acl_aro_groups AS g ON g.id = gm.group_id' . ( count($where) ? ' WHERE (' . implode(') AND (', $where) . ')' : '' ) . ' GROUP BY a.id, a.name, a.username, g.name' . ' ORDER BY ' . trim(implode(' ', $orderby)) ; } $db->setQuery($query, $pagination->limitstart, $pagination->limit); $rows = $db->loadObjectList(); $options = array( JHTML::_('select.option', '', '- ' . WFText::_('WF_USERS_GROUP_SELECT') . ' -') ); if (defined('JPATH_PLATFORM')) { $query = $db->getQuery(true); $query->select('a.id AS value, a.title AS text')->from('#__usergroups AS a'); // Add the level in the tree. $query->select('COUNT(DISTINCT b.id) AS level'); $query->join('LEFT OUTER', '#__usergroups AS b ON a.lft > b.lft AND a.rgt < b.rgt'); $query->group('a.id, a.lft, a.rgt, a.parent_id, a.title'); $query->order('a.lft ASC'); // Get the options. $db->setQuery($query); $items = $db->loadObjectList() or die($db->stdErr()); // Pad the option text with spaces using depth level as a multiplier. for ($i = 0, $n = count($items); $i < $n; $i++) { $options[] = JHTML::_('select.option', $items[$i]->value, str_repeat('- ', $items[$i]->level) . $items[$i]->text); } } else { // get list of Groups for dropdown filter $query = 'SELECT id AS value, name AS text' . ' FROM #__core_acl_aro_groups' // Exclude ROOT, USERS, Super Administrator, Public Frontend, Public Backend . ' WHERE id NOT IN (17,28,29,30)'; $db->setQuery($query); $items = $db->loadObjectList(); $i = '-'; //$options[] = JHTML::_('select.option', '0', WFText::_('Guest')); foreach ($items as $item) { $options[] = JHTML::_('select.option', $item->value, $i . WFText::_($item->text)); $i .= '-'; } } $lists['group'] = JHTML::_('select.genericlist', $options, 'filter_type', 'class="inputbox" size="1" onchange="document.adminForm.submit( );"', 'value', 'text', (int) $filter_type); // table ordering $lists['order_Dir'] = $filter_order_Dir; $lists['order'] = $filter_order; // search filter $lists['search'] = $search; $this->assign('user', JFactory::getUser()); $this->assign('lists', $lists); $this->assign('items', $rows); $this->assign('pagination', $pagination); $this->addStyleSheet(JURI::root(true) . '/administrator/components/com_jce/media/css/users.css'); parent::display($tpl); } } components/com_jce/views/users/tmpl/default.php000066600000012040150771655450015757 0ustar00
    lists['group']; ?>
    items); $i < $n; $i++) { $row = $this->items[$i]; ?>
    lists['order_Dir'], @$this->lists['order']); ?> lists['order_Dir'], @$this->lists['order']); ?> lists['order_Dir'], @$this->lists['order']); ?>
    pagination->getListFooter(); ?>
    id); ?> name; ?> username; ?> groupname); ?>
    components/com_jce/views/users/tmpl/index.html000066600000000054150771655450015621 0ustar00components/com_jce/views/users/index.html000066600000000054150771655450014645 0ustar00components/com_jce/views/profiles/view.html.php000066600000064044150771655450015771 0ustar00 array('label' => WFText::_('WF_TOOLS_EDITABLESELECT_LABEL')), 'extensions' => array( 'labels' => array( 'type_new' => WFText::_('WF_EXTENSION_MAPPER_TYPE_NEW'), 'group_new' => WFText::_('WF_EXTENSION_MAPPER_GROUP_NEW'), 'acrobat' => WFText::_('WF_FILEGROUP_ACROBAT'), 'office' => WFText::_('WF_FILEGROUP_OFFICE'), 'flash' => WFText::_('WF_FILEGROUP_FLASH'), 'shockwave' => WFText::_('WF_FILEGROUP_SHOCKWAVE'), 'quicktime' => WFText::_('WF_FILEGROUP_QUICKTIME'), 'windowsmedia' => WFText::_('WF_FILEGROUP_WINDOWSMEDIA'), 'silverlight' => WFText::_('WF_FILEGROUP_SILVERLIGHT'), 'openoffice' => WFText::_('WF_FILEGROUP_OPENOFFICE'), 'divx' => WFText::_('WF_FILEGROUP_DIVX'), 'real' => WFText::_('WF_FILEGROUP_REAL'), 'video' => WFText::_('WF_FILEGROUP_VIDEO'), 'audio' => WFText::_('WF_FILEGROUP_AUDIO') ) ), 'colorpicker' => array( 'stylesheets' => (array) WFModelEditor::getStyleSheets(), 'labels' => array( 'title' => WFText::_('WF_COLORPICKER_TITLE'), 'picker' => WFText::_('WF_COLORPICKER_PICKER'), 'palette' => WFText::_('WF_COLORPICKER_PALETTE'), 'named' => WFText::_('WF_COLORPICKER_NAMED'), 'template' => WFText::_('WF_COLORPICKER_TEMPLATE'), 'custom' => WFText::_('WF_COLORPICKER_CUSTOM'), 'color' => WFText::_('WF_COLORPICKER_COLOR'), 'apply' => WFText::_('WF_COLORPICKER_APPLY'), 'name' => WFText::_('WF_COLORPICKER_NAME') ) ), 'browser' => array( 'title' => WFText::_('WF_BROWSER_TITLE') ) ); return $options; } public function display($tpl = null) { $app = JFactory::getApplication(); $db = JFactory::getDBO(); $user = JFactory::getUser(); $acl = JFactory::getACL(); $client = 'admin'; $view = JRequest::getWord('view'); $task = JRequest::getWord('task'); $option = JRequest::getWord('option'); $lists = array(); $model = $this->getModel(); switch ($task) { default: case 'publish': case 'unpublish': case 'remove': case 'save': case 'copy': $filter_order = $app->getUserStateFromRequest("$option.$view.filter_order", 'filter_order', 'p.ordering', 'cmd'); $filter_order_Dir = $app->getUserStateFromRequest("$option.$view.filter_order_Dir", 'filter_order_Dir', '', 'word'); $filter_state = $app->getUserStateFromRequest("$option.$view.filter_state", 'filter_state', '', 'word'); $search = $app->getUserStateFromRequest("$option.$view.search", 'search', '', 'cmd'); $search = JString::strtolower($search); $limit = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->getCfg('list_limit'), 'int'); $limitstart = $app->getUserStateFromRequest("$option.$view.limitstart", 'limitstart', 0, 'int'); $where = array(); if (!empty($search)) { if (defined('JPATH_PLATFORM')) { $quoted = $db->quote('%' . $search . '%', false); } else { $quoted = $db->Quote('%' . $search . '%', false); } $where[] = 'LOWER( p.name ) LIKE ' . $quoted; } if ($filter_state) { if ($filter_state == 'P') { $where[] = 'p.published = 1'; } else if ($filter_state == 'U') { $where[] = 'p.published = 0'; } } $order = array($filter_order, $filter_order_Dir); // get the total number of records $query = $db->getQuery(true); if (is_object($query)) { $query->select('COUNT(p.id)')->from('#__wf_profiles AS p'); if (count($where)) { $query->where($where); } } else { $query = 'SELECT COUNT(p.id)' . ' FROM #__wf_profiles AS p' . (count($where) ? ' WHERE ' . implode(' AND ', $where) : ''); } $db->setQuery($query); $total = $db->loadResult(); jimport('joomla.html.pagination'); $pagination = new JPagination($total, $limitstart, $limit); $query = $db->getQuery(true); if (is_object($query)) { $query->select('p.*, u.name AS editor')->from('#__wf_profiles AS p')->join('LEFT', '#__users AS u ON u.id = p.checked_out'); if (count($where)) { $query->where($where); } $query->order(trim(implode(' ', $order))); } else { $query = 'SELECT p.*, u.name AS editor' . ' FROM #__wf_profiles AS p' . ' LEFT JOIN #__users AS u ON u.id = p.checked_out' . (count($where) ? ' WHERE ' . implode(' AND ', $where) : '') . ' ORDER BY ' . trim(implode(' ', $order)); } $db->setQuery($query, $pagination->limitstart, $pagination->limit); $rows = $db->loadObjectList(); if ($db->getErrorNum()) { echo $db->stderr(); return false; } // table ordering $lists['order_Dir'] = $filter_order_Dir; $lists['order'] = $filter_order; // search filter $lists['search'] = $search; $this->assignRef('user', $user); $this->assignRef('lists', $lists); $this->assignRef('rows', $rows); $this->assignRef('pagination', $pagination); //JToolBarHelper::title(WFText::_('WF_PROFILES_TITLE').' : '.WFText::_('WF_PROFILES_LIST'), 'profiles.png' ); WFToolbarHelper::addNewX(); WFToolbarHelper::editListX(); WFToolbarHelper::custom('copy', 'copy.png', 'copy_f2.png', 'WF_PROFILES_COPY', true); WFToolbarHelper::export(); if (count($rows) > 1) { WFToolbarHelper::publishList(); WFToolbarHelper::unpublishList(); } WFToolbarHelper::deleteList('', 'remove', 'WF_PROFILES_DELETE'); WFToolbarHelper::help('profiles.about'); $options = array( 'button' => '#upload_button', 'task' => 'import', 'labels' => array( 'browse' => WFText::_('WF_LABEL_BROWSE'), 'alert' => WFText::_('WF_PROFILES_IMPORT_BROWSE_ERROR') ) ); $this->addScript(JURI::root(true) . '/administrator/components/com_jce/media/js/uploads.js'); $this->addScriptDeclaration('jQuery(document).ready(function($){$(\'input[type="file"]\').upload(' . json_encode($options) . ')});'); // load styles $this->addStyleSheet(JURI::root(true) . '/administrator/components/com_jce/media/css/upload.css'); $this->setLayout('default'); break; case 'apply': case 'add': case 'edit': JHtml::_('behavior.modal'); // Load media $scripts = array( 'profiles.js', 'extensions.js', 'checklist.js', 'styleformat.js', 'fonts.js', 'blockformats.js' ); // Load scripts foreach ($scripts as $script) { $this->addScript(JURI::root(true) . '/administrator/components/com_jce/media/js/' . $script); } $this->addScript(JURI::root(true) . '/components/com_jce/editor/libraries/js/colorpicker.js'); $this->addScript(JURI::root(true) . '/components/com_jce/editor/libraries/js/select.js'); // load styles $this->addStyleSheet(JURI::root(true) . '/administrator/components/com_jce/media/css/profiles.css'); $cid = JRequest::getVar('cid', array(0), '', 'array'); JArrayHelper::toInteger($cid, array(0)); $lists = array(); $row = JTable::getInstance('profiles', 'WFTable'); // load the row from the db table $row->load($cid[0]); // fail if checked out not by 'me' if ($row->isCheckedOut($user->get('id'))) { $msg = JText::sprintf('WF_PROFILES_CHECKED_OUT', $row->name); $this->setRedirect('index.php?option=' . $option . '&view=profiles', $msg, 'error'); return false; } // Load editor params $component = JComponentHelper::getComponent('com_jce'); // Load Language $language = JFactory::getLanguage(); $language->load('com_jce', JPATH_ADMINISTRATOR); $language->load('com_jce', JPATH_SITE); $language->load('plg_editors_jce', JPATH_ADMINISTRATOR); $plugins = $model->getPlugins(); // load plugin languages foreach ($plugins as $plugin) { if ($plugin->core == 0) { // Load Language for plugin $language->load('com_jce_' . $plugin->name, JPATH_SITE); } } // load the row from the db table if ($cid[0]) { $row->checkout($user->get('id')); } else { $query = $db->getQuery(true); if (is_object($query)) { $query->select('COUNT(id)')->from('#__wf_profiles'); } else { $query = 'SELECT COUNT(id)' . ' FROM #__wf_profiles'; } $db->setQuery($query); $total = $db->loadResult(); // get the defaults from xml $row = $model->getDefaultProfile(); if (!is_object($row)) { $row->name = ''; $row->description = ''; $row->types = ''; $row->components = ''; $row->area = 0; $row->types = ''; $row->rows = ''; $row->plugins = ''; $row->published = 1; $row->ordering = 0; $row->params = '{}'; } $row->params = json_decode($row->params . ',' . $component->params); } $row->area = (isset($row->area)) ? $row->area : 0; $query = $db->getQuery(true); if (is_object($query)) { $query->select('ordering AS value, name AS text')->from('#__wf_profiles')->where(array('published = 1', 'ordering > -10000', 'ordering < 10000'))->order('ordering'); } else { // build the html select list for ordering $query = 'SELECT ordering AS value, name AS text' . ' FROM #__wf_profiles' . ' WHERE published = 1' . ' AND ordering > -10000' . ' AND ordering < 10000' . ' ORDER BY ordering'; } $order = JHTML::_('list.genericordering', $query); $lists['ordering'] = JHTML::_('select.genericlist', $order, 'ordering', 'class="inputbox" size="1"', 'value', 'text', intval($row->ordering)); $lists['published'] = ''; $options = array( 1 => WFText::_('WF_OPTION_YES'), 0 => WFTEXT::_('WF_OPTION_NO') ); foreach($options as $value => $text) { $checked = ''; if ($value == $row->published) { $checked = ' checked="checked"'; } $lists['published'] .= ''; } $exclude = array( 'com_admin', 'com_cache', 'com_checkin', 'com_config', //'com_cpanel', 'com_finder', 'com_installer', 'com_languages', 'com_jce', 'com_login', 'com_mailto', 'com_menus', 'com_media', 'com_messages', 'com_newsfeeds', 'com_plugins', 'com_redirect', 'com_templates', 'com_users', 'com_wrapper', 'com_search', 'com_user', 'com_updates' ); $query = $db->getQuery(true); if (is_object($query)) { $query->select('element AS value, name AS text')->from('#__extensions')->where(array('type = ' . $db->Quote('component'), 'enabled = 1'))->order('name'); } else { $query = "SELECT `option` AS value, name AS text" . " FROM #__components" . " WHERE parent = 0" . " AND enabled = 1" . " ORDER BY name"; } $db->setQuery($query); $components = $db->loadObjectList(); $options = array(); // load component languages for ($i = 0; $i < count($components); $i++) { if (!in_array($components[$i]->value, $exclude)) { $options[] = $components[$i]; // load system language file $language->load($components[$i]->value . '.sys', JPATH_ADMINISTRATOR); } } // set disabled attribute $disabled = (!$row->components) ? ' disabled="disabled"' : ''; // components list $lists['components'] = '
      '; foreach ($options as $option) { $checked = in_array($option->value, explode(',', $row->components)) ? ' checked="checked"' : ''; $lists['components'] .= '
    • '; } $lists['components'] .= '
    '; // components select $options = array( 'all' => WFText::_('WF_PROFILES_COMPONENTS_ALL'), 'select' => WFText::_('WF_PROFILES_COMPONENTS_SELECT') ); $lists['components-select'] = ''; foreach($options as $value => $text) { $checked = ''; if ($row->components) { if ($value == 'select') { $checked = ' checked="checked"'; } } else { if ($value == 'all') { $checked = ' checked="checked"'; } } $lists['components-select'] .= ''; } // area $options = array( 1 => WFText::_('WF_PROFILES_AREA_FRONTEND'), 2 => WFText::_('WF_PROFILES_AREA_BACKEND') ); $lists['area'] = ''; foreach($options as $value => $text) { $checked = ''; if (!isset($row->area) || empty($row->area) || in_array($value, explode(',', $row->area))) { $checked = ' checked="checked"'; } $lists['area'] .= ''; } // device $options = array( 'desktop' => WFText::_('WF_PROFILES_DEVICE_DESKTOP'), 'tablet' => WFText::_('WF_PROFILES_DEVICE_TABLET'), 'phone' => WFText::_('WF_PROFILES_DEVICE_PHONE') ); $lists['device'] = ''; foreach($options as $value => $text) { $checked = ''; if (!isset($row->device) || empty($row->device) || in_array($value, explode(',', $row->device))) { $checked = ' checked="checked"'; } $lists['device'] .= ''; } // user types from profile $query = $db->getQuery(true); if (is_object($query)) { $query->select('types')->from('#__wf_profiles')->where('id NOT IN (17,28,29,30)'); $db->setQuery($query); $types = $db->loadColumn(); } else { $query = 'SELECT types' . ' FROM #__wf_profiles' // Exclude ROOT, USERS, Super Administrator, Public Frontend, Public Backend . ' WHERE id NOT IN (17,28,29,30)'; $db->setQuery($query); $types = $db->loadResultArray(); } if (defined('JPATH_PLATFORM')) { $options = array(); $query = $db->getQuery(true); $query->select('a.id AS value, a.title AS text')->from('#__usergroups AS a'); // Add the level in the tree. $query->select('COUNT(DISTINCT b.id) AS level'); $query->join('LEFT OUTER', '#__usergroups AS b ON a.lft > b.lft AND a.rgt < b.rgt'); $query->group('a.id, a.lft, a.rgt, a.parent_id, a.title'); $query->order('a.lft ASC'); // Get the options. $db->setQuery($query); $options = $db->loadObjectList() or die($db->stdErr()); // Pad the option text with spaces using depth level as a multiplier. for ($i = 0, $n = count($options); $i < $n; $i++) { $options[$i]->text = str_repeat('|—', $options[$i]->level) . $options[$i]->text; } } else { // get list of Groups for dropdown filter $query = 'SELECT id AS value, name AS text' . ' FROM #__core_acl_aro_groups' // Exclude ROOT, USERS, Super Administrator, Public Frontend, Public Backend . ' WHERE id NOT IN (17,28,29,30)'; $db->setQuery($query); $types = $db->loadObjectList(); $i = '-'; $options = array( JHTML::_('select.option', '0', WFText::_('Guest')) ); foreach ($types as $type) { $options[] = JHTML::_('select.option', $type->value, $i . WFText::_($type->text)); $i .= '|—'; } } $lists['usergroups'] = '
      '; foreach ($options as $option) { $checked = in_array($option->value, explode(',', $row->types)) ? ' checked="checked"' : ''; $lists['usergroups'] .= '
    • '; } $lists['usergroups'] .= '
    '; // users $options = array(); if ($row->id && $row->users) { $query = $db->getQuery(true); if (is_object($query)) { $query->select('id AS value, username AS text')->from('#__users')->where('id IN (' . $row->users . ')'); } else { $query = 'SELECT id as value, username as text' . ' FROM #__users' . ' WHERE id IN (' . $row->users . ')'; } $db->setQuery($query); $gusers = $db->loadObjectList(); if ($gusers) { foreach ($gusers as $guser) { $options[] = JHTML::_('select.option', $guser->value, $guser->text); } } } $lists['users'] = '
      '; foreach ($options as $option) { $lists['users'] .= '
    • '; } $lists['users'] .= '
    '; // Get layout rows $rows = $model->getRowArray($row->rows); // assign params to row $model->getEditorParams($row); $model->getLayoutParams($row); // create $params object for "editor" $params = new WFParameter($row->params, '', 'editor'); // load other theme css foreach ($model->getThemes() as $theme) { $files = JFolder::files($theme, 'ui([\w\.]*)\.css$'); foreach ($files as $file) { $this->addStyleSheet(JURI::root(true) . '/components/com_jce/editor/tiny_mce/themes/advanced/skins/' . basename($theme) . '/' . $file); } } // assign references $this->assignRef('lists', $lists); $this->assignRef('profile', $row); $this->assignRef('rows', $rows); $this->assignRef('params', $params); $this->assignRef('plugins', $plugins); // get options for various widgets $options = $this->getOptions($params); // set suhosin flag $options['suhosin'] = ini_get('suhosin.post.max_vars') && (int) ini_get('suhosin.post.max_vars') < 1000; $this->addScriptDeclaration('jQuery.jce.Profiles.options = ' . json_encode($options) . ';'); // set toolbar if ($row->id) { JToolBarHelper::title(WFText::_('WF_ADMINISTRATION') . ' :: ' . WFText::_('WF_PROFILES_EDIT') . ' - [' . $row->name . ']', 'logo.png'); } else { JToolBarHelper::title(WFText::_('WF_ADMINISTRATION') . ' :: ' . WFText::_('WF_PROFILES_NEW'), 'logo.png'); } // set buttons WFToolbarHelper::apply(); WFToolbarHelper::save(); WFToolbarHelper::cancel('cancelEdit', 'Close'); WFToolbarHelper::help('profiles.edit'); JRequest::setVar('hidemainmenu', 1); $this->setLayout('form'); break; } $this->assignRef('model', $model); parent::display($tpl); } } components/com_jce/views/profiles/tmpl/default.php000066600000017077150771655450016460 0ustar00
    rows; $k = 0; for ($i = 0, $n = count($rows); $i < $n; $i++) { $row = $rows[$i]; $profile = JTable::getInstance('profiles', 'WFTable'); $profile->bind($row); $profile->editor = null; $link = JRoute::_('index.php?option=com_jce&view=profiles&task=edit&cid[]=' . $row->id); // state $state = JHTML::_('grid.published', $profile, $i); // checked out $checked = JHTML::_('grid.checkedout', $profile, $i); ?>
    lists['order_Dir'], @$this->lists['order']); ?> lists['order_Dir'], @$this->lists['order']); ?> lists['order_Dir'], @$this->lists['order']); ?> rows) > 1) { echo JHTML::_('grid.order', $this->rows); } ?> lists['order_Dir'], @$this->lists['order']); ?>
    pagination->getListFooter(); ?>
    isCheckedOut($this->user->get('id'), $row->checked_out)) { echo $row->name; } else { ?> name; ?>

    description; ?>

    1 ? '' : 'disabled="disabled"'; ?> class="text_area" style="text-align: center" /> id; ?>
    components/com_jce/views/profiles/tmpl/form_features.php000066600000022303150771655450017661 0ustar00profile->layout_params->get('toolbar_align', 'center')); // width and height $width = $this->profile->layout_params->get('editor_width', 600); $height = $this->profile->layout_params->get('editor_height', 'auto'); if (is_numeric($width) || strpos('%', $width) === false) { $width .= 'px'; } if (is_numeric($height) || strpos('%', $height) === false) { $height .= 'px'; } if (strpos('%', $width) !== false) { $height = '600px'; } if (strpos('%', $height) !== false) { $height = 'auto'; } $theme = $this->profile->layout_params->get('toolbar_theme', 'default'); if (strpos($theme, '.') === false) { $theme = $theme.'Skin'; } else { $theme = str_replace(array('o2k7.silver', 'o2k7.black'), array('o2k7.Silver', 'o2k7.Black'), $theme); $theme = preg_replace('#([\w]+)\.([\w]+)#', '$1Skin $1Skin$2', $theme); } ?>
    profile->layout_groups as $group) : ?>
    profile->layout_params->render('params[editor]', $group); ?>
    • profile->layout_params->get('toggle_label', '[Toggle Editor]');?>
        rows); $i++) : ?>
      • rows); $x++) : ?> rows[$x]) as $icon) : ?> plugins as $plugin) : ?> icon && $plugin->name == $icon) : ?> model->getIcon($plugin); ?>

      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

      Path:
      • plugins as $plugin) : if (!in_array($plugin->name, explode(',', implode(',', $this->rows)))) : if ($plugin->icon && (int)$plugin->row == $i) : echo '' . $this->model->getIcon($plugin) . ''; endif; endif; endforeach; ?>
      plugins as $plugin) : if (!$plugin->icon) : if ($plugin->editable) : ?>
    • name, explode(',', $this->profile->plugins)) ? 'checked="checked"' : ''; ?>/> name) . '_DESC'); ?>
    • name, explode(',', $this->profile->plugins)) ? 'checked="checked"' : ''; ?>/> name) . '_DESC'); ?>
    components/com_jce/views/profiles/tmpl/index.html000066600000000054150771655450016303 0ustar00components/com_jce/views/profiles/tmpl/form_setup.php000066600000011530150771655450017203 0ustar00
    • lists['published']; ?>
    • lists['ordering']; ?>
    • lists['area']; ?>
    • lists['device']; ?>
    • lists['components-select']; ?>
      lists['components']; ?>
    • lists['usergroups']; ?>
    • lists['users']; ?>
    components/com_jce/views/profiles/tmpl/form.php000066600000011047150771655450015766 0ustar00
    loadTemplate('setup'); ?>
    loadTemplate('features'); ?>
    loadTemplate('editor'); ?>
    loadTemplate('plugin'); ?>
    components/com_jce/views/profiles/tmpl/form_editor.php000066600000001623150771655450017333 0ustar00
    profile->editor_groups as $group) : ?>

    profile->editor_params->render('params[editor]', $group); ?>
    components/com_jce/views/profiles/tmpl/form_plugin.php000066600000014114150771655450017342 0ustar00plugins as $plugin) : if ($plugin->type == 'plugin') : $path = JPATH_SITE . $plugin->path; $manifest = $path . '/' . $plugin->name . '.xml'; if ($plugin->editable && is_file($manifest)) : jimport('joomla.filesystem.folder'); jimport('joomla.filesystem.file'); $name = trim($plugin->name); $params = new WFParameter($this->profile->params, $manifest, $plugin->name); // set element paths $params->addElementPath(array( WF_EDITOR . '/elements' )); // set plugin specific elements if (JFolder::exists($path . '/elements')) { $params->addElementPath($path . '/elements'); } $class = in_array($plugin->name, explode(',', $this->profile->plugins)) ? 'tabs-plugin-parameters' : ''; $groups = $params->getGroups(); if (count($groups)) : $count++; ?>

    title); ?>

    render('params[' . $plugin->name . ']', $group); if (!empty($data)) : echo '
    '; echo '' . WFText::_('WF_PROFILES_PLUGINS_' . strtoupper($group)) . ''; //echo '

    ' . WFText::_('WF_PROFILES_PLUGINS_' . strtoupper($group) . '_DESC') . '

    '; echo $data; echo '
    '; endif; endforeach; $extensions = $this->model->getExtensions($plugin->name); // Get extensions supported by this plugin foreach ($extensions as $type => $items) : $html = ''; // get extension type specific parameters $file = WF_EDITOR_LIBRARIES . '/xml/config/' . $type . '.xml'; if (is_file($file)) { $params = new WFParameter($this->profile->params, $file, $plugin->name . '.' . $type); // add element paths $params->addElementPath(array( WF_EDITOR . '/elements' )); foreach ($params->getGroups() as $group) : $html .= $params->render('params[' . $plugin->name . '][' . $type . ']', $group); endforeach; } foreach ($items as $extension) : // get extension xml file $manifest = $extension->manifest; if ($extension->core == 0) { // Load extension language file $language = JFactory::getLanguage(); $language->load('com_jce_' . $extension->folder . '_' . trim($extension->extension), JPATH_SITE); } if (JFile::exists($manifest)) : // get params for plugin $key = $plugin->name . '.' . $type . '.' . $extension->extension; $params = new WFParameter($this->profile->params, $manifest, $key); // add element paths $params->addElementPath(array( WF_EDITOR . '/elements' )); // render params if (!$params->hasParent()) : $key = array($plugin->name, $type, $extension->extension); $enabled = (int) $params->get('enable', 1); $checked = $enabled ? ' checked="checked"' : ''; $html .= '

    ' . WFText::_($extension->name) . '

    '; $html .= '

    ' . WFText::_($extension->description) . '

    '; foreach ($params->getGroups() as $group) : $html .= $params->render('params[' . implode('][', $key) . ']', $group, array('enable')); endforeach; endif; endif; endforeach; if ($html) : echo '
    ' . WFText::_('WF_EXTENSIONS_' . strtoupper($type) . '_TITLE') . ''; echo $html; echo '
    '; endif; endforeach; ?>
    components/com_jce/views/profiles/index.html000066600000000054150771655450015327 0ustar00components/com_jce/views/config/view.html.php000066600000003647150771655450015415 0ustar00load('plg_editors_jce', JPATH_ADMINISTRATOR); $client = JRequest::getWord('client', 'site'); $model = $this->getModel(); $plugin = WFExtensionHelper::getPlugin(); $xml = WF_EDITOR_LIBRARIES.'/xml/config/editor.xml'; $data = null; // get params from editor plugin if ($plugin->params && $plugin->params !== "{}") { $data = json_decode($plugin->params); } else { $component = WFExtensionHelper::getComponent(); // get params from component "params" field (legacy) if ($component->params) { $data = json_decode($component->params); } } // get params definitions $params = new WFParameter($data, $xml, 'editor'); $params->addElementPath(JPATH_COMPONENT.'/elements'); $this->assign('model', $model); $this->assign('params', $params); $this->assign('client', $client); WFToolbarHelper::apply(); WFToolbarHelper::save(); WFToolbarHelper::help('config.about'); parent::display($tpl); } } components/com_jce/views/config/tmpl/default.php000066600000002740150771655450016071 0ustar00
    params->getGroups() as $group): ?>
    params->render('params', $group) ?>
    components/com_jce/views/config/tmpl/index.html000066600000000054150771655450015725 0ustar00components/com_jce/views/config/index.html000066600000000054150771655450014751 0ustar00components/com_jce/views/index.html000066600000000054150771655450013504 0ustar00components/com_jce/views/updates/view.html.php000066600000004123150771655450015603 0ustar00getModel(); $this->addScript('components/com_jce/media/js/update.js'); $options = array( 'language' => array( 'check' => WFText::_('WF_UPDATES_CHECK'), 'install' => WFText::_('WF_UPDATES_INSTALL'), 'installed' => WFText::_('WF_UPDATES_INSTALLED'), 'no_updates' => WFText::_('WF_UPDATES_NONE'), 'high' => WFText::_('WF_UPDATES_HIGH'), 'medium' => WFText::_('WF_UPDATES_MEDIUM'), 'low' => WFText::_('WF_UPDATES_LOW'), 'full' => WFText::_('WF_UPDATES_FULL'), 'patch' => WFText::_('WF_UPDATES_PATCH'), 'auth_failed' => WFText::_('WF_UPDATES_AUTH_FAIL'), 'update_info' => WFText::_('WF_UPDATES_INFO'), 'install_info' => WFText::_('WF_UPDATES_INSTALL_INFO'), 'check_updates' => WFText::_('WF_UPDATES_CHECKING'), 'read_more' => WFText::_('WF_UPDATES_READMORE'), 'read_less' => WFText::_('WF_UPDATES_READLESS') ) ); $options = json_encode($options); $this->addScriptDeclaration('jQuery(document).ready(function($){$.jce.Update.init(' . $options . ');});'); // load styles $this->addStyleSheet(JURI::root(true) . '/administrator/components/com_jce/media/css/updates.css'); parent::display($tpl); } } ?> components/com_jce/views/updates/tmpl/default.php000066600000002515150771655450016271 0ustar00

     
    components/com_jce/views/updates/tmpl/index.html000066600000000054150771655450016125 0ustar00components/com_jce/views/updates/index.html000066600000000054150771655450015151 0ustar00components/com_jce/views/cpanel/view.html.php000066600000010335150771655450015402 0ustar00getModel(); $version = $model->getVersion(); $component = WFExtensionHelper::getComponent(); // get params definitions $params = new WFParameter($component->params, '', 'preferences'); $canUpdate = WFModelUpdates::canUpdate() && WFModel::authorize('installer'); $options = array( 'feed' => (int) $params->get('feed', 0), 'updates' => (int) $params->get('updates', $canUpdate ? 1 : 0), 'labels' => array( 'feed' => WFText::_('WF_CPANEL_FEED_LOAD'), 'updates' => WFText::_('WF_UPDATES'), 'updates_available' => WFText::_('WF_UPDATES_AVAILABLE') ) ); JHtml::_('behavior.modal'); $this->addScript('components/com_jce/media/js/cpanel.js'); $this->addScriptDeclaration('jQuery.jce.Cpanel.options = ' . json_encode($options) . ';'); // load styles $this->addStyleSheet(JURI::root(true) . '/administrator/components/com_jce/media/css/cpanel.css'); if (WFModel::authorize('preferences')) { WFToolbarHelper::preferences(); } if (WFModel::authorize('installer')) { WFToolbarHelper::updates($canUpdate); } WFToolbarHelper::help('cpanel.about'); $views = array('config', 'profiles', 'installer', 'browser', 'mediabox'); $icons = array(); foreach ($views as $view) { // check if its allowed... if (WFModel::authorize($view) === false) { continue; } $attribs = array('target="_self"'); $title = 'WF_' . strtoupper($view); $description = 'WF_' . strtoupper($view) . '_DESC'; $link = 'index.php?option=com_jce&view=' . $view; if ($view == 'browser') { $link = WFModel::getBrowserLink(); $component = WFExtensionHelper::getComponent(); // get params definitions $params = new WFParameter($component->params, '', 'preferences'); $width = (int) $params->get('browser_width', 790); $height = (int) $params->get('browser_height', 560); if (empty($link)) { continue; } $attribs = array('target="_blank"', 'class="browser"', 'onclick="Joomla.modal(this, \'' . $link . '\', '. $width .', '. $height .');return false;"'); $title = 'WF_' . strtoupper($view) . '_TITLE'; $description = 'WF_CPANEL_' . strtoupper($view); } // if its mediabox, check the plugin is installed and enabled if ($view == 'mediabox' && !JPluginHelper::isEnabled('system', 'jcemediabox')) { continue; } $icons[] = '
  • ' . WFText::_($title) . '
  • '; } $this->assign('icons', $icons); $this->assign('model', $model); $this->assign('params', $params); $this->assign('version', $version); parent::display($tpl); } } ?> components/com_jce/views/cpanel/tmpl/default.php000066600000004762150771655450016074 0ustar00
      icons); ?>

    components/com_jce/views/cpanel/tmpl/index.html000066600000000054150771655450015722 0ustar00components/com_jce/views/cpanel/index.html000066600000000054150771655450014746 0ustar00components/com_jce/views/preferences/view.html.php000066600000003774150771655450016452 0ustar00getModel(); $this->document->setTitle(WFText::_('WF_PREFERENCES_TITLE')); $this->document->addStyleSheet('templates/system/css/system.css'); $component = WFExtensionHelper::getComponent(); $xml = JPATH_COMPONENT . '/models/preferences.xml'; // get params definitions $params = new WFParameter($component->params, $xml, 'preferences'); $params->addElementPath(JPATH_COMPONENT . '/elements'); if (WFModel::authorize('admin')) { $form = $model->getForm('permissions'); } else { $form = null; } $this->assign('params', $params); $this->assign('permissons', $form); $this->addStyleSheet('components/com_jce/media/css/preferences.css'); $this->addScript('components/com_jce/media/js/preferences.js'); if (JRequest::getInt('close') == 1) { $this->addScriptDeclaration('jQuery(document).ready(function($){$.jce.Preferences.close();});'); } else { $this->addScriptDeclaration('jQuery(document).ready(function($){$.jce.Preferences.init();});'); } parent::display($tpl); } }components/com_jce/views/preferences/tmpl/default.php000066600000005056150771655450017130 0ustar00
    params->getGroups() as $group) : ?>
    params->render('params[preferences]', $group); ?>
    permissons) : ?>
    '; echo $this->permissons; echo '
    '; endif; ?>
    components/com_jce/views/preferences/tmpl/index.html000066600000000054150771655450016761 0ustar00components/com_jce/views/preferences/index.html000066600000000054150771655450016005 0ustar00components/com_jce/views/help/view.html.php000066600000004560150771655450015073 0ustar00getModel(); $language = $model->getLanguage(); $lang = JFactory::getLanguage(); $section = JRequest::getWord('section'); $category = JRequest::getWord('category'); $article = JRequest::getWord('article'); $component = JComponentHelper::getComponent('com_jce'); require_once(WF_ADMINISTRATOR . '/classes/parameter.php'); $params = new WFParameter($component->params); $url = $params->get('preferences.help.url', 'http://www.joomlacontenteditor.net'); $method = $params->get('preferences.help.method', 'reference'); $pattern = $params->get('preferences.help.pattern', ''); switch ($method) { default: case 'reference': $url .= '/index.php?option=com_content&view=article&tmpl=component&print=1&mode=inline&task=findkey&lang=' . $language . '&keyref='; break; case 'xml': break; case 'sef': break; } $this->assign('model', $model); $key = array(); if ($section) { $key[] = $section; if ($category) { $key[] = $category; if ($article) { $key[] = $article; } } } $options = array( 'url' => $url, 'key' => $key, 'pattern' => $pattern ); $this->addStyleSheet(JURI::root(true) . '/components/com_jce/editor/libraries/css/help.css'); $this->addScriptDeclaration('jQuery(document).ready(function($){$.jce.Help.init(' . json_encode($options) . ');});'); parent::display($tpl); } } components/com_jce/views/help/tmpl/default.php000066600000001747150771655450015562 0ustar00
    model->renderTopics();?>
    components/com_jce/views/help/tmpl/index.html000066600000000054150771655450015410 0ustar00components/com_jce/views/help/index.html000066600000000054150771655450014434 0ustar00components/com_jce/views/mediabox/view.html.php000066600000006354150771655450015736 0ustar00 'config:fields:fieldset')); $params->addElementPath(JPATH_PLUGINS . '/system/jcemediabox/elements'); $groups = array(); $array = array(); foreach ($params->getGroups() as $group) { $groups[] = $params->getParams('params', $group); } foreach ($groups as $group) { $array = array_merge($array, $group); } return $array; } else { // get params definitions $params = new JParameter($data, JPATH_PLUGINS . '/system/jcemediabox.xml'); $xml = JPATH_PLUGINS . '/system/jcemediabox.xml'; $params->loadSetupFile($xml); return $params->getParams(); } } function display($tpl = null) { $db = JFactory::getDBO(); $lang = JFactory::getLanguage(); $lang->load('plg_system_jcemediabox'); $client = JRequest::getWord('client', 'site'); $model = $this->getModel(); $plugin = JPluginHelper::getPlugin('system', 'jcemediabox'); $params = $this->getParams($plugin->params); $this->assign('params', $params); $this->assign('client', $client); $this->addScript(JURI::root(true) . '/components/com_jce/editor/libraries/js/colorpicker.js'); $this->addStyleSheet('components/com_jce/media/css/colorpicker.css'); wfimport('admin.models.editor'); $options = array( 'stylesheets' => (array) WFModelEditor::getStyleSheets(), 'labels' => array( 'picker' => WFText::_('WF_COLORPICKER_PICKER'), 'palette' => WFText::_('WF_COLORPICKER_PALETTE'), 'named' => WFText::_('WF_COLORPICKER_NAMED'), 'template' => WFText::_('WF_COLORPICKER_TEMPLATE'), 'color' => WFText::_('WF_COLORPICKER_COLOR'), 'apply' => WFText::_('WF_COLORPICKER_APPLY'), 'name' => WFText::_('WF_COLORPICKER_NAME') ), 'parent' => '#jce' ); $this->addScriptDeclaration('jQuery(document).ready(function($){$("input.color").colorpicker(' . json_encode($options) . ');});'); WFToolbarHelper::apply(); WFToolbarHelper::save(); WFToolbarHelper::help('mediabox.config'); parent::display($tpl); } } components/com_jce/views/mediabox/tmpl/default.php000066600000002311150771655450016406 0ustar00
      params as $param) { echo '
    • ' . $param[0] . $param[1] . '
    • '; } ?>
    components/com_jce/views/mediabox/tmpl/index.html000066600000000054150771655450016250 0ustar00components/com_jce/views/mediabox/index.html000066600000000054150771655450015274 0ustar00components/com_jce/sql/index.html000066600000000054150771655450013146 0ustar00components/com_jce/sql/sqlsrv.sql000066600000001436150771655450013231 0ustar00IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[#__wf_profiles]') AND type in (N'U')) BEGIN CREATE TABLE [#__wf_profiles]( [id] [bigint] IDENTITY(1,1) NOT NULL, [name] [nvarchar](250) NOT NULL, [description] [text] NOT NULL, [users] [text] NOT NULL, [types] [text] NOT NULL, [components] [nvarchar](max) NOT NULL, [area] [smallint] NOT NULL, [device] [nvarchar](250) NOT NULL, [rows] [nvarchar](max) NOT NULL, [plugins] [nvarchar](max) NOT NULL, [published] [smallint] NOT NULL, [ordering] [int] NOT NULL, [checked_out] [smallint] NOT NULL, [checked_out_time] [datetime] NOT NULL, [params] [nvarchar](max) NOT NULL, CONSTRAINT [PK_#__wf_profiles_id] PRIMARY KEY CLUSTERED ( [id] ASC )WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ) END;components/com_jce/sql/postgresql.sql000066600000001073150771655450014077 0ustar00CREATE TABLE "#__wf_profiles" ( "id" serial NOT NULL, "name" character varying(255) NOT NULL, "description" text NOT NULL, "users" text NOT NULL, "types" text NOT NULL, "components" text NOT NULL, "area" smallint NOT NULL, "device" character varying(255) NOT NULL, "rows" text NOT NULL, "plugins" text NOT NULL, "published" smallint NOT NULL, "ordering" integer NOT NULL, "checked_out" smallint NOT NULL, "checked_out_time" timestamp without time zone NOT NULL, "params" text NOT NULL, PRIMARY KEY ("id") );components/com_jce/sql/mysql.sql000066600000001115150771655450013036 0ustar00CREATE TABLE IF NOT EXISTS `#__wf_profiles` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `description` text NOT NULL, `users` text NOT NULL, `types` text NOT NULL, `components` text NOT NULL, `area` tinyint(3) NOT NULL, `device` varchar(255) NOT NULL, `rows` text NOT NULL, `plugins` text NOT NULL, `published` tinyint(3) NOT NULL, `ordering` int(11) NOT NULL, `checked_out` tinyint(3) NOT NULL, `checked_out_time` datetime NOT NULL, `params` text NOT NULL, PRIMARY KEY (`id`) ) DEFAULT CHARSET=utf8;components/com_jce/index.html000066600000000054150771655450012347 0ustar00components/com_jce/config.xml000066600000004707150771655450012352 0ustar00
    components/com_jce/media/js/installer.js000066600000002140150771655450014376 0ustar00/* JCE Editor - 2.4.3 | 11 September 2014 | http://www.joomlacontenteditor.net | Copyright (C) 2006 - 2014 Ryan Demmer. All rights reserved | GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html */ (function($){Joomla.submitbutton=submitbutton=function(button){try{Joomla.submitform(button);}catch(e){submitform(button);}};$.jce.Installer={options:{},init:function(options){$.extend(this.options,options||{});$(":file").upload(this.options);var n=$('#tabs-plugins, #tabs-extensions, #tabs-languages, #tabs-related').find('input[type="checkbox"]');$(n).click(function(){$('input[name="boxchecked"]').val($(n).filter(':checked').length);});$('#upload_button').click(function(e){$(this).addClass('loading');$('input[name="task"]').val('install');$('form[name="adminForm"]').submit();e.preventDefault();});$('button.install_uninstall').click(function(e){if($('div#tabs input:checkbox:checked').length){$(this).addClass('ui-state-loading');$('input[name="task"]').val('remove');$('form[name="adminForm"]').submit();} e.preventDefault();});}};$(document).ready(function(){$.jce.Installer.init();});})(jQuery);components/com_jce/media/js/profiles.js000066600000020511150771655450014226 0ustar00/* JCE Editor - 2.4.3 | 11 September 2014 | http://www.joomlacontenteditor.net | Copyright (C) 2006 - 2014 Ryan Demmer. All rights reserved | GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html */ (function($){Joomla.submitbutton=submitbutton=function(button){if(button=="cancelEdit"){try{Joomla.submitform(button);}catch(e){submitform(button);} return;} var $profiles=$jce.Profiles;if($profiles.validate()){$profiles.onSubmit();try{Joomla.submitform(button);}catch(e){submitform(button);}}};$.jce.Profiles={options:{},init:function(){var self=this,init=true;var dir=$('body').css('direction')=='rtl'?'right':'left';$('a#users-add').button({icons:{primary:'ui-icon-person'}});$("#tabs-editor").tabs({'active':0,beforeActivate:function(event,ui){$(ui.oldTab).removeClass('active');$(ui.newTab).addClass('active');}}).find('ul.ui-tabs-nav > li.ui-state-default:first-child').addClass('active');$("#tabs-plugins").tabs({beforeActivate:function(event,ui){$(ui.oldTab).removeClass('active');$(ui.newTab).addClass('active');}}).find('ul.ui-tabs-nav > li.ui-state-default').not('.tab-disabled').first().addClass('active').children('a.ui-tabs-anchor').click();$('input.checkbox-list-toggle-all').click(function(){$('input[type="checkbox"]','#user-groups').prop('checked',this.checked).trigger('check');});$('input[name="components-select"]').click(function(){$('input[type="checkbox"]','#components').prop('disabled',(this.value=='all')).trigger('disable').filter(':checked').prop('checked',false).trigger('check');});$("select.editable, select.combobox").combobox(this.options.combobox);$('input.color').colorpicker($.extend(this.options.colorpicker,{parent:'#jce'}));$('select.extensions, input.extensions, textarea.extensions').extensionmapper(this.options.extensions);this.createLayout();$('select.checklist, input.checklist').checkList({onCheck:function(){self.setRows();}});$('#paramseditorwidth').change(function(){var v=$(this).val()||600,s=v+'px';if(/%/.test(v)){s=v,v=600;}else{v=parseInt(v),s=v+'px';} $('span.widthMarker span','#profileLayoutTable').html(s);$('#editor_container').width(v);$('span.widthMarker, #statusbar_container span.mceStatusbar').width(v);});$('#paramseditorheight').change(function(){var v=$(this).val()||'auto';if(/%/.test(v)){v='auto';}else{if($.type(v)=='number'){v=parseInt(v);}}});$('#paramseditortoolbar_theme').change(function(){var v=$(this).val();if(v.indexOf('.')!=-1){v=v.split('.');var s=v[0]+'Skin';var c=v[1];v=s+' '+s+c.charAt(0).toUpperCase()+c.substring(1);}else{v+='Skin';} $('span.profileLayoutContainer').each(function(){var cls=this.className;cls=cls.replace(/([a-z0-9]+)Skin([a-z0-9]*)/gi,'');this.className=$.trim(cls);}).addClass(v);});$('#paramseditortoolbar_align').change(function(){var v=$(this).val();$('ul.sortableList','#toolbar_container').removeClass('mceLeft mceCenter mceRight').addClass('mce'+v.charAt(0).toUpperCase()+v.substring(1));self._fixLayout();}).change();$('#paramseditorpath').change(function(){$('span.mceStatusbar span.mcePathLabel').toggle($(this).val()==1);}).change();$('ul#profileAdditionalFeatures input:checkbox').click(function(){self.setPlugins();});$('#paramseditortoolbar_location').change(function(){var $after=$('#editor_container');if($(this).val()=='top'){$after=$('span.widthMarker');} $('#toolbar_container').insertAfter($after);}).change();$('#paramseditorstatusbar_location').change(function(){var v=$(this).val();$('#statusbar_container').show();if(v=='none'){$('#statusbar_container').hide();} var $after=$('#editor_container');if(v=='top'){$after=$('span.widthMarker');if($('#paramseditortoolbar_location').val()=='top'){$after=$('#toolbar_container');}} $('#statusbar_container').insertAfter($after);}).change();$('#paramseditorresizing').change(function(){var v=$(this).val();$('a.mceResize','#statusbar_container').toggle(v==1);}).change();$('#paramseditortoggle').change(function(){var v=$(this).val();$('#editor_toggle').toggle(v==1);}).change();$('#paramseditortoggle_label').on('change keyup',function(){if(this.value){$('#editor_toggle').text(this.value);}});$('#users').click(function(e){var n=e.target;if($(n).is('span.users-list-delete')){$(n).parent().parent().remove();}});$('#tabs-features :input[name], #tabs-editor :input[name], #tabs-plugins :input[name]').change(function(){if(init){return;} var name=this.name.replace('!"#$%&()*+,./:;<=>?@[\]^`{|}~','\\$1','g');$(this).add('[name="'+name+'"]').addClass('isdirty');});$('input.plugins-enable-checkbox').on('click',function(){var s=this.checked,name=$(this).data('name'),proxy=$(this).next('input[type="hidden"]');if($(proxy).length==0){proxy=$('').insertAfter(this);} $(this).change().val(s?1:0).removeAttr('name');$(proxy).val(s?1:0).change();$('select.plugins-default-select',$(this).parents('fieldset:first')).children('option[value="'+name+'"]').prop('disabled',!s).parent().val(function(i,v){if(v===name){return"";} return v;});}).change(function(){$(this).removeClass('isdirty');});init=false;},validate:function(){var required=[];$(':input.required').each(function(){if($(this).val()===''){var parent=$(this).parents('div.tab-pane').get(0);required.push("\n"+$('#tabs ul li a[href=#'+parent.id+']').html()+' - '+$.trim($('label[for="'+this.id+'"]').html()));}});if(required.length){var msg=$.jce.options.labels.required;msg+=required.join(',');alert(msg);return false;} return true;},onSubmit:function(){$('div#tabs-editor, div#tabs-plugins').find(':input[name].placeholder').prop('disabled',true);$('#tabs-features :input[name], #tabs-editor :input[name], #tabs-plugins :input[name]').not('.isdirty').prop('disabled',true).parents('.ui-radio, .ui-checkbox').addClass('disabled');},_fixLayout:function(){$('span.mceButton, span.mceSplitButton').removeClass('mceStart mceEnd');$('span.mceListBox').parent('span.sortableRowItem').prev('span.sortableRowItem').children('span.mceButton:last, span.mceSplitButton:last').addClass('mceEnd');$('span.mceListBox').parent('span.sortableRowItem').next('span.sortableRowItem').children('span.mceButton:first, span.mceSplitButton:first').addClass('mceStart');},createLayout:function(){var self=this;$("ul.sortableList").sortable({connectWith:'ul.sortableList',axis:'y',update:function(event,ui){self.setRows();self.setPlugins();},start:function(event,ui){$(ui.placeholder).width($(ui.item).width());},placeholder:'sortableListItem sortable-highlight',opacity:0.8});$('span.sortableOption').hover(function(){$(this).append('');},function(){$(this).empty();}).click(function(){var $parent=$(this).parents('li.sortableListItem').first();var $target=$('ul.sortableList','#profileLayoutTable').not($parent.parent());$parent.appendTo($target);$(this).empty();self.setRows();self.setPlugins();});$('span.sortableRow').sortable({connectWith:'span.sortableRow',tolerance:'pointer',update:function(event,ui){self.setRows();self.setPlugins();self._fixLayout();},start:function(event,ui){$(ui.placeholder).width($(ui.item).width());},opacity:0.8,placeholder:'sortableRowItem sortable-highlight'});this._fixLayout();},setRows:function(){var rows=[];$('span.sortableRow','#toolbar_container').has('span.sortableRowItem').each(function(){rows.push($.map($('span.sortableRowItem',this),function(el){return $(el).data('name');}).join(','));});var v=rows.join(';');$('input[name="rows"]').val(v).change();},setLayout:function(){var $spans=$('span.profileLayoutContainerCurrent > span').not('span.widthMarker');$.each(['toolbar','editor','statusbar'],function(){$('#paramseditor'+this+'_location').val($spans.index($('#'+this+'_container')));});},setPlugins:function(){var self=this,plugins=[];$('span.sortableRow span.plugin','#toolbar_container').each(function(){plugins.push($(this).data('name'));});$('ul#profileAdditionalFeatures input:checkbox:checked').each(function(){plugins.push($(this).val());});$('input[name="plugins"]').val(plugins.join(',')).change();this.setParams(plugins);},setParams:function(plugins){var $tabs=$('div#tabs-plugins > ul.nav.nav-tabs > li');$tabs.removeClass('tab-disabled ui-state-disabled active ui-tabs-active ui-state-active').each(function(i){var name=$(this).data('name');var s=$.inArray(name,plugins)!=-1;$('input[name], select[name]',this).prop('disabled',!s);if(!s){$(this).addClass('tab-disabled');}});$tabs.not('.tab-disabled').first().addClass('active ui-tabs-active ui-state-active').children('a.ui-tabs-anchor').click();}};$(document).ready(function(){$.jce.Profiles.init();});})(jQuery);components/com_jce/media/js/fonts.js000066600000003114150771655450013534 0ustar00/* JCE Editor - 2.4.3 | 11 September 2014 | http://www.joomlacontenteditor.net | Copyright (C) 2006 - 2014 Ryan Demmer. All rights reserved | GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html */ (function($){$(document).ready(function(){$('div.fontlist').on('update',function(){var data={},v="";$('li input[type="checkbox"]:checked',this).each(function(){var s=this.value.split('=');if(s.length===2){data[s[0]]=s[1];}});$('li.font-item',this).not('.hide').each(function(){var k=$('input',this).first().val(),v=$('input',this).last().val();if(k&&v){data[k]=v;}});if(!$.isEmptyObject(data)){v=JSON.stringify(data);} $('input[type="hidden"]',this).val(v).change();});$('input[type="checkbox"]','div.fontlist').on('click',function(){$('div.fontlist').trigger('update');});$('input[type="text"]','div.fontlist').on('change',function(){$('div.fontlist').trigger('update');});$('a.close','div.fontlist').not('.plus').click(function(e){$(this).parent().remove();$('div.fontlist').trigger('update');e.preventDefault();});$('a.close.plus','div.fontlist').click(function(e){var $item=$('div.fontlist ul li.font-item').last().clone(true).appendTo('div.fontlist ul').removeClass('hide');$('input',$item).val("").first().focus();e.preventDefault();});$('div.fontlist ul li.font-item.hide input').change(function(){$('div.fontlist').trigger('update');});$('div.fontlist ul').sortable({axis:'y',update:function(event,ui){$('div.fontlist').trigger('update');},placeholder:"fontlist-highlight",start:function(event,ui){$(ui.placeholder).height($(ui.item).height()).width($(ui.item).width());},});});})(jQuery);components/com_jce/media/js/extensions.js000066600000022751150771655450014612 0ustar00/* JCE Editor - 2.4.3 | 11 September 2014 | http://www.joomlacontenteditor.net | Copyright (C) 2006 - 2014 Ryan Demmer. All rights reserved | GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html */ (function($){$.widget("ui.extensionmapper",{options:{labels:{'type_new':'Add new type...','group_new':'Add new group...'},defaults:''},_init:function(){var self=this,el=this.element,v=$(el).val()||'',name=$(el).attr('name').replace(/\[\]/,'');this.defaultMap={};var dv=this.options.defaults||$(el).data('default');if(dv){$.each(dv.split(';'),function(i,s){var parts=s.split('=');self.defaultMap[parts[0]]=parts[1].split(',');});} v=$.type(v)=='array'?v.join(';'):v;var $input=$('').addClass(function(){return $(el).hasClass('create')?'create':'';}).insertBefore(el).hide().val(v);$(el).remove();this.element=$input;$('').val(v).insertBefore(this.element);$('').click(function(){var $edit=this;if(!this.mapper){$(this).addClass('loader');this.mapper=self._buildMapper();$(this.mapper).hide().insertAfter(this).slideDown(450,function(){$($edit).removeClass('loader');$('div.extension_group_container ul.extension_list',this).each(function(){if(this.firstChild.offsetHeight*this.childNodes.length>this.parentNode.offsetHeight){$(this).parent('div.extension_list_container').next('div.extension_list_scroll_bottom').css('visibility','visible');}});});}else{$(this.mapper).slideToggle(450);}}).insertAfter(this.element);},_buildMapper:function(){var self=this,v=$(this.element).val();var $container=$('');$.each(v.split(';'),function(i,s){$container.append(self._createGroup(s.split('=')));});if($(this.element).hasClass('create')){$('
    '+this.options.labels.group_new+'
    ').click(function(){var group=self._createGroup();$(group).hide().insertBefore(this).fadeIn('fast');self._createSortable($('ul.extension_list',group));}).appendTo($container);} this._createSortable($('ul.extension_list',$container));$container.sortable({tolerance:'intersect',placeholder:'sortable-highlight',handle:'span.extension_group_handle',update:function(event,ui){self._setValues();},start:function(event,ui){$(ui.placeholder).width($(ui.item).width()).height($(ui.item).height());}});return $container;},_createSortable:function(list){var self=this;$(list).sortable({connectWith:'ul.extension_list',placeholder:'sortable-highlight',update:function(event,ui){if(!ui.sender) return;self._showScroll($(ui.item).parent(),['bottom']);self._showScroll($(ui.sender),['top','bottom']);self._setValues();}});},_createGroup:function(values){var self=this;values=values||['custom','custom'];var $tmpl=$('
    '+'
    '+' '+' '+'
    '+'
    '+this.options.labels.type_new+'
    '+'
    '+'
    '+'
      '+'
      '+'
      '+'
      ');var name=values[0],list=values[1]||'';if(name=='custom'){$('').change(function(){if(this.value=='') return;var v=this.value.toLowerCase();$('span.extension_group_title',$tmpl).addClass(v).attr('title',v);}).appendTo($('span.extension_group_title',$tmpl)).focus().pattern();var $remove=$('').click(function(){$($tmpl).fadeOut('fast',function(){$tmpl.remove();self._setValues();});});$('div.extension_group_titlebar',$tmpl).append($remove);}else{var key=name.replace(/[\W]/g,'');if(this.defaultMap[key]){var $check=$('').addClass(function(){return name.charAt(0)=='-'?'':'checked';}).attr('aria-checked',!(name.charAt(0)=='-'));$check.click(function(){var s=name;if(s.charAt(0)==='-'){s=s.substr(1);} if($(this).is('.checked')){$(this).removeClass('checked').attr('aria-checked',false).prev('span.extension_group_title').attr('title','-'+s);}else{$(this).addClass('checked').attr('aria-checked',true).prev('span.extension_group_title').attr('title',s);} self._setValues();});$('div.extension_group_titlebar',$tmpl).append($check);}else{var $remove=$('').click(function(){$($tmpl).fadeOut('fast',function(){$tmpl.remove();self._setValues();});});$('div.extension_group_titlebar',$tmpl).append($remove);} var title=this.options.labels[key]||(key.charAt(0).toUpperCase()+key.substr(1));$('span.extension_group_title',$tmpl).html(title);} $('span.extension_group_title',$tmpl).attr('title',name).addClass(name);$('div.extension_list_add span',$tmpl).click(function(){self._createItem('custom').hide().prependTo($('ul.extension_list',$tmpl)).fadeIn('fast',function(){var parent=this.parentNode;if(parent.firstChild.offsetHeight*parent.childNodes.length>parent.parentNode.offsetHeight){$(parent).parent('div.extension_list_container').next('div.extension_list_scroll_bottom').css('visibility','visible');} $(this).focus();});});$('div.extension_list_scroll_top',$tmpl).click(function(){self._scrollTo('top',$('ul.extension_list',$tmpl));});$('div.extension_list_scroll_bottom',$tmpl).click(function(){self._scrollTo('bottom',$('ul.extension_list',$tmpl));});list=list.replace(/^[;,]/,'').replace(/[;,]$/,'');$.each(list.split(','),function(){$('ul.extension_list',$tmpl).append(self._createItem(this,key));});return $tmpl;},_createItem:function(value,group){var self=this,v=value.replace(/[^a-z0-9]/gi,''),$item;if(value=='custom'){$item=$('
    • '+' '+' '+'
    • ');$('input',$item).change(function(){if(this.value==''){$(this).removeClass('duplicate');$($item).removeClass(function(){return this.className.replace(/(file|custom)/,'');});return;} if(new RegExp(new RegExp('[=,]'+this.value+'[,;]')).test($(self.element).val())){$(this).addClass('duplicate');$item.addClass('duplicate');}else{$(this).removeClass('duplicate');$item.removeClass(function(){return this.className.replace(/(file|custom)/,'');}).addClass(this.value);if(this.value!=''){self._setValues();}}}).focus().pattern();}else{$item=$('
    • '+' '+value.replace(/[\W]+/,'')+''+' '+'
    • ');var map=this.defaultMap[group];if($.inArray(v,map)==-1){$('span.checkbox',$item).removeClass('checkbox').addClass('extension_list_remove').attr('role','button')}else{$('span.checkbox',$item).addClass(function(){return value.charAt(0)=='-'?'':'checked';}).attr('aria-checked',!(value.charAt(0)=='-')).click(function(){if($(this).is('.checked')){$(this).removeClass('checked').attr('aria-checked',false).prev('span.extension_title').attr('title','-'+v);}else{$(this).addClass('checked').attr('aria-checked',true).prev('span.extension_title').attr('title',v);} self._setValues();});}} $('span.extension_list_remove',$item).click(function(){$item.fadeOut('fast',function(){var parent=this.parentNode;if(parent.firstChild.offsetHeight*parent.childNodes.length0) return;}else{v=v-1;} inv=(dir=='top')?p.next():p.prev();$(ul).animate({'marginTop':v},500,function(){$(inv).css('visibility','visible');self._showScroll(ul,[dir]);});},_setValues:function(){var id=$(this.element).attr('id'),groups=[],title='';$('div.extension_group_container','#'+id+'_mapper').each(function(){var n=$('span.extension_group_title:first',this);if($(n).is('.custom')){title=$('input',n).val();}else{title=$(n).attr('title');} if(title){var list=[],v,title=title.toLowerCase();$('li span',this).each(function(){v=$('input',this).val()||$(this).attr('title');if(v){list.push(v);}});groups.push(title+'='+list.join(','));}});var data=groups.join(';').replace(/([a-z]+)=;/g,'').replace(/^[;,]/,'').replace(/[;,]$/,'');$(this.element).val(data).change();},destroy:function(){$.Widget.prototype.destroy.apply(this,arguments);}});})(jQuery);components/com_jce/media/js/update.js000066600000015655150771655450013702 0ustar00/* JCE Editor - 2.4.3 | 11 September 2014 | http://www.joomlacontenteditor.net | Copyright (C) 2006 - 2014 Ryan Demmer. All rights reserved | GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html */ (function($){$.jce.Update={updates:{},options:{language:{'check':'Check for Updates','install':'Install Updates','installed':'Installed','no_updates':'No Updates Available','high':'High','medium':'Medium','low':'Low','full':'Full Install','patch':'Patch','auth_failed':'Authorisation Failed','install_failed':'Install Failed','update_info':'Update Information','install_info':'Install Information','check_updates':'Checking for Updates...','info':'Show Information','read_more':'More','read_less':'Less'}},init:function(options){var self=this;$.extend(this.options,options);$('button#update-button').click(function(){self.execute(this);}).click();},execute:function(el){if($(el).hasClass('check')){this.check(el);} if($(el).hasClass('install')){this.download(el);}},translate:function(s,v){return this.options.language[s]||v;},check:function(btn){var self=this;$('#install-button').remove();var list=$('div#updates-list');$('div.body',list).html('
      '+this.translate('check_updates')+'
      ');$(btn).addClass('loading').prop('disabled',true);var priority=[''+this.translate('high')+'',''+this.translate('medium')+'',''+this.translate('low')+''];$.getJSON("index.php?option=com_jce&view=updates&task=update&step=check",{},function(r){$(btn).removeClass('loading');$(btn).prop('disabled',false);$('div.body',list).empty();if(r){if($.type(r)=='string'){r=$.parseJSON(r);} if(r.error){$('div.body',list).html('
      '+r.error+'
      ');return false;} if(r.length){$(btn).clone().click(function(){self.execute(this);}).insertAfter(btn).attr({'id':'install-button','disabled':'disabled'}).removeClass('check').addClass('install').prop('disabled',true).html(' '+self.translate('install'));$.each(r,function(n,s){$('div.body',list).append('
      '+s.title+'
      '+s.version+'
      '+priority[s.priority-1]+'
      ');var $info=$('
      '+s.text+'
      ').appendTo($('div.body',list));var $readmore=$(''+self.translate('read_more','More')+'').click(function(){$('div.body .item',list).toggle();$(this).toggleClass('readmore readless').parent().toggleClass('expand').toggle().prev('.item').toggle();$(this).html(function(){if($(this).hasClass('readless')){return self.translate('read_less','Less');}else{return self.translate('read_more','More');}});}).appendTo($info);if(!$.support.leadingWhitespace){$readmore.css('top',0);} $('div.body div.item.info',list).on('scroll',function(){if(!$.support.leadingWhitespace){$readmore.css('top',$(this).scrollTop());}else{$readmore.css('bottom',-$(this).scrollTop());}});var sb=$('div.body',list).get(0).clientWidth-$('div.header',list).get(0).clientWidth;if(sb<0){$('div.body',list).addClass('scrolling');} var el=$('span[data-uid='+s.id+']');if(s.auth){if(parseInt(s.forced)==1||s.priority==1){$(el).addClass('checked').addClass('disabled');$('button#install-button').prop('disabled',false);if(s.negates){$('span[data-uid='+s.negates+']').removeClass('checked').addClass('disabled');}} if(parseInt(s.forced)==1){$(el).addClass('disabled');} if(s.required){$('span[data-uid='+s.required+']').addClass('checked');} $(el).click(function(){if($(this).is('.disabled, .error, .alert')){return;} if($(this).hasClass('checked')){$(this).removeClass('checked');}else{$(this).addClass('checked');} if(s.negates){if($(this).hasClass('checked')){$('span[data-uid='+s.negates+']').removeClass('checked').addClass('disabled');}else{$('span[data-uid='+s.negates+']').removeClass('disabled');}} var len=$('div.body span.checkbox.checked',list).length;if(len){$('button#install-button').attr('disabled','').prop('disabled',false);if(len==$('div.body span.checkbox',list).length){$('div.header div:first-child span.checkbox',list).addClass('checked');}else{$('div.header div:first-child span.checkbox',list).removeClass('checked');}}else{$('button#install-button').attr('disabled','disabled').prop('disabled',true);$('div.header div:first-child span.checkbox',list).removeClass('checked');}});}else{$(el).removeClass('disabled').addClass('alert');$('div.body',list).append('
      '+s.title+' : '+self.translate('auth_failed')+'
      ');}});if(r.length>1){$('').appendTo($('div.header div:first',list)).click(function(){$('div.body span.checkbox',list).click();});}}else{$('div.body',list).append('
      '+self.translate('no_updates')+'
      ');}}else{$('div.body',list).append('
      '+self.translate('no_updates')+'
      ');}});},download:function(btn){var t=this,n=1;var s=$('#updates-list div.body div.item span.checkbox.checked');$(s).addClass('disabled');$(btn).prop('disabled',true);$('button#update-button').prop('disabled',true);$.extend(t.updates,{'joomla':[],'jce':[]});$.each(s,function(){var el=this,uid=$(this).data('uid');$(el).removeClass('error').addClass('loader');$.post("index.php?option=com_jce&view=updates&task=update&step=download",{'id':uid},function(r){if(r&&r.error){$(el).removeClass('loader disabled check').addClass('error').parents('div.item').next('div.item.info').replaceWith('
      '+r.error+'
      ');}else{if(r.file){$(el).addClass('downloaded');$.extend(r,{'id':uid});t.updates[r.installer].push(r);}} if(n==(s.length)){t.install(btn);} n++;},'json');});},install:function(btn){var t=this,n=0;var s=$('div.body div.item span.checkbox.checked.downloaded');function __run(){var updates=t.updates['joomla'].length?t.updates['joomla']:t.updates['jce'];if(updates.length){var file=updates[0],id=file.id,el=$('span[data-uid='+id+']');if($(el).hasClass('downloaded')){$.post("index.php?option=com_jce&view=updates&task=update&step=install",file,function(r){$(el).removeClass('loader');if(r&&r.error){$(el).removeClass('loader disabled check').addClass('error').parents('div.item').next('div.item.info').replaceWith('
      '+r.error+'
      ');}else{$(el).addClass('tick').removeClass('check');$('div#update_info_'+id,'').append('

      '+t.options.language['install_info']+'

      '+r.text+'
      ');$(el).parents('div.item').find('span.priority').removeClass('label-warning label-important label-info').addClass('label-success').html(t.options.language['installed']);} updates.splice(0,1);n++;if(n');} $.each(elms,function(){self.createElement(el,ul,this);});if($(el).hasClass('sortable')){$(ul).addClass('sortable').sortable({axis:'y',tolerance:'intersect',update:function(event,ui){self.setValue(el,$(ui.item).parent());},placeholder:"ui-state-highlight"});}},createElement:function(el,ul,n){var self=this,d=document,li=d.createElement('li'),plugin,button,toolbar;$(li).attr({title:n.value}).addClass('ui-widget-content ui-corner-all').appendTo(ul);if($(el).hasClass('buttonlist')){var name=el.name,s=name.split(/[^\w]+/);if(s&&s.length>1){plugin=s[1];}} if(plugin){toolbar=$('span.profileLayoutContainerToolbar ul','#profileLayoutTable');button=$('span[data-button="'+n.value+'"]',toolbar);} $('').addClass('checkbox inline').prop('checked',n.selected).prop('disabled',n.disabled).click(function(){$(this).trigger('checklist:check',this.checked);}).appendTo(li).on('checklist:check',function(e,state){self.setValue(el,ul);if(button){$(button).toggle(state);} self.options.onCheck.call(self,[this,n]);}).val(n.value);$(li).append('');if(button&&$(el).hasClass('buttonlist')){$('label',li).before($(button).clone());}},setValue:function(el,ul,init){var x=$.map($('input[type="checkbox"]:checked',$('li',ul)),function(n){return $(n).val();});if(el.nodeName=='SELECT'){var options=[];$('option',el).each(function(i){var n=$.inArray(this.value,x);if(n>=0){$(this).attr('selected','selected').prop('selected',true);}else{$(this).removeAttr('selected').prop('selected',false);}});el.name=el.name.replace("[]","");if(x.length===0){$(el).change().removeClass('isdirty').after('');}else{$(el).change().next('input[type="hidden"]').remove();el.name+="[]";}}else{$(el).val(x.join(',')).change();}}};})(jQuery);components/com_jce/media/js/preferences.js000066600000002002150771655450014677 0ustar00/* JCE Editor - 2.4.3 | 11 September 2014 | http://www.joomlacontenteditor.net | Copyright (C) 2006 - 2014 Ryan Demmer. All rights reserved | GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html */ (function($){$.jce.Preferences={init:function(){var self=this;$('#tabs, #tabs-access-permissions').tabs({beforeActivate:function(event,ui){$(ui.oldTab).removeClass('active');$(ui.newTab).addClass('active');}}).find('ul.nav.nav-tabs > li:first-child').addClass('active');$('.hasTip').removeClass('hasTip');$('input[name="task"]').val('apply');$('#apply, #save').button().click(function(){if($(this).attr('id')=='save'){$('input[name="task"]').val('save');} $('form').submit();});$('#cancel').button().click(function(e){var win=window.parent;if(typeof win.SqueezeBox!=='undefined'){return win.SqueezeBox.close();}else{this.close();} e.preventDefault();});},close:function(){this.init();window.setTimeout(function(){window.parent.document.location.href="index.php?option=com_jce&view=cpanel";},1000);}};})(jQuery);components/com_jce/media/js/cpanel.js000066600000003746150771655450013660 0ustar00/* JCE Editor - 2.4.3 | 11 September 2014 | http://www.joomlacontenteditor.net | Copyright (C) 2006 - 2014 Ryan Demmer. All rights reserved | GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html */ (function($){$.jce.Cpanel={options:{labels:{feed:'Feed',updates:'Updates',updates_available:'Updates Available'},feed:true,updates:true},init:function(options){$.extend(this.options,options||{});var o=this.options;if(o.feed){$('ul.newsfeed').addClass('loading').html('
    • '+o.labels.feed+'
    • ');$.getJSON("index.php?option=com_jce&view=cpanel&task=feed",{},function(r){$('ul.newsfeed').removeClass('loading').empty();$.each(r.feeds,function(k,n){$('ul.newsfeed').append('
    • '+n.title+'
    • ');});});} if(o.updates){$.getJSON("index.php?option=com_jce&view=updates&task=update&step=check",{},function(r){if(r){if($.type(r)=='string'){r=$.parseJSON(r);} if(r.error){var $list=$('div#jce ul.adminformlist').append('
    • '+o.labels.updates+' '+r.error+'
    • ');return false;} if(r.length){var $list=$('div#jce ul.adminformlist').append('
    • '+o.labels.updates+' '+o.labels.updates_available+'
    • ');$('a.updates',$list).click(function(e){$('#toolbar-updates button').click();$('#toolbar-updates a.updates').each(function(){$.jce.createDialog(this,{src:$(this).attr('href'),options:{'width':780,'height':560}});e.preventDefault();});});}}});} $('#newsfeed_enable').click(function(e){$('#toolbar-options button').click();$('#toolbar-popup-options a.modal, #toolbar-config a.preferences').each(function(){$.jce.createDialog(this,{src:$(this).attr('href'),options:{'width':780,'height':560}});});e.preventDefault();});}};$(document).ready(function(){$.jce.Cpanel.init();});})(jQuery);components/com_jce/media/js/index.html000066600000000054150771655450014042 0ustar00components/com_jce/media/js/users.js000066600000002126150771655450013546 0ustar00/* JCE Editor - 2.4.3 | 11 September 2014 | http://www.joomlacontenteditor.net | Copyright (C) 2006 - 2014 Ryan Demmer. All rights reserved | GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html */ (function($){$.jce.Users={select:function(){var u=[],v,o,h,s=window.parent.document.getElementById('users');$('input:checkbox:checked').each(function(){v=$(this).val();if(u=document.getElementById('username_'+v)){h=$.trim(u.innerHTML);if($.jce.Users.check(s,v)){return;} var li=document.createElement('li');li.innerHTML='';s.appendChild(li);}});this.close();},check:function(s,v){$.each(s.childNodes,function(i,n){var input=n.firstChild;if(input.value===v){return true;}});return false;},close:function(){var win=window.parent;if(typeof win.SqueezeBox!=='undefined'){win.SqueezeBox.close();}}};$(document).ready(function(){$('#cancel').click(function(e){$.jce.Users.close();e.preventDefault();});$('#select').click(function(e){$.jce.Users.select();e.preventDefault();});});})(jQuery);components/com_jce/media/js/blockformats.js000066600000001472150771655450015076 0ustar00/* JCE Editor - 2.4.3 | 11 September 2014 | http://www.joomlacontenteditor.net | Copyright (C) 2006 - 2014 Ryan Demmer. All rights reserved | GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html */ (function($){$(document).ready(function(){$('div.blockformats').on('update',function(){var v=$('li input[type="checkbox"]:checked',this).map(function(){return this.value;}).get().join();$('input[type="hidden"]',this).val(v).change();});$('input[type="checkbox"]','div.blockformats').on('click',function(){$('div.blockformats').trigger('update');});$('div.blockformats ul').sortable({axis:'y',update:function(event,ui){$('div.blockformats').trigger('update');},placeholder:"blockformat-highlight",start:function(event,ui){$(ui.placeholder).height($(ui.item).height()).width($(ui.item).width());}});});})(jQuery);components/com_jce/media/js/uploads.js000066600000007223150771655450014057 0ustar00/* JCE Editor - 2.4.3 | 11 September 2014 | http://www.joomlacontenteditor.net | Copyright (C) 2006 - 2014 Ryan Demmer. All rights reserved | GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html */ (function($){$.widget("ui.upload",{options:{labels:{browse:'Browse',alert:'Incorrect file type'},extensions:['xml'],readonly:false,width:200,task:null,button:null,iframe:false,report:null},_init:function(){var self=this;$(document).ready(function(){self._createUploader();});},_createUploader:function(){var self=this,o=this.options,iframe;var re='.('+o.extensions.join('|')+')$';var $form=$('form[name="adminForm"]');if(o.iframe){iframe=this.createIFrame();} var $button=$(''; } else { $html = ''; $html .= '' . WFText::_('WF_HELP') . ''; } $bar->appendButton('Custom', $html, 'help'); } /** * Writes a configuration button and invokes a cancel operation (eg a checkin) * @param string The name of the component, eg, com_content * @param int The height of the popup * @param int The width of the popup * @param string The name of the button * @param string An alternative path for the configuation xml relative to JPATH_SITE * @since 1.0 */ public static function preferences() { if (defined('JPATH_PLATFORM')) { JToolbarHelper::preferences('com_jce'); } else { $bar = JToolBar::getInstance('toolbar'); $link = 'index.php?option=com_jce&view=preferences&tmpl=component'; $w = 780; $h = 560; $html = ''; $html .= '' . WFText::_('WF_PREFERENCES') . ''; $bar->appendButton('Custom', $html, 'config'); } } /** * Writes a configuration button and invokes a cancel operation (eg a checkin) * @param string The name of the component, eg, com_content * @param int The height of the popup * @param int The width of the popup * @param string The name of the button * @param string An alternative path for the configuation xml relative to JPATH_SITE * @since 1.0 */ public static function updates($enabled = false) { $bar = JToolBar::getInstance('toolbar'); // Add a configuration button $w = 780; $h = 560; $link = 'index.php?option=com_jce&view=updates&tmpl=component'; if ($enabled) { JHtml::_('behavior.modal'); if (class_exists('JHtmlSidebar')) { $html = ''; } else { $html = ''; $html .= '' . WFText::_('WF_UPDATES') . ''; } $bar->appendButton('Custom', $html, 'updates'); } } /*public static function access() { $bar = JToolBar::getInstance('toolbar'); $options = array( 'width' => 760, 'height' => 540, 'modal' => true, 'buttons' => '{}' ); $html = ''; $html .= '' . WFText::_('WF_ACCESS') . ''; $bar->appendButton('Custom', $html, 'access'); }*/ public static function export() { if (class_exists('JHtmlSidebar')) { $icon = 'download'; } else { $icon = defined('JPATH_PLATFORM') ? 'export' : 'unarchive'; } self::custom('export', $icon, $icon . '_f2', 'WF_PROFILES_EXPORT', true); } public static function save($task = 'save') { return JToolBarHelper::save($task); } public static function apply($task = 'apply') { return JToolbarHelper::apply($task); } public static function cancel($task = 'cancel') { return JToolbarHelper::cancel($task); } public static function editListx($task = 'edit') { if (method_exists('JToolbarHelper', 'editListx')) { return JToolbarHelper::editListx($task); } return JToolbarHelper::editList($task); } public static function addNewx($task = 'add') { if (method_exists('JToolbarHelper', 'addNewx')) { return JToolbarHelper::addNewx($task); } return JToolbarHelper::addNew($task); } public static function custom($task = '', $icon = '', $iconOver = '', $alt = '', $listSelect = true, $x = false) { return JToolbarHelper::custom($task, $icon, $iconOver, $alt, $listSelect, $x); } public static function publishList($task = 'publish') { return JToolbarHelper::publishList($task); } public static function unpublishList($task = 'unpublish') { return JToolbarHelper::unpublishList($task); } public static function deleteList($msg = '', $task = 'remove', $alt = '') { return JToolbarHelper::deleteList($msg, $task, $alt); } } ?> components/com_jce/helpers/plugins.php000066600000007111150771655450014207 0ustar00load('com_jce', JPATH_ADMINISTRATOR); foreach ($plugins as $plugin) { $name = basename($plugin); $manifest = $plugin . '/' . $name . '.xml'; if (is_file($manifest)) { $xml = JFactory::getXML($manifest); // cannot load xml file if (!$xml) { continue; } // not a valid plugin/extension if ($xml->getName() != 'install' && $xml->getName() != 'extension') { continue; } if ((int) $xml->attributes()->core == 0) { $language->load('com_jce_' . $name, JPATH_SITE); $addons[$name] = array( 'version' => (string) $xml->version, 'title' => JText::_((string) $xml->name), 'description' => JText::_((string) $xml->description), 'path' => 'components/com_jce/editor/tiny_mce/plugins/' . $name ); } } } foreach ($extensions as $extension) { // extension name, eg: jcemediabox $name = basename($extension, '.xml'); // extension folder, eg: popups $folder = basename(dirname($extension)); $xml = JFactory::getXML($extension); // cannot load xml file if (!$xml) { continue; } // not a valid plugin/extension if ($xml->getName() != 'install' && $xml->getName() != 'extension') { continue; } if ((int) $xml->attributes()->core == 0) { $language->load('com_jce_' . $folder . '_' . $name, JPATH_SITE); $addons[$folder . '_' . $name] = array( 'version' => (string) $xml->version, 'title' => JText::_((string) $xml->name), 'description' => JText::_((string) $xml->description), 'path' => 'components/com_jce/editor/extensions/' . $folder ); } } return $addons; } } ?>components/com_jce/helpers/editor.php000066600000002431150771655450014014 0ustar00#', // replace template css etc. '#]+>#', // remove body class etc. '#]*>#', // remove extra line breaks '#\n{4}+#' ); $replace = array( '', '', '', '' ); $buffer = preg_replace(str_replace('/', '\/', $search), $replace, $buffer); JResponse::setBody($buffer); return true; } } ?>components/com_jce/helpers/updates.php000066600000034662150771655450014206 0ustar00 * * Based on the LiveUpdateDownloadHelper class from Akeeba LiveUpdate */ defined('_JEXEC') or die(); /** * Check for and download updates from a remote server */ class UpdatesHelper { private static function applyCACert(&$ch) { $cacert = dirname(__FILE__) . '/cacert.pem'; if (file_exists($cacert)) { @curl_setopt($ch, CURLOPT_CAINFO, $cacert); return true; } return false; } /** * Fetches update information from the server using cURL or fopen * @param string $url The URL to check * @param string $data Data to send via POST * * @return mixed Result string on success, false on failure */ public function check($url, $data) { $result = false; if (self::hasCURL()) { $ch = curl_init($url); self::applyCACert($ch); curl_setopt($ch, CURLOPT_HEADER, 0); // Pretend we are Firefox, so that webservers play nice with us curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.14) Gecko/20110105 Firefox/3.6.14'); curl_setopt($ch, CURLOPT_ENCODING, 'gzip'); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // The @ sign allows the next line to fail if open_basedir is set or if safe mode is enabled @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); @curl_setopt($ch, CURLOPT_MAXREDIRS, 20); // add post data if ($data) { curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); } $result = curl_exec($ch); // file download if ($result === false) { return array('error' => 'CURL ERROR : ' . curl_error($ch)); } curl_close($ch); } else if (self::hasFOPEN()) { $options = array('http' => array('method' => 'POST', 'timeout' => 10, 'content' => $data)); $context = stream_context_create($options); $result = @file_get_contents($url, false, $context); if ($result === false) { return array('error' => WFText::_('Update check failed : Invalid response from update server')); } } return $result; } /** * Downloads from a URL and saves the result as a local file * * @param string $url The URL to fetch * @param string $target Where to save the file * * @return boolean True on success */ public static function download($url, $target) { // Import Joomla! libraries JLoader::import('joomla.filesystem.file'); /** @var bool Did we try to force permissions? */ $hackPermissions = false; // Make sure the target does not exist if (JFile::exists($target)) { if (!@unlink($target)) { JFile::delete($target); } } // Try to open the output file for writing $fp = @fopen($target, 'wb'); if ($fp === false) { // The file can not be opened for writing. Let's try a hack. $empty = ''; if (JFile::write($target, $empty)) { if (self::chmod($target, 511)) { $fp = @fopen($target, 'wb'); $hackPermissions = true; } } } $result = false; if ($fp !== false) { // First try to download directly to file if $fp !== false $adapters = self::getAdapters(); $result = false; while (!empty($adapters) && ($result === false)) { // Run the current download method $method = 'get' . strtoupper(array_shift($adapters)); $result = self::$method($url, $fp); // Check if we have a download if ($result === true) { // The download is complete, close the file pointer @fclose($fp); // If the filesize is not at least 1 byte, we consider it failed. clearstatcache(); $filesize = @filesize($target); if ($filesize <= 0) { $result = false; $fp = @fopen($target, 'wb'); } } } // If we have no download, close the file pointer if ($result === false) { @fclose($fp); } } if ($result === false) { // Delete the target file if it exists if (file_exists($target)) { if (!@unlink($target)) { JFile::delete($target); } } // Download and write using JFile::write(); $result = JFile::write($target, self::downloadAndReturn($url)); } return $result; } /** * Downloads from a URL and returns the result as a string * * @param string $url The URL to download from * * @return mixed Result string on success, false on failure */ public static function downloadAndReturn($url) { $adapters = self::getAdapters(); $result = false; while (!empty($adapters) && ($result === false)) { // Run the current download method $method = 'get' . strtoupper(array_shift($adapters)); $result = self::$method($url, null); } return $result; } /** * Does the server support PHP's cURL extension? * * @return boolean True if it is supported */ public static function hasCURL() { static $result = null; if (is_null($result)) { $result = function_exists('curl_init'); if ($result) { $cacert = JPATH_LIBRARIES . '/joomla/http/transport/cacert.pem'; // check for SSL support $version = curl_version(); $ssl_supported = ($version['features'] & CURL_VERSION_SSL); $result = (bool) $ssl_supported && file_exists($cacert); } } return $result; } /** * Downloads the contents of a URL and writes them to disk (if $fp is not null) * or returns them as a string (if $fp is null) using cURL * * @param string $url The URL to download from * @param resource $fp The file pointer to download to. Omit to return the contents. * * @return boolean|string False on failure, true on success ($fp not null) or the URL contents (if $fp is null) */ private static function &getCURL($url, $fp = null, $nofollow = false) { $result = false; $ch = curl_init($url); self::applyCACert($ch); if (!@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1) && !$nofollow) { // Safe Mode is enabled. We have to fetch the headers and // parse any redirections present in there. curl_setopt($ch, CURLOPT_AUTOREFERER, true); curl_setopt($ch, CURLOPT_FAILONERROR, true); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_TIMEOUT, 30); // Get the headers $data = curl_exec($ch); curl_close($ch); // Init $newURL = $url; // Parse the headers $lines = explode("\n", $data); foreach ($lines as $line) { if (substr($line, 0, 9) == "Location:") { $newURL = trim(substr($line, 9)); } } // Download from the new URL if ($url != $newURL) { return self::getCURL($newURL, $fp); } else { return self::getCURL($newURL, $fp, true); } } else { @curl_setopt($ch, CURLOPT_MAXREDIRS, 20); } curl_setopt($ch, CURLOPT_AUTOREFERER, true); curl_setopt($ch, CURLOPT_FAILONERROR, true); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_TIMEOUT, 30); // Pretend we are IE7, so that webservers play nice with us curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)'); if (is_resource($fp)) { curl_setopt($ch, CURLOPT_FILE, $fp); } $result = curl_exec($ch); curl_close($ch); return $result; } /** * Does the server support URL fopen() wrappers? * * @return boolean */ public static function hasFOPEN() { static $result = null; if (is_null($result)) { // If we are not allowed to use ini_get, we assume that URL fopen is // disabled. if (!function_exists('ini_get')) { $result = false; } else { // get wrappers $wrappers = stream_get_wrappers(); $result = ini_get('allow_url_fopen') && in_array('https', $wrappers); } } return $result; } /** * Downloads the contents of a URL and writes them to disk (if $fp is not null) * or returns them as a string (if $fp is null) using fopen() URL wrappers * * @param string $url The URL to download from * @param resource $fp The file pointer to download to. Omit to return the contents. * * @return boolean|string False on failure, true on success ($fp not null) or the URL contents (if $fp is null) */ private static function &getFOPEN($url, $fp = null) { $result = false; // Track errors if (function_exists('ini_set')) { $track_errors = ini_set('track_errors', true); } // Open the URL for reading if (function_exists('stream_context_create')) { // PHP 5+ way (best) $httpopts = array( 'user_agent' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)', 'timeout' => 10.0, ); $context = stream_context_create(array('http' => $httpopts)); $ih = @fopen($url, 'r', false, $context); } else { // PHP 4 way (actually, it's just a fallback as we can't run this code in PHP4) if (function_exists('ini_set')) { ini_set('user_agent', 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)'); } $ih = @fopen($url, 'r'); } // If fopen() fails, abort if (!is_resource($ih)) { return $result; } // Try to download $bytes = 0; $result = true; $return = ''; while (!feof($ih) && $result) { $contents = fread($ih, 4096); if ($contents === false) { @fclose($ih); $result = false; return $result; } else { $bytes += strlen($contents); if (is_resource($fp)) { $result = @fwrite($fp, $contents); } else { $return .= $contents; unset($contents); } } } @fclose($ih); if (is_resource($fp)) { return $result; } elseif ($result === true) { return $return; } else { return $result; } } /** * Detect and return available download methods * * @return array */ private static function getAdapters() { // Detect available adapters $adapters = array(); if (self::hasCURL()) $adapters[] = 'curl'; if (self::hasFOPEN()) $adapters[] = 'fopen'; return $adapters; } /** * Change the permissions of a file, optionally using FTP * * @param string $file Absolute path to file * @param int $mode Permissions, e.g. 0755 * * @return boolean Ture if successful */ private static function chmod($path, $mode) { if (is_string($mode)) { $mode = octdec($mode); if (($mode < 0600) || ($mode > 0777)) $mode = 0755; } // Initialize variables JLoader::import('joomla.client.helper'); $ftpOptions = JClientHelper::getCredentials('ftp'); // Check to make sure the path valid and clean $path = JPath::clean($path); if ($ftpOptions['enabled'] == 1) { // Connect the FTP client JLoader::import('joomla.client.ftp'); if (version_compare(JVERSION, '3.0', 'ge')) { $ftp = JClientFTP::getInstance( $ftpOptions['host'], $ftpOptions['port'], array(), $ftpOptions['user'], $ftpOptions['pass'] ); } else { if (version_compare(JVERSION, '3.0', 'ge')) { $ftp = JClientFTP::getInstance( $ftpOptions['host'], $ftpOptions['port'], array(), $ftpOptions['user'], $ftpOptions['pass'] ); } else { $ftp = JFTP::getInstance( $ftpOptions['host'], $ftpOptions['port'], array(), $ftpOptions['user'], $ftpOptions['pass'] ); } } } if (@chmod($path, $mode)) { $ret = true; } elseif ($ftpOptions['enabled'] == 1) { // Translate path and delete JLoader::import('joomla.client.ftp'); $path = JPath::clean(str_replace(JPATH_ROOT, $ftpOptions['root'], $path), '/'); // FTP connector throws an error $ret = $ftp->chmod($path, $mode); } else { return false; } } } components/com_jce/helpers/encrypt.php000066600000014765150771655450014227 0ustar00"; $filename = JPATH_COMPONENT_ADMINISTRATOR . '/serverkey.php'; $result = JFile::write($filename, $filecontents); if (!$result) { return ''; } else { return base64_decode($key); } } /** * Gets the configured server key, automatically loading the server key storage file * if required. * @return string */ public static function getKey() { if (defined('WF_SERVERKEY')) { return base64_decode(WF_SERVERKEY); } $filename = dirname(dirname(__FILE__)) . '/serverkey.php'; if (file_exists($filename)) { include_once $filename; if (defined('WF_SERVERKEY')) { return base64_decode(WF_SERVERKEY); } } else { return self::generateKey(); } } /** * Do the server options allow us to use settings encryption? * @return bool */ public static function supportsEncryption() { // Do we have base64_encode/_decode required for encryption? if (!function_exists('base64_encode') || !function_exists('base64_decode')) { return false; } // Pre-requisites met. We can encrypt and decrypt! return true; } /** * Gets the preferred encryption mode. Currently, if mcrypt is installed and activated we will * use AES128. * @return string */ public static function preferredEncryption() { if (function_exists('mcrypt_module_open')) { return 'AES128'; } else { return 'CTR128'; } } /** * Encrypts the settings using the automatically detected preferred algorithm * @param $settingsINI string The raw settings INI string * @return string The encrypted data to store in the database */ public static function encrypt($data, $key = null) { // Do we really support encryption? if (!self::supportsEncryption()) return $data; // Does any of the preferred encryption engines exist? $encryption = self::preferredEncryption(); if (empty($encryption)) return $data; // Do we have a non-empty key to begin with? if (empty($key)) $key = self::getKey(); if (empty($key)) return $data; if ($encryption == 'AES128') { $encrypted = WFUtilEncrypt::AESEncryptCBC($data, $key, 128); if (empty($encrypted)) { $encryption = 'CTR128'; } else { // Note: CBC returns the encrypted data as a binary string and requires Base 64 encoding $data = '###AES128###' . base64_encode($encrypted); } } if ($encryption == 'CTR128') { $encrypted = WFUtilEncrypt::AESEncryptCtr($settingsINI, $key, 128); if (empty($encrypted)) { $encryption = ''; } else { // Note: CTR returns the encrypted data readily encoded in Base 64 $data = '###CTR128###' . $encrypted; } } return $data; } /** * Decrypts the encrypted settings and returns the plaintext INI string * @param $encrypted string The encrypted data * @return string The decrypted data */ public static function decrypt($encrypted, $key = null) { if (substr($encrypted, 0, 12) == '###AES128###') { $mode = 'AES128'; } elseif (substr($encrypted, 0, 12) == '###CTR128###') { $mode = 'CTR128'; } else { return $encrypted; } if (empty($key)) { $key = self::getKey(); } $encrypted = substr($encrypted, 12); switch ($mode) { case 'AES128': $encrypted = base64_decode($encrypted); $decrypted = WFUtilEncrypt::AESDecryptCBC($encrypted, $key, 128); break; case 'CTR128': $decrypted = WFUtilEncrypt::AESDecryptCtr($encrypted, $key, 128); break; } return rtrim($decrypted, "\0"); } } components/com_jce/install.php000066600000125706150771655450012545 0ustar00load('com_jce', JPATH_ADMINISTRATOR, null, true); $language->load('com_jce.sys', JPATH_ADMINISTRATOR, null, true); // get manifest $manifest = $installer->getManifest(); $new_version = (string) $manifest->version; // Joomla! 1.5 if (!defined('JPATH_PLATFORM') && !$new_version) { $new_version = (string) $manifest->document->getElementByPath('version')->data(); } // get version from xml file if (!$manifest) { $manifest = JApplicationHelper::parseXMLInstallFile($installer->getPath('manifest')); if (is_array($manifest)) { $new_version = $manifest['version']; } } $state = false; // the current version $current_version = $new_version; if (defined('JPATH_PLATFORM')) { $xml_file = $installer->getPath('extension_administrator') . '/jce.xml'; // check for an xml file if (is_file($xml_file)) { if ($xml = JApplicationHelper::parseXMLInstallFile($xml_file)) { $current_version = $xml['version']; } } } else { if (basename($installer->getPath('manifest')) == 'legacy.xml') { $xml_file = JPATH_PLUGINS . '/editors/jce.xml'; // check for an xml file if ($xml = JApplicationHelper::parseXMLInstallFile($xml_file)) { $current_version = $xml['version']; } else { // check for old tables if (self::checkTable('#__jce_groups')) { $current_version = '1.5.0'; } // check for old tables if (self::checkTable('#__jce_profiles')) { $current_version = '2.0.0beta1'; } } } } // install profiles etc. $state = self::installProfiles(); // perform upgrade if (version_compare($current_version, $new_version, '<')) { $state = self::upgrade($current_version); } // Add device column if (self::checkTableColumn('#__wf_profiles', 'device') === false) { $db = JFactory::getDBO(); switch (strtolower($db->name)) { case 'mysql': case 'mysqli': $query = 'ALTER TABLE #__wf_profiles CHANGE `description` `description` TEXT'; $db->setQuery($query); $db->query(); // Change types field to TEXT $query = 'ALTER TABLE #__wf_profiles CHANGE `types` `types` TEXT'; $db->setQuery($query); $db->query(); // Add device field - MySQL $query = 'ALTER TABLE #__wf_profiles ADD `device` VARCHAR(255) AFTER `area`'; break; case 'sqlsrv': case 'sqlazure': case 'sqlzure': $query = 'ALTER TABLE #__wf_profiles ADD `device` NVARCHAR(250)'; break; case 'postgresql': $query = 'ALTER TABLE #__wf_profiles ADD "device" character varying(255) NOT NULL'; break; } $db->setQuery($query); $db->query(); } if ($state) { // legacy (JCE 1.5) cleanup if (!defined('JPATH_PLATFORM')) { self::legacyCleanup(); } $message = '
      '; $message .= '

      ' . JText::_('WF_ADMIN_TITLE') . ' ' . $new_version . '

      '; $message .= '
        '; $message .= '
      • ' . JText::_('WF_ADMIN_DESC') . '
      • '; // install packages (editor plugin, quickicon etc) $packages = $installer->getPath('source') . '/packages'; // install additional packages if (is_dir($packages)) { $message .= self::installPackages($packages); } $message .= '
      '; $message .= '
      '; $installer->set('message', $message); // post-install self::addIndexfiles(array(dirname(__FILE__), JPATH_SITE . '/components/com_jce', JPATH_PLUGINS . '/jce')); } else { $installer->abort(); return false; } } private static function paramsToObject($data) { $registry = new JRegistry(); $registry->loadIni($data); return $registry->toObject(); } private static function loadXMLFile($file) { $xml = null; // Disable libxml errors and allow to fetch error information as needed libxml_use_internal_errors(true); if (is_file($file)) { // Try to load the xml file $xml = simplexml_load_file($file); } return $xml; } // Upgrade from JCE 1.5.x private static function upgradeLegacy() { $app = JFactory::getApplication(); $db = JFactory::getDBO(); $admin = JPATH_ADMINISTRATOR . '/components/com_jce'; $site = JPATH_SITE . '/components/com_jce'; //require_once($admin . '/helpers/parameter.php'); // check for groups table / data if (self::checkTable('#__jce_groups') && self::checkTableContents('#__jce_groups')) { jimport('joomla.plugin.helper'); // get plugin $plugin = JPluginHelper::getPlugin('editors', 'jce'); // get JCE component $table = JTable::getInstance('component'); $table->loadByOption('com_jce'); // process params to JSON string $params = self::paramsToObject($table->params); // set params $table->params = json_encode(array('editor' => $params)); // store $table->store(); // get all groups data $query = 'SELECT * FROM #__jce_groups'; $db->setQuery($query); $groups = $db->loadObjectList(); // get all plugin data $query = 'SELECT id, name, icon FROM #__jce_plugins'; $db->setQuery($query); $plugins = $db->loadAssocList('id'); $map = array( 'advlink' => 'link', 'advcode' => 'source', 'tablecontrols' => 'table', 'cut,copy,paste' => 'clipboard', 'paste' => 'clipboard', 'search,replace' => 'searchreplace', 'cite,abbr,acronym,del,ins,attribs' => 'xhtmlxtras', 'styleprops' => 'style', 'readmore,pagebreak' => 'article', 'ltr,rtl' => 'directionality', 'insertlayer,moveforward,movebackward,absolute' => 'layer' ); if (self::createProfilesTable()) { foreach ($groups as $group) { $row = JTable::getInstance('profiles', 'WFTable'); $rows = array(); // transfer row ids to names foreach (explode(';', $group->rows) as $item) { $icons = array(); foreach (explode(',', $item) as $id) { // spacer if ($id == '00') { $icon = 'spacer'; } else { if (isset($plugins[$id])) { $icon = $plugins[$id]['icon']; // map old icon names to new if (array_key_exists($icon, $map)) { $icon = $map[$icon]; } } } $icons[] = $icon; } $rows[] = implode(',', $icons); } // re-assign rows $row->rows = implode(';', $rows); $names = array('anchor'); // add lists if (preg_match('#(numlist|bullist)#', $row->rows)) { $names[] = 'lists'; } // add charmap if (strpos($row->rows, 'charmap') !== false) { $names[] = 'charmap'; } // transfer plugin ids to names foreach (explode(',', $group->plugins) as $id) { if (isset($plugins[$id])) { $name = $plugins[$id]['name']; // map old icon names to new if (array_key_exists($name, $map)) { $name = $map[$name]; } $names[] = $name; } } // re-assign plugins $row->plugins = implode(',', $names); // convert params to JSON $params = self::paramsToObject($group->params); $data = new StdClass(); // Add lists plugin $buttons = array(); if (strpos($row->rows, 'numlist') !== false) { $buttons[] = 'numlist'; // replace "numlist" with "lists" $row->rows = str_replace('numlist', 'lists', $row->rows); } if (strpos($row->rows, 'bullist') !== false) { $buttons[] = 'bullist'; // replace "bullist" with "lists" if (strpos($row->rows, 'lists') === false) { $row->rows = str_replace('bullist', 'lists', $row->rows); } } // remove bullist and numlist $row->rows = str_replace(array('bullist', 'numlist'), '', $row->rows); // add lists buttons parameter if (!empty($buttons)) { $params->lists_buttons = $buttons; } // convert parameters foreach ($params as $key => $value) { $parts = explode('_', $key); $node = array_shift($parts); // special consideration for imgmanager_ext!! if (strpos($key, 'imgmanager_ext_') !== false) { $node = $node . '_' . array_shift($parts); } // convert some nodes if (isset($map[$node])) { $node = $map[$node]; } $key = implode('_', $parts); if ($value !== '') { if (!isset($data->$node) || !is_object($data->$node)) { $data->$node = new StdClass(); } // convert Link parameters if ($node == 'link' && $key != 'target') { $sub = $key; $key = 'links'; if (!isset($data->$node->$key)) { $data->$node->$key = new StdClass(); } if (preg_match('#^(content|contacts|static|weblinks|menu)$#', $sub)) { if (!isset($data->$node->$key->joomlalinks)) { $data->$node->$key->joomlalinks = new StdClass(); $data->$node->$key->joomlalinks->enable = 1; } $data->$node->$key->joomlalinks->$sub = $value; } else { $data->$node->$key->$sub = new StdClass(); $data->$node->$key->$sub->enable = 1; } } else { $data->$node->$key = $value; } } } // re-assign params $row->params = json_encode($data); // re-assign other values $row->name = $group->name; $row->description = $group->description; $row->users = $group->users; $row->types = $group->types; $row->components = $group->components; $row->published = $group->published; $row->ordering = $group->ordering; // add area data if ($row->name == 'Default') { $row->area = 0; } if ($row->name == 'Front End') { $row->area = 1; } if (self::checkTable('#__wf_profiles')) { $name = $row->name; // check for existing profile $query = 'SELECT id FROM #__wf_profiles' . ' WHERE name = ' . $db->Quote($name); $db->setQuery($query); // create name copy if exists while ($db->loadResult()) { $name = JText::sprintf('WF_PROFILES_COPY_OF', $name); $query = 'SELECT id FROM #__wf_profiles' . ' WHERE name = ' . $db->Quote($name); $db->setQuery($query); } // set name $row->name = $name; } if (!$row->store()) { $app->enqueueMessage('Conversion of group data failed : ' . $row->name, 'error'); } else { $app->enqueueMessage('Conversion of group data successful : ' . $row->name); } unset($row); } // If profiles table empty due to error, install profiles data if (!self::checkTableContents('#__wf_profiles')) { self::installProfiles(); } else { // add Blogger profile self::installProfile('Blogger'); // add Mobile profile self::installProfile('Mobile'); } } else { return false; } // Install profiles } else { self::installProfiles(); } // Remove Plugins menu item $query = 'DELETE FROM #__components' . ' WHERE admin_menu_link = ' . $db->Quote('option=com_jce&type=plugins'); $db->setQuery($query); $db->query(); // Update Component Name $query = 'UPDATE #__components' . ' SET name = ' . $db->Quote('COM_JCE') . ' WHERE ' . $db->Quote('option') . '=' . $db->Quote('com_jce') . ' AND parent = 0'; $db->setQuery($query); $db->query(); // Fix links for other views and edit names $menus = array('install' => 'installer', 'group' => 'profiles', 'groups' => 'profiles', 'config' => 'config'); $row = JTable::getInstance('component'); foreach ($menus as $k => $v) { $query = 'SELECT id FROM #__components' . ' WHERE admin_menu_link = ' . $db->Quote('option=com_jce&type=' . $k); $db->setQuery($query); $id = $db->loadObject(); if ($id) { $row->load($id); $row->name = $v; $row->admin_menu_link = 'option=com_jce&view=' . $v; if (!$row->store()) { $mainframe->enqueueMessage('Unable to update Component Links for view : ' . strtoupper($v), 'error'); } } } // remove old admin language files $folders = JFolder::folders(JPATH_ADMINISTRATOR . '/language', '.', false, true, array('.svn', 'CVS', 'en-GB')); foreach ($folders as $folder) { $name = basename($folder); $files = array($name . '.com_jce.ini', $name . '.com_jce.menu.ini', $name . '.com_jce.xml'); foreach ($files as $file) { if (is_file($folder . '/' . $file)) { @JFile::delete($folder . '/' . $file); } } } // remove old site language files $folders = JFolder::folders(JPATH_SITE . '/language', '.', false, true, array('.svn', 'CVS', 'en-GB')); foreach ($folders as $folder) { $files = JFolder::files($folder, '^' . basename($folder) . '\.com_jce([_a-z0-9]+)?\.(ini|xml)$', false, true); @JFile::delete($files); } // remove legacy admin folders $folders = array('cpanel', 'config', 'css', 'groups', 'plugins', 'img', 'installer', 'js'); foreach ($folders as $folder) { if (is_dir($admin . '/' . $folder)) { @JFolder::delete($admin . '/' . $folder); } } // remove legacy admin files $files = array('editor.php', 'helper.php', 'updater.php'); foreach ($files as $file) { if (is_file($admin . '/' . $file)) { @JFile::delete($admin . '/' . $file); } } // remove legacy admin folders $folders = array('controller', 'css', 'js'); foreach ($folders as $folder) { if (is_dir($site . '/' . $folder)) { @JFolder::delete($site . '/' . $folder); } } // remove legacy admin files $files = array('popup.php'); foreach ($files as $file) { if (is_file($site . '/' . $file)) { @JFile::delete($site . '/' . $file); } } if (!defined('JPATH_PLATFORM')) { // remove old plugin folder $path = JPATH_PLUGINS . '/editors'; if (is_dir($path . '/jce')) { @JFolder::delete($path . '/jce'); } } return true; } private static function installProfile($name) { $db = JFactory::getDBO(); $query = $db->getQuery(true); if (is_object($query)) { $query->select('COUNT(id)')->from('#__wf_profiles')->where('name = ' . $db->Quote($name)); } else { $query = 'SELECT COUNT(id) FROM #__wf_profiles WHERE name = ' . $db->Quote($name); } $db->setQuery($query); $id = $db->loadResult(); if (!$id) { // Blogger $file = JPATH_ADMINISTRATOR . '/components/com_jce/models/profiles.xml'; $xml = self::loadXMLFile($file); if ($xml) { foreach ($xml->profiles->children() as $profile) { if ((string) $profile->attributes()->name == $name) { $row = JTable::getInstance('profiles', 'WFTable'); require_once(JPATH_ADMINISTRATOR . '/components/com_jce/models/profiles.php'); $groups = WFModelProfiles::getUserGroups((int) $profile->children('area')); foreach ($profile->children() as $item) { switch ((string) $item->getName()) { case 'types': $row->types = implode(',', $groups); break; case 'area': $row->area = (int) $item; break; case 'rows': $row->rows = (string) $item; break; case 'plugins': $row->plugins = (string) $item; break; default: $key = $item->getName(); $row->$key = (string) $item; break; } } $row->store(); } } } } } /** * Upgrade database tables and remove legacy folders * @return Boolean */ private static function upgrade($version) { $app = JFactory::getApplication(); $db = JFactory::getDBO(); jimport('joomla.filesystem.folder'); jimport('joomla.filesystem.file'); $admin = JPATH_ADMINISTRATOR . '/components/com_jce'; $site = JPATH_SITE . '/components/com_jce'; // add tables path JTable::addIncludePath($admin . '/tables'); // upgrade from 1.5.x to 2.0.0 (only in Joomla! 1.5) if (version_compare($version, '2.0.0', '<') && !defined('JPATH_PLATFORM')) { return self::upgradeLegacy(); }// end JCE 1.5 upgrade // Remove folders $folders = array( // Remove JQuery folders from admin $admin . '/media/css/jquery', $admin . '/media/js/jquery', // remove plugin package folder $admin . '/plugin', // remove legend view $admin . '/views/legend', // remove controller from site $site . '/controller', // Remove plugin language files (incorporated into main language file) $site . '/editor/tiny_mce/plugins/article/langs', $site . '/editor/tiny_mce/plugins/imgmanager/langs', $site . '/editor/tiny_mce/plugins/link/langs', $site . '/editor/tiny_mce/plugins/searchreplace/langs', $site . '/editor/tiny_mce/plugins/style/langs', $site . '/editor/tiny_mce/plugins/table/langs', $site . '/editor/tiny_mce/plugins/xhtmlxtras/langs', // remove paste folder $site . '/editor/tiny_mce/plugins/paste', // remove jquery $site . '/editor/libraries/js/jquery', // remove browser extension $site . '/editor/extensions/browser', // remove browser langs $site . '/editor/tiny_mce/plugins/browser/langs', // remove packages $admin . '/packages', // remove tinymce langs $site . '/editor/tiny_mce/langs', // remove dragupload folder (ranamed to upload) $site . '/editor/tiny_mce/plugins/dragupload', // remove googlemaps $site . '/editor/extensions/aggregator/googlemaps' ); foreach ($folders as $folder) { if (JFolder::exists($folder)) { @JFolder::delete($folder); } } // Remove files $files = array( // remove javascript files from admin (moved to site) $admin . '/media/js/colorpicker.js', $admin . '/media/js/help.js', $admin . '/media/js/html5.js', $admin . '/media/js/select.js', $admin . '/media/js/tips.js', // remove legend.js $admin . '/media/js/legend.js', // remove css files from admin (moved to site) $admin . '/media/css/help.css', $admin . '/media/css/select.css', $admin . '/media/css/tips.css', // remove legend model $admin . '/models/legend.php', // remove extension adapter $admin . '/adapters/extension.php', // remove error class from site (moved to admin) $site . '/editor/libraries/classes/error.php', // remove popup file $site . '/popup.php', // remove anchor from theme (moved to plugins) $site . '/editor/tiny_mce/themes/advanced/css/anchor.css', $site . '/editor/tiny_mce/themes/advanced/css/js/anchor.js', $site . '/editor/tiny_mce/themes/advanced/css/tmpl/anchor.php', // remove redundant file $site . '/editor/tiny_mce/themes/advanced/css/skins/default/img/items.gif', // remove search files from file browser (renamed to filter) $site . '/editor/extensions/browser/css/search.css', $site . '/editor/extensions/browser/js/search.js', $site . '/editor/extensions/browser/search.php', // remove dilg language file from theme (incorporated into main dlg file) $site . '/editor/tiny_mce/themes/advanced/langs/en_dlg.js', // remove old jquery UI $site . '/editor/libraries/jquery/js/jquery-ui-1.9.0.custom.min.js', // remove "theme" files $site . '/editor/libraries/classes/theme.php', $site . '/editor/tiny_mce/themes/advanced/theme.php', // remove system helper $admin . '/helpers/system.php', // remove tools helper $admin . '/helpers/tools.php', // old language files $site . '/language/en-GB/en-GB.com_jce_advlink.ini', $site . '/language/en-GB/en-GB.com_jce_browser.ini', $site . '/language/en-GB/en-GB.com_jce_imgmanager.ini', $site . '/language/en-GB/en-GB.com_jce_media.ini', $site . '/language/en-GB/en-GB.com_jce_paste.ini', $site . '/language/en-GB/en-GB.com_jce_spellchecker.ini', // remove redundant parameter.js $admin . '/media/js/parameter.js', // remove build.xml files $site . '/editor/extensions/filesystem/build.xml', $site . '/editor/extensions/links/build.xml', $site . '/editor/extensions/popups/build.xml', // remove legend.css $admin . '/media/css/legend.css', // remove googlemaps $site . '/editor/extensions/aggregator/googlemaps.php', $site . '/editor/extensions/aggregator/googlemaps.xml' ); foreach ($files as $file) { if (JFile::exists($file)) { @JFile::delete($file); } } // 2.1 - Add visualblocks plugin if (version_compare($version, '2.1', '<')) { $profiles = self::getProfiles(); $profile = JTable::getInstance('Profiles', 'WFTable'); if (!empty($profiles)) { foreach ($profiles as $item) { $profile->load($item->id); if (strpos($profile->rows, 'visualblocks') === false) { $profile->rows = str_replace('visualchars', 'visualchars,visualblocks', $profile->rows); } if (strpos($profile->plugins, 'visualblocks') === false) { $profile->plugins = str_replace('visualchars', 'visualchars,visualblocks', $profile->plugins); } $profile->store(); } } } // 2.1.1 - Add anchor plugin if (version_compare($version, '2.1.1', '<')) { $profiles = self::getProfiles(); $profile = JTable::getInstance('Profiles', 'WFTable'); if (!empty($profiles)) { foreach ($profiles as $item) { $profile->load($item->id); // add anchor to end of plugins list if (strpos($profile->rows, 'anchor') !== false) { $profile->plugins .= ',anchor'; } $profile->store(); } } } // 2.2.1 - Add "Blogger" profile if (version_compare($version, '2.2.1', '<')) { self::installProfile('Blogger'); } // 2.2.1 to 2.2.5 - Remove K2Links partial install if (version_compare($version, '2.2.1', '>') && version_compare($version, '2.2.5', '<')) { $path = $site . '/editor/extensions/links'; if (is_file($path . '/k2links.php') && is_file($path . '/k2links.xml') && !is_dir($path . '/k2links')) { @JFile::delete($path . '/k2links.php'); @JFile::delete($path . '/k2links.xml'); } } // replace some profile row items if (version_compare($version, '2.2.8', '<')) { $profiles = self::getProfiles(); $profile = JTable::getInstance('Profiles', 'WFTable'); if (!empty($profiles)) { foreach ($profiles as $item) { $profile->load($item->id); $profile->rows = str_replace('paste', 'clipboard', $profile->rows); $profile->plugins = str_replace('paste', 'clipboard', $profile->plugins); $data = json_decode($profile->params, true); // swap paste data to 'clipboard' if ($data && array_key_exists('paste', $data)) { $params = array(); // add 'paste_' prefix foreach ($data['paste'] as $k => $v) { $params['paste_' . $k] = $v; } // remove paste parameters unset($data['paste']); // assign new params to clipboard $data['clipboard'] = $params; } $profile->params = json_encode($data); $profile->store(); } } } if (version_compare($version, '2.3.0beta', '<')) { // add Mobile profile self::installProfile('Mobile'); } if (version_compare($version, '2.2.9', '<') || version_compare($version, '2.3.0beta3', '<')) { $profiles = self::getProfiles(); $profile = JTable::getInstance('Profiles', 'WFTable'); if (!empty($profiles)) { foreach ($profiles as $item) { $profile->load($item->id); $buttons = array('buttons' => array()); if (strpos($profile->rows, 'numlist') !== false) { $buttons['buttons'][] = 'numlist'; $profile->rows = str_replace('numlist', 'lists', $profile->rows); } if (strpos($profile->rows, 'bullist') !== false) { $buttons['buttons'][] = 'bullist'; if (strpos($profile->rows, 'lists') === false) { $profile->rows = str_replace('bullist', 'lists', $profile->rows); } } // remove bullist and numlist $profile->rows = str_replace(array('bullist', 'numlist'), '', $profile->rows); // replace multiple commas with a single one $profile->rows = preg_replace('#,+#', ',', $profile->rows); // fix rows $profile->rows = str_replace(',;', ';', $profile->rows); if (!empty($buttons['buttons'])) { $profile->plugins .= ',lists'; $data = json_decode($profile->params, true); $data['lists'] = $buttons; $profile->params = json_encode($data); $profile->store(); } } } } // transfer charmap to a plugin if (version_compare($version, '2.3.2', '<')) { $profiles = self::getProfiles(); $table = JTable::getInstance('Profiles', 'WFTable'); if (!empty($profiles)) { foreach ($profiles as $item) { $table->load($item->id); if (strpos($table->rows, 'charmap') !== false) { $table->plugins .= ',charmap'; $table->store(); } } } } // transfer styleselect, fontselect, fontsize etc. to a plugin if (version_compare($version, '2.3.5', '<')) { $profiles = self::getProfiles(); $table = JTable::getInstance('Profiles', 'WFTable'); if (!empty($profiles)) { foreach ($profiles as $item) { $table->load($item->id); $plugins = explode(',', $table->plugins); if (strpos($table->rows, 'formatselect') !== false) { $plugins[] = 'formatselect'; } if (strpos($table->rows, 'styleselect') !== false) { $plugins[] = 'styleselect'; } if (strpos($table->rows, 'fontselect') !== false) { $plugins[] = 'fontselect'; } if (strpos($table->rows, 'fontsizeselect') !== false) { $plugins[] = 'fontsizeselect'; } if (strpos($table->rows, 'forecolor') !== false || strpos($table->rows, 'backcolor') !== false) { $plugins[] = 'fontcolor'; } $table->plugins = implode(',', $plugins); $table->store(); } } } return true; } private static function getProfiles() { $db = JFactory::getDBO(); $query = $db->getQuery(true); if (is_object($query)) { $query->select('id')->from('#__wf_profiles'); } else { $query = 'SELECT id FROM #__wf_profiles'; } $db->setQuery($query); return $db->loadObjectList(); } private static function createProfilesTable() { include_once (dirname(__FILE__) . '/includes/base.php'); include_once (dirname(__FILE__) . '/models/profiles.php'); $profiles = new WFModelProfiles(); if (method_exists($profiles, 'createProfilesTable')) { return $profiles->createProfilesTable(); } return false; } private static function installProfiles() { include_once (dirname(__FILE__) . '/includes/base.php'); include_once (dirname(__FILE__) . '/models/profiles.php'); $profiles = new WFModelProfiles(); if (method_exists($profiles, 'installProfiles')) { return $profiles->installProfiles(); } return false; } /** * Install additional packages * @return Array or false * @param object $path[optional] Path to package folder */ private static function installPackages($source) { jimport('joomla.installer.installer'); $db = JFactory::getDBO(); $result = ''; JTable::addIncludePath(JPATH_LIBRARIES . '/joomla/database/table'); $packages = array( 'editor' => array('jce'), 'quickicon' => array('jcefilebrowser'), 'module' => array('mod_jcefilebrowser') ); foreach ($packages as $folder => $element) { // Joomla! 2.5 if (defined('JPATH_PLATFORM')) { if ($folder == 'module') { continue; } // Joomla! 1.5 } else { if ($folder == 'quickicon') { continue; } } $installer = new JInstaller(); $installer->setOverwrite(true); if ($installer->install($source . '/' . $folder)) { if (method_exists($installer, 'loadLanguage')) { $installer->loadLanguage(); } if ($installer->message) { $result .= '
    • ' . JText::_($installer->message, $installer->message) . '
    • '; } // enable quickicon if ($folder == 'quickicon') { $plugin = JTable::getInstance('extension'); foreach ($element as $item) { $id = $plugin->find(array('type' => 'plugin', 'folder' => $folder, 'element' => $item)); $plugin->load($id); $plugin->publish(); } } // enable module if ($folder == 'module') { $module = JTable::getInstance('module'); $id = self::getModule('mod_jcefilebrowser'); $module->load($id); $module->position = 'icon'; $module->ordering = 100; $module->published = 1; $module->store(); } // rename editor manifest if ($folder == 'editor') { $manifest = $installer->getPath('manifest'); if (basename($manifest) == 'legacy.xml') { // rename legacy.xml to jce.xml JFile::move($installer->getPath('extension_root') . '/' . basename($manifest), $installer->getPath('extension_root') . '/jce.xml'); } } // add index files if ($folder == 'editor' && !defined('JPATH_PLATFORM')) { self::addIndexfiles(array($installer->getPath('extension_root') . '/jce')); } else { self::addIndexfiles(array($installer->getPath('extension_root'))); } } else { $result .= '
    • ' . JText::_($installer->message, $installer->message) . '
    • '; } } return $result; } private static function getModule($name) { // Joomla! 2.5 if (defined('JPATH_PLATFORM')) { $module = JTable::getInstance('extension'); return $module->find(array('type' => 'module', 'element' => $name)); // Joomla! 1.5 } else { $db = JFactory::getDBO(); $query = 'SELECT id FROM #__modules' . ' WHERE module = ' . $db->Quote($name); $db->setQuery($query); return $db->loadResult(); } } private static function getPlugin($folder, $element) { // Joomla! 2.5 if (defined('JPATH_PLATFORM')) { $plugin = JTable::getInstance('extension'); return $plugin->find(array('type' => 'plugin', 'folder' => $folder, 'element' => $element)); // Joomla! 1.5 } else { $plugin = JTable::getInstance('plugin'); $db = JFactory::getDBO(); $query = 'SELECT id FROM #__plugins' . ' WHERE folder = ' . $db->Quote($folder) . ' AND element = ' . $db->Quote($element); $db->setQuery($query); return $db->loadResult(); } } private static function addIndexfiles($paths) { jimport('joomla.filesystem.folder'); jimport('joomla.filesystem.file'); // get the base file $file = JPATH_ADMINISTRATOR . '/components/com_jce/index.html'; if (is_file($file)) { foreach ((array) $paths as $path) { if (is_dir($path)) { // admin component $folders = JFolder::folders($path, '.', true, true); foreach ($folders as $folder) { JFile::copy($file, $folder . '/' . basename($file)); } } } } } private static function legacyCleanup() { $db = JFactory::getDBO(); $query = 'DROP TABLE IF EXISTS #__jce_groups'; $db->setQuery($query); $db->query(); $query = 'DROP TABLE IF EXISTS #__jce_plugins'; $db->setQuery($query); $db->query(); $query = 'DROP TABLE IF EXISTS #__jce_extensions'; $db->setQuery($query); $db->query(); } private static function checkTable($table) { $db = JFactory::getDBO(); $tables = $db->getTableList(); if (!empty($tables)) { // swap array values with keys, convert to lowercase and return array keys as values $tables = array_keys(array_change_key_case(array_flip($tables))); $app = JFactory::getApplication(); $match = str_replace('#__', strtolower($app->getCfg('dbprefix', '')), $table); return in_array($match, $tables); } // try with query $query = $db->getQuery(true); if (is_object($query)) { $query->select('COUNT(id)')->from($table); } else { $query = 'SELECT COUNT(id) FROM ' . $table; } $db->setQuery($query); return $db->query(); } /** * Check table contents * @return integer * @param string $table Table name */ private static function checkTableContents($table) { $db = JFactory::getDBO(); $query = $db->getQuery(true); if (is_object($query)) { $query->select('COUNT(id)')->from($table); } else { $query = 'SELECT COUNT(id) FROM ' . $table; } $db->setQuery($query); return $db->loadResult(); } private static function checkTableColumn($table, $column) { $db = JFactory::getDBO(); // use built in function if (method_exists($db, 'getTableColumns')) { $fields = $db->getTableColumns($table); } else { $db->setQuery('DESCRIBE ' . $table); if (method_exists($db, 'loadColumn')) { $fields = $db->loadColumn(); } else { $fields = $db->loadResultArray(); } // we need to check keys not values $fields = array_flip($fields); } return array_key_exists($column, $fields); } } ?> components/com_jce/models/cpanel.php000066600000006116150771655450013615 0ustar00
    • GNU General Public License, version 2'; } public function getFeeds() { $app = JFactory::getApplication(); $params = JComponentHelper::getParams('com_jce'); $limit = $params->get('feed_limit', 2); $feeds = array(); $options = array( 'rssUrl' => 'http://www.joomlacontenteditor.net/news/feed/rss/latest-news?format=feed', 'cache_time' => $params->get('feed_cachetime', 86400) ); // prevent Strict Standards errors in simplepie error_reporting(32767 ^ 2048); // use this directly instead of JFactory::getXMLParser to avoid the feed data error jimport('simplepie.simplepie'); if (!is_writable(JPATH_BASE . '/cache')) { $options['cache_time'] = 0; } $rss = new SimplePie($options['rssUrl'], JPATH_BASE . '/cache', isset($options['cache_time']) ? $options['cache_time'] : 0); $rss->force_feed(true); $rss->handle_content_type(); if ($rss->init()) { $count = $rss->get_item_quantity(); if ($count) { $count = ($count > $limit) ? $limit : $count; for ($i = 0; $i < $count; $i++) { $feed = new StdClass(); $item = $rss->get_item($i); $feed->link = $item->get_link(); $feed->title = $item->get_title(); $feed->description = $item->get_description(); $feeds[] = $feed; } } } return $feeds; } } ?>components/com_jce/models/plugins.xml000066600000026406150771655450014051 0ustar00 article WF_ARTICLE_TITLE WF_ARTICLE_DESC readmore,pagebreak 1 4 1 WF_ANCHOR_TITLE WF_ANCHOR_DESC anchor 1 anchor 4 0 autosave WF_AUTOSAVE_TITLE WF_AUTOSAVE_DESC autosave 0 4 1 browser WF_BROWSER_TITLE WF_BROWSER_DESC 1 4 1 charmap WF_CHARMAP_TITLE WF_CHARMAP_DESC charmap 0 2 1 cleanup WF_CLEANUP_TITLE WF_CLEANUP_DESC cleanup 0 0 1 clipboard WF_CLIPBOARD_TITLE WF_CLIPBOARD_DESC cut,copy,paste,pastetext 1 2 1 code WF_CODE_TITLE WF_CODE_DESC 0 0 1 colorpicker WF_COLORPICKER_TITLE WF_COLORPICKER_DESC 0 0 1 contextmenu WF_CONTEXTMENU_TITLE WF_CONTEXTMENU_DESC 0 4 1 directionality WF_DIRECTIONALITY_TITLE WF_DIRECTIONALITY_DESC ltr,rtl 0 3 1 format WF_FORMAT_TITLE WF_FORMAT_DESC 0 0 1 WF_FORMATSELECT_TITLE WF_FORMATSELECT_DESC formatselect 1 formatselect 1 1 WF_FONTCOLOR_TITLE WF_FONTCOLOR_DESC fontcolor 1 forecolor,backcolor 2 1 WF_FONTSELECT_TITLE WF_FONTSELECT_DESC fontselect 1 fontselect 2 1 WF_FONTSIZESELECT_TITLE WF_FONTSIZESELECT_DESC fontsizeselect 1 fontsizeselect 2 1 fullpage WF_FULLPAGE_TITLE WF_FULLPAGE_DESC fullpage 1 4 1 fullscreen WF_FULLSCREEN_TITLE WF_FULLSCREEN_DESC fullscreen 0 3 1 imgmanager WF_IMGMANAGER_TITLE WF_IMGMANAGER_DESC imgmanager 1 4 1 inlinepopups WF_INLINEPOPUPS_TITLE WF_INLINEPOPUPS_DESC 0 4 1 layer WF_LAYER_TITLE WF_LAYER_DESC insertlayer,moveforward,movebackward,absolute 0 4 1 link WF_LINK_TITLE WF_LINK_DESC link 1 4 1 lists WF_LISTS_TITLE WF_LISTS_DESC numlist,bullist 1 2 1 media WF_MEDIA_TITLE WF_MEDIA_DESC 1 4 1 nonbreaking WF_NONBREAKING_TITLE WF_NONBREAKING_DESC nonbreaking 0 4 1 preview WF_PREVIEW_TITLE WF_PREVIEW_DESC preview 0 3 1 print WF_PRINT_TITLE WF_PRINT_DESC print 0 3 1 searchreplace WF_SEARCHREPLACE_TITLE WF_SEARCHREPLACE_DESC search,replace 0 2 1 source WF_SOURCE_TITLE WF_SOURCE_DESC source 1 4 1 spellchecker WF_SPELLCHECKER_TITLE WF_SPELLCHECKER_DESC spellchecker 1 4 1 style WF_STYLE_TITLE WF_STYLE_DESC style 0 4 1 WF_STYLESELECT_TITLE WF_STYLESELECT_DESC styleselect 1 styleselect 1 1 tabfocus WF_TABFOCUS_TITLE WF_TABFOCUS_DESC 0 0 1 table WF_TABLE_TITLE WF_TABLE_DESC table_insert,delete_table,|,row_props,cell_props,|,row_before,row_after,delete_row,|,col_before,col_after,delete_col,|,split_cells,merge_cells 1 3 1 textcase WF_TEXTCASE_TITLE WF_TEXTCASE_DESC textcase 0 4 1 visualchars WF_VISUALCHARS_TITLE WF_VISUALCHARS_DESC visualchars 0 4 1 wordcount WF_WORDCOUNT_TITLE WF_WORDCOUNT_DESC 0 0 1 xhtmlxtras WF_XHTMLXTRAS_TITLE WF_XHTMLXTRAS_DESC cite,abbr,acronym,del,ins,attribs 1 4 1 WF_KITCHENSINK_TITLE WF_KITCHENSINK_DESC kitchensink 1 kitchensink 1 0 components/com_jce/models/commands.xml000066600000020271150771655450014163 0ustar00 help WF_HELP_TITLE WF_HELP_DESC help 0 1 1 WF_UNDO_TITLE WF_UNDO_DESC undo 1 undo 1 0 WF_REDO_TITLE WF_REDO_DESC redo 1 redo 1 0 WF_BOLD_TITLE WF_BOLD_DESC bold 1 bold 1 0 WF_ITALIC_TITLE WF_ITALIC_DESC italic 1 italic 1 0 WF_UNDERLINE_TITLE WF_UNDERLINE_DESC underline 1 underline 1 0 WF_STRIKETHROUGH_TITLE WF_STRIKETHROUGH_DESC strikethrough 1 strikethrough 1 0 WF_JUSTIFYFULL_TITLE WF_JUSTIFYFULL_DESC justifyfull 1 justifyfull 1 0 WF_JUSTIFYCENTER_TITLE WF_JUSTIFYCENTER_DESC justifycenter 1 justifycenter 1 0 WF_JUSTIFYLEFT_TITLE WF_JUSTIFYLEFT_DESC justifyleft 1 justifyleft 1 0 WF_JUSTIFYRIGHT_TITLE WF_JUSTIFYRIGHT_DESC justifyright 1 justifyright 1 0 WF_FORMATSELECT_TITLE WF_FORMATSELECT_DESC formatselect 1 formatselect 1 0 WF_NEWDOCUMENT_TITLE WF_NEWDOCUMENT_DESC newdocument 1 newdocument 1 0 WF_UNLINK_TITLE WF_UNLINK_DESC unlink 1 unlink 4 0 WF_INDENT_TITLE WF_INDENT_DESC indent 1 indent 2 0 WF_OUTDENT_TITLE WF_OUTDENT_DESC outdent 1 outdent 2 0 WF_BLOCKQUOTE_TITLE WF_BLOCKQUOTE_DESC blockquote 1 blockquote 1 0 WF_REMOVEFORMAT_TITLE WF_REMOVEFORMAT_DESC removeformat 1 removeformat 1 0 WF_HR_TITLE WF_HR_DESC hr 1 hr 3 0 WF_SUB_TITLE WF_SUB_DESC sub 1 sub 2 0 WF_SUP_TITLE WF_SUP_DESC sup 1 sup 2 0 WF_VISUALAID_TITLE WF_VISUALAID_DESC visualaid 1 visualaid 4 0 components/com_jce/models/installer.xml000066600000001434150771655450014357 0ustar00 components/com_jce/models/cpanel.xml000066600000000447150771655450013627 0ustar00 components/com_jce/models/index.html000066600000000054150771655450013632 0ustar00components/com_jce/models/config.xml000066600000000717150771655450013632 0ustar00 components/com_jce/models/profiles.xml000066600000013106150771655450014204 0ustar00 WF_PROFILES_DEFAULT_DESC 0 desktop,tablet,phone help,newdocument,undo,redo,spacer,bold,italic,underline,strikethrough,justifyfull,justifycenter,justifyleft,justifyright,spacer,blockquote,formatselect,styleselect,removeformat,cleanup;fontselect,fontsizeselect,forecolor,backcolor,spacer,clipboard,indent,outdent,lists,sub,sup,textcase,charmap,hr;directionality,fullscreen,preview,source,print,searchreplace,spacer,table;visualaid,visualchars,visualblocks,nonbreaking,style,xhtmlxtras,anchor,unlink,link,imgmanager,spellchecker,article charmap,contextmenu,browser,inlinepopups,media,help,clipboard,searchreplace,directionality,fullscreen,preview,source,table,textcase,print,style,nonbreaking,visualchars,visualblocks,xhtmlxtras,imgmanager,anchor,link,spellchecker,article,lists,formatselect,styleselect,fontselect,fontsizeselect,fontcolor 1 1 WF_PROFILES_FRONTEND_DESC 1 desktop,tablet,phone help,newdocument,undo,redo,spacer,bold,italic,underline,strikethrough,justifyfull,justifycenter,justifyleft,justifyright,spacer,formatselect,styleselect;clipboard,searchreplace,indent,outdent,lists,cleanup,charmap,removeformat,hr,sub,sup,textcase,nonbreaking,visualchars,visualblocks;fullscreen,preview,print,visualaid,style,xhtmlxtras,anchor,unlink,link,imgmanager,spellchecker,article charmap,contextmenu,inlinepopups,help,clipboard,searchreplace,fullscreen,preview,print,style,textcase,nonbreaking,visualchars,visualblocks,xhtmlxtras,imgmanager,anchor,link,spellchecker,article,lists,formatselect,styleselect 0 2 Blogger Simple Blogging Profile 0 desktop,tablet,phone bold,italic,strikethrough,lists,blockquote,spacer,justifyleft,justifycenter,justifyright,spacer,link,unlink,imgmanager,article,spellchecker,fullscreen,kitchensink;formatselect,styleselect,underline,justifyfull,clipboard,removeformat,charmap,indent,outdent,undo,redo,help link,imgmanager,article,spellchecker,fullscreen,kitchensink,clipboard,contextmenu,inlinepopups,lists,formatselect,styleselect 0 3 {"editor":{"toggle":"0"}} Mobile Sample Mobile Profile 0 tablet,phone undo,redo,spacer,bold,italic,underline,formatselect,spacer,justifyleft,justifycenter,justifyfull,justifyright,spacer,fullscreen,kitchensink;styleselect,lists,spellchecker,article,link,unlink fullscreen,kitchensink,spellchecker,article,link,inlinepopups,lists,formatselect,styleselect 0 4 {"editor":{"toolbar_theme":"mobile","resizing":"0","resize_horizontal":"0","resizing_use_cookie":"0","toggle":"0","links":{"popups":{"default":"","jcemediabox":{"enable":"0"},"window":{"enable":"0"}}}}} components/com_jce/models/help.xml000066600000000262150771655450013310 0ustar00 components/com_jce/models/help.php000066600000011434150771655450013302 0ustar00getTag(); return substr($tag, 0, strpos($tag, '-')); } function getTopics($file) { $result = ''; if (file_exists($file)) { // load xml $xml = WFXMLElement::load($file); if ($xml) { foreach ($xml->help->children() as $topic) { $subtopics = $topic->subtopic; $class = count($subtopics) ? ' class="subtopics"' : ''; $key = (string) $topic->attributes()->key; $title = (string) $topic->attributes()->title; $file = (string) $topic->attributes()->file; // if file attribute load file if ($file) { $result .= $this->getTopics(WF_EDITOR . '/' . $file); } else { $result .= '' . trim(WFText::_($title)) . ''; } if (count($subtopics)) { $result .= ''; } } } } return $result; } /** * Returns a formatted list of help topics * * @access public * @return String * @since 1.5 */ function renderTopics() { $section = JRequest::getWord('section', 'admin'); $category = JRequest::getWord('category', 'cpanel'); $document = JFactory::getDocument(); $language = JFactory::getLanguage(); $document->setTitle(WFText::_('WF_HELP') . ' : ' . WFText::_('WF_' . strtoupper($category) . '_TITLE')); $file = WF_EDITOR_PLUGINS . '/' . $category . '/' . $category . ".xml"; switch ($section) { case 'admin' : $file = JPATH_ADMINISTRATOR . '/components/com_jce/models/' . $category . '.xml'; break; case 'editor' : $file = WF_EDITOR_PLUGINS . '/' . $category . '/' . $category . ".xml"; if (!is_file($file)) { $file = WF_EDITOR_LIBRARIES . '/xml/help/editor.xml'; } else { $language->load('com_jce_' . $category, JPATH_SITE); } break; } $result = ''; $result .= '
      ' . WFText::_('WF_' . strtoupper($category) . '_TITLE') . '
      '; $result .= $this->getTopics($file); $result .= '
      '; return $result; } } ?>components/com_jce/models/model.php000066600000010123150771655450013444 0ustar00authorise($action, 'com_jce')) { return false; } } else { // get rules from parameters $component = JComponentHelper::getComponent('com_jce'); $params = json_decode($component->params); $rules = isset($params->access) ? $params->access : null; if (is_object($rules)) { $action = ($task == 'admin' || $task == 'manage') ? 'core.' . $task : 'jce.' . $task; if (isset($rules->$action)) { $rule = $rules->$action; $gid = $user->gid; if (isset($rule->$gid) && $rule->$gid == 0) { return false; } } } } return true; } /** * Get the current version * @return Version */ public function getVersion() { $xml = WFXMLHelper::parseInstallManifest(JPATH_ADMINISTRATOR . '/components/com_jce/jce.xml'); // return cleaned version number or date $version = preg_replace('/[^0-9a-z]/i', '', $xml['version']); if (!$version) { return date('Y-m-d', strtotime('today')); } return $version; } public function getStyles() { $view = JRequest::getCmd('view'); $params = JComponentHelper::getParams('com_jce'); $theme = $params->get('theme', 'smoothness'); $path = JPATH_COMPONENT . '/media/css'; // Load styles $styles = array(); $files = JFolder::files($path . '/' . $theme, '\.css'); foreach ($files as $file) { $styles[] = $theme . '/' . $file; } $styles = array_merge($styles, array('styles.css', 'tips.css', 'icons.css', 'select.css')); jimport('joomla.environment.browser'); $browser = JBrowser::getInstance(); if ($browser->getBrowser() == 'msie' && $browser->getMajor() < 8) { $styles[] = 'styles_ie.css'; } if (JFile::exists($path . '/' . $view . '.css')) { $styles[] = $view . '.css'; } return $styles; } public function loadStyles() { $styles = $this->getStyles(); foreach ($styles as $style) { echo '' . "\n"; } } public static function getBrowserLink($element = null, $filter = '') { // load base classes require_once(JPATH_ADMINISTRATOR . '/components/com_jce/includes/base.php'); // set $url as empty string $url = ''; wfimport('editor.libraries.classes.editor'); wfimport('editor.libraries.classes.token'); $wf = WFEditor::getInstance(); // check the current user is in a profile if ($wf->getProfile('browser')) { $token = WFToken::getToken(); $url = 'index.php?option=com_jce&view=editor&layout=plugin&plugin=browser&standalone=1&' . $token . '=1'; if ($element) { $url .= '&element=' . $element; } if ($filter) { $url .= '&filter=' . $filter; } } return $url; } } ?> components/com_jce/models/users.php000066600000001271150771655450013511 0ustar00components/com_jce/models/preferences.xml000066600000004204150771655450014661 0ustar00 components/com_jce/models/plugins.php000066600000030143150771655450014031 0ustar00children() as $command) { $name = (string) $command->name; if ($name) { $commands[$name] = new StdClass(); foreach ($command->children() as $item) { $key = $item->getName(); $value = (string) $item; $commands[$name]->$key = $value; } $commands[$name]->type = 'command'; } } } return $commands; } public function getPlugins() { jimport('joomla.filesystem.folder'); $plugins = array(); // get core xml $xml = WFXMLElement::load(dirname(__FILE__) . '/plugins.xml'); if ($xml) { foreach ($xml->children() as $plugin) { $name = (string) $plugin->name; if ($name) { $plugins[$name] = new StdClass(); foreach ($plugin->children() as $item) { $key = $item->getName(); $value = (string) $item; if (is_numeric($value)) { $value = (int) $value; } $plugins[$name]->$key = $value; } $plugins[$name]->type = 'plugin'; $plugins[$name]->path = str_replace(JPATH_SITE, '', WF_EDITOR_PLUGINS) . '/' . $name; } } } unset($xml); // get all Plugins $folders = JFolder::folders(WF_EDITOR_PLUGINS, '.', false, true, array_merge(array('.svn', 'CVS'), array_keys($plugins))); foreach ($folders as $folder) { $name = basename($folder); $file = $folder . '/' . $name . '.xml'; if (is_file($file)) { $xml = WFXMLElement::load($folder . '/' . $name . '.xml'); if ($xml) { if ((string) $xml->getName() != 'extension' && (string) $xml->getName() != 'install') { continue; } $params = $xml->params; if (!isset($plugins[$name])) { $plugins[$name] = new StdClass(); $plugins[$name]->name = $name; $plugins[$name]->title = (string) $xml->name; $plugins[$name]->icon = (string) $xml->icon; $editable = (int) $xml->attributes()->editable; $plugins[$name]->editable = $editable ? $editable : ($params && count($params->children()) ? 1 : 0); $row = (int) $xml->attributes()->row; $plugins[$name]->row = $row ? $row : 4; $plugins[$name]->core = (int) $xml->attributes()->core ? 1 : 0; } // relative path $plugins[$name]->path = str_replace(JPATH_SITE, '', $folder); $plugins[$name]->author = (string) $xml->author; $plugins[$name]->version = (string) $xml->version; $plugins[$name]->creationdate = (string) $xml->creationDate; $plugins[$name]->description = (string) $xml->description; $plugins[$name]->authorUrl = (string) $xml->authorUrl; $plugins[$name]->type = 'plugin'; } } } return $plugins; } /** * Get a plugin's extensions * @param object $plugin * @return */ public function getExtensions() { jimport('joomla.filesystem.folder'); jimport('joomla.filesystem.file'); $extensions = array(); // recursively get all extension files $files = JFolder::files(WF_EDITOR_EXTENSIONS, '\.xml$', true, true); foreach ($files as $file) { $object = new StdClass(); $object->folder = basename(dirname($file)); $object->manifest = $file; $object->plugins = array(); $name = basename($file, '.xml'); $object->name = $name; $object->description = ''; $object->id = $object->folder . '.' . $object->name; // get core xml $xml = WFXMLElement::load($file); if ($xml) { if ((string) $xml->getName() != 'extension' && (string) $xml->getName() != 'install') { continue; } $plugins = (string) $xml->plugins; if ($plugins) { $object->plugins = explode(',', $plugins); } $object->name = (string) $xml->name; $object->title = (string) $xml->name; $object->description = (string) $xml->description; $object->creationdate = (string) $xml->creationDate; $object->author = (string) $xml->author; $object->version = (string) $xml->version; $object->type = (string) $xml->attributes()->folder; $object->authorUrl = (string) $xml->authorUrl; $object->folder = (string) $xml->attributes()->folder; $object->core = (int) $xml->attributes()->core ? 1 : 0; if ($object->core == 0) { // load language $language = JFactory::getLanguage(); $language->load('com_jce_' . $object->folder . '_' . $name, JPATH_SITE); } $object->extension = $name; $extensions[] = $object; } } return $extensions; } /** * Process import data from XML file * @param object $file XML file * @param boolean $install Can be used by the package installer * @return */ public function processImport($file, $install = false) { return true; } public static function addToProfile($id, $plugin) { JTable::addIncludePath(dirname(dirname(__FILE__)) . '/tables'); // Add to Default Group $profile = JTable::getInstance('profiles', 'WFTable'); if ($profile->load($id)) { // Add to plugins list $plugins = explode(',', $profile->plugins); if (!in_array($plugin->name, $plugins)) { $plugins[] = $plugin->name; } $profile->plugins = implode(',', $plugins); if ($plugin->icon) { if (in_array($plugin->name, preg_split('/[;,]+/', $profile->rows)) === false) { // get rows as array $rows = explode(';', $profile->rows); // get key (row number) $key = (int) $plugin->row - 1; // get row contents as array $row = explode(',', $rows[$key]); // add plugin name to end of row $row[] = $plugin->name; // add row data back to rows array $rows[$key] = implode(',', $row); $profile->rows = implode(';', $rows); } if (!$profile->store()) { JError::raiseWarning(100, 'WF_INSTALLER_PLUGIN_PROFILE_ERROR'); } } } return true; } public static function removeFromProfile($id, $plugin) { JTable::addIncludePath(dirname(dirname(__FILE__)) . '/tables'); // Add to Default Group $profile = JTable::getInstance('profiles', 'WFTable'); if ($profile->load($id)) { // Add to plugins list $plugins = explode(',', $profile->plugins); if (!in_array($plugin->name, $plugins)) { $plugins[] = $plugin->name; } $profile->plugins = implode(',', $plugins); if ($plugin->icon) { // check if its in the profile if (in_array($plugin->name, preg_split('/[;,]+/', $profile->rows))) { $lists = array(); foreach (explode(';', $profile->rows) as $list) { $icons = explode(',', $list); foreach ($icons as $k => $v) { if ($plugin->name == $v) { unset($icons[$k]); } } $lists[] = implode(',', $icons); } $profile->rows = implode(';', $lists); } if (!$profile->store()) { JError::raiseWarning(100, JText::sprintf('WF_INSTALLER_REMOVE_FROM_GROUP_ERROR', $plugin->name)); } } } return true; } /** * Add index.html files to each folder * @access private */ private static function addIndexfiles($path) { jimport('joomla.filesystem.folder'); jimport('joomla.filesystem.file'); // get the base file $file = dirname(dirname(__FILE__)) . '/index.html'; if (is_file($file) && is_dir($path)) { JFile::copy($file, $path . '/' . basename($file)); // admin component $folders = JFolder::folders($path, '.', true, true); foreach ($folders as $folder) { JFile::copy($file, $folder . '/' . basename($file)); } } } public static function postInstall($route, $plugin, $installer) { $db = JFactory::getDBO(); jimport('joomla.filesystem.folder'); // load the plugin and enable if (isset($plugin->row) && $plugin->row > 0) { $query = $db->getQuery(true); if (is_object($query)) { $query->select('id')->from('#__wf_profiles')->where('name = ' . $db->Quote('Default') . ' OR id = 1'); } else { $query = 'SELECT id' . ' FROM #__wf_profiles' . ' WHERE name = ' . $db->Quote('Default') . ' OR id = 1'; } $db->setQuery($query); $id = $db->loadResult(); if ($id) { if ($route == 'install') { // add to profile self::addToProfile($id, $plugin); } else { // remove from profile self::removeFromProfile($id, $plugin); } } } if ($route == 'install') { if ($plugin->type == 'extension') { $plugin->path = $plugin->path . '/' . $plugin->name; } // add index.html files self::addIndexfiles($plugin->path); } return true; } }components/com_jce/models/installer.php000066600000031346150771655450014353 0ustar00setRedirect(JRoute::_('index.php?option=com_jce&client=' . $client, false)); } public function install($package = null) { $app = JFactory::getApplication(); if (!$package) { $package = $this->getPackage(); } // Was the package unpacked? if (!$package) { $this->setState('message', 'WF_INSTALLER_NO_PACKAGE'); return false; } // Get an installer instance $installer = WFInstaller::getInstance(); // Install the package if (!$installer->install($package['dir'])) { $result = false; $app->enqueueMessage(WFText::sprintf('WF_INSTALLER_INSTALL_ERROR'), 'error'); } else { $result = true; $app->enqueueMessage(WFText::sprintf('WF_INSTALLER_INSTALL_SUCCESS')); } $this->_result[] = array( 'name' => $installer->get('name'), 'type' => $package['type'], 'version' => $installer->get('version'), 'result' => $result ); $this->setState('install.result', $this->_result); $this->setState('name', WFText::_($installer->get('name'))); $this->setState('message', WFText::_($installer->get('message'))); $this->setState('extension.message', $installer->get('extension.message')); $this->setState('result', $result); // Cleanup the install files if (!is_file($package['packagefile'])) { $package['packagefile'] = $app->getCfg('tmp_path') . '/' . $package['packagefile']; } if (is_file($package['packagefile'])) { JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); } return $result; } public function remove($id, $type) { $app = JFactory::getApplication(); // Use Joomla! Installer class for related extensions if ($type == 'related') { jimport('joomla.installer.installer'); $installer = JInstaller::getInstance(); $result = $installer->uninstall('plugin', $id); } else { $installer = WFInstaller::getInstance(); $installer->setAdapter($type); $result = $installer->uninstall($type, $id); } if (!$result) { $app->enqueueMessage(WFText::sprintf('WF_INSTALLER_UNINSTALL_ERROR'), 'error'); } else { $app->enqueueMessage(WFText::sprintf('WF_INSTALLER_UNINSTALL_SUCCESS')); } $this->_result[] = array( 'name' => $installer->get('name'), 'type' => $type, 'version' => $installer->get('version'), 'result' => $result ); $this->setState('name', WFText::_($installer->get('name'))); $this->setState('result', $result); $this->setState('install.result', $this->_result); return $result; } /** * Get the install package or folder * @return Array $package */ private function getPackage() { $app = JFactory::getApplication(); jimport('joomla.filesystem.file'); jimport('joomla.filesystem.archive'); // set standard method $upload = true; $package = null; // Get the uploaded file information $file = JRequest::getVar('install', null, 'files', 'array'); // get the file path information $path = JRequest::getString('install_input'); if (!(bool) ini_get('file_uploads') || !is_array($file)) { $upload = false; // no path either! if (!$path) { JError::raiseWarning('SOME_ERROR_CODE', WFText::_('WF_INSTALLER_NO_FILE')); return false; } } // Install failed if (!is_uploaded_file($file['tmp_name']) || !$file['tmp_name'] || !$file['name'] || $file['error']) { $upload = false; // no path either! if (!$path) { JError::raiseWarning('SOME_ERROR_CODE', WFText::_('WF_INSTALLER_NO_FILE')); return false; } } // uploaded file if ($upload) { // check extension if (!preg_match('/\.(zip|tar|gz|gzip|tgz|tbz2|bz2|bzip2)$/i', $file['name'])) { JError::raiseWarning('SOME_ERROR_CODE', WFText::_('WF_INSTALLER_INVALID_FILE')); return false; } $dest = JPath::clean($app->getCfg('tmp_path') . '/' . $file['name']); $src = $file['tmp_name']; // upload file if (!JFile::upload($src, $dest)) { JError::raiseWarning('SOME_ERROR_CODE', WFText::_('WF_INSTALLER_UPLOAD_FAILED')); return false; } if (!is_file($dest)) { JError::raiseWarning('SOME_ERROR_CODE', WFText::_('WF_INSTALLER_UPLOAD_FAILED')); return false; } // path to file } else { $dest = JPath::clean($path); } // set install method JRequest::setVar('install_method', 'install'); // Unpack the package file if (preg_match('/\.(zip|tar|gz|gzip|tgz|tbz2|bz2|bzip2)/i', $dest)) { // Make sure that zlib is loaded so that the package can be unpacked if (!extension_loaded('zlib')) { JError::raiseWarning('SOME_ERROR_CODE', WFText::_('WF_INSTALLER_WARNINSTALLZLIB')); return false; } $package = JPath::clean(dirname($dest) . '/' . uniqid('install_')); if (!JArchive::extract($dest, $package)) { JError::raiseWarning('SOME_ERROR_CODE', WFText::_('WF_INSTALLER_EXTRACT_ERROR')); return false; } if (JFolder::exists($package)) { $type = self::detectType($package); } return array( 'manifest' => null, 'packagefile' => $dest, 'extractdir' => $package, 'dir' => $package, 'type' => $type ); // might be a directory } else { if (!is_dir($dest)) { JError::raiseWarning('SOME_ERROR_CODE', WFText::_('WF_INSTALLER_INVALID_SRC')); return false; } // Detect the package type $type = self::detectType($dest); return array( 'manifest' => null, 'packagefile' => null, 'extractdir' => null, 'dir' => $dest, 'type' => $type ); } } private static function detectType($path) { // Search the install dir for an XML file $files = JFolder::files($path, '\.xml$', 1, true); if (!count($files)) { return false; } foreach ($files as $file) { $xml = simplexml_load_file($file); if (!$xml) { continue; } $name = (string) $xml->getName(); if ($name != 'extension' && $name != 'install') { unset($xml); continue; } $type = (string) $xml->attributes()->type; // Free up memory unset($xml); return $type; } return false; } public function getExtensions() { wfimport('admin.models.plugins'); $model = new WFModelPlugins(); // get an array of all installed plugins in plugins folder $extensions = $model->getExtensions(); return $extensions; } public function getPlugins() { wfimport('admin.models.plugins'); $model = new WFModelPlugins(); // get an array of all installed plugins in plugins folder $plugins = $model->getPlugins(); $rows = array(); $language = JFactory::getLanguage(); foreach ($plugins as $plugin) { if ($plugin->core == 0) { $rows[] = $plugin; $language->load('com_jce_' . trim($plugin->name), JPATH_SITE); } } return $rows; } /** * Get additional plugins such as JCE MediaBox etc. * @return */ public function getRelated() { // Get a database connector $db = JFactory::getDBO(); $params = JComponentHelper::getParams('com_jce'); // pre-defined array of other plugins $related = preg_replace('#(\w+)#', "'$1'", $params->get('related_extensions', 'jcemediabox,jceutilities,mediaobject,wfmediabox,wfmediaelement')); $query = $db->getQuery(true); // Joomla! 2.5 if (is_object($query)) { $query->select(array('extension_id', 'name', 'element', 'folder'))->from('#__extensions')->where(array('type = ' . $db->Quote('plugin'), 'element IN (' . $related . ')'))->order('name'); // Joomla! 1.5 } else { $query = 'SELECT id, name, element, folder FROM #__plugins WHERE element IN (' . $related . ') ORDER BY name'; } $db->setQuery($query); $rows = $db->loadObjectList(); $language = JFactory::getLanguage(); $num = count($rows); for ($i = 0; $i < $num; $i++) { $row = $rows[$i]; if (defined('JPATH_PLATFORM')) { $file = JPATH_PLUGINS . '/' . $row->folder . '/' . $row->element . '/' . $row->element . ".xml"; } else { $file = JPATH_PLUGINS . '/' . $row->folder . '/' . $row->element . ".xml"; } if (isset($row->extension_id)) { $row->id = $row->extension_id; } if (is_file($file)) { $xml = WFXMLElement::load($file); if ($xml) { $row->title = (string) $xml->name; $row->author = (string) $xml->author; $row->version = (string) $xml->version; $row->creationdate = (string) $xml->creationDate; $row->description = (string) $xml->description; $row->authorUrl = (string) $xml->authorUrl; } } $language->load('plg_' . trim($row->folder) . '_' . trim($row->element), JPATH_ADMINISTRATOR); $language->load('plg_' . trim($row->folder) . '_' . trim($row->element), JPATH_SITE); } //return array_values($rows); return $rows; } public function getLanguages() { // Get the site languages $base = JLanguage::getLanguagePath(JPATH_SITE); $dirs = JFolder::folders($base); for ($i = 0; $i < count($dirs); $i++) { $lang = new stdClass(); $lang->folder = $dirs[$i]; $lang->baseDir = $base; $languages[] = $lang; } $rows = array(); foreach ($languages as $language) { $files = JFolder::files($language->baseDir . '/' . $language->folder, '\.(com_jce)\.xml$'); foreach ($files as $file) { $data = WFXMLHelper::parseInstallManifest($language->baseDir . '/' . $language->folder . '/' . $file); $row = new StdClass(); $row->language = $language->folder; if ($row->language == 'en-GB') { $row->cbd = 'disabled="disabled"'; $row->style = ' style="color:#999999;"'; } else { $row->cbd = ''; $row->style = ''; } // If we didn't get valid data from the xml file, move on... if (!is_array($data)) { continue; } // Populate the row from the xml meta file foreach ($data as $key => $value) { $row->$key = $value; } $rows[] = $row; } } return $rows; } }components/com_jce/models/editor.php000066600000107616150771655450013650 0ustar00scripts[] = $url; } private function addStyleSheet($url) { $this->stylesheets[] = $url; } private function addScriptDeclaration($text) { $this->javascript[] = $text; } private function addStyleDeclaration($text) { $this->styles[] = $text; } public function __construct() { $wf = WFEditor::getInstance(); // set language $this->language = WFLanguage::getCode(); // set profile $this->profile = $wf->getProfile(); } public function buildEditor() { // get document $document = JFactory::getDocument(); // get an editor instance $wf = WFEditor::getInstance(); // create token $token = WFToken::getToken(); // get current component $option = JRequest::getCmd('option'); $component = WFExtensionHelper::getComponent(null, $option); // get default settings $settings = $this->getEditorSettings(); // set default component id $component_id = 0; $component_id = isset($component->extension_id) ? $component->extension_id : ($component->id ? $component->id : 0); $version = self::getVersion(); // settings array for jce, tinymce etc $init = array(); // if a profile is set if (is_object($this->profile)) { jimport('joomla.filesystem.folder'); $settings = array_merge($settings, array('theme' => 'advanced', 'component_id' => $component_id, 'plugins' => $this->getPlugins()), $this->getToolbar()); // Theme and skins $theme = array( 'toolbar_location' => array('top', 'top', 'string'), 'toolbar_align' => array('left', 'left', 'string'), 'statusbar_location' => array('bottom', 'bottom', 'string'), 'path' => array(1, 1, 'boolean'), 'resizing' => array(1, 0, 'boolean'), 'resize_horizontal' => array(1, 1, 'boolean'), 'resizing_use_cookie' => array(1, 1, 'boolean') ); // set rows key to pass to plugin config $settings['rows'] = $this->profile->rows; foreach ($theme as $k => $v) { $settings['theme_advanced_' . $k] = $wf->getParam('editor.' . $k, $v[0], $v[1], $v[2]); } if (!$wf->getParam('editor.use_cookies', 1)) { $settings['theme_advanced_resizing_use_cookie'] = false; } $settings['width'] = $wf->getParam('editor.width'); $settings['height'] = $wf->getParam('editor.height'); // 'Look & Feel' $skin = explode('.', $wf->getParam('editor.toolbar_theme', 'default', 'default')); $settings['skin'] = $skin[0]; $settings['skin_variant'] = isset($skin[1]) ? $skin[1] : ''; // get body class if any $body_class = $wf->getParam('editor.body_class', ''); // check for editor reset $content_reset = $wf->getParam('editor.content_style_reset', $wf->getParam('editor.highcontrast', 0)) == 1 ? 'mceContentReset' : ''; // combine body class and reset $settings['body_class'] = trim($body_class . ' ' . $content_reset); // set body id $settings['body_id'] = $wf->getParam('editor.body_id', ''); // get stylesheets $stylesheets = (array) self::getStyleSheets(); // set stylesheets as string $settings['content_css'] = implode(',', $stylesheets); // Editor Toggle $settings['toggle'] = $wf->getParam('editor.toggle', 1, 1); $settings['toggle_label'] = htmlspecialchars($wf->getParam('editor.toggle_label', '[Toggle Editor]', '[Toggle Editor]')); $settings['toggle_state'] = $wf->getParam('editor.toggle_state', 1, 1); }// end profile // set compression states $compress = array('javascript' => intval($wf->getParam('editor.compress_javascript', 1)), 'css' => intval($wf->getParam('editor.compress_css', 1))); // set compression if ($compress['css']) { $this->addStyleSheet(JURI::base(true) . '/index.php?option=com_jce&view=editor&layout=editor&task=pack&type=css&component_id=' . $component_id . '&' . $token . '=1'); } else { // CSS $this->addStyleSheet($this->getURL(true) . '/libraries/css/editor.css'); // get plugin styles $this->getPluginStyles($settings); } // set compression if ($compress['javascript']) { $this->addScript(JURI::base(true) . '/index.php?option=com_jce&view=editor&layout=editor&task=pack&component_id=' . $component_id . '&' . $token . '=1'); } else { $this->addScript($this->getURL(true) . '/tiny_mce/tiny_mce.js'); // Editor $this->addScript($this->getURL(true) . '/libraries/js/editor.js'); if (array_key_exists('language_load', $settings)) { // language $this->addScript(JURI::base(true) . '/index.php?option=com_jce&view=editor&layout=editor&task=loadlanguages&lang=' . $this->language . '&component_id=' . $component_id . '&' . $token . '=1'); } } // Get all optional plugin configuration options $this->getPluginConfig($settings); // remove 'rows' key from $settings unset($settings['rows']); // pass compresison states to settings $settings['compress'] = json_encode($compress); //Other - user specified $userParams = $wf->getParam('editor.custom_config', ''); $baseParams = array('mode', 'cleanup_callback', 'save_callback', 'file_browser_callback', 'urlconverter_callback', 'onpageload', 'oninit', 'editor_selector'); if ($userParams) { $userParams = explode(';', $userParams); foreach ($userParams as $userParam) { $keys = explode(':', $userParam); if (!in_array(trim($keys[0]), $baseParams)) { $settings[trim($keys[0])] = count($keys) > 1 ? trim($keys[1]) : ''; } } } // check for language files $this->checkLanguages($settings); $output = ""; $i = 1; foreach ($settings as $k => $v) { // If the value is an array, implode! if (is_array($v)) { $v = ltrim(implode(',', $v), ','); } // Value must be set if ($v !== '') { // objects or arrays or functions or regular expression if (preg_match('/(\[[^\]*]\]|\{[^\}]*\}|function\([^\}]*\}|^#(.*)#$)/', $v)) { // replace hash delimiters with / for javascript regular expression $v = preg_replace('@^#(.*)#$@', '/$1/', $v); } // boolean else if (is_bool($v) === true) { $v = $v ? 'true' : 'false'; } // stringified booleans else if ($v === "true" || $v === "false") { $v = $v === "true" ? 'true' : 'false'; } // anything that is not solely an integer else if (!is_numeric($v)) { if (strpos($v, '"') === 0) { $v = '"' . trim($v, '"') . '"'; } else { $v = '"' . str_replace('"', '\"', $v) . '"'; } } $output .= "\t\t\t" . $k . ": " . $v . ""; if ($i < count($settings)) { $output .= ",\n"; } } // Must have 3 rows, even if 2 are blank! if (preg_match('/theme_advanced_buttons([1-3])/', $k) && $v == '') { $output .= "\t\t\t" . $k . ": \"\""; if ($i < count($settings)) { $output .= ",\n"; } } $i++; } $tinymce = "{\n"; $tinymce .= preg_replace('/,?\n?$/', '', $output) . " }"; $init[] = $tinymce; $this->addScriptDeclaration("\n\t\ttry{WFEditor.init(" . implode(',', $init) . ");}catch(e){console.debug(e);}\n"); if (is_object($this->profile)) { if ($wf->getParam('editor.callback_file')) { $this->addScript(JURI::root(true) . '/' . $wf->getParam('editor.callback_file')); } // add callback file if exists if (is_file(JPATH_SITE . '/media/jce/js/editor.js')) { $this->addScript(JURI::root(true) . '/media/jce/js/editor.js'); } // add custom editor.css if exists if (is_file(JPATH_SITE . '/media/jce/css/editor.css')) { $this->addStyleSheet(JURI::root(true) . '/media/jce/css/editor.css'); } } return $this->getOutput(); } private function getOutput() { $document = JFactory::getDocument(); $end = $document->_getLineEnd(); $tab = $document->_getTab(); $version = self::getVersion(); $output = ''; foreach ($this->stylesheets as $stylesheet) { // don't add hash to dynamic php url if (strpos($stylesheet, 'index.php') === false) { $version = md5(basename($stylesheet) . $version); if (strpos($stylesheet, '?') === false) { $stylesheet .= '?' . $version; } else { $stylesheet .= '&' . $version; } } $output .= $tab . '' . $end; } foreach ($this->scripts as $script) { // don't add hash to dynamic php url if (strpos($script, 'index.php') === false) { $version = md5(basename($script) . $version); if (strpos($script, '?') === false) { $script .= '?' . $version; } else { $script .= '&' . $version; } } $output .= $tab . '' . $end; } foreach ($this->javascript as $script) { $output .= $tab . '' . $end; } foreach ($this->styles as $style) { $output .= $tab . '' . $end; } return $output; } /** * Check the current language pack exists and is complete * @param array $settings Settings array * @return void */ private function checkLanguages(&$settings) { $plugins = array(); $language = $settings['language']; // only if languages are loaded and not english if (array_key_exists('language_load', $settings) === false && $language != 'en') { jimport('joomla.filesystem.file'); // check main languages and reset to english if (!JFile::exists(WF_EDITOR . '/tiny_mce/langs/' . $language . '.js') || !JFile::exists(WF_EDITOR_THEMES . '/advanced/langs/' . $language . '.js')) { $settings['language'] = 'en'; return; } foreach ((array) $settings['plugins'] as $plugin) { $path = WF_EDITOR_PLUGINS . '/' . $plugin; // if english file exists then the installed language file should too if (JFile::exists($path . '/langs/en.js') && !JFile::exists($path . '/langs/' . $language . '.js')) { $plugins[] = $plugin; } } } $settings['skip_plugin_languages'] = $plugins; } /** * Get the current version from the editor manifest * @return Version */ private static function getVersion() { if (!isset(self::$version)) { $xml = WFXMLHelper::parseInstallManifest(JPATH_ADMINISTRATOR . '/components/com_jce/jce.xml'); // return cleaned version number or date self::$version = preg_replace('/[^0-9a-z]/i', '', $xml['version']); if (!self::$version) { self::$version = date('Y-m-d', strtotime('today')); } } return self::$version; } /** * Get default settings array * @return array */ public function getEditorSettings() { wfimport('editor.libraries.classes.token'); $wf = WFEditor::getInstance(); $language = JFactory::getLanguage(); $settings = array( 'token' => WFToken::getToken(), 'etag' => md5($this->getVersion()), 'base_url' => JURI::root(), 'language' => $this->language, //'language_load' => false, 'directionality' => $language->isRTL() ? 'rtl' : 'ltr', 'theme' => 'none', 'plugins' => '' ); $settings['language_load'] = false; return $settings; } /** * Return a list of icons for each JCE editor row * * @access public * @param string The number of rows * @return The row array */ private function getToolbar() { wfimport('admin.models.plugins'); $model = new WFModelPlugins(); $wf = WFEditor::getInstance(); $rows = array('theme_advanced_buttons1' => '', 'theme_advanced_buttons2' => '', 'theme_advanced_buttons3' => ''); // we need a profile object and some defined rows if (!is_object($this->profile) || empty($this->profile->rows)) { return $rows; } // get plugins $plugins = $model->getPlugins(); // get core commands $commands = $model->getCommands(); // merge plugins and commands $icons = array_merge($commands, $plugins); // create an array of rows $lists = explode(';', $this->profile->rows); // backwards compatability map $map = array( 'paste' => 'clipboard', 'spacer' => '|', 'forecolor' => 'fontcolor', 'backcolor' => 'backcolor' ); $x = 0; for ($i = 1; $i <= count($lists); $i++) { $buttons = array(); $items = explode(',', $lists[$x]); foreach ($items as $item) { // set the plugin/command name $name = $item; // map legacy values etc. if (array_key_exists($item, $map)) { $item = $map[$item]; } // check if button should be in toolbar if ($item !== "|") { if (array_key_exists($item, $icons) === false) { continue; } // assign icon $item = $icons[$item]->icon; } // check for custom plugin buttons if (array_key_exists($name, $plugins)) { $custom = $wf->getParam($name . '.buttons'); if (!empty($custom)) { $custom = array_filter((array) $custom); if (empty($custom)) { $item = ""; } else { $a = array(); foreach (explode(',', $item) as $s) { if (in_array($s, $custom) || $s == "|") { $a[] = $s; } } $item = implode(',', $a); // remove leading or trailing | $item = trim($item, '|'); } } } if (!empty($item)) { // remove double | $item = preg_replace('#(\|,)+#', '|,', $item); $buttons[] = $item; } } if (!empty($buttons)) { $rows['theme_advanced_buttons' . $i] = implode(',', $buttons); } $x++; } return $rows; } /** * Return a list of published JCE plugins * * @access public * @return string list */ public function getPlugins() { jimport('joomla.filesystem.file'); static $plugins; if (is_object($this->profile)) { if (!is_array($plugins)) { $wf = WFEditor::getInstance(); $plugins = explode(',', $this->profile->plugins); $plugins = array_unique(array_merge(array('autolink', 'cleanup', 'core', 'code', 'colorpicker', 'upload', 'format'), $plugins)); // add formatselect if (in_array('formatselect', $plugins) === false && strpos($this->profile->rows, 'formatselect') !== false) { $plugins[] = 'formatselect'; } // add styleselect if (in_array('styleselect', $plugins) === false && strpos($this->profile->rows, 'styleselect') !== false) { $plugins[] = 'styleselect'; } // add fontselect if (in_array('fontselect', $plugins) === false && strpos($this->profile->rows, 'fontselect') !== false) { $plugins[] = 'fontselect'; } // add formatselect if (in_array('fontsizeselect', $plugins) === false && strpos($this->profile->rows, 'fontsizeselect') !== false) { $plugins[] = 'fontsizeselect'; } // add font colours if (in_array('fontcolor', $plugins) === false && preg_match('#(forecolor|backcolor)#', $this->profile->rows)) { $plugins[] = 'fontcolor'; } // add importcss if (in_array('styleselect', $plugins) || in_array('fontselect', $plugins)) { $plugins[] = 'importcss'; } // add advlists plugin if lists are loaded if (in_array('lists', $plugins)) { $plugins[] = 'advlist'; } // Load wordcount if path is enabled if ($wf->getParam('editor.path', 1)) { $plugins[] = 'wordcount'; } // add legacy "charmap" if (in_array('charmap', $plugins) === false && strpos($this->profile->rows, 'charmap') !== true) { $plugins[] = 'charmap'; } foreach ($plugins as $k => $v) { // check plugin is correctly installed and is a tinymce plugin, ie: it has an editor_plugin.js file if (!JFile::exists(WF_EDITOR_PLUGINS . '/' . $v . '/editor_plugin.js')) { unset($plugins[$k]); } } // remove empty values $plugins = array_filter($plugins); } } return $plugins; } /** * Get all loaded plugins config options * * @access public * @param array $settings passed by reference */ private function getPluginConfig(&$settings) { $plugins = $settings['plugins']; if ($plugins && is_array($plugins)) { foreach ($plugins as $plugin) { $file = WF_EDITOR_PLUGINS . '/' . $plugin . '/classes/config.php'; if (file_exists($file)) { require_once ($file); // Create class name $classname = 'WF' . ucfirst($plugin) . 'PluginConfig'; // Check class and method if (class_exists($classname) && method_exists($classname, 'getConfig')) { call_user_func_array(array($classname, 'getConfig'), array(&$settings)); } } } } } /** * Get all loaded plugins styles * * @access public * @param array $settings passed by reference */ private function getPluginStyles($settings) { $plugins = $settings['plugins']; if ($plugins && is_array($plugins)) { foreach ($plugins as $plugin) { $file = WF_EDITOR_PLUGINS . '/' . $plugin . '/classes/config.php'; if (file_exists($file)) { require_once ($file); // Create class name $classname = 'WF' . ucfirst($plugin) . 'PluginConfig'; // Check class and method if (class_exists($classname) && method_exists($classname, 'getStyles')) { call_user_func(array($classname, 'getStyles')); } } } } } /** * Remove keys from an array * * @return $array by reference * @param arrau $array Array to edit * @param array $keys Keys to remove */ public function removeKeys(&$array, $keys) { if (!is_array($keys)) { $keys = array($keys); } $array = array_diff($array, $keys); } /** * Add keys to an array * * @return The string list with added key or the key * @param string The array * @param string The keys to add */ public function addKeys(&$array, $keys) { if (!is_array($keys)) { $keys = array($keys); } $array = array_unique(array_merge($array, $keys)); } /** * Get a list of editor font families * * @return string font family list * @param string $add Font family to add * @param string $remove Font family to remove * * Deprecated in 2.3.4 */ public function getEditorFonts() { return ""; } /** * Return the current site template name * * @access public */ private static function getSiteTemplates() { $db = JFactory::getDBO(); $app = JFactory::getApplication(); $id = 0; if ($app->isSite()) { $menus = $app->getMenu(); $menu = $menus->getActive(); if ($menu) { $id = isset($menu->template_style_id) ? $menu->template_style_id : $menu->id; } } $query = $db->getQuery(true); if (is_object($query)) { $query->select('id, template')->from('#__template_styles')->where(array("client_id = 0", "home = '1'")); } else { $query = 'SELECT menuid as id, template' . ' FROM #__templates_menu' . ' WHERE client_id = 0'; } $db->setQuery($query); $templates = $db->loadObjectList(); $assigned = array(); foreach ($templates as $template) { if ($id == $template->id) { array_unshift($assigned, $template->template); } else { $assigned[] = $template->template; } } // return templates return $assigned; } private static function getYoothemePath($template) { $warp7 = JPATH_SITE . '/templates/' . $template . '/warp.php'; if (is_file($warp7)) { // get warp $warp = require($warp7); $layouts = $warp['config']->get('layouts'); $style = $layouts['default']['style']; if (!empty($style)) { return "templates/" . $template . "/styles/" . $style . "/css"; } } return "templates/" . $template . "/css"; } private static function getStyleSheetsList($absolute = false) { jimport('joomla.filesystem.folder'); jimport('joomla.filesystem.file'); // use system template as default $url = 'templates/system/css'; // use 'system' as default $template = 'system'; // use system editor.css as default $styles = 'templates/system/css/editor.css'; // stylesheets $stylesheets = array(); // files $files = array(); // get templates $templates = self::getSiteTemplates(); foreach ($templates as $item) { // Template CSS $path = JPATH_SITE . '/templates/' . $item; // get the first path that exists if (is_dir($path)) { // assign template $template = $item; if (substr($template, 0, 4) === "yoo_") { $url = self::getYoothemePath($template); $path = JPATH_SITE . '/' . $url; } else { // assign url $url = "templates/" . $template . "/css"; } break; } } wfimport('editor.libraries.classes.editor'); $wf = WFEditor::getInstance(); $global = intval($wf->getParam('editor.content_css', 1)); $profile = intval($wf->getParam('editor.profile_content_css', 2)); switch ($global) { // Custom template css files case 0 : // use getParam so result is cleaned $global_custom = $wf->getParam('editor.content_css_custom', ''); // Replace $template variable with site template name $global_custom = str_replace('$template', $template, $global_custom); // explode to array $files = explode(',', $global_custom); break; // Template css (template.css or template_css.css) case 1 : // Joomla! 1.5 standard $file = 'template.css'; $css = array(); if (JFolder::exists($path)) { $css = JFolder::files($path, '(base|core|theme|template|template_css)\.(css|less)$', false, true); } if (!empty($css)) { // use the first result $file = $css[0]; } // check for php version if (JFile::exists($file . '.php')) { $file = $file . '.php'; } $files[] = $url . '/' . basename($file); break; // Nothing, use system default case 2 : $files[] = 'templates/system/css/editor.css'; break; } switch ($profile) { // add to global config value case 0 : case 1 : $profile_custom = $wf->getParam('editor.profile_content_css_custom', ''); // Replace $template variable with site template name (defaults to 'system') $profile_custom = str_replace('$template', $template, $profile_custom); // explode to array $profile_custom = explode(',', $profile_custom); // add to existing list if ($profile == 0) { $files = array_merge($files, $profile_custom); // overwrite global config value } else { $files = (array) $profile_custom; } break; // inherit global config value case 2 : break; } // remove duplicates $files = array_unique($files); // get the root directory $root = $absolute ? JPATH_SITE : JURI::root(true); // check for existence of each file and make array of stylesheets foreach ($files as $file) { // remove leading slash $file = ltrim($file, '/'); if ($file && JFile::exists(JPATH_SITE . '/' . $file)) { $etag = ""; // add etag if ($absolute === false) { // create hash $etag = '?' . md5_file(JPATH_SITE . '/' . $file); } $stylesheets[] = $root . '/' . $file . $etag; } } // remove duplicates $stylesheets = array_unique($stylesheets); return $stylesheets; } /** * Get an array of stylesheets used by the editor. * References the WFEditor class. * If the list contains any LESS stylesheets, the list is returned as a URL to compile * @return string */ public static function getStyleSheets() { $stylesheets = self::getStyleSheetsList(); // check for less files in the array $less = preg_grep('#\.less$#', $stylesheets); // process less files etc. if (!empty($less)) { // create token $token = WFToken::getToken(); $version = self::getVersion(); return JURI::base(true) . '/index.php?option=com_jce&view=editor&layout=editor&task=compileless&' . $token . '=1'; } return $stylesheets; } /** * Get the URL of the editor * @param boolean $relative * @return string */ private function getURL($relative = false) { if ($relative) { return JURI::root(true) . '/components/com_jce/editor'; } return JURI::root() . 'components/com_jce/editor'; } /** * Pack / compress editor files */ public function pack() { // check token WFToken::checkToken('GET') or die('RESTRICTED'); wfimport('admin.classes.packer'); wfimport('admin.classes.language'); $wf = WFEditor::getInstance(); $type = JRequest::getWord('type', 'javascript'); // javascript $packer = new WFPacker(array('type' => $type)); $themes = 'none'; $plugins = array(); $suffix = JRequest::getWord('suffix', ''); $component_id = JRequest::getInt('component_id', 0); // if a profile is set if ($this->profile) { $themes = 'advanced'; $plugins = $this->getPlugins(); } $themes = explode(',', $themes); // toolbar theme $toolbar = explode('.', $wf->getParam('editor.toolbar_theme', 'default')); switch ($type) { case 'language' : $files = array(); $data = $this->loadLanguages(array(), array(), '(^dlg$|_dlg$)', true); $packer->setText($data); break; case 'javascript' : $files = array(); // add core file $files[] = WF_EDITOR . "/tiny_mce/tiny_mce" . $suffix . ".js"; // Add themes foreach ($themes as $theme) { $files[] = WF_EDITOR . "/tiny_mce/themes/" . $theme . "/editor_template" . $suffix . ".js"; } // Add plugins foreach ($plugins as $plugin) { $files[] = WF_EDITOR . "/tiny_mce/plugins/" . $plugin . "/editor_plugin" . $suffix . ".js"; } // add Editor file $files[] = WF_EDITOR . '/libraries/js/editor.js'; // parse ini language files $parser = new WFLanguageParser(); $data = $parser->load(); // add to packer $packer->setContentEnd($data); break; case 'css' : $context = JRequest::getWord('context', 'editor'); if ($context == 'content') { $files = array(); $files[] = WF_EDITOR_THEMES . '/' . $themes[0] . '/skins/' . $toolbar[0] . '/content.css'; // get template stylesheets $styles = self::getStyleSheetsList(true); foreach ($styles as $style) { if (JFile::exists($style)) { $files[] = $style; } } // load content styles dor each plugin if they exist foreach ($plugins as $plugin) { $content = WF_EDITOR_PLUGINS . '/' . $plugin . '/css/content.css'; if (JFile::exists($content)) { $files[] = $content; } } } else { $files = array(); $files[] = WF_EDITOR_LIBRARIES . '/css/editor.css'; $dialog = $wf->getParam('editor.dialog_theme', 'jce'); $files[] = WF_EDITOR_THEMES . '/' . $themes[0] . '/skins/' . $toolbar[0] . '/ui.css'; if (isset($toolbar[1])) { $files[] = WF_EDITOR_THEMES . '/' . $themes[0] . '/skins/' . $toolbar[0] . '/ui_' . $toolbar[1] . '.css'; } // get external styles from config class for each plugin foreach ($plugins as $plugin) { $class = WF_EDITOR_PLUGINS . '/' . $plugin . '/classes/config.php'; if (JFile::exists($class)) { require_once ($class); $classname = 'WF' . ucfirst($plugin) . 'PluginConfig'; if (class_exists($classname) && method_exists(new $classname, 'getStyles')) { $files = array_merge($files, (array) call_user_func(array($classname, 'getStyles'))); } } } } break; } $packer->setFiles($files); $packer->pack(); } public function loadLanguages() { // check token WFToken::checkToken('GET') or die('RESTRICTED'); wfimport('admin.classes.language'); $parser = new WFLanguageParser(array('plugins' => $this->getPlugins())); $data = $parser->load(); $parser->output($data); } public function compileLess() { // check token WFToken::checkToken('GET') or die('RESTRICTED'); wfimport('admin.classes.packer'); $wf = WFEditor::getInstance(); $files = self::getStyleSheetsList(true); if (!empty($files)) { $packer = new WFPacker(array('files' => $files, 'type' => 'css')); $packer->pack(false); } } public function getToken($id) { return ''; } } ?> components/com_jce/models/profiles.php000066600000045647150771655450014212 0ustar00extensions) { $supported = explode(',', (string) $xml->extensions); } } } foreach ($model->getExtensions() as $extension) { $type = $extension->folder; // the plugin only supports some extensions, move along if (!in_array($type, $supported)) { continue; } // this extension only supports some plugins, move along if (!empty($extension->plugins) && !in_array($plugin, $extension->plugins)) { continue; } $extensions[$type][] = $extension; } return $extensions; } public function getPlugins($plugins = array()) { wfimport('admin.models.plugins'); $model = new WFModelplugins(); $commands = array(); if (empty($plugins)) { $commands = $model->getCommands(); } // only need plugins with xml files foreach ($model->getPlugins() as $plugin => $properties) { if (is_file(JPATH_SITE . $properties->path . '/' . $plugin . '.xml')) { $plugins[$plugin] = $properties; } } return array_merge($commands, $plugins); } public function getUserGroups($area) { $db = JFactory::getDBO(); if (defined('JPATH_PLATFORM')) { jimport('joomla.access.access'); $query = $db->getQuery(true); if (is_object($query)) { $query->select('id')->from('#__usergroups'); } else { $query = 'SELECT id FROM #__usergroups'; } $db->setQuery($query); if (method_exists($db, 'loadColumn')) { $groups = $db->loadColumn(); } else { $groups = $db->loadResultArray(); } $front = array(); $back = array(); foreach ($groups as $group) { $create = JAccess::checkGroup($group, 'core.create'); $admin = JAccess::checkGroup($group, 'core.login.admin'); $super = JAccess::checkGroup($group, 'core.admin'); if ($super) { $back[] = $group; } else { // group can create if ($create) { // group has admin access if ($admin) { $back[] = $group; } else { $front[] = $group; } } } } } else { $front = array( '19', '20', '21' ); $back = array( '23', '24', '25' ); } switch ($area) { case 0: return array_merge($front, $back); break; case 1: return $front; break; case 2: return $back; break; } return array(); } /** * Create the Profiles table * @return boolean */ public function createProfilesTable() { jimport('joomla.installer.helper'); $mainframe = JFactory::getApplication(); $db = JFactory::getDBO(); $driver = strtolower($db->name); switch ($driver) { default: case 'mysql': case 'mysqli': $driver = 'mysql'; break; case 'sqlsrv': case 'sqlazure': case 'sqlzure': $driver = 'sqlsrv'; break; case 'postgresql' : $driver = 'postgresql'; break; } $file = dirname(dirname(__FILE__)) . '/sql/' . $driver . '.sql'; $error = null; if (is_file($file)) { $query = file_get_contents($file); if ($query) { // replace prefix $query = $db->replacePrefix((string) $query); // Postgresql needs special attention because of the query syntax if ($driver == 'postgresql') { $query = "CREATE OR REPLACE FUNCTION create_table_if_not_exists (create_sql text) RETURNS bool as $$ BEGIN BEGIN EXECUTE create_sql; EXCEPTION WHEN duplicate_table THEN RETURN false; END; RETURN true; END; $$ LANGUAGE plpgsql; SELECT create_table_if_not_exists ('" . $query . "');"; } // set query $db->setQuery(trim($query)); if (!$db->query()) { $mainframe->enqueueMessage(WFText::_('WF_INSTALL_TABLE_PROFILES_ERROR') . $db->stdErr(), 'error'); return false; } else { return true; } } else { $error = 'NO SQL QUERY'; } } else { $error = 'SQL FILE MISSING'; } $mainframe->enqueueMessage(WFText::_('WF_INSTALL_TABLE_PROFILES_ERROR') . !is_null($error) ? ' - ' . $error : '', 'error'); return false; } /** * Install Profiles * @return boolean * @param object $install[optional] */ public function installProfiles() { $app = JFactory::getApplication(); $db = JFactory::getDBO(); if ($this->createProfilesTable()) { self::buildCountQuery(); $profiles = array('Default' => false, 'Front End' => false); // No Profiles table data if (!$db->loadResult()) { $xml = dirname(__FILE__) . '/profiles.xml'; if (is_file($xml)) { if (!$this->processImport($xml)) { $app->enqueueMessage(WFText::_('WF_INSTALL_PROFILES_ERROR'), 'error'); return false; } } else { $app->enqueueMessage(WFText::_('WF_INSTALL_PROFILES_NOFILE_ERROR'), 'error'); return false; } } return true; } return false; } private static function buildCountQuery($name = '') { $db = JFactory::getDBO(); $query = $db->getQuery(true); // check for name if (is_object($query)) { $query->select('COUNT(id)')->from('#__wf_profiles'); if ($name) { $query->where('name = ' . $db->Quote($name)); } } else { $query = 'SELECT COUNT(id) FROM #__wf_profiles'; if ($name) { $query .= ' WHERE name = ' . $db->Quote($name); } } $db->setQuery($query); } /** * Process import data from XML file * @param object $file XML file * @param boolean $install Can be used by the package installer * @return */ public function processImport($file) { $app = JFactory::getApplication(); $db = JFactory::getDBO(); $view = JRequest::getCmd('view'); $language = JFactory::getLanguage(); $language->load('com_jce', JPATH_ADMINISTRATOR); JTable::addIncludePath(dirname(dirname(__FILE__)) . '/tables'); $xml = WFXMLElement::load($file); if ($xml) { $n = 0; foreach ($xml->profiles->children() as $profile) { $row = JTable::getInstance('profiles', 'WFTable'); // get profile name $name = (string) $profile->attributes()->name; // backwards compatability if ($name) { self::buildCountQuery($name); // create name copy if exists while ($db->loadResult()) { $name = JText::sprintf('WF_PROFILES_COPY_OF', $name); self::buildCountQuery($name); } // set name $row->name = $name; } foreach ($profile->children() as $item) { switch ($item->getName()) { case 'name': $name = (string) $item; // only if name set and table name not set if ($name && !$row->name) { self::buildCountQuery($name); // create name copy if exists while ($db->loadResult()) { $name = JText::sprintf('WF_PROFILES_COPY_OF', $name); self::buildCountQuery($name); } // set name $row->name = $name; } break; case 'description': $row->description = WFText::_((string) $item); break; case 'types': if (!(string) $item) { $area = (string) $profile->area[0]; $groups = $this->getUserGroups($area); $data = implode(',', array_unique($groups)); } else { $data = (string) $item; } $row->types = $data; break; case 'params': $params = array(); foreach ($item->children() as $param) { $params[] = (string) $param; } $row->params = implode("\n", $params); break; case 'rows': $row->rows = (string) $item; break; case 'plugins': $row->plugins = (string) $item; break; default: $key = $item->getName(); $row->$key = (string) $item; break; } } if (!$row->store()) { $app->enqueueMessage(WFText::_('WF_PROFILES_IMPORT_ERROR'), $row->getError(), 'error'); return false; } else { $n++; } } return true; } } /** * Get default profile data * @return $row Profile table object */ function getDefaultProfile() { $mainframe = JFactory::getApplication(); $file = JPATH_COMPONENT . '/models/profiles.xml'; $xml = WFXMLElement::load($file); if ($xml) { foreach ($xml->profiles->children() as $profile) { if ($profile->attributes()->default) { $row = JTable::getInstance('profiles', 'WFTable'); foreach ($profile->children() as $item) { switch ($item->getName()) { case 'rows': $row->rows = (string) $item; break; case 'plugins': $row->plugins = (string) $item; break; default: $key = $item->getName(); $row->$key = (string) $item; break; } } // reset name and description $row->name = ''; $row->description = ''; return $row; } } } return null; } function getEditorParams(&$row) { // get params definitions $xml = WF_EDITOR_LIBRARIES . '/xml/config/profiles.xml'; // get editor params $params = new WFParameter($row->params, $xml, 'editor'); $params->addElementPath(JPATH_COMPONENT . '/elements'); $params->addElementPath(WF_EDITOR . '/elements'); $groups = $params->getGroups(); $row->editor_params = $params; $row->editor_groups = $groups; } function getLayoutParams(&$row) { // get params definitions $xml = WF_EDITOR_LIBRARIES . '/xml/config/layout.xml'; // get editor params $params = new WFParameter($row->params, $xml, 'editor'); $params->addElementPath(JPATH_COMPONENT . '/elements'); $params->addElementPath(WF_EDITOR . '/elements'); $groups = $params->getGroups(); $row->layout_params = $params; $row->layout_groups = $groups; } function getPluginParameters() { } function getThemes() { jimport('joomla.filesystem.folder'); $path = WF_EDITOR_THEMES . '/advanced/skins'; return JFolder::folders($path, '.', false, true); } /** * Check whether a table exists * @return boolean * @param string $table Table name */ public static function checkTable() { $db = JFactory::getDBO(); $tables = $db->getTableList(); if (!empty($tables)) { // swap array values with keys, convert to lowercase and return array keys as values $tables = array_keys(array_change_key_case(array_flip($tables))); $app = JFactory::getApplication(); $match = str_replace('#__', strtolower($app->getCfg('dbprefix', '')), '#__wf_profiles'); return in_array($match, $tables); } // try with query self::buildCountQuery(); return $db->query(); } /** * Check table contents * @return integer * @param string $table Table name */ public static function checkTableContents() { $db = JFactory::getDBO(); self::buildCountQuery(); return $db->loadResult(); } private function getIconType($icon) { // TODO - Enhance this later to get the type from xml if (in_array($icon, array('styleselect', 'formatselect', 'fontselect', 'fontsizeselect'))) { return 'mceListBox'; } if (in_array($icon, array('numlist', 'bullist', 'forecolor', 'backcolor', 'spellchecker', 'textcase'))) { return 'mceSplitButton'; } return 'mceButton'; } public function getIcon($plugin) { if ($plugin->type == 'command') { $base = 'components/com_jce/editor/tiny_mce/themes/advanced/img'; } else { if (isset($plugin->path)) { $base = $plugin->path . '/img/'; } else { $base = 'components/com_jce/editor/tiny_mce/plugins/' . $plugin->name . '/img'; } } // convert backslashes $base = preg_replace('#[/\\\\]+#', '/', $base); $span = ''; $img = ''; $icons = explode(',', $plugin->icon); foreach ($icons as $icon) { if ($icon == '|' || $icon == 'spacer') { $span .= ''; } else { $path = $base . $icon . '.png'; if (JFile::exists(JPATH_SITE . '/' . $path)) { $img = '' . WFText::_($plugin->title) . ''; } $span .= '' . $img . ''; } } return $span; } public function saveOrder($cid, $order) { $db = JFactory::getDBO(); $total = count($cid); JArrayHelper::toInteger($cid, array(0)); JArrayHelper::toInteger($order, array(0)); $row = JTable::getInstance('profiles', 'WFTable'); $conditions = array(); // update ordering values for ($i = 0; $i < $total; $i++) { $row->load((int) $cid[$i]); if ($row->ordering != $order[$i]) { $row->ordering = $order[$i]; if (!$row->store()) { return false; } // remember to updateOrder this group $condition = ' ordering > -10000 AND ordering < 10000'; $found = false; foreach ($conditions as $cond) { if ($cond[1] == $condition) { $found = true; break; } } if (!$found) $conditions[] = array($row->id, $condition); } } // execute updateOrder for each group foreach ($conditions as $cond) { $row->load($cond[0]); $row->reorder($cond[1]); } return true; } }components/com_jce/models/config.php000066600000001315150771655450013614 0ustar00 components/com_jce/models/preferences.php000066600000013472150771655450014657 0ustar00$action)) { $rule = $rules->$action; return (isset($rule->$gid) && $rule->$gid != 0); } } // set Manager to false, Administrator and Super Administrator to true return $gid > 23; } public function getForm($group = null) { jimport('joomla.form.form'); if (class_exists('JForm')) { JForm::addFormPath(JPATH_ADMINISTRATOR . '/components/com_jce'); $form = JForm::getInstance('com_jce.component', 'config', array('control' => 'params'), false, '/config'); if ($group) { return $form->getFieldset($group); } return $form; } else { $component = WFExtensionHelper::getComponent(); // get params definitions $params = json_decode($component->params); $rules = isset($params->access) ? $params->access : null; // Build the form control. $curLevel = 0; $actions = $this->getActions(); $groups = $this->getUserGroups(); $tabs = array(''; $content[] = '
      '; return implode('', array_merge($tabs, $content)); } return null; } /** * Get Actions from access.xml file */ protected function getActions() { $file = JPATH_COMPONENT_ADMINISTRATOR . '/access.xml'; $xml = WFXMLElement::load($file); $actions = array(); if ($xml) { // Iterate over the children and add to the actions. foreach ($xml->section->children() as $element) { if ($element->getName() == 'action') { $actions[] = (object) array( 'name' => (string) $element['name'], 'title' => (string) $element['title'], 'description' => (string) $element['description'] ); } } } return $actions; } /** * Get a list of the user groups. */ protected function getUserGroups() { $db = JFactory::getDBO(); // Initialise variables. $db = JFactory::getDBO(); $query = 'SELECT a.id AS value, a.name AS text, COUNT(DISTINCT b.id) AS level, a.parent_id' . ' FROM #__core_acl_aro_groups AS a' . ' LEFT JOIN #__core_acl_aro_groups AS b ON a.lft >= b.lft AND a.rgt <= b.rgt' . ' WHERE a.id IN (23,24,25) AND b.id IN (23,24,25)' . ' GROUP BY a.id' . ' ORDER BY a.lft ASC' ; // Get the options. $db->setQuery($query); return $db->loadObjectList(); } }components/com_jce/models/updates.php000066600000033317150771655450014023 0ustar00 array(), 'jce' => array()); // Get Component xml $com_xml = WFXMLHelper::parseInstallManifest(JPATH_ADMINISTRATOR . '/components/com_jce/jce.xml'); // set component version $versions['joomla']['com_jce'] = $com_xml['version']; // get mediabox version $mediabox_xml_file = WF_JOOMLA15 ? JPATH_PLUGINS . '/system/jcemediabox.xml' : JPATH_PLUGINS . '/system/jcemediabox/jcemediabox.xml'; // set mediabox version if (file_exists($mediabox_xml_file)) { $mediabox_xml = WFXMLHelper::parseInstallManifest($mediabox_xml_file); $versions['joomla']['plg_jcemediabox'] = $mediabox_xml['version']; } wfimport('admin.models.plugins'); $model = new WFModelPlugins(); // get all plugins $plugins = $model->getPlugins(); // get all extensions $extensions = $model->getExtensions(); foreach ($plugins as $plugin) { if ($plugin->core == 0) { $file = WF_EDITOR_PLUGINS . '/' . $plugin->name . '/' . $plugin->name . '.xml'; $xml = WFXMLHelper::parseInstallManifest($file); $versions['jce']['jce_' . $plugin->name] = $xml['version']; } } foreach ($extensions as $extension) { if ($extension->core == 0) { $file = WF_EDITOR_EXTENSIONS . '/' . $extension->folder . '/' . $extension->extension . '.xml'; $xml = WFXMLHelper::parseInstallManifest($file); $versions['jce']['jce_' . $extension->folder . '_' . $extension->extension] = $xml['version']; } } return $versions; } /** * Check for extension updates * @return String JSON string of updates */ public function check() { $result = false; // Get all extensions and version numbers $data = array('task' => 'check', 'jversion' => WF_JOOMLA15 ? '1.5' : '2.5'); wfimport('admin.helpers.extension'); $component = WFExtensionHelper::getComponent(); $params = new WFParameter($component->params, '', 'preferences'); // get update key $key = $params->get('updates_key', ''); $type = $params->get('updates_type', ''); // encode it if (!empty($key)) { $data['key'] = urlencode($key); } if ($type) { $data['type'] = $type; } $req = array(); // create request data foreach ($this->getVersions() as $type => $extension) { foreach ($extension as $item => $value) { $data[$type . '[' . urlencode($item) . ']'] = urlencode($value); } } foreach ($data as $key => $value) { $req[] = $key . '=' . urlencode($value); } // connect $result = $this->connect(self::$updateURL, implode('&', $req)); return $result; } /** * Download update * @return String JSON string */ public function download() { $app = JFactory::getApplication(); jimport('joomla.filesystem.folder'); jimport('joomla.filesystem.file'); $config = JFactory::getConfig(); $result = array('error' => WFText::_('WF_UPDATES_DOWNLOAD_ERROR')); $id = JRequest::getInt('id'); $data = $this->connect(self::$updateURL . '&task=download&id=' . $id); if ($data) { $data = json_decode($data); if (isset($data->error)) { return json_encode(array('error' => $data->error)); } // get update file if ($data->name && $data->url && $data->hash) { // create path for package file $path = $app->getCfg('tmp_path') . '/' . basename($data->name); // download file if ($this->connect($data->url, null, $path)) { if (JFile::exists($path) && @filesize($path) > 0) { // check hash and file type if ($data->hash == md5(md5_file($path)) && preg_match('/\.(zip|tar|gz)$/', $path)) { $result = array('file' => basename($path), 'hash' => $data->hash, 'installer' => $data->installer, 'type' => isset($data->type) ? $data->type : ''); } else { // fail and delete file $result = array('error' => WFText::_('WF_UPDATES_ERROR_FILE_VERIFICATION_FAIL')); if (JFile::exists($path)) { @JFile::delete($path); } } } else { $result = array('error' => WFText::_('WF_UPDATES_ERROR_FILE_MISSING_OR_INVALID')); } } else { $result = array('error' => WFText::_('WF_UPDATES_DOWNLOAD_ERROR_DATA_TRANSFER')); } } else { $result = array('error' => WFText::_('WF_UPDATES_DOWNLOAD_ERROR_MISSING_DATA')); } } return json_encode($result); } /** * Method to detect the extension type from a package directory * * @param string $dir Path to package directory * @return mixed Extension type string or boolean false on fail * * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved. */ public static function detectType($dir) { // Search the install dir for an XML file $files = JFolder::files($dir, '\.xml$', 1, true); if (!count($files)) { return false; } foreach ($files as $file) { $xml = simplexml_load_file($file); if (!$xml) { continue; } $name = $xml->getName(); if ($name != 'extension' && $name != 'install') { unset($xml); continue; } $type = (string) $xml->attributes()->type; // Free up memory unset($xml); return $type; } // Free up memory. unset($xml); return false; } /** * Unpacks a file and verifies it as a Joomla element package * Supports .gz .tar .tar.gz and .zip * * @param string $archive The uploaded package filename or install directory * @return mixed Array on success or boolean false on failure * * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved. */ private static function unpack($archive) { jimport('joomla.filesystem.file'); jimport('joomla.filesystem.archive'); // Temporary folder to extract the archive into $tmpdir = uniqid('install_'); // Clean the paths to use for archive extraction $extractdir = JPath::clean(dirname($archive) . '/' . $tmpdir); // Do the unpacking of the archive try { JArchive::extract($archive, $extractdir); } catch (Exception $e) { return false; } /* * Let's set the extraction directory and package file in the result array so we can * cleanup everything properly later on. */ $retval['extractdir'] = $extractdir; $retval['packagefile'] = $archive; /* * Try to find the correct install directory. In case the package is inside a * subdirectory detect this and set the install directory to the correct path. * * List all the items in the installation directory. If there is only one, and * it is a folder, then we will set that folder to be the installation folder. */ $dirList = array_merge(JFolder::files($extractdir, ''), JFolder::folders($extractdir, '')); if (count($dirList) == 1) { if (JFolder::exists($extractdir . '/' . $dirList[0])) { $extractdir = JPath::clean($extractdir . '/' . $dirList[0]); } } $retval['dir'] = $extractdir; /* * Get the extension type and return the directory/type array on success or * false on fail. */ $retval['type'] = self::detectType($extractdir); if ($retval['type']) { return $retval; } else { return false; } } /** * Install extension update * @return String JSON string */ public function install() { jimport('joomla.installer.installer'); jimport('joomla.installer.helper'); jimport('joomla.filesystem.file'); $app = JFactory::getApplication(); $result = array('error' => WFText::_('WF_UPDATES_INSTALL_ERROR')); // get vars $file = JRequest::getCmd('file'); $hash = JRequest::getVar('hash', '', 'POST', 'alnum'); $method = JRequest::getWord('installer'); $type = JRequest::getWord('type'); // check for vars if ($file && $hash && $method) { $path = $app->getCfg('tmp_path') . '/' . $file; // check if file exists if (JFile::exists($path)) { // check hash if ($hash == md5(md5_file($path))) { if ($package = self::unpack($path)) { // Install a JCE Add-on if ($method == 'jce') { wfimport('admin.classes.installer'); $installer = WFInstaller::getInstance(); // install if ($installer->install($package['dir'])) { // installer message $result = array('error' => '', 'text' => WFText::_($installer->get('message'), $installer->get('message'))); } // Install a Joomla! Extension } else { jimport('joomla.installer.installer'); // get new Installer instance $installer = JInstaller::getInstance(); if ($installer->install($package['dir'])) { // installer message $result = array('error' => '', 'text' => WFText::_($installer->get('message'), $installer->get('message'))); } } // Cleanup the install files if (!is_file($package['packagefile'])) { $package['packagefile'] = $app->getCfg('tmp_path') . '/' . $package['packagefile']; } if (is_file($package['packagefile'])) { JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); } } else { $result = array('error' => WFText::_('WF_UPDATES_ERROR_FILE_EXTRACT_FAIL')); } } else { $result = array('error' => WFText::_('WF_UPDATES_ERROR_FILE_VERIFICATION_FAIL')); } } else { $result = array('error' => WFText::_('WF_UPDATES_ERROR_FILE_MISSING_OR_INVALID')); } } return json_encode($result); } /** * @copyright Copyright (C) 2009 Ryan Demmer. All rights reserved. * @copyright Copyright (C) 2006-2010 Nicholas K. Dionysopoulos * @param String $url URL to resource * @param Array $data [optional] Array of key value pairs * @param String $download [optional] path to file to write to * @return Mixed Boolean or JSON String on error */ protected function connect($url, $data = '', $download = '') { @error_reporting(E_ERROR); $result = false; if ($download) { return UpdatesHelper::download($url, $download); } else { $result = UpdatesHelper::check($url, $data); if ($result === false) { return array('error' => WFText::_('Update check failed : Invalid response from update server')); } } return $result; } } ?>components/com_jce/models/mediabox.php000066600000001150150771655450014134 0ustar00components/com_jce/install.script.php000066600000017117150771655450014044 0ustar00getParent() : $parent->parent; return WFInstall::install($installer); } public function uninstall() { $db = JFactory::getDBO(); // remove Profiles table if its empty if ((int) self::checkTableContents('#__wf_profiles') == 0) { if (method_exists($db, 'dropTable')) { $db->dropTable('#__wf_profiles', true); } else { $query = 'DROP TABLE IF EXISTS #__wf_profiles'; $db->setQuery($query); } $db->query(); } // remove packages self::removePackages(); } public function update($parent) { return $this->install($parent); } public function postflight($type, $parent) { } /** * Check table contents * @return integer * @param string $table Table name */ private static function checkTableContents($table) { $db = JFactory::getDBO(); $query = $db->getQuery(true); if (is_object($query)) { $query->select('COUNT(id)')->from($table); } else { $query = 'SELECT COUNT(id) FROM ' . $table; } $db->setQuery($query); return $db->loadResult(); } private static function getModule($name) { // Joomla! 2.5 if (defined('JPATH_PLATFORM')) { $module = JTable::getInstance('extension'); return $module->find(array('type' => 'module', 'element' => $name)); // Joomla! 1.5 } else { $db = JFactory::getDBO(); $query = 'SELECT id FROM #__modules' . ' WHERE module = ' . $db->Quote($name); $db->setQuery($query); return $db->loadResult(); } } private static function getPlugin($folder, $element) { // Joomla! 2.5 if (defined('JPATH_PLATFORM')) { $plugin = JTable::getInstance('extension'); return $plugin->find(array('type' => 'plugin', 'folder' => $folder, 'element' => $element)); // Joomla! 1.5 } else { $plugin = JTable::getInstance('plugin'); $db = JFactory::getDBO(); $query = 'SELECT id FROM #__plugins' . ' WHERE folder = ' . $db->Quote($folder) . ' AND element = ' . $db->Quote($element); $db->setQuery($query); return $db->loadResult(); } } /** * Uninstall the editor * @return boolean */ private static function removePackages() { $app = JFactory::getApplication(); $db = JFactory::getDBO(); jimport('joomla.module.helper'); jimport('joomla.installer.installer'); $plugins = array( 'editors' => array('jce'), 'quickicon' => array('jcefilebrowser') ); $modules = array('mod_jcefilebrowser'); // items to remove $items = array( 'plugin' => array(), 'module' => array() ); foreach ($plugins as $folder => $elements) { foreach ($elements as $element) { $item = self::getPlugin($folder, $element); if ($item) { $items['plugin'][] = $item; } } } foreach ($modules as $module) { $item = self::getModule($module); if ($item) { $items['module'][] = $item; } } foreach ($items as $type => $extensions) { if ($extensions) { foreach ($extensions as $id) { $installer = new JInstaller(); $installer->uninstall($type, $id); $app->enqueueMessage($installer->message); } } } } public static function checkRequirements() { $requirements = array(); // check PHP version if (version_compare(PHP_VERSION, '5.2.4', '<')) { $requirements[] = array( 'name' => 'PHP Version', 'info' => 'JCE Requires PHP version 5.2.4 or later. Your version is : ' . PHP_VERSION ); } // check JSON is installed if (function_exists('json_encode') === false || function_exists('json_decode') === false) { $requirements[] = array( 'name' => 'JSON', 'info' => 'JCE requires the PHP JSON extension which is not available on this server.' ); } // check SimpleXML if (function_exists('simplexml_load_string') === false || function_exists('simplexml_load_file') === false || class_exists('SimpleXMLElement') === false) { $requirements[] = array( 'name' => 'SimpleXML', 'info' => 'JCE requires the PHP SimpleXML library which is not available on this server.' ); } if (!empty($requirements)) { $message = '
      '; $message .= '

      ' . JText::_('WF_ADMIN_TITLE') . ' - Install Failed

      '; $message .= '

      JCE could not be installed as this site does not meet technical requirements (see below)

      '; $message .= '
        '; foreach ($requirements as $requirement) { $message .= '
      • ' . $requirement['name'] . ' : ' . $requirement['info'] . '
      • '; } $message .= '
      '; $message .= '
      '; return $message; } return true; } } /** * Installer function * @return */ function com_install() { if (!defined('JPATH_PLATFORM')) { require_once(JPATH_ADMINISTRATOR . '/components/com_jce/install.php'); $installer = JInstaller::getInstance(); $requirements = com_jceInstallerScript::checkRequirements(); if ($requirements !== true) { $installer->set('message', $requirements); $installer->abort(); WFInstall::cleanupInstall(); return false; } return WFInstall::install($installer); } return true; } /** * Uninstall function * @return */ function com_uninstall() { if (!defined('JPATH_PLATFORM')) { $script = new com_jceInstallerScript(); return $script->uninstall(); } return true; } ?> components/com_jce/jce.xml000066600000010140150771655450011632 0ustar00 JCE Ryan Demmer 11 September 2014 Copyright (C) 2006 - 2014 Ryan Demmer. All rights reserved GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html info@joomlacontenteditor.net www.joomlacontenteditor.net 2.4.3 WF_ADMIN_DESC install.script.php editor media views index.html jce.php licence.txt mediaplayer en-GB.com_jce.xml en-GB.com_jce.ini sql/mysql.sql sql/mysql.sql sql/sqlsrv.sql sql/sqlsrv.sql sql/sqlsrv.sql JCE WF_MENU_CPANEL WF_MENU_CONFIG WF_MENU_PROFILES WF_MENU_INSTALL adapters classes controller elements helpers includes media models sql tables views access.xml controller.php config.xml index.html install.php install.script.php jce.php licence.txt en-GB.com_jce.ini en-GB.com_jce.sys.ini en-GB.plg_editors_jce.ini en-GB.plg_editors_jce.sys.ini en-GB.plg_quickicon_jcefilebrowser.ini en-GB.plg_quickicon_jcefilebrowser.sys.ini components/com_jce/adapters/language.php000066600000015266150771655450014464 0ustar00parent = $parent; } private function setManifest($manifest = null) { $values = array('name', 'version', 'description', 'tag'); foreach($values as $value) { $this->parent->set($value, WFXMLHelper::getElement($manifest, $value)); } $elements = array('administration', 'site', 'tinymce'); foreach($elements as $element) { $this->set($element, WFXMLHelper::getElements($manifest, $element)); } } /** * Install method * * @access public * @return boolean True on success */ public function install() { $manifest = $this->parent->getManifest(); // Get the extension manifest object $this->setManifest($manifest); // Check language tag - if we didn't, we may be trying to install from an older language package if (!$this->parent->get('tag')) { $this->parent->abort(WFText::_('WF_INSTALLER_LANGUAGE_INSTALL') . ' : ' . WFText::_('WF_INSTALLER_LANGUAGE_NO_TAG')); return false; } $folder = $this->parent->get('tag'); // Set the installation target paths $this->parent->setPath('extension_site', JPATH_SITE . '/language/' . $folder); $this->parent->setPath('extension_administrator', JPATH_ADMINISTRATOR . '/language/' . $folder); // Set overwrite flag if not set by Manifest $this->parent->setOverwrite(true); // Copy admin files if ($this->parent->parseFiles($this->get('administration'), 1) === false) { $this->parent->abort(); return false; } // Copy site files if ($this->parent->parseFiles($this->get('site')) === false) { $this->parent->abort(); return false; } // Copy tinymce files $this->parent->setPath('extension_site', JPATH_COMPONENT_SITE . '/editor/tiny_mce'); if ($this->parent->parseFiles($this->get('tinymce')) === false) { $this->parent->abort(); return false; } $this->addIndexfiles($this->parent->getPath('site')); // Set path back to site for manifest $this->parent->setPath('extension_site', JPATH_SITE . '/language/' . $folder); // Lastly, we will copy the manifest file to its appropriate place. if (!$this->parent->copyManifest(0)) { // Install failed, rollback changes $this->parent->abort(WFText::_('WF_INSTALLER_LANGUAGE_INSTALL') . ' : ' . WFText::_('WF_INSTALLER_SETUP_COPY_ERROR')); return false; } return true; } /** * Add index.html files to each folder * @access private */ private function addIndexfiles($path) { jimport('joomla.filesystem.folder'); jimport('joomla.filesystem.file'); // get the base file $file = WF_ADMINISTRATOR . '/index.html'; if (is_file($file) && is_dir($path)) { JFile::copy($file, $path . '/' . basename($file)); // admin component $folders = JFolder::folders($path, '.', true, true); foreach ($folders as $folder) { JFile::copy($file, $folder . '/' . basename($file)); } } } /** * Uninstall method * * @access public * @param string $tag The tag of the language to uninstall * @return mixed Return value for uninstall method in component uninstall file */ function uninstall($tag) { // Set defaults $this->parent->set('name', $tag); $this->parent->set('version', ''); // Clean tag $tag = trim($tag); $path = JPATH_SITE . '/language/' . $tag; if (!JFolder::exists($path)) { JError::raiseWarning(100, WFText::_('WF_INSTALLER_LANGUAGE_UNINSTALL') . ' : ' . WFText::_('WF_INSTALLER_LANGUAGE_PATH_EMPTY')); return false; } // Because JCE languages don't have their own folders we cannot use the standard method of finding an installation manifest $manifest = $path . '/' . $tag . '.com_jce.xml'; if (file_exists($manifest)) { $xml = WFXMLHelper::getXML($manifest); if (!$xml) { JError::raiseWarning(100, WFText::_('WF_INSTALLER_LANGUAGE_UNINSTALL') . ' : ' . WFText::_('WF_INSTALLER_MANIFEST_INVALID')); } $this->setManifest($xml); // Set the installation target paths $this->parent->setPath('extension_site', $path); $this->parent->setPath('extension_administrator', JPATH_ADMINISTRATOR . "/language/" . $tag); if (!$this->parent->removeFiles($this->get('site'))) { JError::raiseWarning(100, WFText::_('WF_INSTALLER_LANGUAGE_UNINSTALL') . ' : ' . WFText::_('WF_INSTALL_DELETE_FILES_ERROR')); return false; } if (!$this->parent->removeFiles($this->get('administration'), 1)) { JError::raiseWarning(100, WFText::_('WF_INSTALLER_LANGUAGE_UNINSTALL') . ' : ' . WFText::_('WF_INSTALL_DELETE_FILES_ERROR')); return false; } $this->parent->setPath('extension_site', JPATH_COMPONENT_SITE . '/editor/tiny_mce'); if (!$this->parent->removeFiles($this->get('tinymce'))) { JError::raiseWarning(100, WFText::_('WF_INSTALLER_LANGUAGE_UNINSTALL') . ' : ' . WFText::_('WF_INSTALL_DELETE_FILES_ERROR')); return false; } JFile::delete($manifest); } else { JError::raiseWarning(100, WFText::_('WF_INSTALLER_LANGUAGE_UNINSTALL') . ' : ' . WFText::_('WF_INSTALLER_MANIFEST_ERROR')); return false; } return true; } } components/com_jce/adapters/plugin.php000066600000036255150771655450014200 0ustar00parent = $parent; } private function setManifest() { $manifest = $this->parent->getManifest(); if (!$manifest) { return false; } $values = array('name', 'description', 'install.script', 'uninstall.script', 'icon'); foreach ($values as $value) { $this->parent->set($value, WFXMLHelper::getElement($manifest, $value)); } $attributes = array('version', 'plugin', 'group', 'type', 'folder', 'row', 'extension'); foreach ($attributes as $attribute) { $this->set($attribute, WFXMLHelper::getAttribute($manifest, $attribute)); } $elements = array('files', 'languages', 'media'); foreach ($elements as $element) { $this->set($element, WFXMLHelper::getElements($manifest, $element)); } } /** * Install method * * @access public * @return boolean True on success */ public function install() { // Get a database connector object $db = $this->parent->getDBO(); $this->setManifest(); $plugin = $this->get('plugin'); $group = $this->get('group'); $type = $this->get('type'); $folder = $this->get('folder'); $extension = $this->get('extension'); // JCE Plugin if (!empty($plugin) || !empty($extension)) { if (version_compare((string) $this->get('version'), '2.0', '<')) { $this->parent->abort(WFText::_('WF_INSTALLER_INCORRECT_VERSION')); return false; } // its an "extension" if ($extension) { $this->parent->setPath('extension_root', JPATH_COMPONENT_SITE . '/editor/extensions/' . $folder); } else { $this->parent->setPath('extension_root', JPATH_COMPONENT_SITE . '/editor/tiny_mce/plugins/' . $plugin); } } else { // Non-JCE plugin type, probably JCE MediaBox if ($type == 'plugin' && $group == 'system') { // check manifest type against Joomla version $manifest = $this->parent->getManifest(); if (defined('JPATH_PLATFORM') && $manifest->getName() == 'install') { $this->parent->abort(WFText::_('WF_INSTALLER_EXTENSION_INSTALL') . ' : ' . WFText::_('WF_INSTALLER_INVALID_MANIFEST')); } else { @include_once(JPATH_LIBRARIES . '/joomla/installer/adapters/plugin.php'); // try cms path for Joomla 3.1 if (defined('JPATH_PLATFORM')) { @include_once(JPATH_LIBRARIES . '/cms/installer/adapter/plugin.php'); } if (!class_exists('JInstallerPlugin')) { $this->parent->abort(); } // create adapter $adapter = new JInstallerPlugin($this->parent, $db); if (method_exists($adapter, 'loadLanguage')) { $adapter->loadLanguage($this->parent->getPath('source')); } // set adapter $this->parent->setAdapter('plugin', $adapter); // isntall return $adapter->install(); } return false; } else { $this->parent->abort(WFText::_('WF_INSTALLER_EXTENSION_INSTALL') . ' : ' . WFText::_('WF_INSTALLER_NO_PLUGIN_FILE')); return false; } } /** * --------------------------------------------------------------------------------------------- * Filesystem Processing Section * --------------------------------------------------------------------------------------------- */ // If the extension directory does not exist, lets create it $created = false; if (!file_exists($this->parent->getPath('extension_root'))) { if (!$created = JFolder::create($this->parent->getPath('extension_root'))) { $this->parent->abort(WFText::_('WF_INSTALLER_PLUGIN_INSTALL') . ' : ' . WFText::_('WF_INSTALLER_MKDIR_ERROR') . ' : "' . $this->parent->getPath('extension_root') . '"'); return false; } } // Set overwrite flag if not set by Manifest $this->parent->setOverwrite(true); /* * If we created the extension directory and will want to remove it if we * have to roll back the installation, lets add it to the installation * step stack */ if ($created) { $this->parent->pushStep(array( 'type' => 'folder', 'path' => $this->parent->getPath('extension_root') )); } // Copy all necessary files if (!$this->parent->parseFiles($this->get('files'), -1)) { // Install failed, roll back changes $this->parent->abort(); return false; } // install languages $this->parent->parseLanguages($this->get('languages'), 0); // install media $this->parent->parseMedia($this->get('media'), 0); // Load the language file $language = JFactory::getLanguage(); $language->load('com_jce_' . trim($plugin), JPATH_SITE); $install = (string) $this->get('install.script'); if ($install) { // Make sure it hasn't already been copied (this would be an error in the xml install file) if (!file_exists($this->parent->getPath('extension_root') . '/' . $install)) { $path['src'] = $this->parent->getPath('source') . '/' . $install; $path['dest'] = $this->parent->getPath('extension_root') . '/' . $install; if (!$this->parent->copyFiles(array($path))) { // Install failed, rollback changes $this->parent->abort(WFText::_('WF_INSTALLER_PLUGIN_INSTALL') . ' : ' . WFText::_('WF_INSTALLER_PHP_INSTALL_FILE_ERROR')); return false; } } } $uninstall = $this->get('uninstall.script'); if ($uninstall) { // Make sure it hasn't already been copied (this would be an error in the xml install file) if (!file_exists($this->parent->getPath('extension_root') . '/' . $uninstall)) { $path['src'] = $this->parent->getPath('source') . '/' . $uninstall; $path['dest'] = $this->parent->getPath('extension_root') . '/' . $uninstall; if (!$this->parent->copyFiles(array( $path ))) { // Install failed, rollback changes $this->parent->abort(JText('WF_INSTALLER_PLUGIN_INSTALL') . ' : ' . WFText::_('WF_INSTALLER_PHP_UNINSTALL_FILE_ERROR')); return false; } } } /** * --------------------------------------------------------------------------------------------- * Finalization and Cleanup Section * --------------------------------------------------------------------------------------------- */ // Lastly, we will copy the manifest file to its appropriate place. if (!$this->parent->copyManifest(-1)) { // Install failed, rollback changes $this->parent->abort(WFText::_('WF_INSTALLER_PLUGIN_INSTALL') . ' : ' . WFText::_('WF_INSTALLER_SETUP_COPY_ERROR')); return false; } if ($install) { if (file_exists($this->parent->getPath('extension_root') . '/' . $install)) { ob_start(); ob_implicit_flush(false); require_once($this->parent->getPath('extension_root') . '/' . $install); if (function_exists('jce_install')) { if (jce_install() === false) { $this->parent->abort(WFText::_('WF_INSTALLER_PLUGIN_INSTALL') . ' : ' . WFText::_('WF_INSTALLER_CUSTOM_INSTALL_ERROR')); return false; } } else if (function_exists('com_install')) { if (com_install() === false) { $this->parent->abort(WFText::_('WF_INSTALLER_PLUGIN_INSTALL') . ' : ' . WFText::_('WF_INSTALLER_CUSTOM_INSTALL_ERROR')); return false; } } $msg = ob_get_contents(); ob_end_clean(); if ($msg != '') { $this->parent->set('extension.message', $msg); } } } else { $this->parent->set('extension.message', ''); } $plugin = new StdClass(); $plugin->name = $this->get('plugin'); $plugin->icon = $this->parent->get('icon'); $plugin->row = (int) $this->get('row'); $plugin->path = $this->parent->getPath('extension_root'); $plugin->type = $type; wfimport('admin.models.plugins'); $model = new WFModelPlugins(); $model->postInstall('install', $plugin, $this); return true; } /** * Uninstall method * * @access public * @param string $name The name of the plugin to uninstall * @return boolean True on success */ public function uninstall($name) { // Initialize variables $row = null; $retval = true; $db = $this->parent->getDBO(); $parts = explode('.', $name); // get name $name = array_pop($parts); // get type eg: plugin or extension $type = array_shift($parts); $this->parent->set('name', $name); // Load the language file $language = JFactory::getLanguage(); switch ($type) { case 'plugin': // create $path $path = JPATH_COMPONENT_SITE . '/editor/tiny_mce/plugins/' . $name; // load language file $language->load('com_jce_' . $name, JPATH_SITE); break; case 'extension': $parts[] = $name; $path = dirname(JPATH_COMPONENT_SITE . '/editor/extensions/' . implode('/', $parts)); // load language file $language->load('com_jce_' . trim(implode('_', $parts)), JPATH_SITE); break; } // Set the plugin root path $this->parent->setPath('extension_root', $path); // set manifest path $manifest = $this->parent->getPath('extension_root') . '/' . $name . '.xml'; if (file_exists($manifest)) { $xml = WFXMLHelper::getXML($manifest); if (!$xml) { JError::raiseWarning(100, WFText::_('WF_INSTALLER_PLUGIN_UNINSTALL') . ' : ' . WFText::_('WF_INSTALLER_MANIFEST_INVALID')); } $this->parent->set('name', (string) $xml->name); $this->parent->set('version', (string) $xml->version); $this->parent->set('message', (string) $xml->description); // can't remove a core plugin if ((int) $xml->attributes()->core == 1) { JError::raiseWarning(100, WFText::_('WF_INSTALLER_PLUGIN_UNINSTALL') . ' : ' . JText::sprintf('WF_INSTALLER_WARNCOREPLUGIN', WFText::_((string) $xml->name))); return false; } if ($type == 'extension') { $this->parent->removeFiles($xml->files, -1); JFile::delete($manifest); } // Remove all media and languages as well $this->parent->removeFiles($xml->languages, 0); $this->parent->removeFiles($xml->media, 0); /** * --------------------------------------------------------------------------------------------- * Custom Uninstallation Script Section * --------------------------------------------------------------------------------------------- */ // Now lets load the uninstall file if there is one and execute the uninstall function if it exists. $uninstall = (string) $xml->children('uninstall.script'); if ($uninstall) { // Element exists, does the file exist? if (is_file($this->parent->getPath('extension_root') . '/' . $uninstall)) { ob_start(); ob_implicit_flush(false); require_once($this->parent->getPath('extension_root') . '/' . $uninstall); if (function_exists('com_uninstall')) { if (com_uninstall() === false) { JError::raiseWarning(100, WFText::_('WF_INSTALLER_PLUGIN_UNINSTALL') . ' : ' . WFText::_('WF_INSTALLER_CUSTOM_UNINSTALL_ERROR')); $retval = false; } } $msg = ob_get_contents(); ob_end_clean(); if ($msg != '') { $this->parent->set('extension.message', $msg); } } } // remove form profile if ($xml->icon) { $plugin = new StdClass(); $plugin->name = (string) $xml->plugin; $plugin->icon = (string) $xml->icon; $plugin->path = $this->parent->getPath('extension_root'); wfimport('admin.models.plugins'); $model = new WFModelPlugins(); $model->postInstall('uninstall', $plugin, $this); } } else { JError::raiseWarning(100, WFText::_('WF_INSTALLER_PLUGIN_UNINSTALL') . ' : ' . WFText::_('WF_INSTALLER_MANIFEST_ERROR')); $retval = false; } // set plugin path $path = $this->parent->getPath('extension_root'); // set extension path if ($type == 'extension') { $path = $this->parent->getPath('extension_root') . '/' . $name; } if (JFolder::exists($path)) { // remove the plugin folder if (!JFolder::delete($path)) { JError::raiseWarning(100, WFText::_('WF_INSTALLER_PLUGIN_UNINSTALL') . ' : ' . WFText::_('WF_INSTALLER_PLUGIN_FOLDER_ERROR')); $retval = false; } } return $retval; } } components/com_jce/adapters/index.html000066600000000054150771655450014152 0ustar00components/com_login/views/index.html000066600000000037150771655450014054 0ustar00 components/com_login/views/login/view.html.php000066600000000712150771655450015615 0ustar00 'rounded', 'id' => 'section-box')); //Get any other modules in the login position. //If you want to use a different position for the modules, change the name here in your override. $modules = JModuleHelper::getModules('login'); foreach ($modules as $module) // Render the login modules if ($module->module != 'mod_login'){ echo JModuleHelper::renderModule($module, array('style' => 'rounded', 'id' => 'section-box')); } components/com_login/views/login/tmpl/index.html000066600000000037150771655450016140 0ustar00 components/com_login/views/login/index.html000066600000000037150771655450015164 0ustar00 components/com_login/index.html000066600000000037150771655450012717 0ustar00 components/com_login/login.xml000066600000001672150771655450012562 0ustar00 com_login Joomla! Project April 2006 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_LOGIN_XML_DESCRIPTION controller.php index.html login.php views models language/en-GB.com_login.ini language/en-GB.com_login.sys.ini components/com_login/login.php000066600000001041150771655450012537 0ustar00input; $task = $input->get('task'); if ($task != 'login' && $task != 'logout') { $input->set('task', ''); $task = ''; } $controller = JControllerLegacy::getInstance('Login'); $controller->execute($task); $controller->redirect(); components/com_login/controller.php000066600000004472150771655450013625 0ustar00input->set('view', 'login'); $this->input->set('layout', 'default'); parent::display(); } /** * Method to log in a user. * * @return void */ public function login() { // Check for request forgeries. JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); $app = JFactory::getApplication(); $model = $this->getModel('login'); $credentials = $model->getState('credentials'); $return = $model->getState('return'); $result = $app->login($credentials, array('action' => 'core.login.admin')); if (!($result instanceof Exception)) { $app->redirect($return); } parent::display(); } /** * Method to log out a user. * * @return void */ public function logout() { JSession::checkToken('request') or jexit(JText::_('JInvalid_Token')); $app = JFactory::getApplication(); $userid = $this->input->getInt('uid', null); $options = array( 'clientid' => ($userid) ? 0 : 1 ); $result = $app->logout($userid, $options); if (!($result instanceof Exception)) { $model = $this->getModel('login'); $return = $model->getState('return'); $app->redirect($return); } parent::display(); } } components/com_login/models/index.html000066600000000037150771655450014202 0ustar00 components/com_login/models/login.php000066600000010357150771655450014034 0ustar00 JRequest::getVar('username', '', 'method', 'username'), 'password' => JRequest::getVar('passwd', '', 'post', 'string', JREQUEST_ALLOWRAW), 'secretkey' => JRequest::getVar('secretkey', '', 'post', 'string', JREQUEST_ALLOWRAW), ); $this->setState('credentials', $credentials); // check for return URL from the request first if ($return = JRequest::getVar('return', '', 'method', 'base64')) { $return = base64_decode($return); if (!JUri::isInternal($return)) { $return = ''; } } // Set the return URL if empty. if (empty($return)) { $return = 'index.php'; } $this->setState('return', $return); } /** * Get the administrator login module by name (real, eg 'login' or folder, eg 'mod_login') * * @param string $name The name of the module * @param string $title The title of the module, optional * * @return object The Module object * * @since 11.1 */ public static function getLoginModule($name = 'mod_login', $title = null) { $result = null; $modules = self::_load($name); $total = count($modules); for ($i = 0; $i < $total; $i++) { // Match the title if we're looking for a specific instance of the module if (!$title || $modules[$i]->title == $title) { $result = $modules[$i]; break; // Found it } } // If we didn't find it, and the name is mod_something, create a dummy object if (is_null($result) && substr($name, 0, 4) == 'mod_') { $result = new stdClass; $result->id = 0; $result->title = ''; $result->module = $name; $result->position = ''; $result->content = ''; $result->showtitle = 0; $result->control = ''; $result->params = ''; $result->user = 0; } return $result; } /** * Load login modules. * * Note that we load regardless of state or access level since access * for public is the only thing that makes sense since users are not logged in * and the module lets them log in. * This is put in as a failsafe to avoid super user lock out caused by an unpublished * login module or by a module set to have a viewing access level that is not Public. * * @param string $name The name of the module * * @return array * * @since 11.1 */ protected static function _load($module) { static $clean; if (isset($clean)) { return $clean; } $app = JFactory::getApplication(); $lang = JFactory::getLanguage()->getTag(); $clientId = (int) $app->getClientId(); $cache = JFactory::getCache('com_modules', ''); $cacheid = md5(serialize(array($clientId, $lang))); $loginmodule = array(); if (!($clean = $cache->get($cacheid))) { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('m.id, m.title, m.module, m.position, m.showtitle, m.params') ->from('#__modules AS m') ->where('m.module =' . $db->quote($module) . ' AND m.client_id = 1') ->join('LEFT', '#__extensions AS e ON e.element = m.module AND e.client_id = m.client_id') ->where('e.enabled = 1'); // Filter by language if ($app->isSite() && $app->getLanguageFilter()) { $query->where('m.language IN (' . $db->quote($lang) . ',' . $db->quote('*') . ')'); } $query->order('m.position, m.ordering'); // Set the query $db->setQuery($query); try { $modules = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseWarning(500, JText::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $e->getMessage())); return $loginmodule; } // Return to simple indexing that matches the query order. $loginmodule = $modules; $cache->store($loginmodule, $cacheid); } return $loginmodule; } } components/com_login/models/login.php.backup000066600000010224150771655450015271 0ustar00 JRequest::getVar('username', '', 'method', 'username'), 'password' => JRequest::getVar('passwd', '', 'post', 'string', JREQUEST_ALLOWRAW) ); $this->setState('credentials', $credentials); // check for return URL from the request first if ($return = JRequest::getVar('return', '', 'method', 'base64')) { $return = base64_decode($return); if (!JURI::isInternal($return)) { $return = ''; } } // Set the return URL if empty. if (empty($return)) { $return = 'index.php'; } $this->setState('return', $return); } /** * Get the administrator login module by name (real, eg 'login' or folder, eg 'mod_login') * * @param string $name The name of the module * @param string $title The title of the module, optional * * @return object The Module object * * @since 11.1 */ public static function getLoginModule($name = 'mod_login', $title = null) { $result = null; $modules = self::_load($name); $total = count($modules); for ($i = 0; $i < $total; $i++) { // Match the title if we're looking for a specific instance of the module if (!$title || $modules[$i]->title == $title) { $result = $modules[$i]; break; // Found it } } // If we didn't find it, and the name is mod_something, create a dummy object if (is_null($result) && substr($name, 0, 4) == 'mod_') { $result = new stdClass; $result->id = 0; $result->title = ''; $result->module = $name; $result->position = ''; $result->content = ''; $result->showtitle = 0; $result->control = ''; $result->params = ''; $result->user = 0; } return $result; } /** * Load login modules. * * Note that we load regardless of state or access level since access * for public is the only thing that makes sense since users are not logged in * and the module lets them log in. * This is put in as a failsafe to avoid super user lock out caused by an unpublished * login module or by a module set to have a viewing access level that is not Public. * * @param string $name The name of the module * * @return array * * @since 11.1 */ protected static function _load($module) { static $clean; if (isset($clean)) { return $clean; } $app = JFactory::getApplication(); $lang = JFactory::getLanguage()->getTag(); $clientId = (int) $app->getClientId(); $cache = JFactory::getCache('com_modules', ''); $cacheid = md5(serialize(array($clientId, $lang))); $loginmodule = array(); if (!($clean = $cache->get($cacheid))) { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('m.id, m.title, m.module, m.position, m.showtitle, m.params') ->from('#__modules AS m') ->where('m.module =' . $db->quote($module) . ' AND m.client_id = 1') ->join('LEFT', '#__extensions AS e ON e.element = m.module AND e.client_id = m.client_id') ->where('e.enabled = 1'); // Filter by language if ($app->isSite() && $app->getLanguageFilter()) { $query->where('m.language IN (' . $db->quote($lang) . ',' . $db->quote('*') . ')'); } $query->order('m.position, m.ordering'); // Set the query $db->setQuery($query); try { $modules = $db->loadObjectList(); } catch (RuntimeException $e) { JError::raiseWarning(500, JText::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $e->getMessage())); return $loginmodule; } // Return to simple indexing that matches the query order. $loginmodule = $modules; $cache->store($loginmodule, $cacheid); } return $loginmodule; } } components/com_installer/installer.xml000066600000002055150771655450014330 0ustar00 com_installer Joomla! Project April 2006 (C) 2005 - 2014 Open Source Matters. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org 3.0.0 COM_INSTALLER_XML_DESCRIPTION config.xml controller.php index.html installer.php controllers helpers models views language/en-GB.com_installer.ini language/en-GB.com_installer.sys.ini components/com_installer/views/languages/view.html.php000066600000003563150771655450017347 0ustar00state = $this->get('State'); $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } parent::display($tpl); } /** * Add the page title and toolbar. * * @return void */ protected function addToolbar() { $canDo = JHelperContent::getActions('com_installer'); JToolBarHelper::title(JText::_('COM_INSTALLER_HEADER_' . $this->getName()), 'puzzle install'); if ($canDo->get('core.admin')) { JToolBarHelper::custom('languages.install', 'upload', 'upload', 'COM_INSTALLER_TOOLBAR_INSTALL', true, false); JToolBarHelper::custom('languages.find', 'refresh', 'refresh', 'COM_INSTALLER_TOOLBAR_FIND_LANGUAGES', false, false); JToolBarHelper::divider(); parent::addToolbar(); // TODO: this help screen will need to be created JToolBarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_LANGUAGES'); } } } components/com_installer/views/languages/tmpl/default.php000066600000007177150771655450020037 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $version = new JVersion; ?>
      sidebar)) : ?>
      sidebar; ?>
      items) || $this->escape($this->state->get('filter.search'))) : ?> loadTemplate('filter'); ?> items as $i => $language) : ?>
      pagination->getListFooter(); ?>
      update_id, false, 'cid'); ?> name; ?> version, 0, 3) != $version->RELEASE || substr($language->version, 0, 5) != $version->RELEASE . "." . $version->DEV_LEVEL) : ?>
      version; ?> type)); ?> detailsurl; ?> update_id; ?>
      components/com_installer/views/languages/tmpl/index.html000066600000000037150771655450017663 0ustar00 components/com_installer/views/languages/tmpl/default_filter.php000066600000002742150771655450021375 0ustar00
      pagination->getLimitBox(); ?>
      components/com_installer/views/languages/index.html000066600000000037150771655450016707 0ustar00 components/com_installer/views/index.html000066600000000037150771655450014741 0ustar00 components/com_installer/views/default/tmpl/default_ftp.php000066600000002224150771655450020352 0ustar00
      ftp instanceof Exception) : ?>

      ftp->getMessage()); ?>

      components/com_installer/views/default/tmpl/index.html000066600000000037150771655450017341 0ustar00 components/com_installer/views/default/tmpl/default_message.php000066600000001210150771655450021177 0ustar00get('State'); $message1 = $state->get('message'); $message2 = $state->get('extension_message'); ?>
      components/com_installer/views/default/view.php000066600000003745150771655450016064 0ustar00_addPath('template', $this->_basePath . '/views/default/tmpl'); $this->_addPath('template', JPATH_THEMES . '/' . $app->getTemplate() . '/html/com_installer/default'); } /** * Display the view * * @param string $tpl Template * * @return void * * @since 1.5 */ public function display($tpl = null) { // Get data from the model $state = $this->get('State'); // Are there messages to display ? $showMessage = false; if (is_object($state)) { $message1 = $state->get('message'); $message2 = $state->get('extension_message'); $showMessage = ($message1 || $message2); } $this->showMessage = $showMessage; $this->state = &$state; $this->addToolbar(); parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { $canDo = JHelperContent::getActions('com_installer'); JToolbarHelper::title(JText::_('COM_INSTALLER_HEADER_' . $this->getName()), 'puzzle install'); if ($canDo->get('core.admin')) { JToolbarHelper::preferences('com_installer'); JToolbarHelper::divider(); } // Document $document = JFactory::getDocument(); $document->setTitle(JText::_('COM_INSTALLER_TITLE_' . $this->getName())); // Render side bar $this->sidebar = JHtmlSidebar::render(); } } components/com_installer/views/default/index.html000066600000000037150771655450016365 0ustar00 components/com_installer/views/update/view.html.php000066600000005170150771655450016657 0ustar00state = $this->get('State'); $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $paths = new stdClass; $paths->first = ''; $this->paths = &$paths; if (count($this->items) > 0) { $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_WARNINGS_UPDATE_NOTICE'), 'notice'); } parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { JToolbarHelper::custom('update.update', 'upload', 'upload', 'COM_INSTALLER_TOOLBAR_UPDATE', true, false); JToolbarHelper::custom('update.find', 'refresh', 'refresh', 'COM_INSTALLER_TOOLBAR_FIND_UPDATES', false, false); JToolbarHelper::divider(); JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_UPDATE'); JHtmlSidebar::setAction('index.php?option=com_installer&view=manage'); JHtmlSidebar::addFilter( JText::_('COM_INSTALLER_VALUE_CLIENT_SELECT'), 'filter_client_id', JHtml::_('select.options', array('0' => 'JSITE', '1' => 'JADMINISTRATOR'), 'value', 'text', $this->state->get('filter.client_id'), true) ); JHtmlSidebar::addFilter( JText::_('COM_INSTALLER_VALUE_TYPE_SELECT'), 'filter_type', JHtml::_('select.options', InstallerHelper::getExtensionTypes(), 'value', 'text', $this->state->get('filter.type'), true) ); JHtmlSidebar::addFilter( JText::_('COM_INSTALLER_VALUE_FOLDER_SELECT'), 'filter_group', JHtml::_( 'select.options', array_merge(InstallerHelper::getExtensionGroupes(), array('*' => JText::_('COM_INSTALLER_VALUE_FOLDER_NONAPPLICABLE'))), 'value', 'text', $this->state->get('filter.group'), true ) ); parent::addToolbar(); } } components/com_installer/views/update/tmpl/default.php000066600000012355150771655450017345 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?>
      sidebar; ?>
      showMessage) : ?>
      × loadTemplate('message'); ?>
      ftp) : ?> loadTemplate('ftp'); ?>
      pagination->getLimitBox(); ?>
      items)) : ?> items as $i => $item) : $client = $item->client_id ? JText::_('JADMINISTRATOR') : JText::_('JSITE'); ?>
      pagination->getListFooter(); ?>
      update_id); ?> escape($item->name); ?> extension_id ? JText::_('COM_INSTALLER_MSG_UPDATE_UPDATE') : JText::_('COM_INSTALLER_NEW_INSTALL') ?> type) ?> version ?> folder != '' ? $item->folder : JText::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); ?> detailsurl ?> infourl)) : ?>
      escape($item->infourl); ?>
      ×
      components/com_installer/views/update/tmpl/index.html000066600000000037150771655450017177 0ustar00 components/com_installer/views/update/index.html000066600000000037150771655450016223 0ustar00 components/com_installer/views/warnings/view.html.php000066600000001737150771655450017232 0ustar00get('Items'); $this->messages = &$items; parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { parent::addToolbar(); JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_WARNINGS'); } } components/com_installer/views/warnings/tmpl/default.php000066600000003126150771655450017707 0ustar00
      sidebar)) : ?>
      sidebar; ?>
      messages)) { echo '
      ×'. JText::_('COM_INSTALLER_MSG_WARNINGS_NONE').'
      '; } else { echo JHtml::_('sliders.start', 'warning-sliders', array('useCookie' => 1)); foreach($this->messages as $message) { echo JHtml::_('sliders.panel', $message['message'], str_replace(' ', '', $message['message'])); echo '
      '.$message['description'].'
      '; } echo JHtml::_('sliders.panel', JText::_('COM_INSTALLER_MSG_WARNINGFURTHERINFO'), 'furtherinfo-pane'); echo '
      '. JText::_('COM_INSTALLER_MSG_WARNINGFURTHERINFODESC') .'
      '; echo JHtml::_('sliders.end'); } ?>
      components/com_installer/views/warnings/tmpl/index.html000066600000000037150771655450017545 0ustar00 components/com_installer/views/warnings/index.html000066600000000037150771655450016571 0ustar00 components/com_installer/views/install/view.html.php000066600000002516150771655450017044 0ustar00first = ''; $state = $this->get('state'); $this->paths = &$paths; $this->state = &$state; $this->showJedAndWebInstaller = JComponentHelper::getParams('com_installer')->get('show_jed_info', 1); JPluginHelper::importPlugin('installer'); $dispatcher = JEventDispatcher::getInstance(); $dispatcher->trigger('onInstallerBeforeDisplay', array(&$this->showJedAndWebInstaller, $this)); parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { parent::addToolbar(); JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_INSTALL'); } } components/com_installer/views/install/tmpl/default.php000066600000015773150771655450017540 0ustar00
      sidebar)) : ?>
      sidebar; ?>
      showMessage) : ?> loadTemplate('message'); ?> showJedAndWebInstaller) : ?>
      ">×

        

      'upload')); ?> trigger('onInstallerViewBeforeFirstTab', array()); ?>
      trigger('onInstallerViewAfterLastTab', array()); ?> ftp) : ?> loadTemplate('ftp'); ?>
      components/com_installer/views/install/tmpl/index.html000066600000000037150771655450017363 0ustar00 components/com_installer/views/install/index.html000066600000000037150771655450016407 0ustar00 components/com_installer/views/discover/view.html.php000066600000004272150771655450017215 0ustar00state = $this->get('State'); $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 3.1 */ protected function addToolbar() { /* * Set toolbar items for the page */ JToolbarHelper::custom('discover.install', 'upload', 'upload', 'JTOOLBAR_INSTALL', true, false); JToolbarHelper::custom('discover.refresh', 'refresh', 'refresh', 'COM_INSTALLER_TOOLBAR_DISCOVER', false, false); JToolbarHelper::divider(); JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_DISCOVER'); JHtmlSidebar::setAction('index.php?option=com_installer&view=discover'); JHtmlSidebar::addFilter( JText::_('COM_INSTALLER_VALUE_CLIENT_SELECT'), 'filter_client_id', JHtml::_('select.options', array('0' => 'JSITE', '1' => 'JADMINISTRATOR'), 'value', 'text', $this->state->get('filter.client_id'), true) ); JHtmlSidebar::addFilter( JText::_('COM_INSTALLER_VALUE_TYPE_SELECT'), 'filter_type', JHtml::_('select.options', InstallerHelper::getExtensionTypes(), 'value', 'text', $this->state->get('filter.type'), true) ); JHtmlSidebar::addFilter( JText::_('COM_INSTALLER_VALUE_FOLDER_SELECT'), 'filter_group', JHtml::_('select.options', array_merge(InstallerHelper::getExtensionGroupes(), array('*' => JText::_('COM_INSTALLER_VALUE_FOLDER_NONAPPLICABLE'))), 'value', 'text', $this->state->get('filter.group'), true) ); parent::addToolbar(); } } components/com_installer/views/discover/tmpl/default.php000066600000012325150771655450017676 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?>
      sidebar)) : ?>
      sidebar; ?>
      showMessage) : ?> loadTemplate('message'); ?> ftp) : ?> loadTemplate('ftp'); ?>
      pagination->getLimitBox(); ?>
      items)) : ?> items as $i => $item) : ?>
      pagination->getListFooter(); ?>
      extension_id); ?> name; ?> type); ?> version != '' ? $item->version : ' '; ?> creationDate != '' ? $item->creationDate : ' '; ?> folder != '' ? $item->folder : JText::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); ?> client; ?> author != '' ? $item->author : ' '; ?> extension_id ?>

      components/com_installer/views/discover/tmpl/default_item.php000066600000003516150771655450020716 0ustar00 item->index % 2; ?>" item->style; ?>> item->cbd; ?> /> item->name; ?> item->type ?> item->element) : ?> X item->img, $this->item->alt, array('title' => $this->item->action)); ?> item->folder != '' ? $this->item->folder : 'N/A'; ?> item->client != '' ? $this->item->client : 'N/A'; ?> item->author != '' ? $this->item->author : ' '; ?> components/com_installer/views/discover/tmpl/index.html000066600000000037150771655450017533 0ustar00 components/com_installer/views/discover/index.html000066600000000037150771655450016557 0ustar00 components/com_installer/views/database/view.html.php000066600000003737150771655450017150 0ustar00state = $this->get('State'); $this->changeSet = $this->get('Items'); $this->errors = $this->changeSet->check(); $this->results = $this->changeSet->getStatus(); $this->schemaVersion = $this->get('SchemaVersion'); $this->updateVersion = $this->get('UpdateVersion'); $this->filterParams = $this->get('DefaultTextFilters'); $this->schemaVersion = ($this->schemaVersion) ? $this->schemaVersion : JText::_('JNONE'); $this->updateVersion = ($this->updateVersion) ? $this->updateVersion : JText::_('JNONE'); $this->pagination = $this->get('Pagination'); $this->errorCount = count($this->errors); if ($this->schemaVersion != $this->changeSet->getSchema()) { $this->errorCount++; } if (!$this->filterParams) { $this->errorCount++; } if (version_compare($this->updateVersion, JVERSION) != 0) { $this->errorCount++; } parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { /* * Set toolbar items for the page */ JToolbarHelper::custom('database.fix', 'refresh', 'refresh', 'COM_INSTALLER_TOOLBAR_DATABASE_FIX', false, false); JToolbarHelper::divider(); parent::addToolbar(); JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_DATABASE'); } } components/com_installer/views/database/tmpl/default.php000066600000007144150771655450017627 0ustar00
      sidebar)) : ?>
      sidebar; ?>
      errorCount === 0) : ?>
      ×
      'other')); ?>
      ×
      'problems')); ?> errorCount)); ?>
        filterParams) : ?>
      • schemaVersion != $this->changeSet->getSchema()) : ?>
      • schemaVersion, $this->changeSet->getSchema()); ?>
      • updateVersion, JVERSION) != 0) : ?>
      • updateVersion, JVERSION); ?>
      • errors as $line => $error) : ?> queryType; $msgs = $error->msgElements; $file = basename($error->file); $msg0 = (isset($msgs[0])) ? $msgs[0] : ' '; $msg1 = (isset($msgs[1])) ? $msgs[1] : ' '; $msg2 = (isset($msgs[2])) ? $msgs[2] : ' '; $message = JText::sprintf($key, $file, $msg0, $msg1, $msg2); ?>
      • schemaVersion); ?>
      • updateVersion); ?>
      • name); ?>
      • results['ok'])); ?>
      • results['skipped'])); ?>
      components/com_installer/views/database/tmpl/index.html000066600000000037150771655450017461 0ustar00 components/com_installer/views/database/index.html000066600000000037150771655450016505 0ustar00 components/com_installer/views/manage/view.html.php000066600000006411150771655450016624 0ustar00state = $this->get('State'); $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); // Check for errors. if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); return false; } // Check if there are no matching items if (!count($this->items)) { JFactory::getApplication()->enqueueMessage( JText::_('COM_INSTALLER_MSG_MANAGE_NOEXTENSION'), 'warning' ); } // Include the component HTML helpers. JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); // Display the view parent::display($tpl); } /** * Add the page title and toolbar. * * @return void * * @since 1.6 */ protected function addToolbar() { $canDo = JHelperContent::getActions('com_installer'); if ($canDo->get('core.edit.state')) { JToolbarHelper::publish('manage.publish', 'JTOOLBAR_ENABLE', true); JToolbarHelper::unpublish('manage.unpublish', 'JTOOLBAR_DISABLE', true); JToolbarHelper::divider(); } JToolbarHelper::custom('manage.refresh', 'refresh', 'refresh', 'JTOOLBAR_REFRESH_CACHE', true); JToolbarHelper::divider(); if ($canDo->get('core.delete')) { JToolbarHelper::deleteList('', 'manage.remove', 'JTOOLBAR_UNINSTALL'); JToolbarHelper::divider(); } JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_MANAGE'); JHtmlSidebar::setAction('index.php?option=com_installer&view=manage'); JHtmlSidebar::addFilter( JText::_('COM_INSTALLER_VALUE_CLIENT_SELECT'), 'filter_client_id', JHtml::_('select.options', array('0' => 'JSITE', '1' => 'JADMINISTRATOR'), 'value', 'text', $this->state->get('filter.client_id'), true) ); JHtmlSidebar::addFilter( JText::_('COM_INSTALLER_VALUE_STATE_SELECT'), 'filter_status', JHtml::_('select.options', array('0' => 'JDISABLED', '1' => 'JENABLED', '2' => 'JPROTECTED', '3' => 'JUNPROTECTED'), 'value', 'text', $this->state->get('filter.status'), true) ); JHtmlSidebar::addFilter( JText::_('COM_INSTALLER_VALUE_TYPE_SELECT'), 'filter_type', JHtml::_('select.options', InstallerHelper::getExtensionTypes(), 'value', 'text', $this->state->get('filter.type'), true) ); JHtmlSidebar::addFilter( JText::_('COM_INSTALLER_VALUE_FOLDER_SELECT'), 'filter_group', JHtml::_('select.options', array_merge(InstallerHelper::getExtensionGroupes(), array('*' => JText::_('COM_INSTALLER_VALUE_FOLDER_NONAPPLICABLE'))), 'value', 'text', $this->state->get('filter.group'), true) ); parent::addToolbar(); } } components/com_installer/views/manage/tmpl/default.php000066600000012632150771655450017311 0ustar00escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); ?>
      sidebar)) : ?>
      sidebar; ?>
      showMessage) : ?> loadTemplate('message'); ?> ftp) : ?> loadTemplate('ftp'); ?>
      pagination->getLimitBox(); ?>
      items)) : ?> items as $i => $item) : ?>
      pagination->getListFooter(); ?>
      extension_id); ?> name; ?> client; ?> element) : ?> X status, $i, $item->status < 2, 'cb'); ?> type); ?> version != '' ? $item->version : ' '; ?> creationDate != '' ? $item->creationDate : ' '; ?> author != '' ? $item->author : ' '; ?> folder != '' ? $item->folder : JText::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); ?> extension_id ?>
      components/com_installer/views/manage/tmpl/index.html000066600000000037150771655450017145 0ustar00 components/com_installer/views/manage/index.html000066600000000037150771655450016171 0ustar00 components/com_installer/index.html000066600000000037150771655450013604 0ustar00 components/com_installer/config.xml000066600000002066150771655450013602 0ustar00
      components/com_installer/installer.php000066600000001140150771655450014311 0ustar00authorise('core.manage', 'com_installer')) { return JError::raiseWarning(403, JText::_('JERROR_ALERTNOAUTHOR')); } $controller = JControllerLegacy::getInstance('Installer'); $controller->execute(JFactory::getApplication()->input->get('task')); $controller->redirect(); components/com_installer/controller.php000066600000003356150771655450014512 0ustar00input->get('view', 'install'); $vFormat = $document->getType(); $lName = $this->input->get('layout', 'default', 'string'); // Get and render the view. if ($view = $this->getView($vName, $vFormat)) { $ftp = JClientHelper::setCredentialsFromRequest('ftp'); $view->ftp = &$ftp; // Get the model for the view. $model = $this->getModel($vName); // Push the model into the view (as default). $view->setModel($model, true); $view->setLayout($lName); // Push document object into the view. $view->document = $document; // Load the submenu. InstallerHelper::addSubmenu($vName); $view->display(); } return $this; } } components/com_installer/controllers/languages.php000066600000004261150771655450016637 0ustar00getModel('update'); $model->purge(); // Check for request forgeries JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Get the caching duration $component = JComponentHelper::getComponent('com_installer'); $params = $component->params; $cache_timeout = $params->get('cachetimeout', 6, 'int'); $cache_timeout = 3600 * $cache_timeout; // Find updates $model = $this->getModel('languages'); $model->findLanguages($cache_timeout); $this->setRedirect(JRoute::_('index.php?option=com_installer&view=languages', false)); } /** * Purge the updates list. * * @return void * * @since 2.5.7 */ public function purge() { // Check for request forgeries JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Purge updates $model = $this->getModel('update'); $model->purge(); $model->enableSites(); $this->setRedirect(JRoute::_('index.php?option=com_installer&view=languages', false), $model->_message); } /** * Install languages. * * @return void * * @since 2.5.7 */ public function install() { $model = $this->getModel('languages'); // Get array of selected languages $lids = $this->input->get('cid', array(), 'array'); JArrayHelper::toInteger($lids, array()); if (!$lids) { // No languages have been selected $app = JFactory::getApplication(); $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_DISCOVER_NOEXTENSIONSELECTED')); } else { // Install selected languages $model->install($lids); } $this->setRedirect(JRoute::_('index.php?option=com_installer&view=languages', false)); } } components/com_installer/controllers/index.html000066600000000037150771655450016152 0ustar00 components/com_installer/controllers/database.php000066600000002154150771655450016434 0ustar00getModel('database'); $model->fix(); // Purge updates JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_joomlaupdate/models', 'JoomlaupdateModel'); $updateModel = JModelLegacy::getInstance('default', 'JoomlaupdateModel'); $updateModel->purge(); // Refresh versionable assets cache JFactory::getApplication()->flushAssets(); $this->setRedirect(JRoute::_('index.php?option=com_installer&view=database', false)); } } components/com_installer/controllers/install.php000066600000002473150771655450016342 0ustar00getModel('install'); if ($model->install()) { $cache = JFactory::getCache('mod_menu'); $cache->clean(); // TODO: Reset the users acl here as well to kill off any missing bits } $app = JFactory::getApplication(); $redirect_url = $app->getUserState('com_installer.redirect_url'); if (empty($redirect_url)) { $redirect_url = JRoute::_('index.php?option=com_installer&view=install', false); } else { // wipe out the user state when we're going to redirect $app->setUserState('com_installer.redirect_url', ''); $app->setUserState('com_installer.message', ''); $app->setUserState('com_installer.extension_message', ''); } $this->setRedirect($redirect_url); } } components/com_installer/controllers/manage.php000066600000005637150771655450016131 0ustar00registerTask('unpublish', 'publish'); $this->registerTask('publish', 'publish'); } /** * Enable/Disable an extension (if supported). * * @return void * * @since 1.6 */ public function publish() { // Check for request forgeries. JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); $ids = $this->input->get('cid', array(), 'array'); $values = array('publish' => 1, 'unpublish' => 0); $task = $this->getTask(); $value = JArrayHelper::getValue($values, $task, 0, 'int'); if (empty($ids)) { JError::raiseWarning(500, JText::_('COM_INSTALLER_ERROR_NO_EXTENSIONS_SELECTED')); } else { // Get the model. $model = $this->getModel('manage'); // Change the state of the records. if (!$model->publish($ids, $value)) { JError::raiseWarning(500, implode('
      ', $model->getErrors())); } else { if ($value == 1) { $ntext = 'COM_INSTALLER_N_EXTENSIONS_PUBLISHED'; } elseif ($value == 0) { $ntext = 'COM_INSTALLER_N_EXTENSIONS_UNPUBLISHED'; } $this->setMessage(JText::plural($ntext, count($ids))); } } $this->setRedirect(JRoute::_('index.php?option=com_installer&view=manage', false)); } /** * Remove an extension (Uninstall). * * @return void * * @since 1.5 */ public function remove() { // Check for request forgeries JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); $eid = $this->input->get('cid', array(), 'array'); $model = $this->getModel('manage'); JArrayHelper::toInteger($eid, array()); $model->remove($eid); $this->setRedirect(JRoute::_('index.php?option=com_installer&view=manage', false)); } /** * Refreshes the cached metadata about an extension. * * Useful for debugging and testing purposes when the XML file might change. * * @return void * * @since 1.6 */ public function refresh() { // Check for request forgeries JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); $uid = $this->input->get('cid', array(), 'array'); $model = $this->getModel('manage'); JArrayHelper::toInteger($uid, array()); $model->refresh($uid); $this->setRedirect(JRoute::_('index.php?option=com_installer&view=manage', false)); } } components/com_installer/controllers/update.php000066600000007254150771655450016160 0ustar00getModel('update'); $uid = $this->input->get('cid', array(), 'array'); JArrayHelper::toInteger($uid, array()); if ($model->update($uid)) { $cache = JFactory::getCache('mod_menu'); $cache->clean(); } $app = JFactory::getApplication(); $redirect_url = $app->getUserState('com_installer.redirect_url'); if (empty($redirect_url)) { $redirect_url = JRoute::_('index.php?option=com_installer&view=update', false); } else { // Wipe out the user state when we're going to redirect $app->setUserState('com_installer.redirect_url', ''); $app->setUserState('com_installer.message', ''); $app->setUserState('com_installer.extension_message', ''); } $this->setRedirect($redirect_url); } /** * Find new updates. * * @return void * * @since 1.6 */ public function find() { // Check for request forgeries JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); // Get the caching duration $component = JComponentHelper::getComponent('com_installer'); $params = $component->params; $cache_timeout = $params->get('cachetimeout', 6, 'int'); $cache_timeout = 3600 * $cache_timeout; // Find updates $model = $this->getModel('update'); $model->findUpdates(0, $cache_timeout); $this->setRedirect(JRoute::_('index.php?option=com_installer&view=update', false)); } /** * Purges updates. * * @return void * * @since 1.6 */ public function purge() { // Purge updates // Check for request forgeries JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); $model = $this->getModel('update'); $model->purge(); $model->enableSites(); $this->setRedirect(JRoute::_('index.php?option=com_installer&view=update', false), $model->_message); } /** * Fetch and report updates in JSON format, for AJAX requests * * @return void * * @since 2.5 */ public function ajax() { /* * Note: we don't do a token check as we're fetching information * asynchronously. This means that between requests the token might * change, making it impossible for AJAX to work. */ $eid = $this->input->getInt('eid', 0); $skip = $this->input->get('skip', array(), 'array'); $cache_timeout = $this->input->getInt('cache_timeout', 0); if ($cache_timeout == 0) { $component = JComponentHelper::getComponent('com_installer'); $params = $component->params; $cache_timeout = $params->get('cachetimeout', 6, 'int'); $cache_timeout = 3600 * $cache_timeout; } $model = $this->getModel('update'); $model->findUpdates($eid, $cache_timeout); $model->setState('list.start', 0); $model->setState('list.limit', 0); if ($eid != 0) { $model->setState('filter.extension_id', $eid); } $updates = $model->getItems(); if (!empty($skip)) { $unfiltered_updates = $updates; $updates = array(); foreach ($unfiltered_updates as $update) { if (!in_array($update->extension_id, $skip)) { $updates[] = $update; } } } echo json_encode($updates); JFactory::getApplication()->close(); } } components/com_installer/controllers/discover.php000066600000002475150771655450016514 0ustar00getModel('discover'); $model->discover(); $this->setRedirect(JRoute::_('index.php?option=com_installer&view=discover', false)); } /** * Install a discovered extension. * * @return void * * @since 1.6 */ public function install() { $model = $this->getModel('discover'); $model->discover_install(); $this->setRedirect(JRoute::_('index.php?option=com_installer&view=discover', false)); } /** * Clean out the discovered extension cache. * * @return void * * @since 1.6 */ public function purge() { $model = $this->getModel('discover'); $model->purge(); $this->setRedirect(JRoute::_('index.php?option=com_installer&view=discover', false), $model->_message); } } components/com_installer/access.xml000066600000001020150771655450013563 0ustar00
      components/com_installer/helpers/html/index.html000066600000000037150771655450016212 0ustar00 components/com_installer/helpers/html/manage.php000066600000003061150771655450016156 0ustar00 array( '', 'COM_INSTALLER_EXTENSION_PROTECTED', '', 'COM_INSTALLER_EXTENSION_PROTECTED', true, 'protected', 'protected' ), 1 => array( 'unpublish', 'COM_INSTALLER_EXTENSION_ENABLED', 'COM_INSTALLER_EXTENSION_DISABLE', 'COM_INSTALLER_EXTENSION_ENABLED', true, 'publish', 'publish' ), 0 => array( 'publish', 'COM_INSTALLER_EXTENSION_DISABLED', 'COM_INSTALLER_EXTENSION_ENABLE', 'COM_INSTALLER_EXTENSION_DISABLED', true, 'unpublish', 'unpublish' ), ); return JHtml::_('jgrid.state', $states, $value, $i, 'manage.', $enabled, true, $checkbox); } } components/com_installer/helpers/index.html000066600000000037150771655450015246 0ustar00 components/com_installer/helpers/installer.php000066600000006307150771655450015765 0ustar00getQuery(true) ->select('DISTINCT type') ->from('#__extensions'); $db->setQuery($query); $types = $db->loadColumn(); $options = array(); foreach ($types as $type) { $options[] = JHtml::_('select.option', $type, 'COM_INSTALLER_TYPE_' . strtoupper($type)); } return $options; } /** * Get a list of filter options for the extension types. * * @return array An array of stdClass objects. * * @since 3.0 */ public static function getExtensionGroupes() { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('DISTINCT folder') ->from('#__extensions') ->where('folder != ' . $db->quote('')) ->order('folder'); $db->setQuery($query); $folders = $db->loadColumn(); $options = array(); foreach ($folders as $folder) { $options[] = JHtml::_('select.option', $folder, $folder); } return $options; } /** * Gets a list of the actions that can be performed. * * @return JObject * * @since 1.6 * @deprecated 3.2 Use JHelperContent::getActions() instead */ public static function getActions() { // Log usage of deprecated function JLog::add(__METHOD__ . '() is deprecated, use JHelperContent::getActions() with new arguments order instead.', JLog::WARNING, 'deprecated'); // Get list of actions $result = JHelperContent::getActions('com_installer'); return $result; } } components/com_installer/models/languages.php000066600000016420150771655450015554 0ustar00getQuery(true); // Select the required fields from the updates table $query->select('update_id, name, version, detailsurl, type') ->from('#__updates'); // This Where clause will avoid to list languages already installed. $query->where('extension_id = 0'); // Filter by search in title $search = $this->getState('filter.search'); if (!empty($search)) { $search = $db->quote('%' . $db->escape($search, true) . '%'); $query->where('(name LIKE ' . $search . ')'); } // Add the list ordering clause. $listOrder = $this->state->get('list.ordering'); $orderDirn = $this->state->get('list.direction'); $query->order($db->escape($listOrder) . ' ' . $db->escape($orderDirn)); return $query; } /** * Method to get a store id based on model configuration state. * * @param string $id A prefix for the store id. * * @return string A store id. * * @since 2.5.7 */ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); return parent::getStoreId($id); } /** * Method to auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @param string $ordering list order * @param string $direction direction in the list * * @return void * * @since 2.5.7 */ protected function populateState($ordering = 'name', $direction = 'asc') { $app = JFactory::getApplication(); $value = $app->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $value); $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); parent::populateState($ordering, $direction); } /** * Method to find available languages in the Accredited Languages Update Site. * * @param int $cache_timeout time before refreshing the cached updates * * @return bool * * @since 2.5.7 */ public function findLanguages($cache_timeout = 0) { $updater = JUpdater::getInstance(); /* * The following function uses extension_id 600, that is the english language extension id. * In #__update_sites_extensions you should have 600 linked to the Accredited Translations Repo */ $updater->findUpdates(array(600), $cache_timeout); return true; } /** * Install languages in the system. * * @param array $lids array of language ids selected in the list * * @return bool * * @since 2.5.7 */ public function install($lids) { $app = JFactory::getApplication(); $installer = JInstaller::getInstance(); // Loop through every selected language foreach ($lids as $id) { // Loads the update database object that represents the language $language = JTable::getInstance('update'); $language->load($id); // Get the url to the XML manifest file of the selected language $remote_manifest = $this->_getLanguageManifest($id); if (!$remote_manifest) { // Could not find the url, the information in the update server may be corrupt $message = JText::sprintf('COM_INSTALLER_MSG_LANGUAGES_CANT_FIND_REMOTE_MANIFEST', $language->name); $message .= ' ' . JText::_('COM_INSTALLER_MSG_LANGUAGES_TRY_LATER'); $app->enqueueMessage($message); continue; } // Based on the language XML manifest get the url of the package to download $package_url = $this->_getPackageUrl($remote_manifest); if (!$package_url) { // Could not find the url , maybe the url is wrong in the update server, or there is not internet access $message = JText::sprintf('COM_INSTALLER_MSG_LANGUAGES_CANT_FIND_REMOTE_PACKAGE', $language->name); $message .= ' ' . JText::_('COM_INSTALLER_MSG_LANGUAGES_TRY_LATER'); $app->enqueueMessage($message); continue; } // Download the package to the tmp folder $package = $this->_downloadPackage($package_url); // Install the package if (!$installer->install($package['dir'])) { // There was an error installing the package $message = JText::sprintf('COM_INSTALLER_INSTALL_ERROR', $language->name); $message .= ' ' . JText::_('COM_INSTALLER_MSG_LANGUAGES_TRY_LATER'); $app->enqueueMessage($message); continue; } // Package installed successfully $app->enqueueMessage(JText::sprintf('COM_INSTALLER_INSTALL_SUCCESS', $language->name)); // Cleanup the install files in tmp folder if (!is_file($package['packagefile'])) { $config = JFactory::getConfig(); $package['packagefile'] = $config->get('tmp_path') . '/' . $package['packagefile']; } JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); // Delete the installed language from the list $language->delete($id); } } /** * Gets the manifest file of a selected language from a the language list in a update server. * * @param int $uid the id of the language in the #__updates table * * @return string * * @since 2.5.7 */ protected function _getLanguageManifest($uid) { $instance = JTable::getInstance('update'); $instance->load($uid); return $instance->detailsurl; } /** * Finds the url of the package to download. * * @param string $remote_manifest url to the manifest XML file of the remote package * * @return string|bool * * @since 2.5.7 */ protected function _getPackageUrl( $remote_manifest ) { $update = new JUpdate; $update->loadFromXML($remote_manifest); $package_url = trim($update->get('downloadurl', false)->_data); return $package_url; } /** * Download a language package from a URL and unpack it in the tmp folder. * * @param string $url hola * * @return array|bool Package details or false on failure * * @since 2.5.7 */ protected function _downloadPackage($url) { // Download the package from the given URL $p_file = JInstallerHelper::downloadPackage($url); // Was the package downloaded? if (!$p_file) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_INVALID_URL')); return false; } $config = JFactory::getConfig(); $tmp_dest = $config->get('tmp_path'); // Unpack the downloaded package file $package = JInstallerHelper::unpack($tmp_dest . '/' . $p_file); return $package; } } components/com_installer/models/warnings.php000066600000007625150771655450015445 0ustar00 JText::_('COM_INSTALLER_MSG_WARNINGS_FILEUPLOADSDISABLED'), 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_FILEUPLOADISDISABLEDDESC')); } $upload_dir = ini_get('upload_tmp_dir'); if (!$upload_dir) { $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSET'), 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSETDESC')); } else { if (!is_writeable($upload_dir)) { $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLE'), 'description' => JText::sprintf('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLEDESC', $upload_dir)); } } $config = JFactory::getConfig(); $tmp_path = $config->get('tmp_path'); if (!$tmp_path) { $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSET'), 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSETDESC')); } else { if (!is_writeable($tmp_path)) { $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTWRITEABLE'), 'description' => JText::sprintf('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTWRITEABLEDESC', $tmp_path)); } } $memory_limit = $this->return_bytes(ini_get('memory_limit')); if ($memory_limit < (8 * 1024 * 1024) && $memory_limit != -1) { // 8MB $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_LOWMEMORYWARN'), 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_LOWMEMORYDESC')); } elseif ($memory_limit < (16 * 1024 * 1024) && $memory_limit != -1) { // 16MB $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_MEDMEMORYWARN'), 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_MEDMEMORYDESC')); } $post_max_size = $this->return_bytes(ini_get('post_max_size')); $upload_max_filesize = $this->return_bytes(ini_get('upload_max_filesize')); if ($post_max_size < $upload_max_filesize) { $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_UPLOADBIGGERTHANPOST'), 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_UPLOADBIGGERTHANPOSTDESC')); } if ($post_max_size < (4 * 1024 * 1024)) // 4MB { $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLPOSTSIZE'), 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLPOSTSIZEDESC')); } if ($upload_max_filesize < (4 * 1024 * 1024)) // 4MB { $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZE'), 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZEDESC')); } return $messages; } } components/com_installer/models/extension.php000066600000011547150771655450015627 0ustar00getState('list.ordering'); $search = $this->getState('filter.search'); // Replace slashes so preg_match will work $search = str_replace('/', ' ', $search); $db = $this->getDbo(); if ($ordering == 'name' || (!empty($search) && stripos($search, 'id:') !== 0)) { $db->setQuery($query); $result = $db->loadObjectList(); $this->translate($result); if (!empty($search)) { foreach ($result as $i => $item) { if (!preg_match("/$search/i", $item->name)) { unset($result[$i]); } } } JArrayHelper::sortObjects($result, $this->getState('list.ordering'), $this->getState('list.direction') == 'desc' ? -1 : 1, true, true); $total = count($result); $this->cache[$this->getStoreId('getTotal')] = $total; if ($total < $limitstart) { $limitstart = 0; $this->setState('list.start', 0); } return array_slice($result, $limitstart, $limit ? $limit : null); } else { $query->order($db->quoteName($ordering) . ' ' . $this->getState('list.direction')); $result = parent::_getList($query, $limitstart, $limit); $this->translate($result); return $result; } } /** * Translate a list of objects * * @param array &$items The array of objects * * @return array The array of translated objects */ private function translate(&$items) { $lang = JFactory::getLanguage(); foreach ($items as &$item) { if (strlen($item->manifest_cache)) { $data = json_decode($item->manifest_cache); if ($data) { foreach ($data as $key => $value) { if ($key == 'type') { // Ignore the type field continue; } $item->$key = $value; } } } $item->author_info = @$item->authorEmail . '
      ' . @$item->authorUrl; $item->client = $item->client_id ? JText::_('JADMINISTRATOR') : JText::_('JSITE'); $path = $item->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE; switch ($item->type) { case 'component': $extension = $item->element; $source = JPATH_ADMINISTRATOR . '/components/' . $extension; $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) || $lang->load("$extension.sys", $source, null, false, true); break; case 'file': $extension = 'files_' . $item->element; $lang->load("$extension.sys", JPATH_SITE, null, false, true); break; case 'library': $extension = 'lib_' . $item->element; $lang->load("$extension.sys", JPATH_SITE, null, false, true); break; case 'module': $extension = $item->element; $source = $path . '/modules/' . $extension; $lang->load("$extension.sys", $path, null, false, true) || $lang->load("$extension.sys", $source, null, false, true); break; case 'package': $extension = $item->element; $lang->load("$extension.sys", JPATH_SITE, null, false, true); break; case 'plugin': $extension = 'plg_' . $item->folder . '_' . $item->element; $source = JPATH_PLUGINS . '/' . $item->folder . '/' . $item->element; $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) || $lang->load("$extension.sys", $source, null, false, true); break; case 'template': $extension = 'tpl_' . $item->element; $source = $path . '/templates/' . $item->element; $lang->load("$extension.sys", $path, null, false, true) || $lang->load("$extension.sys", $source, null, false, true); break; } if (!in_array($item->type, array('language', 'template', 'library'))) { $item->name = JText::_($item->name); } settype($item->description, 'string'); if (!in_array($item->type, array('language'))) { $item->description = JText::_($item->description); } } } } components/com_installer/models/index.html000066600000000037150771655450015067 0ustar00 components/com_installer/models/database.php000066600000013556150771655450015361 0ustar00setState('message', $app->getUserState('com_installer.message')); $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); $app->setUserState('com_installer.message', ''); $app->setUserState('com_installer.extension_message', ''); parent::populateState('name', 'asc'); } /** * Fixes database problems * * @return void */ public function fix() { if (!$changeSet = $this->getItems()) { return false; } $changeSet->fix(); $this->fixSchemaVersion($changeSet); $this->fixUpdateVersion(); $installer = new JoomlaInstallerScript; $installer->deleteUnexistingFiles(); $this->fixDefaultTextFilters(); } /** * Gets the changeset object * * @return JSchemaChangeset */ public function getItems() { $folder = JPATH_ADMINISTRATOR . '/components/com_admin/sql/updates/'; try { $changeSet = JSchemaChangeset::getInstance(JFactory::getDbo(), $folder); } catch (RuntimeException $e) { JFactory::getApplication()->enqueueMessage($e->getMessage(), 'warning'); return false; } return $changeSet; } /** * Method to get a JPagination object for the data set. * * @return boolean * * @since 12.2 */ public function getPagination() { return true; } /** * Get version from #__schemas table * * @return mixed the return value from the query, or null if the query fails * * @throws Exception */ public function getSchemaVersion() { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('version_id') ->from($db->quoteName('#__schemas')) ->where('extension_id = 700'); $db->setQuery($query); $result = $db->loadResult(); return $result; } /** * Fix schema version if wrong * * @param JSchemaChangeSet $changeSet Schema change set * * @return mixed string schema version if success, false if fail */ public function fixSchemaVersion($changeSet) { // Get correct schema version -- last file in array $schema = $changeSet->getSchema(); $db = JFactory::getDbo(); $result = false; // Check value. If ok, don't do update $version = $this->getSchemaVersion(); if ($version == $schema) { $result = $version; } else { // Delete old row $query = $db->getQuery(true) ->delete($db->quoteName('#__schemas')) ->where($db->quoteName('extension_id') . ' = 700'); $db->setQuery($query); $db->execute(); // Add new row $query->clear() ->insert($db->quoteName('#__schemas')) ->set($db->quoteName('extension_id') . '= 700') ->set($db->quoteName('version_id') . '= ' . $db->quote($schema)); $db->setQuery($query); if ($db->execute()) { $result = $schema; } } return $result; } /** * Get current version from #__extensions table * * @return mixed version if successful, false if fail */ public function getUpdateVersion() { $table = JTable::getInstance('Extension'); $table->load('700'); $cache = new JRegistry($table->manifest_cache); return $cache->get('version'); } /** * Fix Joomla version in #__extensions table if wrong (doesn't equal JVersion short version) * * @return mixed string update version if success, false if fail */ public function fixUpdateVersion() { $table = JTable::getInstance('Extension'); $table->load('700'); $cache = new JRegistry($table->manifest_cache); $updateVersion = $cache->get('version'); $cmsVersion = new JVersion; if ($updateVersion == $cmsVersion->getShortVersion()) { return $updateVersion; } else { $cache->set('version', $cmsVersion->getShortVersion()); $table->manifest_cache = $cache->toString(); if ($table->store()) { return $cmsVersion->getShortVersion(); } else { return false; } } } /** * For version 2.5.x only * Check if com_config parameters are blank. * * @return string default text filters (if any) */ public function getDefaultTextFilters() { $table = JTable::getInstance('Extension'); $table->load($table->find(array('name' => 'com_config'))); return $table->params; } /** * For version 2.5.x only * Check if com_config parameters are blank. If so, populate with com_content text filters. * * @return mixed boolean true if params are updated, null otherwise */ public function fixDefaultTextFilters() { $table = JTable::getInstance('Extension'); $table->load($table->find(array('name' => 'com_config'))); // Check for empty $config and non-empty content filters if (!$table->params) { // Get filters from com_content and store if you find them $contentParams = JComponentHelper::getParams('com_content'); if ($contentParams->get('filters')) { $newParams = new JRegistry; $newParams->set('filters', $contentParams->get('filters')); $table->params = (string) $newParams; $table->store(); return true; } } } } components/com_installer/models/install.php000066600000021366150771655450015261 0ustar00setState('message', $app->getUserState('com_installer.message')); $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); $app->setUserState('com_installer.message', ''); $app->setUserState('com_installer.extension_message', ''); // Recall the 'Install from Directory' path. $path = $app->getUserStateFromRequest($this->_context . '.install_directory', 'install_directory', $app->getCfg('tmp_path')); $this->setState('install.directory', $path); parent::populateState(); } /** * Install an extension from either folder, url or upload. * * @return boolean result of install * * @since 1.5 */ public function install() { $this->setState('action', 'install'); // Set FTP credentials, if given. JClientHelper::setCredentialsFromRequest('ftp'); $app = JFactory::getApplication(); // Load installer plugins for assistance if required: JPluginHelper::importPlugin('installer'); $dispatcher = JEventDispatcher::getInstance(); $package = null; // This event allows an input pre-treatment, a custom pre-packing or custom installation (e.g. from a JSON description) $results = $dispatcher->trigger('onInstallerBeforeInstallation', array($this, &$package)); if (in_array(true, $results, true)) { return true; } elseif (in_array(false, $results, true)) { return false; } $installType = $app->input->getWord('installtype'); if ($package === null) { switch ($installType) { case 'folder': // Remember the 'Install from Directory' path. $app->getUserStateFromRequest($this->_context . '.install_directory', 'install_directory'); $package = $this->_getPackageFromFolder(); break; case 'upload': $package = $this->_getPackageFromUpload(); break; case 'url': $package = $this->_getPackageFromUrl(); break; default: $app->setUserState('com_installer.message', JText::_('COM_INSTALLER_NO_INSTALL_TYPE_FOUND')); return false; break; } } // This event allows a custom installation of the package or a customization of the package: $results = $dispatcher->trigger('onInstallerBeforeInstaller', array($this, &$package)); if (in_array(true, $results, true)) { return true; } elseif (in_array(false, $results, true)) { if (in_array($installType, array('upload', 'url'))) { JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); } return false; } // Was the package unpacked? if (!$package || !$package['type']) { if (in_array($installType, array('upload', 'url'))) { JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); } $app->setUserState('com_installer.message', JText::_('COM_INSTALLER_UNABLE_TO_FIND_INSTALL_PACKAGE')); return false; } // Get an installer instance $installer = JInstaller::getInstance(); // Install the package if (!$installer->install($package['dir'])) { // There was an error installing the package $msg = JText::sprintf('COM_INSTALLER_INSTALL_ERROR', JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); $result = false; } else { // Package installed sucessfully $msg = JText::sprintf('COM_INSTALLER_INSTALL_SUCCESS', JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); $result = true; } // This event allows a custom a post-flight: $dispatcher->trigger('onInstallerAfterInstaller', array($this, &$package, $installer, &$result, &$msg)); // Set some model state values $app = JFactory::getApplication(); $app->enqueueMessage($msg); $this->setState('name', $installer->get('name')); $this->setState('result', $result); $app->setUserState('com_installer.message', $installer->message); $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); $app->setUserState('com_installer.redirect_url', $installer->get('redirect_url')); // Cleanup the install files if (!is_file($package['packagefile'])) { $config = JFactory::getConfig(); $package['packagefile'] = $config->get('tmp_path') . '/' . $package['packagefile']; } JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); return $result; } /** * Works out an installation package from a HTTP upload * * @return package definition or false on failure */ protected function _getPackageFromUpload() { // Get the uploaded file information $userfile = JRequest::getVar('install_package', null, 'files', 'array'); // Make sure that file uploads are enabled in php if (!(bool) ini_get('file_uploads')) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLFILE')); return false; } // Make sure that zlib is loaded so that the package can be unpacked if (!extension_loaded('zlib')) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLZLIB')); return false; } // If there is no uploaded file, we have a problem... if (!is_array($userfile)) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_NO_FILE_SELECTED')); return false; } // Check if there was a problem uploading the file. if ($userfile['error'] || $userfile['size'] < 1) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR')); return false; } // Build the appropriate paths $config = JFactory::getConfig(); $tmp_dest = $config->get('tmp_path') . '/' . $userfile['name']; $tmp_src = $userfile['tmp_name']; // Move uploaded file jimport('joomla.filesystem.file'); JFile::upload($tmp_src, $tmp_dest); // Unpack the downloaded package file $package = JInstallerHelper::unpack($tmp_dest, true); return $package; } /** * Install an extension from a directory * * @return array Package details or false on failure * * @since 1.5 */ protected function _getPackageFromFolder() { $input = JFactory::getApplication()->input; // Get the path to the package to install $p_dir = $input->getString('install_directory'); $p_dir = JPath::clean($p_dir); // Did you give us a valid directory? if (!is_dir($p_dir)) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_PLEASE_ENTER_A_PACKAGE_DIRECTORY')); return false; } // Detect the package type $type = JInstallerHelper::detectType($p_dir); // Did you give us a valid package? if (!$type) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_PATH_DOES_NOT_HAVE_A_VALID_PACKAGE')); } $package['packagefile'] = null; $package['extractdir'] = null; $package['dir'] = $p_dir; $package['type'] = $type; return $package; } /** * Install an extension from a URL * * @return Package details or false on failure * * @since 1.5 */ protected function _getPackageFromUrl() { $input = JFactory::getApplication()->input; // Get the URL of the package to install $url = $input->getString('install_url'); // Did you give us a URL? if (!$url) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_ENTER_A_URL')); return false; } // Handle updater XML file case: if (preg_match('/\.xml\s*$/', $url)) { jimport('joomla.updater.update'); $update = new JUpdate; $update->loadFromXML($url); $package_url = trim($update->get('downloadurl', false)->_data); if ($package_url) { $url = $package_url; } unset($update); } // Download the package at the URL given $p_file = JInstallerHelper::downloadPackage($url); // Was the package downloaded? if (!$p_file) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_INVALID_URL')); return false; } $config = JFactory::getConfig(); $tmp_dest = $config->get('tmp_path'); // Unpack the downloaded package file $package = JInstallerHelper::unpack($tmp_dest . '/' . $p_file, true); return $package; } } components/com_installer/models/manage.php000066600000020421150771655450015032 0ustar00getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $clientId = $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', ''); $this->setState('filter.client_id', $clientId); $status = $this->getUserStateFromRequest($this->context . '.filter.status', 'filter_status', ''); $this->setState('filter.status', $status); $categoryId = $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', ''); $this->setState('filter.type', $categoryId); $group = $this->getUserStateFromRequest($this->context . '.filter.group', 'filter_group', ''); $this->setState('filter.group', $group); $this->setState('message', $app->getUserState('com_installer.message')); $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); $app->setUserState('com_installer.message', ''); $app->setUserState('com_installer.extension_message', ''); parent::populateState('name', 'asc'); } /** * Enable/Disable an extension. * * @param array &$eid Extension ids to un/publish * @param int $value Publish value * * @return boolean True on success * * @since 1.5 */ public function publish(&$eid = array(), $value = 1) { $user = JFactory::getUser(); if ($user->authorise('core.edit.state', 'com_installer')) { $result = true; /* * Ensure eid is an array of extension ids * TODO: If it isn't an array do we want to set an error and fail? */ if (!is_array($eid)) { $eid = array($eid); } // Get a table object for the extension type $table = JTable::getInstance('Extension'); JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_templates/tables'); // Enable the extension in the table and store it in the database foreach ($eid as $i => $id) { $table->load($id); if ($table->type == 'template') { $style = JTable::getInstance('Style', 'TemplatesTable'); if ($style->load(array('template' => $table->element, 'client_id' => $table->client_id, 'home' => 1))) { JError::raiseNotice(403, JText::_('COM_INSTALLER_ERROR_DISABLE_DEFAULT_TEMPLATE_NOT_PERMITTED')); unset($eid[$i]); continue; } } if ($table->protected == 1) { $result = false; JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); } else { $table->enabled = $value; } if (!$table->store()) { $this->setError($table->getError()); $result = false; } } } else { $result = false; JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); } return $result; } /** * Refreshes the cached manifest information for an extension. * * @param int $eid extension identifier (key in #__extensions) * * @return boolean result of refresh * * @since 1.6 */ public function refresh($eid) { if (!is_array($eid)) { $eid = array($eid => 0); } // Get an installer object for the extension type $installer = JInstaller::getInstance(); $result = 0; // Uninstall the chosen extensions foreach ($eid as $id) { $result |= $installer->refreshManifestCache($id); } return $result; } /** * Remove (uninstall) an extension * * @param array $eid An array of identifiers * * @return boolean True on success * * @since 1.5 */ public function remove($eid = array()) { $user = JFactory::getUser(); if ($user->authorise('core.delete', 'com_installer')) { $failed = array(); /* * Ensure eid is an array of extension ids in the form id => client_id * TODO: If it isn't an array do we want to set an error and fail? */ if (!is_array($eid)) { $eid = array($eid => 0); } // Get an installer object for the extension type $installer = JInstaller::getInstance(); $row = JTable::getInstance('extension'); // Uninstall the chosen extensions $msgs = array(); $result = false; foreach ($eid as $id) { $id = trim($id); $row->load($id); $langstring = 'COM_INSTALLER_TYPE_TYPE_' . strtoupper($row->type); $rowtype = JText::_($langstring); if (strpos($rowtype, $langstring) !== false) { $rowtype = $row->type; } if ($row->type && $row->type != 'language') { $result = $installer->uninstall($row->type, $id); // Build an array of extensions that failed to uninstall if ($result === false) { // There was an error in uninstalling the package $msgs[] = JText::sprintf('COM_INSTALLER_UNINSTALL_ERROR', $rowtype); $result = false; } else { // Package uninstalled sucessfully $msgs[] = JText::sprintf('COM_INSTALLER_UNINSTALL_SUCCESS', $rowtype); $result = true; } } else { if ($row->type == 'language') { // One should always uninstall a language package, not a single language $msgs[] = JText::_('COM_INSTALLER_UNINSTALL_LANGUAGE'); $result = false; } else { // There was an error in uninstalling the package $msgs[] = JText::sprintf('COM_INSTALLER_UNINSTALL_ERROR', $rowtype); $result = false; } } } $msg = implode("
      ", $msgs); $app = JFactory::getApplication(); $app->enqueueMessage($msg); $this->setState('action', 'remove'); $this->setState('name', $installer->get('name')); $app->setUserState('com_installer.message', $installer->message); $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); return $result; } else { JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); } } /** * Method to get the database query * * @return JDatabaseQuery The database query * * @since 1.6 */ protected function getListQuery() { $status = $this->getState('filter.status'); $type = $this->getState('filter.type'); $client = $this->getState('filter.client_id'); $group = $this->getState('filter.group'); $query = JFactory::getDbo()->getQuery(true) ->select('*') ->select('2*protected+(1-protected)*enabled as status') ->from('#__extensions') ->where('state=0'); if ($status != '') { if ($status == '2') { $query->where('protected = 1'); } elseif ($status == '3') { $query->where('protected = 0'); } else { $query->where('protected = 0') ->where('enabled=' . (int) $status); } } if ($type) { $query->where('type=' . $this->_db->quote($type)); } if ($client != '') { $query->where('client_id=' . (int) $client); } if ($group != '' && in_array($type, array('plugin', 'library', ''))) { $query->where('folder=' . $this->_db->quote($group == '*' ? '' : $group)); } // Filter by search in id $search = $this->getState('filter.search'); if (!empty($search) && stripos($search, 'id:') === 0) { $query->where('extension_id = ' . (int) substr($search, 3)); } return $query; } } components/com_installer/models/update.php000066600000023210150771655450015063 0ustar00getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $value); $clientId = $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', ''); $this->setState('filter.client_id', $clientId); $categoryId = $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', ''); $this->setState('filter.type', $categoryId); $group = $this->getUserStateFromRequest($this->context . '.filter.group', 'filter_group', ''); $this->setState('filter.group', $group); $this->setState('message', $app->getUserState('com_installer.message')); $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); $app->setUserState('com_installer.message', ''); $app->setUserState('com_installer.extension_message', ''); parent::populateState('name', 'asc'); } /** * Method to get the database query * * @return JDatabaseQuery The database query * * @since 1.6 */ protected function getListQuery() { $db = $this->getDbo(); $query = $db->getQuery(true); $type = $this->getState('filter.type'); $client = $this->getState('filter.client_id'); $group = $this->getState('filter.group'); // Grab updates ignoring new installs $query->select('*') ->from('#__updates') ->where('extension_id != 0') ->order($this->getState('list.ordering') . ' ' . $this->getState('list.direction')); if ($type) { $query->where('type=' . $db->quote($type)); } if ($client != '') { $query->where('client_id = ' . intval($client)); } if ($group != '' && in_array($type, array('plugin', 'library', ''))) { $query->where('folder=' . $db->quote($group == '*' ? '' : $group)); } // Filter by extension_id if ($eid = $this->getState('filter.extension_id')) { $query->where($db->quoteName('extension_id') . ' = ' . $db->quote((int) $eid)); } else { $query->where($db->quoteName('extension_id') . ' != ' . $db->quote(0)) ->where($db->quoteName('extension_id') . ' != ' . $db->quote(700)); } // Filter by search $search = $this->getState('filter.search'); if (!empty($search)) { $query->where('name LIKE ' . $db->quote('%' . $search . '%')); } return $query; } /** * Finds updates for an extension. * * @param int $eid Extension identifier to look for * @param int $cache_timeout Cache timout * * @return boolean Result * * @since 1.6 */ public function findUpdates($eid = 0, $cache_timeout = 0) { // Purge the updates list $this->purge(); $updater = JUpdater::getInstance(); $updater->findUpdates($eid, $cache_timeout); return true; } /** * Removes all of the updates from the table. * * @return boolean result of operation * * @since 1.6 */ public function purge() { $db = JFactory::getDbo(); // Note: TRUNCATE is a DDL operation // This may or may not mean depending on your database $db->setQuery('TRUNCATE TABLE #__updates'); if ($db->execute()) { // Reset the last update check timestamp $query = $db->getQuery(true) ->update($db->quoteName('#__update_sites')) ->set($db->quoteName('last_check_timestamp') . ' = ' . $db->quote(0)); $db->setQuery($query); $db->execute(); $this->_message = JText::_('COM_INSTALLER_PURGED_UPDATES'); return true; } else { $this->_message = JText::_('COM_INSTALLER_FAILED_TO_PURGE_UPDATES'); return false; } } /** * Enables any disabled rows in #__update_sites table * * @return boolean result of operation * * @since 1.6 */ public function enableSites() { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->update('#__update_sites') ->set('enabled = 1') ->where('enabled = 0'); $db->setQuery($query); if ($db->execute()) { if ($rows = $db->getAffectedRows()) { $this->_message .= JText::plural('COM_INSTALLER_ENABLED_UPDATES', $rows); } return true; } else { $this->_message .= JText::_('COM_INSTALLER_FAILED_TO_ENABLE_UPDATES'); return false; } } /** * Update function. * * Sets the "result" state with the result of the operation. * * @param array $uids Array[int] List of updates to apply * * @return void * * @since 1.6 */ public function update($uids) { $result = true; foreach ($uids as $uid) { $update = new JUpdate; $instance = JTable::getInstance('update'); $instance->load($uid); $update->loadFromXML($instance->detailsurl); $update->set('extra_query', $instance->extra_query); // Install sets state and enqueues messages $res = $this->install($update); if ($res) { $instance->delete($uid); } $result = $res & $result; } // Set the final state $this->setState('result', $result); } /** * Handles the actual update installation. * * @param JUpdate $update An update definition * * @return boolean Result of install * * @since 1.6 */ private function install($update) { $app = JFactory::getApplication(); if (isset($update->get('downloadurl')->_data)) { $url = $update->downloadurl->_data; $extra_query = $update->get('extra_query'); if ($extra_query) { if (strpos($url, '?') === false) { $url .= '?'; } else { $url .= '&'; } $url .= $extra_query; } } else { JError::raiseWarning('', JText::_('COM_INSTALLER_INVALID_EXTENSION_UPDATE')); return false; } $p_file = JInstallerHelper::downloadPackage($url); // Was the package downloaded? if (!$p_file) { JError::raiseWarning('', JText::sprintf('COM_INSTALLER_PACKAGE_DOWNLOAD_FAILED', $url)); return false; } $config = JFactory::getConfig(); $tmp_dest = $config->get('tmp_path'); // Unpack the downloaded package file $package = JInstallerHelper::unpack($tmp_dest . '/' . $p_file); // Get an installer instance $installer = JInstaller::getInstance(); $update->set('type', $package['type']); // Install the package if (!$installer->update($package['dir'])) { // There was an error updating the package $msg = JText::sprintf('COM_INSTALLER_MSG_UPDATE_ERROR', JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); $result = false; } else { // Package updated successfully $msg = JText::sprintf('COM_INSTALLER_MSG_UPDATE_SUCCESS', JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); $result = true; } // Quick change $this->type = $package['type']; // Set some model state values $app->enqueueMessage($msg); // TODO: Reconfigure this code when you have more battery life left $this->setState('name', $installer->get('name')); $this->setState('result', $result); $app->setUserState('com_installer.message', $installer->message); $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); // Cleanup the install files if (!is_file($package['packagefile'])) { $config = JFactory::getConfig(); $package['packagefile'] = $config->get('tmp_path') . '/' . $package['packagefile']; } JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); return $result; } /** * Method to get the row form. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return mixed A JForm object on success, false on failure * * @since 2.5.2 */ public function getForm($data = array(), $loadData = true) { // Get the form. JForm::addFormPath(JPATH_COMPONENT . '/models/forms'); JForm::addFieldPath(JPATH_COMPONENT . '/models/fields'); $form = JForm::getInstance('com_installer.update', 'update', array('load_data' => $loadData)); // Check for an error. if ($form == false) { $this->setError($form->getMessage()); return false; } // Check the session for previously entered form data. $data = $this->loadFormData(); // Bind the form data if present. if (!empty($data)) { $form->bind($data); } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * * @since 2.5.2 */ protected function loadFormData() { // Check the session for previously entered form data. $data = JFactory::getApplication()->getUserState($this->context . '.data', array()); return $data; } } components/com_installer/models/discover.php000066600000012672150771655450015431 0ustar00getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); $clientId = $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', ''); $this->setState('filter.client_id', $clientId); $categoryId = $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', ''); $this->setState('filter.type', $categoryId); $group = $this->getUserStateFromRequest($this->context . '.filter.group', 'filter_group', ''); $this->setState('filter.group', $group); $this->setState('message', $app->getUserState('com_installer.message')); $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); $app->setUserState('com_installer.message', ''); $app->setUserState('com_installer.extension_message', ''); parent::populateState('name', 'asc'); } /** * Method to get the database query. * * @return JDatabaseQuery the database query * * @since 3.1 */ protected function getListQuery() { $type = $this->getState('filter.type'); $client = $this->getState('filter.client_id'); $group = $this->getState('filter.group'); $query = JFactory::getDbo()->getQuery(true) ->select('*') ->from('#__extensions') ->where('state=-1'); if ($type) { $query->where('type=' . $this->_db->quote($type)); } if ($client != '') { $query->where('client_id=' . (int) $client); } if ($group != '' && in_array($type, array('plugin', 'library', ''))) { $query->where('folder=' . $this->_db->quote($group == '*' ? '' : $group)); } // Filter by search in id $search = $this->getState('filter.search'); if (!empty($search) && stripos($search, 'id:') === 0) { $query->where('extension_id = ' . (int) substr($search, 3)); } return $query; } /** * Discover extensions. * * Finds uninstalled extensions * * @return void * * @since 1.6 */ public function discover() { // Purge the list of discovered extensions $this->purge(); $installer = JInstaller::getInstance(); $results = $installer->discover(); // Get all templates, including discovered ones $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('extension_id, element, folder, client_id, type') ->from('#__extensions'); $db->setQuery($query); $installedtmp = $db->loadObjectList(); $extensions = array(); foreach ($installedtmp as $install) { $key = implode(':', array($install->type, $install->element, $install->folder, $install->client_id)); $extensions[$key] = $install; } unset($installedtmp); foreach ($results as $result) { // Check if we have a match on the element $key = implode(':', array($result->type, $result->element, $result->folder, $result->client_id)); if (!array_key_exists($key, $extensions)) { // Put it into the table $result->store(); } } } /** * Installs a discovered extension. * * @return void * * @since 1.6 */ public function discover_install() { $app = JFactory::getApplication(); $installer = JInstaller::getInstance(); $eid = JRequest::getVar('cid', 0); if (is_array($eid) || $eid) { if (!is_array($eid)) { $eid = array($eid); } JArrayHelper::toInteger($eid); $failed = false; foreach ($eid as $id) { $result = $installer->discover_install($id); if (!$result) { $failed = true; $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_DISCOVER_INSTALLFAILED') . ': ' . $id); } } $this->setState('action', 'remove'); $this->setState('name', $installer->get('name')); $app->setUserState('com_installer.message', $installer->message); $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); if (!$failed) { $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_DISCOVER_INSTALLSUCCESSFUL')); } } else { $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_DISCOVER_NOEXTENSIONSELECTED')); } } /** * Cleans out the list of discovered extensions. * * @return bool True on success * * @since 1.6 */ public function purge() { $db = JFactory::getDbo(); $query = $db->getQuery(true) ->delete('#__extensions') ->where('state = -1'); $db->setQuery($query); if ($db->execute()) { $this->_message = JText::_('COM_INSTALLER_MSG_DISCOVER_PURGEDDISCOVEREDEXTENSIONS'); return true; } else { $this->_message = JText::_('COM_INSTALLER_MSG_DISCOVER_FAILEDTOPURGEEXTENSIONS'); return false; } } } components/com_mover/mover_main.php000066600000036216150771655450013617 0ustar00'; //---------------------------------------------------------------------- $h[]= '
      '; $db->setQuery('SELECT c.id as id, concat(s.title," - ",c.title) as name FROM aaa_sections s, aaa_categories c where s.id=c.section order by s.id, c.id', 0, $count); $rows = $db->loadObjectList(); $h[]= ' Из '; $h[]= ' В '; $h[]= ' Сохранить'; $h[]= ' '; $h[]= '
      '; //---------------------------------------------------------------------- if ($_POST[from_cat_id]<>'') { $h[]= '
      '; $db->setQuery('SELECT * FROM aaa_articles a, aaa_content c where c.id=a.id and (a.type="mi" or a.type="bp") and c.catid='.$_POST[from_cat_id].' order by c.id limit 600,200', 0, $count); $rows = $db->loadObjectList(); foreach ($rows as $row){ $it=$row->introtext; preg_match_all("~".'\'."~is", $it, $m); $m=$m[1][0]; preg_match_all("~".'src\=\"'."(.*?)".'"'."~is", $m, $m); $m=$m[1][0]; if(!file_exists('../'.$m))$h[]=$null_value; $h[]= '
      '; $param_path_image=$m; $h[]= 'title: '.$row->title.'
      '; $param_title=$row->title; $h[]= 'id: '.$row->id.'
      '; $param_id=$row->id; $param_alias=myalias($row->title); if (mvGetValue($db,'val','SELECT id val FROM #__zoo_item where alias="'.$param_alias.'"')<>'') $param_alias=$param_alias.'-'.$param_id; $h[]= 'alias: '.$row->alias.'==='.$param_alias.'
      '; $h[]= 'created: '.$row->created.'
      '; $param_created=$row->created; $h[]= 'modified: '.$row->modified.'
      '; $param_modified=$row->modified; $h[]= 'metakey: '.$row->metakey.'
      '; $param_metakey=$row->metakey; if (empty($row->metadesc))$row->metadesc=$param_title; $h[]= 'metadesc: '.$row->metadesc.'
      '; $param_metadesc=$row->metadesc; $h[]= 'hits: '.$row->hits.'
      '; $param_hits=$row->hits; $price= preg_replace('~[^0-9]+~','',$row->price); $h[]= 'price: '.$price.'
      '; preg_match_all("~".'Автор\:'."(.*?)".'\<\/tr\>'."~is", $it, $m); $m=strip_tags($m[1][0]); if ($m=='')$h[]=$null_value; $h[]= 'Автор: '.$m.'
      '; $param_autor=$m; $h[]= 'Дата выхода: '.$row->date.' 00:00:00'.'
      '; $param_exit_date=$row->date.' 00:00:00'; if ($param_created=="0000-00-00 00:00:00") $param_created=$param_exit_date; preg_match_all("~".'Способ предоставления\:'."(.*?)".'\<\/tr\>'."~is", $it, $m); $m=strip_tags($m[1][0]); if ($m=='')$h[]=$null_value; $h[]= 'Способ предоставления: '.$m.'
      '; $param_sposob_predost=$m; preg_match_all("~".'Количество страниц\:'."(.*?)".'\<\/tr\>'."~is", $it, $m); $m=strip_tags($m[1][0]); if ($m=='')$h[]=$null_value; $h[]= 'Количество страниц: '.$m.'
      '; $param_page_count=$m; preg_match_all("~".'Демо-версия'."(.*?)".'Cкачать'."~is", $it, $m); $m=$m[1][0]; preg_match_all("~".'href\=\"'."(.*?)".'"'."~is", $m, $m); $m=$m[1][0]; $m='images/'.$m; if (!file_exists('../'.$m))$h[]=$null_value; $h[]= 'Демо-версия: Cкачать
      '; $param_pdf_link=$m; preg_match_all("~".'Цена\:'."(.*?)".'руб.'."~is", $it, $m); $m=strip_tags($m[1][0]); $m=str_replace(' ','',$m); if ($m=='')$h[]=$null_value; $h[]= 'Цена (ru): '.$m.'
      '; $param_cost_ru=$m; preg_match_all("~".'Цена английской версии\:'."(.*?)".'руб.'."~is", $it, $m); $m=strip_tags($m[1][0]); $m=str_replace(' ','',$m); if ($m=='')$h[]=$null_value; $h[]= 'Цена (en): '.$m.'
      '; $param_cost_en=$m; preg_match_all("~".'ОПИСАНИЕ'."(.*?)".'Ключевые слова'."~is", $it, $m); $m=$m[1][0]; if ($m=='')$h[]=$null_value; $h[]= 'Описание: '.mb_substr(strip_tags($m),0,50).' ... '.mb_substr(strip_tags($m),-50,50).'
      '; $param_description=$m; $m=$row->about; if ($m=='')$h[]=$null_value; $h[]= 'about: '.mb_substr(strip_tags($m),0,50).' ... '.mb_substr(strip_tags($m),-50,50).'
      '; $param_about=$m; $m=$row->oglav; if ($m=='')$h[]=$null_value; $h[]= 'oglav: '.mb_substr(strip_tags($m),0,50).' ... '.mb_substr(strip_tags($m),-50,50).'
      '; $param_oglav=$m; $m=$row->prilog; if ($m=='')$h[]=$null_value; $h[]= 'prilog: '.mb_substr(strip_tags($m),0,50).' ... '.mb_substr(strip_tags($m),-50,50).'
      '; $param_prilog=$m; preg_match_all("~".'Ключевые слова'."(.*?)".'Ссылка на страницу'."~is", $it, $m); $m=strip_tags($m[1][0]); $m=str_replace('бизнес-плана:','',$m); $m=str_replace('исследования:','',$m); $m=str_replace(':','',$m); if ($m=='')$h[]=$null_value; $h[]= 'Ключевые слова: '.$m.'
      '; $param_keywords=$m; //save--------------------------------- if ($_POST['save']=='1' and $_POST[to_cat_id]<>'') { $js_real=mvGetValue($db,'val',"select elements as val from #__zoo_item where id={$param_id}"); if (!empty($js_real)) $js_temp=$js_real; $js=json_decode($js_temp,true); $js['aed9068f-8fd9-4c38-89d1-83187a602ac5']['0']['value']=$param_cost_ru; $js['dbf6c773-0a69-432c-a462-b56e620e2e5e']['0']['value']=$param_cost_en; $js['5ca958c9-4ac5-4d08-821f-b9640e731bd7']['0']['value']=$param_autor; $js['667ea4d6-3745-40b5-b2a2-41fdc13b9a47']['0']['value']=$param_exit_date; $js['d12d446f-f969-49f8-af79-f82080cdbc3f']['0']['value']=$param_sposob_predost; $js['b66a2a93-01c7-4487-9fe3-61ab4c4c7c88']['0']['value']=$param_page_count; $js['9ef0426c-06d1-45da-88e6-477d9d8398fe']['file']=$param_pdf_link; $js['7f743a10-621b-4606-ba91-d4a7eebe3992']['0']['value']=$param_description; $js['8df3b01b-134d-4eba-88ea-687647a4a9fa']['0']['value']=$param_about; $js['73b058b8-a242-4b81-8d0a-2f975c99d0ca']['0']['value']=$param_oglav; $js['23a97f6f-2601-4c88-8324-168c705b61fe']['0']['value']=$param_prilog; $js['57172c66-27cb-442d-a964-19f64f744a3b']['file']=$param_path_image; $js_text=json_encode($js, JSON_FORCE_OBJECT); $js_text=str_replace("\\","\\\\",$js_text); $js_text=str_replace('"','\"',$js_text); $kw=explode(",",$param_keywords); $kw2=explode(",",$param_metakey); $kw=array_merge($kw,$kw2); unset($kw2); $kw=array_unique($kw); foreach($kw as $key=>$value){ $word=$value; $word=trim($word); $word=str_replace("\r","",$word); $kw[$key]=str_replace("\n","",$word); } $par=json_decode($js_param_temp,true); $par['metadata.title']=$param_title; $par['config.primary_category']=$_POST[to_cat_id]; $par['metadata.description']=$param_metadesc; $par['metadata.keywords']=implode(", ",$kw); $par=json_encode($par, JSON_FORCE_OBJECT); $par=str_replace("\\","\\\\",$par); $par=str_replace('"','\"',$par); if (empty($js_real)) { $query = "INSERT INTO #__zoo_item (id,application_id,type,name,alias, created,modified,modified_by,publish_up,publish_down, priority,hits,state,access,created_by, created_by_alias,searchable,elements,params) VALUES (\"{$param_id}\", 1, \"product\", \"{$param_title}\", \"{$param_alias}\", \"{$param_created}\", \"{$param_modified}\", 949, '0000-00-00 00:00:00', '0000-00-00 00:00:00', 0, {$param_hits}, 1, 1, 949, '', 1, \"{$js_text}\", \"{$par}\");"; $h[]= 'Создание нового материала
      '; } else { $query = "UPDATE #__zoo_item SET elements=\"{$js_text}\",params=\"{$par}\" WHERE id={$param_id}"; $h[]= 'Обновление материала
      '; } $db->setquery($query);$b=$db->query($query); if (!$b) $h[]= 'Ошибка при сохранении материала в базу данных!
      '; if (empty($js_real)) { $item_id=mvGetValue($db,'val','SELECT id val FROM #__zoo_item WHERE alias="'.$param_alias.'"'); //save cat if (!empty($item_id) and !empty($_POST[to_cat_id])){ $query = "INSERT INTO #__zoo_category_item (category_id, item_id) VALUES (\"{$_POST[to_cat_id]}\", \"{$item_id}\");"; $db->setquery($query);$b=$db->query($query); if (!$b){ $h[]= 'Ошибка при сохранении категории в базу данных!
      '; } else{ $h[]= 'Категория удачно сохранена в базу данных
      '; } } else{ $h[]= 'Отсутствуют данные для сохранения категории!
      '; } //tags if (!$b){ $h[]= 'Ошибка при сохранении записи в базу данных!
      '; } else{ $h[]= 'Запись удачно сохранена в базу данных
      '; if (count($kw)<>0){ if (!empty($item_id)){ foreach ($kw as $kword){ $word=trim($kword); if (mvGetValue($db,'val','SELECT item_id val FROM #__zoo_tag WHERE item_id="'.$item_id.'" and name="'.$word.'"')==''){ $query = "INSERT INTO #__zoo_tag (item_id,name) VALUES (\"{$item_id}\", \"{$word}\");"; $db->setquery($query);$b=$db->query($query); } if (!$b) $h[]= 'Ошибка при сохранении ключевого слова в базу данных!
      '; else $h[]= 'Ключевое слово удачно сохранено в базу данных
      '; } } else{ $h[]= 'Item_id пустой!
      '; } } else{ $h[]= 'Ключевые слова отсутствуют!
      '; } } } } $h[]= '
      '; } $h[]= '
      '; } $h[]= ''; echo implode("\r\n",$h); function ShowTree($db,$ParentID, $lvl, $id_cat, $id_app, $selected_id) { global $lvl; $lvl++; $hf=''; $count=''; $db->setQuery("SELECT * FROM #__zoo_category WHERE parent=".$ParentID." and application_id=".$id_app." ORDER BY ordering", 0, $count); $rows = $db->loadObjectList(); foreach ($rows as $row) { $hf .= '