Beispiel #1
0
    /**
     * Return available modules
     *
     * @param boolean $useConfig in order to use config.xml file in module dir
     * @return array Modules
     */
    public static function getModulesOnDisk($useConfig = false, $loggedOnAddons = false, $id_employee = false)
    {
        global $_MODULES;
        // Init var
        $module_list = array();
        $module_name_list = array();
        $modulesNameToCursor = array();
        $errors = array();
        // Get modules directory list and memory limit
        $modules_dir = Module::getModulesDirOnDisk();
        $memory_limit = Tools::getMemoryLimit();
        $modules_installed = array();
        $result = Db::getInstance()->executeS('
		SELECT m.name, m.version, mp.interest
		FROM `' . _DB_PREFIX_ . 'module` m
		' . Shop::addSqlAssociation('module', 'm') . '
		LEFT JOIN `' . _DB_PREFIX_ . 'module_preference` mp ON (mp.`module` = m.`name` AND mp.`id_employee` = ' . (int) $id_employee . ')');
        foreach ($result as $row) {
            $modules_installed[$row['name']] = $row;
        }
        foreach ($modules_dir as $module) {
            // Memory usage checking
            if (function_exists('memory_get_usage') && $memory_limit != '-1') {
                $current_memory = memory_get_usage(true);
                // memory_threshold in MB
                $memory_threshold = Tools::isX86_64arch() ? 3 : 1.5;
                if ($memory_limit - $current_memory <= $memory_threshold * 1024 * 1024) {
                    $errors[] = Tools::displayError('All modules cannot be loaded due to memory limit restrictions, please increase your memory_limit value on your server configuration');
                    break;
                }
            }
            // Check if config.xml module file exists and if it's not outdated
            $configFile = _PS_MODULE_DIR_ . $module . '/config.xml';
            $xml_exist = file_exists($configFile);
            if ($xml_exist) {
                $needNewConfigFile = filemtime($configFile) < filemtime(_PS_MODULE_DIR_ . $module . '/' . $module . '.php');
            } else {
                $needNewConfigFile = true;
            }
            // If config.xml exists and that the use config flag is at true
            if ($useConfig && $xml_exist) {
                // Load config.xml
                libxml_use_internal_errors(true);
                $xml_module = simplexml_load_file($configFile);
                foreach (libxml_get_errors() as $error) {
                    $errors[] = '[' . $module . '] ' . Tools::displayError('Error found in config file:') . ' ' . htmlentities($error->message);
                }
                libxml_clear_errors();
                // If no errors in Xml, no need instand and no need new config.xml file, we load only translations
                if (!count($errors) && (int) $xml_module->need_instance == 0 && !$needNewConfigFile) {
                    $file = _PS_MODULE_DIR_ . $module . '/' . Context::getContext()->language->iso_code . '.php';
                    if (Tools::file_exists_cache($file) && (include_once $file)) {
                        if (isset($_MODULE) && is_array($_MODULE)) {
                            $_MODULES = !empty($_MODULES) ? array_merge($_MODULES, $_MODULE) : $_MODULE;
                        }
                    }
                    $item = new stdClass();
                    $item->id = 0;
                    $item->warning = '';
                    foreach ($xml_module as $k => $v) {
                        $item->{$k} = (string) $v;
                    }
                    $item->displayName = stripslashes(Translate::getModuleTranslation((string) $xml_module->name, Module::configXmlStringFormat($xml_module->displayName), (string) $xml_module->name));
                    $item->description = stripslashes(Translate::getModuleTranslation((string) $xml_module->name, Module::configXmlStringFormat($xml_module->description), (string) $xml_module->name));
                    $item->author = stripslashes(Translate::getModuleTranslation((string) $xml_module->name, Module::configXmlStringFormat($xml_module->author), (string) $xml_module->name));
                    if (isset($xml_module->confirmUninstall)) {
                        $item->confirmUninstall = Translate::getModuleTranslation((string) $xml_module->name, Module::configXmlStringFormat($xml_module->confirmUninstall), (string) $xml_module->name);
                    }
                    $item->active = 0;
                    $item->onclick_option = false;
                    $module_list[] = $item;
                    $module_name_list[] = '\'' . pSQL($item->name) . '\'';
                    $modulesNameToCursor[strval($item->name)] = $item;
                }
            }
            // If use config flag is at false or config.xml does not exist OR need instance OR need a new config.xml file
            if (!$useConfig || !$xml_exist || isset($xml_module->need_instance) && (int) $xml_module->need_instance == 1 || $needNewConfigFile) {
                // If class does not exists, we include the file
                if (!class_exists($module, false)) {
                    // Get content from php file
                    $filepath = _PS_MODULE_DIR_ . $module . '/' . $module . '.php';
                    $file = trim(file_get_contents(_PS_MODULE_DIR_ . $module . '/' . $module . '.php'));
                    if (substr($file, 0, 5) == '<?php') {
                        $file = substr($file, 5);
                    }
                    if (substr($file, -2) == '?>') {
                        $file = substr($file, 0, -2);
                    }
                    // If (false) is a trick to not load the class with "eval".
                    // This way require_once will works correctly
                    if (eval('if (false){	' . $file . ' }') !== false) {
                        require_once _PS_MODULE_DIR_ . $module . '/' . $module . '.php';
                    } else {
                        $errors[] = sprintf(Tools::displayError('%1$s (parse error in %2$s)'), $module, substr($filepath, strlen(_PS_ROOT_DIR_)));
                    }
                }
                // If class exists, we just instanciate it
                if (class_exists($module, false)) {
                    $tmp_module = new $module();
                    $item = new stdClass();
                    $item->id = $tmp_module->id;
                    $item->warning = $tmp_module->warning;
                    $item->name = $tmp_module->name;
                    $item->version = $tmp_module->version;
                    $item->tab = $tmp_module->tab;
                    $item->displayName = $tmp_module->displayName;
                    $item->description = stripslashes($tmp_module->description);
                    $item->author = $tmp_module->author;
                    $item->limited_countries = $tmp_module->limited_countries;
                    $item->parent_class = get_parent_class($module);
                    $item->is_configurable = $tmp_module->is_configurable = method_exists($tmp_module, 'getContent') ? 1 : 0;
                    $item->need_instance = isset($tmp_module->need_instance) ? $tmp_module->need_instance : 0;
                    $item->active = $tmp_module->active;
                    $item->currencies = isset($tmp_module->currencies) ? $tmp_module->currencies : null;
                    $item->currencies_mode = isset($tmp_module->currencies_mode) ? $tmp_module->currencies_mode : null;
                    $item->confirmUninstall = isset($tmp_module->confirmUninstall) ? $tmp_module->confirmUninstall : null;
                    $item->onclick_option = method_exists($module, 'onclickOption') ? true : false;
                    if ($item->onclick_option) {
                        $href = Context::getContext()->link->getAdminLink('Module', true) . '&module_name=' . $tmp_module->name . '&tab_module=' . $tmp_module->tab;
                        $item->onclick_option_content = array();
                        $option_tab = array('desactive', 'reset', 'configure', 'delete');
                        foreach ($option_tab as $opt) {
                            $item->onclick_option_content[$opt] = $tmp_module->onclickOption($opt, $href);
                        }
                    }
                    $module_list[] = $item;
                    if (!$xml_exist || $needNewConfigFile) {
                        self::$_generate_config_xml_mode = true;
                        $tmp_module->_generateConfigXml();
                        self::$_generate_config_xml_mode = false;
                    }
                    unset($tmp_module);
                } else {
                    $errors[] = sprintf(Tools::displayError('%1$s (class missing in %2$s)'), $module, substr($filepath, strlen(_PS_ROOT_DIR_)));
                }
            }
        }
        // Get modules information from database
        if (!empty($module_name_list)) {
            $list = Shop::getContextListShopID();
            $sql = 'SELECT m.id_module, m.name, (
						SELECT COUNT(*) FROM ' . _DB_PREFIX_ . 'module_shop ms WHERE m.id_module = ms.id_module AND ms.id_shop IN (' . implode(',', $list) . ')
					) as total
					FROM ' . _DB_PREFIX_ . 'module m
					WHERE m.name IN (' . implode(',', $module_name_list) . ')';
            $results = Db::getInstance()->executeS($sql);
            foreach ($results as $result) {
                $moduleCursor = $modulesNameToCursor[$result['name']];
                $moduleCursor->id = $result['id_module'];
                $moduleCursor->active = $result['total'] == count($list) ? 1 : 0;
            }
        }
        // Get Default Country Modules and customer module
        $files_list = array(array('type' => 'addonsNative', 'file' => _PS_ROOT_DIR_ . self::CACHE_FILE_DEFAULT_COUNTRY_MODULES_LIST, 'loggedOnAddons' => 0), array('type' => 'addonsBought', 'file' => _PS_ROOT_DIR_ . self::CACHE_FILE_CUSTOMER_MODULES_LIST, 'loggedOnAddons' => 1), array('type' => 'addonsMustHave', 'file' => _PS_ROOT_DIR_ . self::CACHE_FILE_MUST_HAVE_MODULES_LIST, 'loggedOnAddons' => 0));
        foreach ($files_list as $f) {
            if (file_exists($f['file']) && ($f['loggedOnAddons'] == 0 || $loggedOnAddons)) {
                $file = $f['file'];
                $content = Tools::file_get_contents($file);
                $xml = @simplexml_load_string($content, null, LIBXML_NOCDATA);
                if ($xml && isset($xml->module)) {
                    foreach ($xml->module as $modaddons) {
                        $flag_found = 0;
                        foreach ($module_list as $k => $m) {
                            if ($m->name == $modaddons->name && !isset($m->available_on_addons)) {
                                $flag_found = 1;
                                if ($m->version != $modaddons->version && version_compare($m->version, $modaddons->version) === -1) {
                                    $module_list[$k]->version_addons = $modaddons->version;
                                }
                            }
                        }
                        if ($flag_found == 0) {
                            $item = new stdClass();
                            $item->id = 0;
                            $item->warning = '';
                            $item->type = strip_tags((string) $f['type']);
                            $item->name = strip_tags((string) $modaddons->name);
                            $item->version = strip_tags((string) $modaddons->version);
                            $item->tab = strip_tags((string) $modaddons->tab);
                            $item->displayName = strip_tags((string) $modaddons->displayName) . ' (Addons)';
                            $item->description = stripslashes(strip_tags((string) $modaddons->description));
                            $item->author = strip_tags((string) $modaddons->author);
                            $item->limited_countries = array();
                            $item->parent_class = '';
                            $item->onclick_option = false;
                            $item->is_configurable = 0;
                            $item->need_instance = 0;
                            $item->not_on_disk = 1;
                            $item->available_on_addons = 1;
                            $item->active = 0;
                            if (isset($modaddons->img)) {
                                if (!file_exists(_PS_TMP_IMG_DIR_ . md5($modaddons->name) . '.jpg')) {
                                    if (!file_put_contents(_PS_TMP_IMG_DIR_ . md5($modaddons->name) . '.jpg', Tools::file_get_contents($modaddons->img))) {
                                        copy(_PS_IMG_DIR_ . '404.gif', _PS_TMP_IMG_DIR_ . md5($modaddons->name) . '.jpg');
                                    }
                                }
                                if (file_exists(_PS_TMP_IMG_DIR_ . md5($modaddons->name) . '.jpg')) {
                                    $item->image = '../img/tmp/' . md5($modaddons->name) . '.jpg';
                                }
                            }
                            if ($item->type == 'addonsMustHave') {
                                $item->addons_buy_url = strip_tags((string) $modaddons->url);
                                $prices = (array) $modaddons->price;
                                $id_default_currency = Configuration::get('PS_CURRENCY_DEFAULT');
                                foreach ($prices as $currency => $price) {
                                    if ($id_currency = Currency::getIdByIsoCode($currency)) {
                                        $item->price = (double) $price;
                                        $item->id_currency = (int) $id_currency;
                                        if ($id_default_currency == $id_currency) {
                                            break;
                                        }
                                    }
                                }
                            }
                            $module_list[] = $item;
                        }
                    }
                }
            }
        }
        foreach ($module_list as &$module) {
            if (isset($modules_installed[$module->name])) {
                $module->installed = true;
                $module->database_version = $modules_installed[$module->name]['version'];
                $module->interest = $modules_installed[$module->name]['interest'];
            } else {
                $module->installed = false;
                $module->database_version = 0;
                $module->interest = 0;
            }
        }
        usort($module_list, create_function('$a,$b', 'return strnatcasecmp($a->displayName, $b->displayName);'));
        if ($errors) {
            echo '<div class="alert error"><h3>' . Tools::displayError('The following module(s) could not be loaded') . ':</h3><ol>';
            foreach ($errors as $error) {
                echo '<li>' . $error . '</li>';
            }
            echo '</ol></div>';
        }
        return $module_list;
    }
