public function execute()
 {
     $update_counter = 0;
     $model = new waAppSettingsModel();
     $license = $model->get('webasyst', 'license', false);
     $apps = new waInstallerApps($license);
     $app_list = array();
     $this->view->assign('error', false);
     try {
         $app_list = $apps->getApplicationsList(false, array(), wa()->getDataPath('images', true));
         $update_counter = waInstallerApps::getUpdateCount($app_list);
         $model->ping();
     } catch (Exception $ex) {
         //$this->view->assign('error', $ex->getMessage());
     }
     $this->redirect(array('module' => $update_counter ? 'update' : 'apps'));
     $this->view->assign('module', false);
 }
 public function execute()
 {
     try {
         $path_cache = waConfig::get('wa_path_cache');
         waFiles::delete($path_cache, true);
         waFiles::protect($path_cache);
         $app_path = waConfig::get('wa_path_apps');
         $apps = new waInstallerApps();
         $app_list = $apps->getApplicationsList(true);
         foreach ($app_list as $app) {
             if (isset($app['enabled']) && $app['enabled']) {
                 $path_cache = $app_path . '/' . $app['slug'] . '/js/compiled';
                 waFiles::delete($path_cache, true);
             }
         }
         $this->response['message'] = _w('Cache cleared');
     } catch (Exception $ex) {
         $this->setError($ex->getMessage());
     }
 }
 public function onCount()
 {
     $args = func_get_args();
     $force = array_shift($args);
     $model = new waAppSettingsModel();
     $app_id = $this->getApplication();
     $update_counter = null;
     if ($force || time() - $model->get($app_id, 'update_counter_timestamp', 0) > 600 || is_null($update_counter = $model->get($app_id, 'update_counter', null))) {
         $license = $model->get('webasyst', 'license', false);
         $apps = new waInstallerApps($license, null, 600, $force);
         $app_list = $apps->getApplicationsList(false);
         $update_counter = waInstallerApps::getUpdateCount($app_list);
         $messages = '';
         installerHelper::getSystemPlugins($messages, $update_counter);
         $model->ping();
         $model->set($app_id, 'update_counter', $update_counter);
         $model->set($app_id, 'update_counter_timestamp', time());
     } elseif (is_null($update_counter)) {
         $update_counter = $model->get($app_id, 'update_counter');
     }
     return $update_counter ? $update_counter : null;
 }
Example #4
0
 public function execute()
 {
     $params = waRequest::param();
     $installer = new waInstallerApps();
     $list = $installer->getVersions();
     //TODO check it
     $fields = array();
     if (isset($params['full'])) {
         $fields = array('vendor' => 'Vendor ID', 'version' => 'Version', 'id' => 'Application ID');
     }
     $apps = array();
     foreach ($list as $item) {
         if (!empty($item['enabled']) && !empty($item['installed'])) {
             if ($id = ifset($item['installed']['id'])) {
                 $apps[$id] = array();
                 foreach ($fields as $field => $name) {
                     $apps[$id][$field] = ifset($item['installed'][$field]);
                 }
             }
         }
     }
     switch (waRequest::param('format')) {
         case 'tsv':
             $separator = "\t";
             break;
         case 'csv':
         default:
             $separator = ",";
             break;
     }
     if ($fields) {
         print implode($separator, $fields) . "\n";
         foreach ($apps as $data) {
             print implode($separator, $data) . "\n";
         }
     } else {
         print implode($separator, array_keys($apps)) . "\n";
     }
 }
 public function __construct($license = null, $locale = null, $ttl = 600, $force = false)
 {
     $this->license = $license;
     $this->identity_hash = self::getGenericConfig('identity_hash');
     if (!$this->identity_hash) {
         $this->updateGenericConfig();
         $this->identity_hash = self::getGenericConfig('identity_hash');
     }
     self::setLocale($locale);
     self::$cache_ttl = max(0, $ttl);
     self::$force = $force;
     if (file_exists(self::$root_path . self::CONFIG_APPS)) {
         $this->installed_apps = (include self::$root_path . self::CONFIG_APPS);
         foreach ($this->installed_apps as $app_id => &$enabled) {
             if ($enabled) {
                 $this->installed_extras[$app_id] = array();
                 $this->installed_extras[$app_id]['plugins'] = self::getConfig(sprintf(self::CONFIG_APP_PLUGINS, $app_id));
                 $this->installed_extras[$app_id]['themes'] = self::getItems(sprintf(self::ITEM_EXTRAS_PATH, $app_id, 'themes'));
                 $build_path = self::$root_path . sprintf(self::ITEM_BUILD, $app_id);
                 if (file_exists($build_path)) {
                     $enabled = max(1, include $build_path);
                 } else {
                     $enabled = 1;
                 }
             }
             unset($enabled);
         }
     }
     if (file_exists(self::$root_path . self::CONFIG_SOURCES)) {
         $this->sources = (include self::$root_path . self::CONFIG_SOURCES);
     }
     //TODO USE config or etc
     $this->extras_list['plugins'] = array('info' => 'plugin', 'subpath' => 'lib/config/');
     $this->extras_list['themes'] = array('info' => 'theme', 'subpath' => '');
 }
 public function execute()
 {
     $installer = new waInstallerApps();
     print $installer->getHash();
 }
