PageRenderTime 17ms CodeModel.GetById 70ms app.highlight 55ms RepoModel.GetById 1ms app.codeStats 1ms

/admin800/tabs/AdminModules.php

http://marocmall.googlecode.com/
PHP | 918 lines | 831 code | 51 blank | 36 comment | 101 complexity | 0f0dea39546a1c4138949c7f495b798c MD5 | raw file
  1<?php
  2/*
  3* 2007-2011 PrestaShop 
  4*
  5* NOTICE OF LICENSE
  6*
  7* This source file is subject to the Open Software License (OSL 3.0)
  8* that is bundled with this package in the file LICENSE.txt.
  9* It is also available through the world-wide-web at this URL:
 10* http://opensource.org/licenses/osl-3.0.php
 11* If you did not receive a copy of the license and are unable to
 12* obtain it through the world-wide-web, please send an email
 13* to license@prestashop.com so we can send you a copy immediately.
 14*
 15* DISCLAIMER
 16*
 17* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
 18* versions in the future. If you wish to customize PrestaShop for your
 19* needs please refer to http://www.prestashop.com for more information.
 20*
 21*  @author PrestaShop SA <contact@prestashop.com>
 22*  @copyright  2007-2011 PrestaShop SA
 23*  @version  Release: $Revision: 6965 $
 24*  @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 25*  International Registered Trademark & Property of PrestaShop SA
 26*/
 27
 28include_once(PS_ADMIN_DIR.'/../tools/tar/Archive_Tar.php');
 29
 30class AdminModules extends AdminTab
 31{
 32	/** @var array map with $_GET keywords and their callback */
 33	private $map = array(
 34		'install' => 'install',
 35		'uninstall' => 'uninstall',
 36		'configure' => 'getContent',
 37		'delete' => 'delete'
 38	);
 39	
 40	private $listTabModules;
 41	private $listPartnerModules = array();
 42	private $listNativeModules = array();
 43	private $_moduleCacheFile;
 44	static private $MAX_DISP_AUTHOR = 20;		// maximum length to display
 45	
 46
 47	function __construct()
 48	{
 49		parent::__construct ();
 50		
 51		$this->_moduleCacheFile = _PS_ROOT_DIR_.'/config/modules_list.xml';
 52		
 53		//refresh modules_list.xml every week
 54		if (!$this->isFresh()) 
 55			$this->refresh();
 56		
 57		$this->listTabModules = array('administration' => $this->l('Administration'), 'advertising_marketing' => $this->l('Advertising & Marketing'),
 58		 'analytics_stats' => $this->l('Analytics & Stats'), 'billing_invoicing' => $this->l('Billing & Invoicing'), 'checkout' => $this->l('Checkout'),
 59		 'content_management' => $this->l('Content Management'), 'export' => $this->l('Export'), 'front_office_features' => $this->l('Front Office Features'),
 60		 'i18n_localization' => $this->l('I18n & Localization'), 'merchandizing' => $this->l('Merchandizing'), 'migration_tools' => $this->l('Migration Tools'),
 61		 'payments_gateways' => $this->l('Payments & Gateways'), 'payment_security' => $this->l('Payment Security'), 'pricing_promotion' => $this->l('Pricing & Promotion'),
 62		 'quick_bulk_update' => $this->l('Quick / Bulk update'), 'search_filter' => $this->l('Search & Filter'), 'seo' => $this->l('SEO'), 'shipping_logistics' => $this->l('Shipping & Logistics'),
 63		 'slideshows' => $this->l('Slideshows'), 'smart_shopping' => $this->l('Smart Shopping'), 'market_place' => $this->l('Market Place'), 'social_networks' => $this->l('Social Networks'), 'others'=> $this->l('Other Modules'));
 64		 
 65		 $xmlModules = @simplexml_load_file($this->_moduleCacheFile);
 66
 67		 foreach($xmlModules->children() as $xmlModule)
 68		 	if ($xmlModule->attributes() == 'native')
 69		 		foreach($xmlModule->children() as $module)
 70		 			foreach($module->attributes() as $key => $value)
 71		 			if ($key == 'name')
 72		 				$this->listNativeModules[] = (string)$value;
 73		 	if ($xmlModule->attributes() == 'partner')
 74		 		foreach($xmlModule->children() as $module)
 75		 			foreach($module->attributes() as $key => $value)
 76		 			if ($key == 'name')
 77		 				$this->listPartnerModules[] = (string)$value;
 78	}
 79	
 80	public function postProcess()
 81	{
 82		global $currentIndex, $cookie;
 83
 84		$id_employee = (int)($cookie->id_employee);
 85		$filter_conf = Configuration::getMultiple(array(
 86												'PS_SHOW_TYPE_MODULES_'.$id_employee,
 87												'PS_SHOW_COUNTRY_MODULES_'.$id_employee,
 88												'PS_SHOW_INSTALLED_MODULES_'.$id_employee,
 89												'PS_SHOW_ENABLED_MODULES_'.$id_employee
 90												));
 91		//reset filtre
 92		if (Tools::isSubmit('desactive') && isset($filter_conf['PS_SHOW_ENABLED_MODULES_'.$id_employee]) && $filter_conf['PS_SHOW_ENABLED_MODULES_'.$id_employee] != 'enabledDisabled')
 93			$this->setFilterModules($filter_conf['PS_SHOW_TYPE_MODULES_'.$id_employee], $filter_conf['PS_SHOW_COUNTRY_MODULES_'.$id_employee], $filter_conf['PS_SHOW_INSTALLED_MODULES_'.$id_employee], 'disabled');
 94			
 95		if (Tools::isSubmit('active') && isset($filter_conf['PS_SHOW_ENABLED_MODULES_'.$id_employee]) && $filter_conf['PS_SHOW_ENABLED_MODULES_'.$id_employee] != 'enabledDisabled')
 96			$this->setFilterModules($filter_conf['PS_SHOW_TYPE_MODULES_'.$id_employee], $filter_conf['PS_SHOW_COUNTRY_MODULES_'.$id_employee], $filter_conf['PS_SHOW_INSTALLED_MODULES_'.$id_employee], 'enabled');
 97			
 98		if (Tools::isSubmit('uninstall') && isset($filter_conf['PS_SHOW_INSTALLED_MODULES_'.$id_employee]) && $filter_conf['PS_SHOW_INSTALLED_MODULES_'.$id_employee] != 'installedUninstalled')
 99			$this->setFilterModules($filter_conf['PS_SHOW_TYPE_MODULES_'.$id_employee], $filter_conf['PS_SHOW_COUNTRY_MODULES_'.$id_employee], 'unistalled', $filter_conf['PS_SHOW_ENABLED_MODULES_'.$id_employee]);
100			
101		if (Tools::isSubmit('install') && isset($filter_conf['PS_SHOW_INSTALLED_MODULES_'.$id_employee]) && $filter_conf['PS_SHOW_INSTALLED_MODULES_'.$id_employee] != 'installedUninstalled')
102			$this->setFilterModules($filter_conf['PS_SHOW_TYPE_MODULES_'.$id_employee], $filter_conf['PS_SHOW_COUNTRY_MODULES_'.$id_employee], 'installed', $filter_conf['PS_SHOW_ENABLED_MODULES_'.$id_employee]);
103		
104		
105		if (Tools::isSubmit('filterModules'))
106		{
107			$this->setFilterModules(Tools::getValue('module_type'), Tools::getValue('country_module_value'), Tools::getValue('module_install'), Tools::getValue('module_status'));
108			Tools::redirectAdmin($currentIndex.'&token='.$this->token);
109		}
110		elseif (Tools::isSubmit('resetFilterModules'))
111		{
112			$this->resetFilterModules();
113			Tools::redirectAdmin($currentIndex.'&token='.$this->token);
114		}
115		if (Tools::isSubmit('active'))
116		{
117		 	if ($this->tabAccess['edit'] === '1')
118			{
119				$module = Module::getInstanceByName(Tools::getValue('module_name'));
120				if (Validate::isLoadedObject($module))
121				{
122					$module->enable();
123					Tools::redirectAdmin($currentIndex.'&conf=5'.'&token='.$this->token.'&tab_module='.$module->tab.'&module_name='.$module->name);
124				} else
125					$this->_errors[] = Tools::displayError('Cannot load module object');
126			} else
127				$this->_errors[] = Tools::displayError('You do not have permission to add here.');
128		}
129		elseif (Tools::isSubmit('desactive'))
130		{
131		 	if ($this->tabAccess['edit'] === '1')
132			{
133				$module = Module::getInstanceByName(Tools::getValue('module_name'));
134				if (Validate::isLoadedObject($module))
135				{
136					$module->disable();
137					Tools::redirectAdmin($currentIndex.'&conf=5'.'&token='.$this->token.'&tab_module='.$module->tab.'&module_name='.$module->name);
138				} else
139					$this->_errors[] = Tools::displayError('Cannot load module object');
140			} else
141				$this->_errors[] = Tools::displayError('You do not have permission to add here.');
142		}
143		elseif (Tools::isSubmit('reset'))
144		{
145			if ($this->tabAccess['edit'] === '1')
146			{
147				$module = Module::getInstanceByName(Tools::getValue('module_name'));
148				if (Validate::isLoadedObject($module))
149				{
150					if ($module->uninstall())
151						if ($module->install())
152							Tools::redirectAdmin($currentIndex.'&conf=21'.'&token='.$this->token.'&tab_module='.$module->tab.'&module_name='.$module->name);
153						else
154							$this->_errors[] = Tools::displayError('Cannot install module');
155					else
156						$this->_errors[] = Tools::displayError('Cannot uninstall module');
157											
158				} else
159					$this->_errors[] = Tools::displayError('Cannot load module object');
160			} else
161				$this->_errors[] = Tools::displayError('You do not have permission to add here.');
162
163		}
164		/* Automatically copy a module from external URL and unarchive it in the appropriated directory */
165		if (Tools::isSubmit('submitDownload'))
166		{
167		 	if ($this->tabAccess['add'] === '1')
168			{
169				if (Validate::isModuleUrl($url = Tools::getValue('url'), $this->_errors))
170				{
171					if (!@copy($url, _PS_MODULE_DIR_.basename($url)))
172						$this->_errors[] = Tools::displayError('404 Module not found');
173					else
174						$this->extractArchive(_PS_MODULE_DIR_.basename($url));
175				}
176			}
177			else
178				$this->_errors[] = Tools::displayError('You do not have permission to add here.');
179		}
180		if (Tools::isSubmit('submitDownload2'))
181		{
182		 	if ($this->tabAccess['add'] === '1')
183			{
184				if (!isset($_FILES['file']['tmp_name']) OR empty($_FILES['file']['tmp_name']))
185					$this->_errors[] = $this->l('no file selected');
186				elseif (substr($_FILES['file']['name'], -4) != '.tar' AND substr($_FILES['file']['name'], -4) != '.zip' AND substr($_FILES['file']['name'], -4) != '.tgz' AND substr($_FILES['file']['name'], -7) != '.tar.gz')
187					$this->_errors[] = Tools::displayError('Unknown archive type');
188				elseif (!@copy($_FILES['file']['tmp_name'], _PS_MODULE_DIR_.$_FILES['file']['name']))
189					$this->_errors[] = Tools::displayError('An error occurred while copying archive to module directory.');
190				else
191					$this->extractArchive(_PS_MODULE_DIR_.$_FILES['file']['name']);
192			}
193			else
194				$this->_errors[] = Tools::displayError('You do not have permission to add here.');
195		}
196		if (Tools::isSubmit('deleteModule'))
197		{
198		 	if ($this->tabAccess['delete'] === '1')
199			{
200				if (Tools::getValue('module_name') != '')
201				{
202					$moduleDir = _PS_MODULE_DIR_.str_replace(array('.', '/', '\\'), array('', '', ''), Tools::getValue('module_name'));
203					$this->recursiveDeleteOnDisk($moduleDir);
204					Tools::redirectAdmin($currentIndex.'&conf=22&token='.$this->token.'&tab_module='.Tools::getValue('tab_module').'&module_name='.Tools::getValue('module_name'));
205				}
206				Tools::redirectAdmin($currentIndex.'&token='.$this->token);
207			}
208			else
209				$this->_errors[] = Tools::displayError('You do not have permission to delete here.');
210		}
211
212		/* Call appropriate module callback */
213		else
214		{
215		 	$return = false;
216			foreach ($this->map as $key => $method)
217			{
218				$modules = Tools::getValue($key);
219				if (strpos($modules, '|'))
220					$modules = explode('|', $modules);
221				else
222					$modules = empty($modules) ? false : array($modules);
223				$module_errors = array();
224				if ($modules)
225					foreach ($modules AS $name)
226					{
227						if (!($module = Module::getInstanceByName(urldecode($name))))
228							$this->_errors[] = $this->l('module not found');
229						elseif ($key == 'install' AND $this->tabAccess['add'] !== '1')
230							$this->_errors[] = Tools::displayError('You do not have permission to add here.');
231						elseif ($key == 'uninstall' AND $this->tabAccess['delete'] !== '1')
232							$this->_errors[] = Tools::displayError('You do not have permission to delete here.');
233						elseif ($key == 'configure' AND $this->tabAccess['edit'] !== '1')
234							$this->_errors[] = Tools::displayError('You do not have permission to edit here.');
235						elseif ($key == 'install' AND Module::isInstalled($module->name))
236							$this->_errors[] = Tools::displayError('This module is already installed : ').$module->name;
237						elseif ($key == 'uninstall' AND !Module::isInstalled($module->name))
238							$this->_errors[] = Tools::displayError('This module is already uninstalled : ').$module->name;
239						elseif (($echo = $module->{$method}()) AND ($key == 'configure') AND Module::isInstalled($module->name))
240						{
241							$backlink = $currentIndex.'&token='.$this->token.'&tab_module='.$module->tab.'&module_name='.$module->name;
242							$hooklink = 'index.php?tab=AdminModulesPositions&token='.Tools::getAdminTokenLite('AdminModulesPositions').'&show_modules='.(int)$module->id;
243							$tradlink = 'index.php?tab=AdminTranslations&token='.Tools::getAdminTokenLite('AdminTranslations').'&type=modules&lang=';
244							
245							$toolbar = '
246							<table class="table" cellpadding="0" cellspacing="0" style="margin:auto;text-align:center">
247								<tr>
248									<th>'.$this->l('Module').' <span style="color: green;">'.$module->name.'</span></th>
249									<th><a href="'.$backlink.'" style="padding:5px 10px">'.$this->l('Back').'</a></th>
250									<th><a href="'.$hooklink.'" style="padding:5px 10px">'.$this->l('Manage hooks').'</a></th>
251									<th style="padding:5px 10px">'.$this->l('Manage translations:').' ';
252									foreach (Language::getLanguages(false) AS $language)
253										$toolbar .= '<a href="'.$tradlink.$language['iso_code'].'#'.$module->name.'" style="margin-left:5px"><img src="'._THEME_LANG_DIR_.$language['id_lang'].'.jpg" alt="'.$language['iso_code'].'" title="'.$language['iso_code'].'" /></a>';
254							$toolbar .= '
255									</th>
256								</tr>
257							</table>';
258							
259							echo 
260							$toolbar.'
261							<div class="clear">&nbsp;</div>'.$echo.'<div class="clear">&nbsp;</div>
262							'.$toolbar;
263						}
264						elseif($echo)
265							$return = ($method == 'install' ? 12 : 13);
266						elseif ($echo === false)
267							$module_errors[] = $name;
268						if ($key != 'configure' AND isset($_GET['bpay']))
269							Tools::redirectAdmin('index.php?tab=AdminPayment&token='.Tools::getAdminToken('AdminPayment'.(int)(Tab::getIdFromClassName('AdminPayment')).(int)($cookie->id_employee)));
270					}
271				if (sizeof($module_errors))
272				{
273					$htmlError = '';
274
275					foreach ($module_errors AS $module_error)
276						$htmlError .= '<li>'.$module_error.'</li>';
277					$htmlError .= '</ul>';
278					$this->_errors[] = Tools::displayError('The following module(s) were not installed successfully:'.$htmlError);
279				}
280			}
281			if ($return)
282				Tools::redirectAdmin($currentIndex.'&conf='.$return.'&token='.$this->token.'&tab_module='.$module->tab.'&module_name='.$module->name);
283		}
284	}
285
286	function extractArchive($file)
287	{
288		global $currentIndex;
289		$success = false;
290		if (substr($file, -4) == '.zip')
291		{
292			if (!Tools::ZipExtract($file, _PS_MODULE_DIR_))
293				$this->_errors[] = Tools::displayError('Error while extracting module (file may be corrupted).');
294		}
295		else
296		{
297			$archive = new Archive_Tar($file);
298			if ($archive->extract(_PS_MODULE_DIR_))
299				$success = true;
300			else
301				$this->_errors[] = Tools::displayError('Error while extracting module (file may be corrupted).');
302		}
303		
304		@unlink($file);
305		if ($success)
306			Tools::redirectAdmin($currentIndex.'&conf=8'.'&token='.$this->token);
307	}
308	
309	public function display()
310	{
311		if (!isset($_GET['configure']) AND !isset($_GET['delete']) OR sizeof($this->_errors) )
312			$this->displayList();
313	}
314
315	public function displayJavascript()
316	{
317		global $currentIndex;
318
319		echo '<script type="text/javascript" src="'._PS_JS_DIR_.'jquery/jquery.autocomplete.js"></script>
320			<script type="text/javascript" src="'._PS_JS_DIR_.'jquery/jquery.fancybox-1.3.4.js"></script>
321
322		<script type="text/javascript">
323			function getPrestaStore(){if (getE("prestastore").style.display!=\'block\')return;$.post("'.dirname($currentIndex).'/ajax.php",{page:"prestastore"},function(a){getE("prestastore-content").innerHTML=a;})}
324			function truncate_author(author)
325			{
326				return ((author.length > '.self::$MAX_DISP_AUTHOR.') ? author.substring(0, '.self::$MAX_DISP_AUTHOR.')+"..." : author);
327			}
328			function modules_management(action)
329			{
330				var modules = document.getElementsByName(\'modules\');
331				var module_list = \'\';
332				for (var i = 0; i < modules.length; i++)
333				{
334					if (modules[i].checked == true)
335					{
336						rel = modules[i].getAttribute(\'rel\');
337						if (rel != "false" && action == "uninstall")
338						{
339							if (!confirm(rel))
340								return false;
341						}
342						module_list += \'|\'+modules[i].value;
343					}
344				}
345				document.location.href=\''.$currentIndex.'&token='.$this->token.'&\'+action+\'=\'+module_list.substring(1, module_list.length);
346			}	
347			$(\'document\').ready( function() {
348				$(\'input[name="filtername"]\').autocomplete(moduleList, {
349					minChars: 0,
350					width: 310,
351					matchContains: true,
352					highlightItem: true,
353					formatItem: function(row, i, max, term) {
354						return "<img src=\"../modules/"+row.name+"/logo.gif\" style=\"float:left;margin:5px\"><strong>" + row.displayName + "</strong>"+((row.author != \'\') ? " '.$this->l("by").' "+ truncate_author(row.author) :"") + "<br /><span style=\'font-size: 80%;\'>"+ row.desc +"</span>";
355					},
356					formatResult: function(row) {
357						return row.displayName;
358					}
359				});
360				$(\'input[name="filtername"]\').result(function(event, data, formatted) {
361				 $(\'#filternameForm\').submit();
362				});
363			});
364			
365		</script>';
366	}
367	public static function sortModule($a, $b)
368	{
369	    if (sizeof($a) == sizeof($b)) {
370	        return 0;
371	    }
372	    return (sizeof($a) < sizeof($b)) ? -1 : 1;
373	}
374	
375
376	/**
377	 * Used for retreiving author name from submited field authorModules[name]
378	 * @param String $value value to be clean
379	 *
380	 * @return String cleant value: name
381	 */
382	private function _getSubmitedModuleAuthor($value)
383	{
384		$value = str_replace('authorModules[', '', $value);
385		$value = str_replace("\'", "'", $value);
386
387		$value = substr($value, 0, -1);
388		return $value;
389	}
390
391	/**
392	 * Used for building option group
393	 * @param Array $authors contains modules authors
394	 * @param String $fieldName name of optiongroup 
395	 * @return String built comp
396	 */
397
398	private function _buildModuleAuthorsOptGroup($authors, $fieldName = "UNDEFINED")
399	{
400		$out = '<optgroup label="'.$this->l('Authors').'">';
401		foreach($authors as $author_item => $status)
402		{
403			$author_item = Tools::htmlentitiesUTF8($author_item);
404			$disp_author = $this->_getDispAuthor($author_item);
405
406			$out .= '<option value="'.$fieldName.'['.$author_item. ']"'. (($status === "selected") ? ' selected>' : '>').$disp_author .'</option>';
407		}
408		$out .= '</optgroup>';
409		return $out;
410	}
411
412	/**
413	 * Used for truncating  author name to display it nicely
414	 * @param String $author original  author
415	 * @return String truncated author name
416	 */
417	private function _getDispAuthor($author)
418	{
419		return ((strlen($author) > self::$MAX_DISP_AUTHOR) ? substr($author, 0, self::$MAX_DISP_AUTHOR).'...' : $author);
420	}
421
422
423	public function displayList()
424	{
425		global $currentIndex, $cookie;
426	
427		$modulesAuthors = array();	
428		$autocompleteList = 'var moduleList = [';
429		
430		$showTypeModules = Configuration::get('PS_SHOW_TYPE_MODULES_'.(int)($cookie->id_employee));
431		$showInstalledModules = Configuration::get('PS_SHOW_INSTALLED_MODULES_'.(int)($cookie->id_employee));
432		$showEnabledModules = Configuration::get('PS_SHOW_ENABLED_MODULES_'.(int)($cookie->id_employee));
433		$showCountryModules = Configuration::get('PS_SHOW_COUNTRY_MODULES_'.(int)($cookie->id_employee));
434
435		$nameCountryDefault = Country::getNameById($cookie->id_lang, Configuration::get('PS_COUNTRY_DEFAULT'));
436		$isoCountryDefault = Country::getIsoById(Configuration::get('PS_COUNTRY_DEFAULT'));
437		
438		$serialModules = '';
439		$modules = Module::getModulesOnDisk(true);
440
441		foreach ($modules AS $module)
442		{
443			if (!in_array($module->name, $this->listNativeModules))
444				$serialModules .= $module->name.' '.$module->version.'-'.($module->active ? 'a' : 'i')."\n";
445
446			$moduleAuthor = $module->author;
447			if (!empty($moduleAuthor)&& ($moduleAuthor != ""))
448				$modulesAuthors[(string)$moduleAuthor] = true;
449		}
450
451		$serialModules = urlencode($serialModules);
452		
453		$filterName = Tools::getValue('filtername');
454		if (!empty($filterName))
455		{
456			echo '
457			<script type="text/javascript">
458				$(document).ready(function() {	
459					$(\'#all_open\').hide();
460					$(\'#all_close\').show();			 
461					$(\'.tab_module_content\').each(function(){
462						$(this).slideDown();
463						$(\'.header_module_img\').each(function(){
464							$(this).attr(\'src\', \'../img/admin/less.png\');
465						});
466					});
467				});
468			</script>';
469		}
470
471		//filter module list
472		foreach($modules as $key => $module)
473		{
474			switch ($showTypeModules)
475			{
476				case 'nativeModules':
477					if (!in_array($module->name, $this->listNativeModules))
478						unset($modules[$key]);
479				break;
480				case 'partnerModules':
481					if (!in_array($module->name, $this->listPartnerModules))
482						unset($modules[$key]);
483				break;
484				case 'otherModules':
485					if (in_array($module->name, $this->listPartnerModules) OR in_array($module->name, $this->listNativeModules))
486						unset($modules[$key]);
487				break;
488				default:
489					if (strpos($showTypeModules, 'authorModules[') !== false)
490					{
491						$author_selected = $this->_getSubmitedModuleAuthor($showTypeModules);
492						$modulesAuthors[$author_selected] = 'selected';		// setting selected author in authors set
493						if (empty($module->author) || $module->author != $author_selected)
494							unset($modules[$key]);
495					}
496
497				break;
498
499			}
500					
501			switch ($showInstalledModules)
502			{
503				case 'installed':
504					if (!$module->id)
505						unset($modules[$key]);
506				break;
507				case 'unistalled':
508					if ($module->id)
509						unset($modules[$key]);
510				break;
511			}
512			
513			switch ($showEnabledModules)
514			{
515				case 'enabled':
516					if (!$module->active)
517						unset($modules[$key]);
518				break;
519				case 'disabled':
520					if ($module->active)
521						unset($modules[$key]);
522				break;
523			}		
524			
525			if ($showCountryModules)		
526				if (isset($module->limited_countries) AND !empty($module->limited_countries) AND ((is_array($module->limited_countries) AND sizeof($module->limited_countries) AND !in_array(strtolower($isoCountryDefault), $module->limited_countries)) OR (!is_array($module->limited_countries) AND strtolower($isoCountryDefault) != strval($module->limited_countries))))
527					unset($modules[$key]);
528			
529			if (!empty($filterName))
530				if (stristr($module->name, $filterName) === false AND stristr($module->displayName, $filterName) === false AND stristr($module->description, $filterName) === false)
531					unset($modules[$key]);
532		}
533		
534		foreach($modules as $module)
535			$autocompleteList .= Tools::jsonEncode(array(
536				'displayName' => (string)$module->displayName,
537				'desc' => (string)$module->description,
538				'name' => (string)$module->name,
539				'author' => (string)$module->author
540			)).', ';
541		
542		$autocompleteList = rtrim($autocompleteList, ' ,').'];';
543		// Display CSS Fancy Box
544		echo '<link href="'._PS_CSS_DIR_.'jquery.fancybox-1.3.4.css" rel="stylesheet" type="text/css" media="screen" />';
545		echo '<script type="text/javascript">'.$autocompleteList.'</script>';
546		$this->displayJavascript();
547		
548		echo '
549		<span onclick="$(\'#module_install\').slideToggle()" style="cursor:pointer"><img src="../img/admin/add.gif" alt="'.$this->l('Add a new module').'" class="middle" />
550			'.$this->l('Add a module from my computer').'
551		</span>
552		&nbsp;|&nbsp;';
553		if (@fsockopen('www.prestashop.com', 80))
554		echo '<a href="index.php?tab=AdminAddonsMyAccount&token='.Tools::getAdminTokenLite('AdminAddonsMyAccount').'">
555			<img src="https://addons.prestashop.com/modules.php?'.(isset($_SERVER['SERVER_ADDR']) ? 'server='.ip2long($_SERVER['SERVER_ADDR']).'&' : '').'mods='.$serialModules.'" alt="Add" class="middle" />
556			'.$this->l('Add a module from PrestaShop Addons').'
557		</a>';
558		echo '<form action="'.$currentIndex.'&token='.$this->token.'" method="post" id="filternameForm" style="float:right"><input type="text" name="filtername" value="'.Tools::htmlentitiesUTF8(Tools::getValue('filtername')).'" /> <input type="submit" value="'.$this->l('Search').'" class="button" /></form>
559		<div class="clear">&nbsp;</div>
560		<div id="module_install" style="width:900px; '.((Tools::isSubmit('submitDownload') OR Tools::isSubmit('submitDownload2')) ? '' : 'display: none;').'">
561			<fieldset>
562				<legend><img src="../img/admin/add.gif" alt="'.$this->l('Add a new module').'" class="middle" /> '.$this->l('Add a new module').'</legend>
563				<p>'.$this->l('The module must be either a zip file or a tarball.').'</p>
564				<hr />
565				<div style="float:right;margin-right:50px;border-left:solid 1px #DFD5C3">
566					<form action="'.$currentIndex.'&token='.$this->token.'" method="post" enctype="multipart/form-data">
567						<label style="width: 100px">'.$this->l('Module file').'</label>
568						<div class="margin-form" style="padding-left: 140px">
569							<input type="file" name="file" />
570							<p>'.$this->l('Upload the module from your computer.').'</p>
571						</div>
572						<div class="margin-form" style="padding-left: 140px">
573							<input type="submit" name="submitDownload2" value="'.$this->l('Upload this module').'" class="button" />
574						</div>
575					</form>
576				</div>
577				<div>
578				<form action="'.$currentIndex.'&token='.$this->token.'" method="post">
579					<label style="width: 100px">'.$this->l('Module URL').'</label>
580					<div class="margin-form" style="padding-left: 140px">
581						<input type="text" name="url" style="width: 200px;" value="'.(Tools::getValue('url') ? Tools::getValue('url') : 'http://').'" />
582						<p>'.$this->l('Download the module directly from a website.').'</p>
583					</div>
584					<div class="margin-form" style="padding-left: 140px">
585						<input type="submit" name="submitDownload" value="'.$this->l('Download this module').'" class="button" />
586					</div>
587				</form>
588				</div>
589			</fieldset>
590			<br />
591		</div>';
592		if (Configuration::get('PRESTASTORE_LIVE'))
593			echo '
594			<div id="prestastore" style="margin-left:40px; display:none; float: left" class="width1">
595			</div>';
596
597		/* Scan modules directories and load modules classes */
598		$warnings = array();
599		$orderModule = array();
600	    $irow = 0;
601		foreach ($modules AS $module)
602			$orderModule[(isset($module->tab) AND !empty($module->tab) AND array_key_exists(strval($module->tab), $this->listTabModules)) ? strval($module->tab) : 'others' ][] = $module;
603		uasort($orderModule,array('AdminModules', 'sortModule'));
604		
605		$concatWarning = array();
606		foreach ($orderModule AS $tabModule)
607			foreach ($tabModule AS $module)
608				if ($module->active AND $module->warning)
609					$warnings[] ='<a href="'.$currentIndex.'&configure='.urlencode($module->name).'&token='.$this->token.'">'.$module->displayName.'</a> - '.stripslashes(pSQL($module->warning));
610		$this->displayWarning($warnings);
611		echo '<form method="POST">
612			<table cellpadding="0" cellspacing="0" style="width:100%;;margin-bottom:5px;">
613				<tr>
614					<th style="border-right:solid 1px;border:inherit">
615						<span class="button" style="padding:0.4em;">
616							<a id="all_open" class="module_toggle_all" style="display:inherit;text-decoration:none;" href="#">
617								<span style="padding-right:0.5em">
618									<img src="../img/admin/more.png" alt="" />
619								</span>
620								<span id="all_open">'.$this->l('Open all tabs').'</span>
621							</a>
622							<a id="all_close" class="module_toggle_all" style="display:none;text-decoration:none;" href="#">
623								<span style="padding-right:0.5em">
624									<img src="../img/admin/less.png" alt="" />
625								</span>
626								<span id="all_open">'.$this->l('Close all tabs').'</span>
627							</a>
628						</span>
629					</th>
630					<th colspan="3" style="border:inherit">
631						<select name="module_type">
632							<option value="allModules" '.($showTypeModules == 'allModules' ? 'selected="selected"' : '').'>'.$this->l('All Modules').'</option>
633							<option value="nativeModules" '.($showTypeModules == 'nativeModules' ? 'selected="selected"' : '').'>'.$this->l('Native Modules').'</option>
634							<option value="partnerModules" '.($showTypeModules == 'partnerModules' ? 'selected="selected"' : '').'>'.$this->l('Partners Modules').'</option>'
635.$this->_buildModuleAuthorsOptGroup($modulesAuthors, 'authorModules')
636.'
637							<option value="otherModules" '.($showTypeModules == 'otherModules' ? 'selected="selected"' : '').'>'.$this->l('Others Modules').'</option>
638						</select>
639						&nbsp;
640						<select name="module_install">
641							<option value="installedUninstalled" '.($showInstalledModules == 'installedUninstalled' ? 'selected="selected"' : '').'>'.$this->l('Installed & Uninstalled').'</option>
642							<option value="installed" '.($showInstalledModules == 'installed' ? 'selected="selected"' : '').'>'.$this->l('Installed Modules').'</option>
643							<option value="unistalled" '.($showInstalledModules == 'unistalled' ? 'selected="selected"' : '').'>'.$this->l('Uninstalled Modules').'</option>
644						</select>
645						&nbsp;
646						<select name="module_status">
647							<option value="enabledDisabled" '.($showEnabledModules == 'enabledDisabled' ? 'selected="selected"' : '').'>'.$this->l('Enabled & Disabled').'</option>
648							<option value="enabled" '.($showEnabledModules == 'enabled' ? 'selected="selected"' : '').'>'.$this->l('Enabled Modules').'</option>
649							<option value="disabled" '.($showEnabledModules == 'disabled' ? 'selected="selected"' : '').'>'.$this->l('Disabled Modules').'</option>
650						</select>
651						&nbsp;
652						<select name="country_module_value">
653							<option value="0" >'.$this->l('All countries').'</option>
654							<option value="1" '.($showCountryModules == 1 ? 'selected="selected"' : '').'>'.$this->l('Current country:').' '.$nameCountryDefault.'</option>
655						</select>
656					</th>
657					<th style="border:inherit">
658						<div style="float:right">
659							<input type="submit" class="button" name="resetFilterModules" value="'.$this->l('Reset').'">
660							<input type="submit" class="button" name="filterModules" value="'.$this->l('Filter').'">
661						</div>
662					</th>
663			  	</tr>
664			</table>
665			</form>';
666		echo $this->displaySelectedFilter();
667		if ($tab_module = Tools::getValue('tab_module'))
668			if (array_key_exists($tab_module, $this->listTabModules))
669				$goto = $tab_module;
670			else
671				$goto = 'others';
672		else
673			$goto = false;
674			
675		echo '
676  		<script src="'.__PS_BASE_URI__.'js/jquery/jquery.scrollTo-1.4.2-min.js"></script>
677		<script>
678		 $(document).ready(function() {
679		 
680		 $(\'.header_module_toggle, .module_toggle_all\').unbind(\'click\').click(function(){
681		 	var id = $(this).attr(\'id\');
682			if (id == \'all_open\')
683				$(\'.tab_module_content\').each(function(){
684					$(this).slideDown();
685					$(\'#all_open\').hide();
686					$(\'#all_close\').show();
687					$(\'.header_module_img\').each(function(){
688						$(this).attr(\'src\', \'../img/admin/less.png\');
689					});
690				});
691			else if (id == \'all_close\')
692				$(\'.tab_module_content\').each(function(){
693					$(\'#all_open\').show();
694					$(\'#all_close\').hide();
695					$(this).slideUp();
696					$(\'.header_module_img\').each(function(){
697						$(this).attr(\'src\', \'../img/admin/more.png\');
698					});
699				});
700			else
701			{
702				if ($(\'#\'+id+\'_content\').css(\'display\') == \'none\')
703		 			$(\'#\'+id+\'_img\').attr(\'src\', \'../img/admin/less.png\');
704		 		else
705		 			$(\'#\'+id+\'_img\').attr(\'src\', \'../img/admin/more.png\');
706		 		
707		 		$(\'#\'+$(this).attr(\'id\')+\'_content\').slideToggle();
708		 	}
709		 	return false;
710		 });
711		'.(!$goto ? '': '$(\'#'.$goto.'_content\').slideToggle( function (){
712		$(\'#'.$goto.'_img\').attr(\'src\', \'../img/admin/less.png\');
713		'.(!$goto ? '' : '$.scrollTo($("#modgo_'.Tools::getValue('module_name').'"), 300 , 
714		{onAfter:function(){
715			$("#modgo_'.Tools::getValue('module_name').'").fadeTo(100, 0, function (){
716				$(this).fadeTo(100, 0, function (){
717					$(this).fadeTo(50, 1, function (){
718						$(this).fadeTo(50, 0, function (){
719							$(this).fadeTo(50, 1 )}
720								)}
721							)}
722						)}
723					)}
724				});').'
725		});').'
726		
727			});
728		 </script>';
729		if (!empty($orderModule))
730		{
731			/* Browse modules by tab type */
732			foreach ($orderModule AS $tab => $tabModule)
733			{
734				echo '
735				<div id="'.$tab.'" class="header_module">
736				<span class="nbr_module" style="width:100px;text-align:right">'.sizeof($tabModule).' '.((sizeof($tabModule) > 1) ? $this->l('modules') : $this->l('module')).'</span>
737					<a class="header_module_toggle" id="'.$tab.'" href="modgo_'.$tab.'" style="margin-left: 5px;">
738						<span style="padding-right:0.5em">
739						<img class="header_module_img" id="'.$tab.'_img" src="../img/admin/more.png" alt="" />
740						</span>'.$this->listTabModules[$tab].'</a> 
741				</div>
742				<div id="'.$tab.'_content" class="tab_module_content" style="display:none;border:solid 1px #CCC">';
743				/* Display modules for each tab type */
744				foreach ($tabModule as $module)
745				{
746					echo '<div id="modgo_'.$module->name.'" title="' . $module->name . '">';
747					if ($module->id)
748					{
749						$img = '<img src="../img/admin/module_install.png" alt="'.$this->l('Module enabled').'" title="'.$this->l('Module enabled').'" />';
750						if ($module->warning)
751							$img = '<img src="../img/admin/module_warning.png" alt="'.$this->l('Module installed but with warnings').'" title="'.$this->l('Module installed but with warnings').'" />';
752						if (!$module->active)
753							$img = '<img src="../img/admin/module_disabled.png" alt="'.$this->l('Module disabled').'" title="'.$this->l('Module disabled').'" />';
754					} else
755						$img = '<img src="../img/admin/module_notinstall.png" alt="'.$this->l('Module not installed').'" title="'.$this->l('Module not installed').'" />';
756					$disp_author = $this->_getDispAuthor($module->author);
757					$disp_author = (empty($disp_author)) ? '' :  ' '.$this->l('by').' <i>'.Tools::htmlentitiesUTF8($disp_author).'</i>';
758					echo '<table style="width:100%" cellpadding="0" cellspacing="0" >
759					<tr'.($irow % 2 ? ' class="alt_row"' : '').' style="height: 42px;">
760						<td style="padding-right: 10px;padding-left:10px;width:30px">
761							<input type="checkbox" name="modules" value="'.urlencode($module->name).'" '.(empty($module->confirmUninstall) ? 'rel="false"' : 'rel="'.addslashes($module->confirmUninstall).'"').' />
762						</td>
763						<td style="padding:2px 4px 2px 10px;width:500px"><img src="../modules/'.$module->name.'/logo.gif" alt="" /> <b>'.stripslashes($module->displayName).'</b>'.($module->version ? ' v'.$module->version.(strpos($module->version, '.') !== false ? '' : '.0') : '').$disp_author.'<br />'.stripslashes($module->description).'</td>
764						<td rowspan="2">';
765						if (Tools::getValue('module_name') == $module->name)
766							$this->displayConf();
767						echo '</td>
768						<td class="center" style="width:60px" rowspan="2">';
769					if ($module->id)
770						echo '<a href="'.$currentIndex.'&token='.$this->token.'&module_name='.$module->name.'&'.($module->active ? 'desactive' : 'active').'">';
771					echo $img;
772					if ($module->id)
773						'</a>';
774					$href = $currentIndex.'&uninstall='.urlencode($module->name).'&token='.$this->token.'&tab_module='.$module->tab.'&module_name='.$module->name;
775					echo '
776						</td>
777						<td class="center" width="120" rowspan="2">'.((!$module->id)
778						? '<input type="button" class="button small" name="Install" value="'.$this->l('Install').'"
779						onclick="javascript:document.location.href=\''.$currentIndex.'&install='.urlencode($module->name).'&token='.$this->token.'&tab_module='.$module->tab.'&module_name='.$module->name.'\'">'
780						: '<input type="button" class="button small" name="Uninstall" value="'.$this->l('Uninstall').'"
781						onclick="'.((!method_exists($module, 'onclickOption')) ? ((empty($module->confirmUninstall)) ? '' : 'if(confirm(\''.addslashes($module->confirmUninstall).'\')) ').'document.location.href=\''.$href.'\'' : $module->onclickOption('uninstall', $href)).'">').'</td>
782						
783					</tr>
784					<tr'.($irow++ % 2 ? ' class="alt_row"' : '').'>
785						<td style="padding-left:50px;padding-bottom:5px;padding-top:5px" colspan="2">'.$this->displayOptions($module).'</td>
786					</tr>
787					</table>
788					</div>';
789				}
790				echo '</div>';
791			}
792			echo '
793				<div style="margin-top: 12px; width:600px;">
794					<input type="button" class="button big" value="'.$this->l('Install the selection').'" onclick="modules_management(\'install\')"/>
795					<input type="button" class="button big" value="'.$this->l('Uninstall the selection').'" onclick="modules_management(\'uninstall\')" />
796				</div>
797				<br />
798				<table cellpadding="0" cellspacing="0" class="table" style="width:100%;">
799					<tr style="height:35px;background-color:#EEEEEE">
800						<td><strong>'.$this->l('Icon legend').' : </strong></td>
801						<td style="text-align:center;border-right:solid 1px gray"><img src="../img/admin/module_install.png" />&nbsp;&nbsp;'.$this->l('Module installed and enabled').'</td>
802						<td style="text-align:center;border-right:solid 1px gray"><img src="../img/admin/module_disabled.png" />&nbsp;&nbsp;'.$this->l('Module installed but disabled').'</td>
803						<td style="text-align:center;border-right:solid 1px gray"><img src="../img/admin/module_warning.png" />&nbsp;&nbsp;'.$this->l('Module installed but with warnings').'</td>
804						<td style="text-align:center"><img src="../img/admin/module_notinstall.png" />&nbsp;&nbsp;'.$this->l('Module not installed').'</td>
805					</tr>
806				</table>
807			<div style="clear:both">&nbsp;</div>';
808		}
809		else
810			echo '<table cellpadding="0" cellspacing="0" class="table" style="width:100%;"><tr><td align="center">'.$this->l('No module found').'</td></tr></table>';
811	}
812	
813	
814	public function recursiveDeleteOnDisk($dir)
815	{
816		if (strpos(realpath($dir), realpath(_PS_MODULE_DIR_)) === false)
817			return ;
818		if (is_dir($dir)) 
819		{
820			$objects = scandir($dir);
821			foreach ($objects as $object)
822				if ($object != "." && $object != "..")
823				{
824					if (filetype($dir."/".$object) == "dir")
825						$this->recursiveDeleteOnDisk($dir."/".$object);
826					else
827						unlink($dir."/".$object);
828				}
829			reset($objects);
830			rmdir($dir);
831		}
832	}
833	
834	public function displayOptions($module)
835	{
836		global $currentIndex;
837		$return = '';
838		$href = $currentIndex.'&token='.$this->token.'&module_name='.
839			urlencode($module->name).'&tab_module='.$module->tab;
840		
841		if ((int)($module->id))
842			$return .= '<a class="action_module" '.($module->active && method_exists($module, 'onclickOption')? 'onclick="'.$module->onclickOption('desactive', $href).'"' : '').' href="'.$currentIndex.'&token='.$this->token.'&module_name='.urlencode($module->name).'&'.($module->active ? 'desactive' : 'active').'&tab_module='.$module->tab.'&module_name='.urlencode($module->name).'">'.($module->active ? $this->l('Disable') : $this->l('Enable')).'</a>&nbsp;&nbsp;';
843		
844		if ((int)($module->id) AND $module->active)
845			$return .= '<a class="action_module" '.(method_exists($module, 'onclickOption')? 'onclick="'.$module->onclickOption('reset', $href).'"' : '').' href="'.$currentIndex.'&token='.$this->token.'&module_name='.urlencode($module->name).'&reset&tab_module='.$module->tab.'&module_name='.urlencode($module->name).'">'.$this->l('Reset').'</a>&nbsp;&nbsp;';
846		
847		if ((int)($module->id) AND (method_exists($module, 'getContent') OR (isset($module->is_configurable) AND (int)$module->is_configurable)))
848			$return .= '<a class="action_module" '.(method_exists($module, 'onclickOption')? 'onclick="'.$module->onclickOption('configure', $href).'"' : '').' href="'.$currentIndex.'&configure='.urlencode($module->name).'&token='.$this->token.'&tab_module='.$module->tab.'&module_name='.urlencode($module->name).'">'.$this->l('Configure').'</a>&nbsp;&nbsp;';
849			
850		$return .= '<a class="action_module" '.(method_exists($module, 'onclickOption')? 'onclick="'.$module->onclickOption('delete', $href).'"' : '').' onclick="return confirm(\''.$this->l('This action will permanently remove the module from the server. Are you sure you want to do this ?').'\');" href="'.$currentIndex.'&deleteModule='.urlencode($module->name).'&token='.$this->token.'&tab_module='.$module->tab.'&module_name='.urlencode($module->name).'">'.$this->l('Delete').'</a>&nbsp;&nbsp;';
851		
852		return $return;
853	}
854	
855	public function isFresh($timeout = 604800000)
856	{
857		if (file_exists($this->_moduleCacheFile))
858			return ((time() - filemtime($this->_moduleCacheFile)) < $timeout);
859		else
860			return false;
861	}
862	
863	public function refresh()
864	{
865		return file_put_contents($this->_moduleCacheFile, Tools::file_get_contents('http://www.prestashop.com/xml/modules_list.xml'));
866	}
867	
868	public function displaySelectedFilter()
869	{
870		global $cookie;
871		$selected_filter = '';
872		$id_employee = (int)($cookie->id_employee);
873		
874		$showTypeModules = Configuration::get('PS_SHOW_TYPE_MODULES_'.(int)($cookie->id_employee));
875		$showInstalledModules = Configuration::get('PS_SHOW_INSTALLED_MODULES_'.(int)($cookie->id_employee));
876		$showEnabledModules = Configuration::get('PS_SHOW_ENABLED_MODULES_'.(int)($cookie->id_employee));
877		$showCountryModules = Configuration::get('PS_SHOW_COUNTRY_MODULES_'.(int)($cookie->id_employee));
878		$selected_filter .= ($showTypeModules == 'allModules' ? $this->l('All Modules').' - ' : '').
879							($showTypeModules == 'nativeModules' ? $this->l('Native Modules').' - ' : '').
880							($showTypeModules == 'partnerModules' ? $this->l('Partners Modules').' - ' : '').
881							($showTypeModules == 'otherModules' ? $this->l('Others Modules').' - ' : '').
882							($showInstalledModules == 'installedUninstalled' ? $this->l('Installed & Uninstalled').' - ' : '').
883							($showInstalledModules == 'installed' ? $this->l('Installed Modules').' - ' : '').
884							($showInstalledModules == 'unistalled' ? $this->l('Uninstalled Modules').' - ' : '').
885							($showEnabledModules == 'enabledDisabled' ? $this->l('Enabled & Disabled').' - ' : '').
886							($showEnabledModules == 'enabled' ? $this->l('Enabled Modules').' - ' : '').
887							($showEnabledModules == 'disabled' ? $this->l('Disabled Modules').' - ' : '').
888							($showCountryModules === 1 ? $this->l('Current country:').' '.$nameCountryDefault.' - ' : '').
889							($showCountryModules === 0 ? $this->l('All countries').' - ' : '');
890
891		if (strlen($selected_filter) != 0)
892			$selected_filter = '<div class="hint" style="display:block;background:#DDE9F7 no-repeat 6px 5px url(../img/admin/filter.png);"><b>'.$this->l('Selected filters').' : </b>'.rtrim($selected_filter, ' - ').'</div>';
893		return $selected_filter;
894	}
895	
896	private function setFilterModules($module_type, $country_module_value, $module_install, $module_status)
897	{
898		global $cookie;
899		
900		Configuration::updateValue('PS_SHOW_TYPE_MODULES_'.(int)($cookie->id_employee), $module_type);
901		Configuration::updateValue('PS_SHOW_COUNTRY_MODULES_'.(int)($cookie->id_employee), $country_module_value);
902		Configuration::updateValue('PS_SHOW_INSTALLED_MODULES_'.(int)($cookie->id_employee), $module_install);
903		Configuration::updateValue('PS_SHOW_ENABLED_MODULES_'.(int)($cookie->id_employee), $module_status);
904	}
905	
906	private function resetFilterModules()
907	{
908		global $cookie;
909		
910		Configuration::updateValue('PS_SHOW_TYPE_MODULES_'.(int)($cookie->id_employee), 'allModules');
911		Configuration::updateValue('PS_SHOW_COUNTRY_MODULES_'.(int)($cookie->id_employee), 0);
912		Configuration::updateValue('PS_SHOW_INSTALLED_MODULES_'.(int)($cookie->id_employee), 'installedUninstalled');
913		Configuration::updateValue('PS_SHOW_ENABLED_MODULES_'.(int)($cookie->id_employee), 'enabledDisabled');
914	}
915	
916}
917
918