Beispiel #2
0
 /**
  * Return available modules
  *
  * @param bool $use_config in order to use config.xml file in module dir
  * @return array Modules
  */
 public static function getModulesOnDisk($use_config = false, $logged_on_addons = false, $id_employee = false)
 {
     global $_MODULES;
     // Init var
     $module_list = array();
     $module_name_list = array();
     $modules_name_to_cursor = array();
     $errors = array();
     // Get modules directory list and memory limit
     $modules_dir = Module::getModulesDirOnDisk();
     $modules_installed = array();
     $result = Db::getInstance()->executeS('
     SELECT m.name, m.version, mp.interest, module_shop.enable_device
     FROM `' . _DB_PREFIX_ . 'module` m
     ' . Shop::addSqlAssociation('module', 'm') . '
     LEFT JOIN `' . _DB_PREFIX_ . 'module_preference` mp ON (mp.`module` = m.`name` AND mp.`id_employee` = ' . (int) $id_employee . ')');
     foreach ($result as $row) {
         $modules_installed[$row['name']] = $row;
     }
     foreach ($modules_dir as $module) {
         $module_errors = array();
         if (Module::useTooMuchMemory()) {
             $module_errors[] = Tools::displayError('All modules cannot be loaded due to memory limit restrictions, please increase your memory_limit value on your server configuration');
             break;
         }
         $iso = substr(Context::getContext()->language->iso_code, 0, 2);
         // Check if config.xml module file exists and if it's not outdated
         if ($iso == 'en') {
             $config_file = _PS_MODULE_DIR_ . $module . '/config.xml';
         } else {
             $config_file = _PS_MODULE_DIR_ . $module . '/config_' . $iso . '.xml';
         }
         $xml_exist = file_exists($config_file);
         $need_new_config_file = $xml_exist ? @filemtime($config_file) < @filemtime(_PS_MODULE_DIR_ . $module . '/' . $module . '.php') : true;
         // If config.xml exists and that the use config flag is at true
         if ($use_config && $xml_exist && !$need_new_config_file) {
             // Load config.xml
             libxml_use_internal_errors(true);
             $xml_module = @simplexml_load_file($config_file);
             if (!$xml_module) {
                 $module_errors[] = Tools::displayError(sprintf('%1s could not be loaded.', $config_file));
                 break;
             }
             foreach (libxml_get_errors() as $error) {
                 $module_errors[] = '[' . $module . '] ' . Tools::displayError('Error found in config file:') . ' ' . htmlentities($error->message);
             }
             libxml_clear_errors();
             // If no errors in Xml, no need instand and no need new config.xml file, we load only translations
             if (!count($module_errors) && (int) $xml_module->need_instance == 0) {
                 $file = _PS_MODULE_DIR_ . $module . '/' . Context::getContext()->language->iso_code . '.php';
                 if (Tools::file_exists_cache($file) && (include_once $file)) {
                     if (isset($_MODULE) && is_array($_MODULE)) {
                         $_MODULES = !empty($_MODULES) ? array_merge($_MODULES, $_MODULE) : $_MODULE;
                     }
                 }
                 $item = new stdClass();
                 $item->id = 0;
                 $item->warning = '';
                 foreach ($xml_module as $k => $v) {
                     $item->{$k} = (string) $v;
                 }
                 $item->displayName = stripslashes(Translate::getModuleTranslation((string) $xml_module->name, Module::configXmlStringFormat($xml_module->displayName), (string) $xml_module->name));
                 $item->description = stripslashes(Translate::getModuleTranslation((string) $xml_module->name, Module::configXmlStringFormat($xml_module->description), (string) $xml_module->name));
                 $item->author = stripslashes(Translate::getModuleTranslation((string) $xml_module->name, Module::configXmlStringFormat($xml_module->author), (string) $xml_module->name));
                 $item->author_uri = isset($xml_module->author_uri) && $xml_module->author_uri ? stripslashes($xml_module->author_uri) : false;
                 if (isset($xml_module->confirmUninstall)) {
                     $item->confirmUninstall = Translate::getModuleTranslation((string) $xml_module->name, html_entity_decode(Module::configXmlStringFormat($xml_module->confirmUninstall)), (string) $xml_module->name);
                 }
                 $item->active = 0;
                 $item->onclick_option = false;
                 $item->trusted = Module::isModuleTrusted($item->name);
                 $module_list[$item->name . '_disk'] = $item;
                 $module_name_list[] = '\'' . pSQL($item->name) . '\'';
                 $modules_name_to_cursor[Tools::strtolower(strval($item->name))] = $item;
             }
         }
         // If use config flag is at false or config.xml does not exist OR need instance OR need a new config.xml file
         if (!$use_config || !$xml_exist || isset($xml_module->need_instance) && (int) $xml_module->need_instance == 1 || $need_new_config_file) {
             // If class does not exists, we include the file
             if (!class_exists($module, false)) {
                 // Get content from php file
                 $file_path = _PS_MODULE_DIR_ . $module . '/' . $module . '.php';
                 $file = trim(file_get_contents(_PS_MODULE_DIR_ . $module . '/' . $module . '.php'));
                 if (substr($file, 0, 5) == '<?php') {
                     $file = substr($file, 5);
                 }
                 if (substr($file, -2) == '?>') {
                     $file = substr($file, 0, -2);
                 }
                 // We check any parse error before including the file.
                 // If (false) is a trick to not load the class with "eval".
                 // This way require_once will works correctly
                 // But namespace and use statements need to be removed
                 $content = preg_replace('/\\n[\\s\\t]*?use\\s.*?;/', '', $file);
                 $content = preg_replace('/\\n[\\s\\t]*?namespace\\s.*?;/', '', $content);
                 try {
                     if (substr(`php -l {$file_path}`, 0, 16) == 'No syntax errors' || eval('if (false){	' . $content . ' }') !== false) {
                         require_once _PS_MODULE_DIR_ . $module . '/' . $module . '.php';
                     } else {
                         throw new ParseError("Parse error");
                     }
                 } catch (ParseError $e) {
                     $errors[] = sprintf(Tools::displayError('%1$s (parse error in %2$s)'), $module, substr($file_path, strlen(_PS_ROOT_DIR_)));
                 }
                 preg_match('/\\n[\\s\\t]*?namespace\\s.*?;/', $file, $ns);
                 if (!empty($ns)) {
                     $ns = preg_replace('/\\n[\\s\\t]*?namespace\\s/', '', $ns[0]);
                     $ns = rtrim($ns, ';');
                     $module = $ns . '\\' . $module;
                 }
             }
             // If class exists, we just instanciate it
             if (class_exists($module, false)) {
                 try {
                     $tmp_module = \PrestaShop\PrestaShop\Adapter\ServiceLocator::get($module);
                     $item = new stdClass();
                     $item->id = (int) $tmp_module->id;
                     $item->warning = $tmp_module->warning;
                     $item->name = $tmp_module->name;
                     $item->version = $tmp_module->version;
                     $item->tab = $tmp_module->tab;
                     $item->displayName = $tmp_module->displayName;
                     $item->description = stripslashes($tmp_module->description);
                     $item->author = $tmp_module->author;
                     $item->author_uri = isset($tmp_module->author_uri) && $tmp_module->author_uri ? $tmp_module->author_uri : false;
                     $item->limited_countries = $tmp_module->limited_countries;
                     $item->parent_class = get_parent_class($module);
                     $item->is_configurable = $tmp_module->is_configurable = method_exists($tmp_module, 'getContent') ? 1 : 0;
                     $item->need_instance = isset($tmp_module->need_instance) ? $tmp_module->need_instance : 0;
                     $item->active = $tmp_module->active;
                     $item->trusted = Module::isModuleTrusted($tmp_module->name);
                     $item->currencies = isset($tmp_module->currencies) ? $tmp_module->currencies : null;
                     $item->currencies_mode = isset($tmp_module->currencies_mode) ? $tmp_module->currencies_mode : null;
                     $item->confirmUninstall = isset($tmp_module->confirmUninstall) ? html_entity_decode($tmp_module->confirmUninstall) : null;
                     $item->description_full = stripslashes($tmp_module->description_full);
                     $item->additional_description = isset($tmp_module->additional_description) ? stripslashes($tmp_module->additional_description) : null;
                     $item->compatibility = isset($tmp_module->compatibility) ? (array) $tmp_module->compatibility : null;
                     $item->nb_rates = isset($tmp_module->nb_rates) ? (array) $tmp_module->nb_rates : null;
                     $item->avg_rate = isset($tmp_module->avg_rate) ? (array) $tmp_module->avg_rate : null;
                     $item->badges = isset($tmp_module->badges) ? (array) $tmp_module->badges : null;
                     $item->url = isset($tmp_module->url) ? $tmp_module->url : null;
                     $item->onclick_option = method_exists($module, 'onclickOption') ? true : false;
                     if ($item->onclick_option) {
                         $href = Context::getContext()->link->getAdminLink('Module', true) . '&module_name=' . $tmp_module->name . '&tab_module=' . $tmp_module->tab;
                         $item->onclick_option_content = array();
                         $option_tab = array('desactive', 'reset', 'configure', 'delete');
                         foreach ($option_tab as $opt) {
                             $item->onclick_option_content[$opt] = $tmp_module->onclickOption($opt, $href);
                         }
                     }
                     $module_list[$item->name . '_disk'] = $item;
                     if (!$xml_exist || $need_new_config_file) {
                         self::$_generate_config_xml_mode = true;
                         $tmp_module->_generateConfigXml();
                         self::$_generate_config_xml_mode = false;
                     }
                     unset($tmp_module);
                 } catch (Exception $e) {
                 }
             } else {
                 $module_errors[] = sprintf(Tools::displayError('%1$s (class missing in %2$s)'), $module, substr($file_path, strlen(_PS_ROOT_DIR_)));
             }
         }
         $errors = array_merge($errors, $module_errors);
     }
     // Get modules information from database
     if (!empty($module_name_list)) {
         $list = Shop::getContextListShopID();
         $sql = 'SELECT m.id_module, m.name, (
                     SELECT COUNT(*) FROM ' . _DB_PREFIX_ . 'module_shop ms WHERE m.id_module = ms.id_module AND ms.id_shop IN (' . implode(',', $list) . ')
                 ) as total
                 FROM ' . _DB_PREFIX_ . 'module m
                 WHERE LOWER(m.name) IN (' . Tools::strtolower(implode(',', $module_name_list)) . ')';
         $results = Db::getInstance()->executeS($sql);
         foreach ($results as $result) {
             if (isset($modules_name_to_cursor[Tools::strtolower($result['name'])])) {
                 $module_cursor = $modules_name_to_cursor[Tools::strtolower($result['name'])];
                 $module_cursor->id = (int) $result['id_module'];
                 $module_cursor->active = $result['total'] == count($list) ? 1 : 0;
             }
         }
     }
     // Get Default Country Modules and customer module
     $files_list = array(array('type' => 'addonsNative', 'file' => _PS_ROOT_DIR_ . self::CACHE_FILE_DEFAULT_COUNTRY_MODULES_LIST, 'loggedOnAddons' => 0), array('type' => 'addonsMustHave', 'file' => _PS_ROOT_DIR_ . self::CACHE_FILE_MUST_HAVE_MODULES_LIST, 'loggedOnAddons' => 0), array('type' => 'addonsBought', 'file' => _PS_ROOT_DIR_ . self::CACHE_FILE_CUSTOMER_MODULES_LIST, 'loggedOnAddons' => 1));
     foreach ($files_list as $f) {
         if (file_exists($f['file']) && ($f['loggedOnAddons'] == 0 || $logged_on_addons)) {
             if (Module::useTooMuchMemory()) {
                 $errors[] = Tools::displayError('All modules cannot be loaded due to memory limit restrictions, please increase your memory_limit value on your server configuration');
                 break;
             }
             $file = $f['file'];
             $content = Tools::file_get_contents($file);
             $xml = @simplexml_load_string($content, null, LIBXML_NOCDATA);
             if ($xml && isset($xml->module)) {
                 foreach ($xml->module as $modaddons) {
                     $flag_found = 0;
                     foreach ($module_list as $k => &$m) {
                         if (Tools::strtolower($m->name) == Tools::strtolower($modaddons->name) && !isset($m->available_on_addons)) {
                             $flag_found = 1;
                             if ($m->version != $modaddons->version && version_compare($m->version, $modaddons->version) === -1) {
                                 $module_list[$k]->version_addons = $modaddons->version;
                             }
                         }
                     }
                     if ($flag_found == 0) {
                         $item = new stdClass();
                         $item->id = 0;
                         $item->warning = '';
                         $item->type = strip_tags((string) $f['type']);
                         $item->name = strip_tags((string) $modaddons->name);
                         $item->version = strip_tags((string) $modaddons->version);
                         $item->tab = strip_tags((string) $modaddons->tab);
                         $item->displayName = strip_tags((string) $modaddons->displayName);
                         $item->description = stripslashes(strip_tags((string) $modaddons->description));
                         $item->description_full = stripslashes(strip_tags((string) $modaddons->description_full));
                         $item->author = strip_tags((string) $modaddons->author);
                         $item->limited_countries = array();
                         $item->parent_class = '';
                         $item->onclick_option = false;
                         $item->is_configurable = 0;
                         $item->need_instance = 0;
                         $item->not_on_disk = 1;
                         $item->available_on_addons = 1;
                         $item->trusted = Module::isModuleTrusted($item->name);
                         $item->active = 0;
                         $item->description_full = stripslashes($modaddons->description_full);
                         $item->additional_description = isset($modaddons->additional_description) ? stripslashes($modaddons->additional_description) : null;
                         $item->compatibility = isset($modaddons->compatibility) ? (array) $modaddons->compatibility : null;
                         $item->nb_rates = isset($modaddons->nb_rates) ? (array) $modaddons->nb_rates : null;
                         $item->avg_rate = isset($modaddons->avg_rate) ? (array) $modaddons->avg_rate : null;
                         $item->badges = isset($modaddons->badges) ? (array) $modaddons->badges : null;
                         $item->url = isset($modaddons->url) ? $modaddons->url : null;
                         if (isset($item->description_full) && trim($item->description_full) != '') {
                             $item->show_quick_view = true;
                         }
                         if (isset($modaddons->img)) {
                             $item->image = Module::copyModAddonsImg($modaddons);
                         }
                         if ($item->type == 'addonsMustHave') {
                             $item->addons_buy_url = strip_tags((string) $modaddons->url);
                             $prices = (array) $modaddons->price;
                             $id_default_currency = Configuration::get('PS_CURRENCY_DEFAULT');
                             foreach ($prices as $currency => $price) {
                                 if ($id_currency = Currency::getIdByIsoCode($currency)) {
                                     $item->price = (double) $price;
                                     $item->id_currency = (int) $id_currency;
                                     if ($id_default_currency == $id_currency) {
                                         break;
                                     }
                                 }
                             }
                         }
                         $module_list[$item->name . '_feed'] = $item;
                     }
                     if (isset($module_list[$modaddons->name . '_disk'])) {
                         $module_list[$modaddons->name . '_disk']->description_full = stripslashes(strip_tags((string) $modaddons->description_full));
                         $module_list[$modaddons->name . '_disk']->additional_description = stripslashes(strip_tags((string) $modaddons->additional_description));
                         $module_list[$modaddons->name . '_disk']->image = Module::copyModAddonsImg($modaddons);
                         $module_list[$modaddons->name . '_disk']->show_quick_view = true;
                     }
                 }
             }
         }
     }
     foreach ($module_list as $key => &$module) {
         if (defined('_PS_HOST_MODE_') && in_array($module->name, self::$hosted_modules_blacklist)) {
             unset($module_list[$key]);
         } elseif (isset($modules_installed[$module->name])) {
             $module->installed = true;
             $module->database_version = $modules_installed[$module->name]['version'];
             $module->interest = $modules_installed[$module->name]['interest'];
             $module->enable_device = $modules_installed[$module->name]['enable_device'];
         } else {
             $module->installed = false;
             $module->database_version = 0;
             $module->interest = 0;
         }
     }
     usort($module_list, create_function('$a,$b', 'return strnatcasecmp($a->displayName, $b->displayName);'));
     if ($errors) {
         if (!isset(Context::getContext()->controller) && !Context::getContext()->controller->controller_name) {
             echo '<div class="alert error"><h3>' . Tools::displayError('The following module(s) could not be loaded') . ':</h3><ol>';
             foreach ($errors as $error) {
                 echo '<li>' . $error . '</li>';
             }
             echo '</ol></div>';
         } else {
             foreach ($errors as $error) {
                 Context::getContext()->controller->errors[] = $error;
             }
         }
     }
     return $module_list;
 }