Example #7
0
     //allow store settings
     if (!file_exists($init_path)) {
         throw new Exception("File <b>wa-installer/lib/init.php</b> not found");
     }
     require_once $init_path;
     if (!class_exists('waInstallerApps')) {
         throw new Exception('Class <b>waInstallerApps</b> not found');
     }
     if (mysql_query('SELECT 1 FROM `wa_app_settings` WHERE 0')) {
         throw new Exception($t->_('Webasyst cannot be installed into "%s" database because this database already contains Webasyst tables. Please specify connection credentials for another MySQL database.', $db_options['database']));
     } elseif ($result = mysql_query('SHOW TABLES')) {
         if ($count = mysql_num_rows($result)) {
             $warning = $t->_('The database already contains %d tables.', $count);
         }
     }
     $installer_apps = new waInstallerApps();
     if (extension_loaded('mysqli')) {
         $db_options['type'] = 'mysqli';
     } else {
         $db_options['type'] = 'mysql';
     }
     if (strpos($db_options['host'], ':')) {
         $db_options['port'] = '';
         list($db_options['host'], $db_options['port']) = explode(':', $db_options['host'], 2);
     }
     $installer_apps->updateDbConfig($db_options);
     mysql_close($link);
     $installer_apps->setGenericOptions($_POST['config']);
     $checked = true;
 } else {
     $error_text = mysql_error($link);
 public function execute()
 {
     $module = 'update';
     $url = parse_url(waRequest::server('HTTP_REFERER'), PHP_URL_QUERY);
     if (preg_match('/(^|&)module=(update|apps|plugins)($|&)/', $url, $matches)) {
         $module = $matches[2];
     }
     try {
         $updater = new waInstaller(waInstaller::LOG_TRACE);
         $state = $updater->getState();
         if (!isset($state['stage_status']) || $state['stage_name'] != waInstaller::STAGE_NONE && $state['heartbeat'] > waInstaller::TIMEOUT_RESUME + 5 || $state['stage_name'] == waInstaller::STAGE_UPDATE && $state['heartbeat'] || $state['stage_status'] == waInstaller::STATE_ERROR && $state['heartbeat'] || $state['stage_name'] == waInstaller::STAGE_NONE && $state['heartbeat'] === false) {
             $updater->setState();
             $this->view->assign('action', 'update');
             $app_ids = waRequest::request('app_id');
             $default_info = array('vendor' => waInstallerApps::VENDOR_SELF, 'edition' => '');
             $vendors = array();
             if ($app_ids && is_array($app_ids)) {
                 foreach ($app_ids as $app_id => &$info) {
                     if (!is_array($info)) {
                         if (strpos($info, ':') === false) {
                             $vendor = $info;
                             $edition = '';
                         } else {
                             list($vendor, $edition) = explode(':', $info, 2);
                         }
                         $info = array('vendor' => $vendor, 'edition' => $edition);
                     } else {
                         $info = array_merge($info, $default_info);
                     }
                     $vendors[] = $info['vendor'];
                     unset($info);
                 }
             } else {
                 $app_ids = array();
             }
             $vendors = array_unique($vendors);
             if (!$vendors) {
                 $vendors = array();
             }
             $model = new waAppSettingsModel();
             $license = $model->get('webasyst', 'license', false);
             $locale = wa()->getLocale();
             $apps = new waInstallerApps($license, $locale);
             $app_list = $vendors ? $apps->getApplicationsList(false, $vendors) : array();
             $model->ping();
             $queue_apps = array();
             foreach ($app_list as &$info) {
                 $app_id = $info['slug'];
                 if ($app_id == 'installer') {
                     $info['name'] = _w('Webasyst Framework');
                 }
                 if (isset($app_ids[$app_id])) {
                     if (installerHelper::equals($app_ids[$app_id], $info)) {
                         $queue_apps[] = $info;
                     }
                 }
                 if (!empty($info['extras'])) {
                     foreach ($info['extras'] as $type => &$extras) {
                         foreach ($extras as $extra_id => &$extras_info) {
                             $extras_id = $extras_info['slug'];
                             $extras_info['name'] .= " ({$info['name']})";
                             if (isset($app_ids[$extras_id]) && installerHelper::equals($app_ids[$extras_id], $extras_info)) {
                                 $queue_apps[] = $extras_info;
                             }
                         }
                         unset($extras_info);
                     }
                     unset($extras);
                 }
                 unset($info);
             }
             $system_list = $apps->getSystemList();
             foreach ($system_list as $item) {
                 if (!empty($item['subject']) && $item['subject'] == 'systemplugins' && isset($app_ids[$item['slug']])) {
                     $queue_apps[] = $item;
                 }
             }
             if (!$queue_apps) {
                 throw new waException(_w('Please select items for update'));
             }
             $this->view->assign('queue_apps', $queue_apps);
             $this->view->assign('apps', $app_list);
             $this->view->assign('install', waRequest::request('install'));
             $this->view->assign('title', _w('Updates'));
         } else {
             $this->redirect(array('module' => $module, 'msg' => installerMessage::getInstance()->raiseMessage(_w('Update is already in progress. Please wait while previous update session is finished before starting update session again.'), 'fail')));
         }
     } catch (Exception $ex) {
         $this->redirect(array('module' => $module, 'msg' => installerMessage::getInstance()->raiseMessage($ex->getMessage(), installerMessage::R_FAIL)));
     }
 }
 private function deleteApp($app_id)
 {
     //remove db tables and etc
     $paths = array();
     /**
      * @var waAppConfig
      */
     $system = wa($app_id);
     $system->setActive($app_id);
     $app = SystemConfig::getAppConfig($app_id);
     $info = $app->getInfo();
     $name = _wd($app_id, $info['name']);
     /**
      * @var waAppConfig $config ;
      */
     $config = $system->getConfig();
     if (!empty($info['plugins'])) {
         $plugins = $config->getPlugins();
         foreach ($plugins as $plugin => $enabled) {
             try {
                 if ($enabled && ($plugin_instance = $system->getPlugin($plugin))) {
                     $plugin_instance->uninstall();
                 }
             } catch (Exception $ex) {
                 waLog::log($ex->getMessage(), 'installer.log');
             }
             $this->apps->updateAppPluginsConfig($app_id, $plugin, null);
             //wa-apps/$app_id/plugins/$slug
             $paths[] = wa()->getAppPath("plugins/" . $plugin, $app_id);
             while ($path = array_shift($paths)) {
                 waFiles::delete($path, true);
             }
             $paths = array();
         }
     }
     $config->uninstall();
     $this->apps->updateAppConfig($app_id, null);
     $paths[] = wa()->getTempPath(null, $app_id);
     //wa-cache/temp/$app_id/
     $paths[] = wa()->getAppCachePath(null, $app_id);
     //wa-cache/apps/$app_id/
     $paths[] = wa()->getDataPath(null, true, $app_id);
     //wa-data/public/$app_id/
     $paths[] = wa()->getDataPath(null, false, $app_id);
     //wa-data/protected/$app_id/
     if ($this->options['log']) {
         $paths[] = wa()->getConfig()->getPath('log') . '/' . $app_id;
         //wa-log/$app_id/
     }
     if ($this->options['config']) {
         $paths[] = wa()->getConfigPath($app_id);
         //wa-config/$app_id/
     }
     $paths[] = wa()->getAppPath(null, $app_id);
     //wa-apps/$app_id/
     $paths[] = wa()->getAppCachePath(null, 'webasyst');
     //wa-cache/apps/webasyst/
     foreach ($paths as $path) {
         try {
             waFiles::delete($path, true);
         } catch (waException $ex) {
         }
     }
     return $name;
 }
 function execute()
 {
     $module = 'apps';
     $url = parse_url(waRequest::server('HTTP_REFERER'), PHP_URL_QUERY);
     if (preg_match('/(^|&)module=(update|apps|plugins)($|&)/', $url, $matches)) {
         $module = $matches[2];
     }
     $app_ids = waRequest::get('app_id');
     try {
         if (!$app_ids || !is_array($app_ids)) {
             throw new waException(_w('Application not found'));
         }
         $vendors = array();
         foreach ($app_ids as $app_id => &$info) {
             if (!is_array($info)) {
                 $info = array('vendor' => $info);
             }
             $vendors[] = $info['vendor'];
             unset($info);
         }
         $vendors = array_unique($vendors);
         $apps = new waInstallerApps();
         $app_list = $apps->getApplicationsList(true, $vendors);
         $deleted_apps = array();
         if (installerHelper::isDeveloper()) {
             throw new waException(_w('Unable to delete application (developer version is on)'));
         }
         foreach ($app_list as $info) {
             $app_id = $info['slug'];
             if (isset($app_ids[$app_id]) && $app_ids[$app_id]['vendor'] == $info['vendor']) {
                 if (isset($info['system']) && $info['system']) {
                     throw new waException(sprintf(_w('Can not delete system application "%s"'), $info['name']));
                 }
                 $apps->updateRoutingConfig($app_id, false);
                 $apps->updateAppConfig($app_id, null);
                 //remove db tables and etc
                 $paths = array();
                 $app_instance = waSystem::getInstance($app_id);
                 $plugins = $app_instance->getConfig()->getPlugins();
                 foreach ($plugins as $plugin_id => $plugin) {
                     if ($plugin && ($plugin_instance = $app_instance->getPlugin($plugin_id))) {
                         $plugin_instance->uninstall();
                     }
                     $apps->updateAppPluginsConfig($app_id, $plugin_id, null);
                     //wa-apps/$app_id/plugins/$slug
                     $paths[] = wa()->getAppPath("plugins/{$plugin_id}", $app_id);
                     foreach ($paths as $path) {
                         waFiles::delete($path, true);
                     }
                     $paths = array();
                 }
                 $app_instance->getConfig()->uninstall();
                 //XXX called at uninstall
                 //$paths[] = wa()->getAppCachePath(null, $app_id);//wa-cache/apps/$app_id/
                 $paths[] = wa()->getTempPath(null, $app_id);
                 //wa-cache/temp/$app_id/
                 $paths[] = wa()->getAppCachePath(null, $app_id);
                 //wa-cache/apps/$app_id/
                 $paths[] = wa()->getDataPath(null, true, $app_id);
                 //wa-data/public/$app_id/
                 $paths[] = wa()->getDataPath(null, false, $app_id);
                 //wa-data/protected/$app_id/
                 //XXX uncomplete code
                 //$paths[] = wa()->   null, false, $app_id);//wa-log/$app_id/
                 //XXX uncomplete code
                 //$paths[] = wa()->getAppPath(null, $app_id);//wa-config/$app_id/
                 $paths[] = wa()->getAppPath(null, $app_id);
                 //wa-apps/$app_id/
                 foreach ($paths as $path) {
                     waFiles::delete($path, true);
                 }
                 $deleted_apps[] = $info['name'];
             }
         }
         if (!$deleted_apps) {
             throw new waException(_w('Application not found'));
         }
         $message = _w('Application %s has been deleted', 'Applications %s have been deleted', min(2, count($deleted_apps)), false);
         $message = sprintf($message, implode(', ', $deleted_apps));
         $msg = installerMessage::getInstance()->raiseMessage($message);
         $this->redirect(array('module' => $module, 'msg' => $msg));
     } catch (Exception $ex) {
         $msg = installerMessage::getInstance()->raiseMessage($ex->getMessage(), installerMessage::R_FAIL);
         $this->redirect(array('module' => $module, 'msg' => $msg));
     }
 }
 public function execute()
 {
     $this->init();
     $extras_ids = waRequest::post('extras_id');
     try {
         /*
         _w('Application themes not found');
         _w('Application plugins not found');
         */
         foreach ($extras_ids as &$info) {
             if (!is_array($info)) {
                 $info = array('vendor' => $info);
             }
             unset($info);
         }
         $options = array('installed' => true, 'local' => true);
         if ($this->extras_type == 'plugins') {
             $options['system'] = true;
         }
         $this->installer = installerHelper::getInstaller();
         $app_list = $this->installer->getItems($options);
         $queue = array();
         foreach ($extras_ids as $slug => $info) {
             $slug_chunks = explode('/', $slug);
             if ($slug_chunks[0] == 'wa-plugins') {
                 $app_id = $slug_chunks[0] . '/' . $slug_chunks[1];
             } else {
                 $app_id = reset($slug_chunks);
             }
             if (isset($app_list[$app_id]) || $slug_chunks == 'wa-plugins') {
                 $app = $app_list[$app_id];
                 if (($installed = $this->installer->getItemInfo($slug, $options)) && $info['vendor'] == $installed['vendor']) {
                     if (!empty($installed['installed']['system'])) {
                         /*
                         _w("Can not delete system application's themes \"%s\"");
                         _w("Can not delete system application's plugins \"%s\"");
                         */
                         $message = "Can not delete system application's {$this->extras_type} \"%s\"";
                         throw new waException(sprintf(_w($message), _wd($slug, isset($info['name']) ? $info['name'] : '???')));
                     }
                     $queue[] = array('app_slug' => $app_id, 'ext_id' => $installed['id'], 'name' => sprintf("%s (%s)", _wd($slug, $installed['installed']['name']), _wd($app_id, $app['name'])));
                     unset($extras_ids[$slug]);
                 }
             }
         }
         $deleted_extras = array();
         foreach ($queue as $q) {
             if ($this->removeExtras($q['app_slug'], $q['ext_id'])) {
                 $deleted_extras[] = $q['name'];
             }
         }
         if (!$deleted_extras) {
             $message = sprintf('Application %s not found', $this->extras_type);
             throw new waException(_w($message));
         }
         /*
         _w('Application plugin %s has been deleted', 'Applications plugins %s have been deleted');
         _w('Application theme %s has been deleted', 'Applications themes %s have been deleted');
         */
         $message_singular = sprintf('Application %s %%s has been deleted', preg_replace('/s$/', '', $this->extras_type));
         $message_plural = sprintf('Applications %a %%s have been deleted', $this->extras_type);
         $message = sprintf(_w($message_singular, $message_plural, count($deleted_extras), false), implode(', ', $deleted_extras));
         $msg = installerMessage::getInstance()->raiseMessage($message);
         $this->redirect('?msg=' . $msg . '#/' . $this->extras_type . '/');
     } catch (Exception $ex) {
         $msg = installerMessage::getInstance()->raiseMessage($ex->getMessage(), installerMessage::R_FAIL);
         $this->redirect('?msg=' . $msg . '#/' . $this->extras_type . '/');
     }
 }
Example #12
0
 private function downloadStandard($source, $temporary_path)
 {
     $source_stream = null;
     $target_stream = null;
     $md5 = null;
     try {
         $this->writeLog(__METHOD__ . ' :download via fopen', self::LOG_TRACE);
         /**
          * @var integer describe download file size
          */
         $content_length = 0;
         $target = null;
         //TODO calculate estimated time / speed
         //TODO allow resume downloading
         $name = md5(preg_replace('/(\\?.*$)/', '', $source));
         $default_socket_timeout = @ini_set('default_socket_timeout', self::TIMEOUT_SOCKET);
         //TODO use file_exists for local sources
         $source_stream = @fopen($source, 'r');
         @ini_set('default_socket_timeout', $default_socket_timeout);
         if (!$source_stream) {
             $hint = 'for details see update log;';
             if (preg_match('@^([a-z\\.]+)://@', $source, $matches)) {
                 $wrappers = stream_get_wrappers();
                 if (!in_array($matches[1], $wrappers)) {
                     $hint .= " Stream {$matches[1]} not supported;";
                 }
             }
             if (preg_match('@^https?://@', $source) && !ini_get('allow_url_fopen')) {
                 $hint .= " PHP ini option 'allow_url_fopen' are disabled;";
             }
             if (!empty($http_response_header)) {
                 foreach ($http_response_header as $header) {
                     if (preg_match('@^status:\\s+(\\d+)\\s+(.+)$@i', $header, $matches)) {
                         $hint .= " {$matches[1]} {$matches[2]}";
                         $hint .= self::getHintByStatus($matches[1]);
                         break;
                     }
                 }
             }
             throw new Exception("Error while opening source stream [{$source}]. Hint: {$hint}");
         } elseif (!empty($http_response_header)) {
             //XXX ????
             foreach ($http_response_header as $header) {
                 $this->writeLog(__METHOD__, self::LOG_DEBUG, $header);
                 if (preg_match('@^X-license:\\s+(\\w+)$@i', $header, $matches)) {
                     waInstallerApps::setGenericOptions(array('license_key' => $matches[1]));
                 } elseif (preg_match('@^Content-MD5:\\s+(.+)$@i', $header, $matches)) {
                     if (preg_match('@^[0-9A-F]{32}$@', $matches[1])) {
                         $md5 = strtolower($matches[1]);
                     } elseif ($matches = unpack('H*', base64_decode($matches[1]))) {
                         if (preg_match('@^[0-9A-F]{32}$@i', $matches[1])) {
                             $md5 = strtolower($matches[1]);
                         }
                     }
                 }
             }
         }
         $this->setState();
         if (stream_is_local($source_stream)) {
             fclose($source_stream);
             $target = $source;
             $this->writeLog(__METHOD__ . ' :Source file is local', self::LOG_TRACE, $target);
         } else {
             //TODO check target path rights
             $target = self::formatPath(self::$root_path . $temporary_path . '/' . $name . '');
             $this->mkdir($temporary_path);
             $target_stream = @fopen($target, 'wb');
             if (!$target_stream) {
                 throw new Exception("Error while write temporal download file {$target}");
             }
             $this->writeLog(__METHOD__ . ' :Source file is distant', self::LOG_TRACE, array('source' => $source, 'target' => $target));
             //{{Read source properties
             list($content_length, $download_content_length, $buf) = $this->getStreamInfo($source_stream);
             //}}Read source properties
             $this->setState(array('stage_value' => $content_length, 'stage_current_value' => $download_content_length));
             if ($buf) {
                 fwrite($target_stream, $buf);
             }
             $download_chunk_size = max($content_length ? ceil($content_length / 10240000) * 102400 : 102400, 102400);
             $retry_counter = 0;
             while (($delta = stream_copy_to_stream($source_stream, $target_stream, $download_chunk_size)) || $content_length && $download_content_length < $content_length && ++$retry_counter < 20 || !$content_length && ++$retry_counter < 3) {
                 if ($delta) {
                     $download_content_length += $delta;
                     if ($retry_counter) {
                         $this->writeLog(__METHOD__ . ' complete server data transfer', self::LOG_TRACE, compact('content_length', 'download_content_length', 'retry_counter', 'delta'));
                         $retry_counter = 0;
                     }
                 } else {
                     $this->writeLog(__METHOD__ . ' wait server data transfer', self::LOG_TRACE, compact('content_length', 'download_content_length', 'retry_counter', 'delta'));
                     sleep(3);
                 }
                 $performance = $this->setState(array('stage_current_value' => $download_content_length, 'debug' => $download_chunk_size));
                 //adjust download chunk size
                 //MAX = 8Mb/s MIN = 100Kb/s step 10Kb
                 $download_chunk_size = $this->adjustStageChunk($download_chunk_size, $performance, __FUNCTION__, 10240, 102400, 8388608);
             }
             fclose($source_stream);
             fclose($target_stream);
         }
         return array($target, $content_length, $md5);
     } catch (Exception $ex) {
         //write state and error message
         if ($source_stream && is_resource($source_stream)) {
             fclose($source_stream);
         }
         if ($target_stream && is_resource($target_stream)) {
             fclose($target_stream);
         }
         throw $ex;
     }
 }
 public static function getSystemPlugins(&$messages, &$update_counter = null, $filter = array())
 {
     if ($update_counter !== null) {
         $update_counter = is_array($update_counter) ? array_merge(array_fill_keys(array('total', 'applicable', 'payware'), 0), $update_counter) : intval($update_counter);
     }
     $items = self::getInstaller()->getSystemList();
     $types = array();
     $icons = array('sms' => 'icon16 mobile', 'payment' => 'icon16 dollar', 'shipping' => 'icon16 box');
     $translate = array('sms' => _w('SMS'), 'payment' => _w('Payment'), 'shipping' => _w('Shipping'));
     foreach ($items as $id => $item) {
         if (!empty($item['subject']) && $item['subject'] == 'systemplugins') {
             $t = $item['type_slug'];
             if (empty($types[$t])) {
                 $types[$t] = array('name' => isset($translate[$t]) ? $translate[$t] : null, 'icon' => isset($icons[$t]) ? $icons[$t] : null, 'plugins' => array());
             }
             $types[$t]['plugins'][$item['id']] = $item;
         }
     }
     $minimize = is_array($update_counter) ? true : false;
     foreach ($types as &$items) {
         if ($update_counter !== null) {
             $update_counter = waInstallerApps::getUpdateCount($items['plugins'], $minimize, $update_counter);
             self::$model->ping();
         }
     }
     self::$model->ping();
     unset($items);
     return $types;
 }
 function execute()
 {
     if (!$this->extras_type && preg_match('/^installer(\\w+)RemoveAction$/', get_class($this), $matches)) {
         $this->extras_type = strtolower($matches[1]);
     }
     $module = $this->extras_type;
     $url = parse_url(waRequest::server('HTTP_REFERER'), PHP_URL_QUERY);
     if (preg_match("/(^|&)module=(update|apps| {\n            {$this->extras_type}})(\$|&)/", $url, $matches)) {
         $module = $matches[2];
     }
     $extras_ids = waRequest::get('extras_id');
     try {
         /*
         _w('Application themes not found');
         _w('Application plugins not found');
         */
         //$message =  sprintf('Application %s not found', $this->extras_type);
         //throw new waException(_w($message));
         if (installerHelper::isDeveloper()) {
             /*
             _w("Unable to delete application's themes (developer version is on)");
             _w("Unable to delete application's plugins (developer version is on)");
             */
             $message = "Unable to delete application's {$this->extras_type} (developer version is on)";
             throw new waException(_w($message));
         }
         $vendors = array();
         foreach ($extras_ids as $extras_id => &$info) {
             if (!is_array($info)) {
                 $info = array('vendor' => $info);
             }
             $vendors[] = $info['vendor'];
             unset($info);
         }
         $vendors = array_unique($vendors);
         $locale = wa()->getLocale();
         $this->installer = new waInstallerApps(null, $locale);
         $app_list = $this->installer->getApplicationsList(true);
         $deleted_extras = array();
         foreach ($app_list as $app) {
             if (isset($app['extras']) && $app['extras'] && isset($app['extras'][$this->extras_type]) && $app['extras'][$this->extras_type]) {
                 foreach ($app['extras'][$this->extras_type] as $extras_id => $info) {
                     $slug = $info['slug'];
                     if (isset($extras_ids[$slug]) && $extras_ids[$slug]['vendor'] == $info['current']['vendor']) {
                         if (isset($info['system']) && $info['system']) {
                             /*
                             _w("Can not delete system application's themes \"%s\"");
                             _w("Can not delete system application's plugins \"%s\"");
                             */
                             $message = "Can not delete system application's {$this->extras_type} \"%s\"";
                             throw new waException(sprintf(_w($message), $info['name']));
                         }
                         if ($this->removeExtras($app['slug'], $extras_id, $info)) {
                             $deleted_extras[] = "{$info['name']} ({$app['name']})";
                         }
                         unset($extras_ids[$slug]);
                     }
                 }
             }
         }
         foreach ($extras_ids as $slug => $data) {
             if (preg_match('@^wa-plugins/([^/]+/[^/]+)$@', $slug, $matches)) {
                 $path = wa()->getConfig()->getPath('plugins') . '/' . $matches[1];
                 $info_path = $path . '/lib/config/plugin.php';
                 if (file_exists($info_path) && ($info = (include $info_path))) {
                     waFiles::delete($path, true);
                     $deleted_extras[] = empty($info['name']) ? $matches[1] : $info['name'];
                 }
             }
         }
         if (!$deleted_extras) {
             $message = sprintf('Application %s not found', $this->extras_type);
             throw new waException(_w($message));
         }
         /*
         _w('Application plugin %s has been deleted', 'Applications plugins %s have been deleted');
         _w('Application theme %s has been deleted', 'Applications themes %s have been deleted');
         */
         $message_singular = sprintf('Application %s %%s has been deleted', preg_replace('/s$/', '', $this->extras_type));
         $message_plural = sprintf('Applications %a %%s have been deleted', $this->extras_type);
         $message = sprintf(_w($message_singular, $message_plural, count($deleted_extras), false), implode(', ', $deleted_extras));
         $msg = installerMessage::getInstance()->raiseMessage($message);
         $this->redirect(array('module' => $module, 'msg' => $msg));
     } catch (Exception $ex) {
         $msg = installerMessage::getInstance()->raiseMessage($ex->getMessage(), installerMessage::R_FAIL);
         $this->redirect(array('module' => $module, 'msg' => $msg));
     }
 }
 function execute()
 {
     $update_ids = waRequest::get('app_id');
     if ($update_ids && is_array($update_ids)) {
         ob_start();
         $app_ids = array();
         $plugins_ids = array();
         $vendors = array();
         foreach ($update_ids as $app_id => &$info) {
             if (!is_array($info)) {
                 if (strpos($info, ':') === false) {
                     $vendor = $info;
                     $edition = '';
                 } else {
                     list($vendor, $edition) = explode(':', $info, 2);
                 }
                 $app_ids[$app_id] = array('vendor' => $info, 'slug' => $app_id);
             } else {
                 if (isset($info['slug'])) {
                     $app_id = $info['slug'];
                 }
                 $app_ids[$app_id] = $info;
             }
             $vendors[] = $info['vendor'];
             unset($info);
         }
         $vendors = array_unique($vendors);
         $model = new waAppSettingsModel();
         $license = $model->get('webasyst', 'license', false);
         $locale = wa()->getLocale();
         try {
             $log_level = waSystemConfig::isDebug() ? waInstaller::LOG_DEBUG : waInstaller::LOG_WARNING;
             $thread_id = $this->getRequest()->request('thread_id', false);
             $updater = new waInstaller($log_level, $thread_id);
             $this->getStorage()->close();
             $updater->init();
             $apps = new waInstallerApps($license, $locale, false);
             $app = $this->getApp();
             if (isset($app_ids[$app]) || true) {
                 $system_list = $apps->getSystemList();
             }
             if (isset($app_ids[$app])) {
                 #update system items
                 foreach ($system_list as $target => $item) {
                     if (empty($item['subject'])) {
                         $this->add(!empty($item['target']) ? $item['target'] : $item['slug'], $item);
                     }
                 }
             }
             foreach ($system_list as $target => $item) {
                 if (!empty($item['subject']) && $item['subject'] == 'systemplugins' && isset($app_ids[$item['slug']])) {
                     $this->add(!empty($item['target']) ? $item['target'] : $item['slug'], $item, $item['slug']);
                     unset($app_ids[$item['slug']]);
                 }
             }
             $app_list = $apps->getApplicationsList(false, $vendors, wa()->getDataPath('images', true));
             $model->ping();
             $this->pass = count($this->urls) || count($app_ids) > 1 ? true : false;
             $added = true;
             $execute_actions = array(waInstallerApps::ACTION_INSTALL, waInstallerApps::ACTION_CRITICAL_UPDATE, waInstallerApps::ACTION_UPDATE);
             while ($app_ids && $added) {
                 $added = false;
                 foreach ($app_list as &$info) {
                     $app_id = $info['slug'];
                     if ($app_id == 'installer') {
                         $info['name'] = _w('Webasyst Framework');
                     }
                     if (isset($app_ids[$app_id]) && installerHelper::equals($app_ids[$app_id], $info)) {
                         $target = 'wa-apps/' . $app_id;
                         $info['subject'] = 'app';
                         $this->add($target, $info, $app_id);
                         unset($app_ids[$app_id]);
                     }
                     if (isset($info['extras']) && is_array($info['extras'])) {
                         foreach ($info['extras'] as $subject => $extras) {
                             foreach ($extras as $extras_id => $extras_info) {
                                 $extras_id = $app_id . '/' . $subject . '/' . $extras_id;
                                 if (isset($app_ids[$extras_id]) && installerHelper::equals($app_ids[$extras_id], $extras_info)) {
                                     if (!empty($app_ids[$extras_id]['dependent']) && (empty($extras_info['action']) || !in_array($extras_info['action'], $execute_actions))) {
                                         continue;
                                     }
                                     $target = 'wa-apps/' . $extras_id;
                                     $extras_info['subject'] = 'app_' . $subject;
                                     $this->add($target, $extras_info, $extras_info['slug']);
                                     if ($extras_info['dependency']) {
                                         foreach ($extras_info['dependency'] as $dependency) {
                                             $app_ids[$dependency] = $app_ids[$extras_id];
                                             $app_ids[$dependency]['slug'] = $dependency;
                                             $app_ids[$dependency]['dependent'] = $target;
                                             $added = true;
                                         }
                                     }
                                     if ($subject == 'themes') {
                                         if (!empty($extras_info['current']['parent_theme_id'])) {
                                             $parent_id = $extras_info['current']['parent_theme_id'];
                                             $parent_app_id = $app_id;
                                             if (strpos($parent_id, ':')) {
                                                 list($parent_app_id, $parent_id) = explode(':', $parent_id);
                                             }
                                             $dependency = "{$parent_app_id}/{$subject}/{$parent_id}";
                                             $app_ids[$dependency] = $app_ids[$extras_id];
                                             $app_ids[$dependency]['slug'] = $dependency;
                                             $app_ids[$dependency]['dependent'] = $target;
                                             $added = true;
                                         }
                                     }
                                     unset($app_ids[$extras_id]);
                                 }
                             }
                         }
                     }
                 }
                 unset($info);
             }
             $storage = wa()->getStorage();
             $storage->close();
             $result_urls = $updater->update($this->urls);
             if (waRequest::get('install')) {
                 $model->ping();
                 $user = $this->getUser();
                 $set_rights = false;
                 if (!$user->isAdmin()) {
                     $set_rights = true;
                 }
                 foreach ($this->urls as $target => $url) {
                     //TODO workaround exceptions
                     if ((!isset($url['skipped']) || !$url['skipped']) && preg_match('@^wa-apps@', $target)) {
                         $apps->installWebAsystItem($url['slug'], null, isset($url['edition']) ? $url['edition'] : true);
                         if ($set_rights) {
                             $user->setRight($url['slug'], 'backend', 2);
                         }
                     }
                 }
             }
             $secure_properties = array('archive', 'source', 'backup', 'md5', 'extract_path');
             foreach ($result_urls as &$result_url) {
                 foreach ($secure_properties as $property) {
                     if (isset($result_url[$property])) {
                         unset($result_url[$property]);
                     }
                 }
                 unset($result_url);
             }
             $this->response['sources'] = $result_urls;
             $this->response['current_state'] = $updater->getState();
             $this->response['state'] = $updater->getFullState(waRequest::get('mode', 'apps'));
             //cleanup cache
             //waFiles::delete(wa()->getAppCachePath(null, false), true);
             $path_cache = waConfig::get('wa_path_cache');
             waFiles::delete($path_cache, true);
             waFiles::protect($path_cache);
             $root_path = waConfig::get('wa_path_root');
             foreach ($this->urls as $url) {
                 if (!isset($url['skipped']) || !$url['skipped']) {
                     $path_cache = $root_path . '/' . $url['target'] . '/js/compiled';
                     waFiles::delete($path_cache, true);
                 }
             }
             $model->ping();
             $this->getConfig()->setCount(false);
             $response = $this->getResponse();
             $response->addHeader('Content-Type', 'application/json; charset=utf-8');
             $response->sendHeaders();
         } catch (Exception $ex) {
             $this->setError($ex->getMessage());
         }
         if ($ob = ob_get_clean()) {
             $this->response['warning'] = $ob;
             waLog::log('Output at ' . __METHOD__ . ': ' . $ob);
         }
     } else {
         throw new Exception('nothing to update');
     }
 }