public function execute() { if ($this->thread_id = waRequest::get('thread_id', false)) { $cache = new waSerializeCache($this->getApp() . '.' . $this->thread_id); $this->urls = $cache->get(); $cache->delete(); } if ($this->urls) { wa()->getStorage()->close(); ob_start(); try { $this->model = new waAppSettingsModel(); $log_level = waSystemConfig::isDebug() ? waInstaller::LOG_DEBUG : waInstaller::LOG_WARNING; $updater = new waInstaller($log_level, $this->thread_id); $this->getStorage()->close(); $updater->init(); $this->model->ping(); $storage = wa()->getStorage(); $storage->close(); $this->urls = $updater->update($this->urls); if (waRequest::request('install')) { $this->install(); } $this->response['sources'] = $this->getResult(); $this->response['current_state'] = $updater->getState(); $this->response['state'] = $updater->getFullState(waRequest::get('mode', 'apps')); //cleanup cache $this->cleanup(); //update themes foreach ($this->urls as $url) { if (preg_match('@(wa-apps/)?(.+)/themes/(.+)@', $url['slug'], $matches)) { try { $theme = new waTheme($matches[3], $matches[2]); $theme->update(); } catch (Exception $ex) { waLog::log(sprintf('Error during theme %s@%s update: %s', $matches[3], $matches[2], $ex->getMessage())); } } } //and again cleanup $this->cleanup(); $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'); } }
/** * * Render html block 'stack-navigation-panel' with json-data for RIA UI * * @param array $stack. Array of photos * @param array $current_photo. Array represented current photo * * @return string $html rendered html with 'photo-stream-cache' json data for RIA UI */ public function getStackNavigationPanel($stack, $current_photo) { $theme_url = $this->theme->getUrl(); $current = 0; $count = count($stack); $prev_in_stack = null; $next_in_stack = null; foreach ($stack as $photo) { if ($photo['id'] == $current_photo['id']) { if ($current > 0) { $prev_in_stack = $stack[$current - 1]; //$prev_in_stack['url'] = str_replace('%url%', $prev_in_stack['url'], $url_template); } if ($current < $count - 1) { $next_in_stack = $stack[$current + 1]; //$next_in_stack['url'] = str_replace('%url%', $next_in_stack['url'], $url_template); } break; } $current++; } $offset = $current + 1; $html = "<div class='stack-nav' data-photo-id='{$current_photo['id']}'>"; $html .= ' <a href="' . ($prev_in_stack ? isset($prev_in_stack['full_url']) ? $prev_in_stack['full_url'] : $prev_in_stack['url'] : 'javascript:void(0);') . '" class="rewind"><img src="' . $theme_url . 'img/stack-rewind.png"></a>'; $html .= " <strong class='offset'>{$offset}</strong> / {$count}"; $html .= ' <a href="' . ($next_in_stack ? isset($next_in_stack['full_url']) ? $next_in_stack['full_url'] : $next_in_stack['url'] : 'javascript:void(0);') . '" class="ff"><img src="' . $theme_url . 'img/stack-ff.png"></a>'; // hidden stack-stream with class thumb need for rich gradual loading photo effect when go next/prev photo in stack $html .= ' <ul class="photostream" style="display:none;">'; for ($i = 0; $i < $count; ++$i) { $html .= " <li data-photo-id='{$stack[$i]['id']}' " . ($i == $current ? 'class="selected"' : '') . ">"; $html .= " <a href='{$stack[$i]['url']}'><img class='thumb' src='{$stack[$i]['thumb']['url']}" . (!is_null($stack[$i]['edit_datetime']) ? '?' . strtotime($stack[$i]['edit_datetime']) : '') . "'></a>"; $html .= " </li>"; } $html .= ' </ul>'; $html .= '</div>'; $html .= '<script>'; $html .= ' var __photo_stack_data = __photo_stack_data || {};'; $html .= " __photo_stack_data['{$current_photo['id']}'] = " . json_encode($stack); $html .= '</script>'; return $html; }
public function update($only_if_not_modified = true) { if (!$this->path_custom || $this->type != self::OVERRIDDEN) { return true; } $files = $this->getFiles(); $modified = array(); foreach ($files as $f_id => $f) { if (!empty($f['modified'])) { $modified[] = $f_id; break; } } if ($only_if_not_modified && $modified) { return false; } $img_files = array(); foreach ($this->getSettings() as $s) { if (ifset($s['control_type']) == 'image' && !empty($s['value'])) { $img_files[] = $s['value']; } } $source_path = $this->path_original; $target_path = $this->path_custom; $list_files = waFiles::listdir($source_path); $skip_pattern = '/\\.(files\\.md5|cvs|svn|git|php\\d*)$/'; foreach ($list_files as $f) { // ignore files if ($f !== 'build.php') { foreach ((array) $skip_pattern as $pattern) { if (preg_match($pattern, $f)) { continue 2; } } } // ignore image settings and modified if ($f == 'theme.xml' || in_array($f, $img_files) || in_array($f, $modified)) { continue; } try { waFiles::copy($source_path . '/' . $f, $target_path . '/' . $f); } catch (waException $e) { } } if ($this->type == self::OVERRIDDEN) { $theme_original = new waTheme($this->id, $this->app_id, self::ORIGINAL); $this->version = $theme_original->version; foreach ($theme_original->getFiles(true) as $f_id => $f) { if (empty($files[$f_id])) { $this->setFiles(array($f_id => $f)); } } foreach ($theme_original->getSettings('full') as $var => $s) { if (!isset($this->info['settings'][$var])) { $this->info['settings'][$var] = $s; $this->settings[$var]['value'] = ifset($s['value'], ''); $this->changed['settings'][$var] = true; } else { $old_s = $this->info['settings'][$var]; if (ifset($old_s['control_type']) != ifset($s['control_type']) || ifset($old_s['options']) != ifset($s['options'])) { $s['value'] = ifset($old_s['value'], ''); $this->info['settings'][$var] = $s; $this->settings[$var]['value'] = $s['value']; $this->changed['settings'][$var] = true; } } } $this->save(); } return true; }
/** * @param string $theme_id * @return string */ public function themeUrl($theme_id) { $app_id = $this->wa->getConfig()->getApplication(); $theme = new waTheme($theme_id, $app_id); return $theme->path ? $theme->getUrl() : null; }
public function viewOriginalAction() { $theme_id = waRequest::get('theme_id'); $template = $this->getConfig()->getRootPath() . '/wa-system/design/templates/DesignViewOriginal.html'; $file = array(); if ($theme_id && ($f = waRequest::get('file'))) { $app_id = $this->getAppId(); $theme = new waTheme($theme_id, $app_id); $file = $theme->getFile($f); if ($file['parent']) { $theme = $theme->parent_theme; $theme_id = $theme->id; $app_id = $theme->app_id; } $theme_path = wa()->getAppPath('themes/' . $theme_id, $app_id) . '/'; $path = $theme_path . $f; if ($theme['type'] == waTheme::OVERRIDDEN && file_exists($path)) { $file = $theme->getFile($f); $file['id'] = $f; $file['content'] = file_get_contents($path); $file['theme_path'] = str_replace(wa()->getConfig()->getRootPath(), '', $theme_path); } } $this->display(array('file' => $file), $template); }
/** * Set template directory and global valiables. * * @param waTheme $theme Instance of theme object * @param string $template Path to template or resource string specifying template * @return bool */ public function setThemeTemplate($theme, $template) { $this->assign('wa_active_theme_path', $theme->path); $this->assign('wa_active_theme_url', $this->getStaticUrl($theme->url)); $theme_settings = $theme->getSettings(true); $theme_settings_config = $theme->getSettings(); $locales = $theme->getLocales(); $version = $theme->version(true); $file = $theme->getFile($template); if ($parent_theme = $theme->parent_theme) { $edition = $theme->edition + $parent_theme->edition; if (!empty($file['parent'])) { if ($parent_theme->version($edition) > $version) { $version = $parent_theme->version($edition); } else { $version = $theme->version($edition); } $theme = $parent_theme; } $this->assign('wa_parent_theme_url', $this->getStaticUrl($parent_theme->url)); $this->assign('wa_parent_theme_path', $parent_theme->path); if ($parent_settings = $parent_theme->getSettings(true)) { $theme_settings = $theme_settings + $parent_settings; foreach ($parent_theme->getSettings() as $k => $v) { if (!isset($theme_settings_config[$k])) { $v['parent'] = 1; $theme_settings_config[$k] = $v; } } } if ($parent_theme->getLocales()) { $locales += $parent_theme->getLocales(); } } $this->assign('wa_theme_version', $version); waLocale::setStrings($locales); $this->assign('theme_settings', $theme_settings); $this->assign('theme_settings_config', $theme_settings_config); $this->assign('wa_theme_url', $this->getStaticUrl($theme->url)); $this->assign('wa_real_theme_url', $theme->url); $this->setTemplateDir($theme->path); return file_exists($theme->path . '/' . $template); }
/** * @param string $theme_id * @return array */ public function themeSettings($theme_id) { $app_id = $this->wa->getConfig()->getApplication(); $theme = new waTheme($theme_id, $app_id); return $theme->getSettings(true); }
protected function create($app_id, $path, $params = array()) { if (!file_exists($path)) { $path .= '/'; mkdir($path); mkdir($path . 'css'); touch($path . 'css/' . $app_id . '.css'); mkdir($path . 'js'); touch($path . 'js/' . $app_id . '.js'); mkdir($path . 'img'); // lib mkdir($path . 'lib'); waFiles::protect($path . 'lib'); mkdir($path . 'lib/actions'); // backend controller mkdir($path . 'lib/actions/backend'); // api if (isset($params['api'])) { mkdir($path . 'lib/api'); if ($params['api'] !== true) { mkdir($path . 'lib/api/' . $params['api']); } } // cli if (isset($params['cli'])) { mkdir($path . 'lib/cli'); } mkdir($path . 'lib/classes'); mkdir($path . 'lib/models'); // config mkdir($path . 'lib/config'); // app description $app = array('name' => empty($params['name']) ? ucfirst($app_id) : $params['name'], 'icon' => 'img/' . $app_id . '.gif', 'version' => $version = empty($params['version']) ? '0.1' : $params['version']); if (isset($params['frontend'])) { $app['frontend'] = true; if (isset($params['themes'])) { $app['themes'] = true; } $routing = array('*' => 'frontend'); waUtils::varExportToFile($routing, $path . 'lib/config/routing.php'); // frontend controller mkdir($path . 'lib/actions/frontend'); } // plugins if (isset($params['plugins'])) { $app['plugins'] = true; mkdir($path . 'plugins'); } waUtils::varExportToFile($app, $path . 'lib/config/app.php'); // templates mkdir($path . 'templates'); waFiles::protect($path . 'templates'); mkdir($path . 'templates/actions'); mkdir($path . 'templates/actions/backend'); // backend template if (isset($params['frontend'])) { // frontend template mkdir($path . 'templates/actions/frontend'); } // locale mkdir($path . 'locale'); if (isset($params['frontend']) && isset($params['themes'])) { // themes mkdir($path . 'themes'); mkdir($path . 'themes/default'); $theme = new waTheme('default', $app_id, true); $theme->name = 'Default theme'; $theme->description = 'Auto generated default theme'; $theme->system = 1; $theme->addFile('index.html', 'Frontend index file'); touch($path . 'themes/default/index.html'); $theme->addFile('default.css', 'Frontend CSS file'); touch($path . 'themes/default/default.css'); $theme->version = $version; $theme->save(); } print "App with id {$app_id} created"; } else { print "App with id {$app_id} already exists"; } }
/** * @param waTheme $theme * @param string $template * @return bool */ public function setThemeTemplate($theme, $template) { $this->assign('wa_active_theme_path', $theme->path); $this->assign('wa_active_theme_url', $theme->url); $file = $theme->getFile($template); if ($parent_theme = $theme->parent_theme) { if ($file['parent']) { $theme = $parent_theme; } else { $this->assign('wa_parent_theme_url', $parent_theme->url); } } $this->assign('wa_theme_url', $theme->url); $this->setTemplateDir($theme->path); return file_exists($theme->path . '/' . $template); }
protected function create($app_id, $path, $params = array()) { $report = ''; if (!file_exists($path)) { $path .= '/'; mkdir($path); mkdir($path . 'css'); touch($path . 'css/' . $app_id . '.css'); mkdir($path . 'js'); touch($path . 'js/' . $app_id . '.js'); mkdir($path . 'img'); // lib mkdir($path . 'lib'); waFiles::protect($path . 'lib'); mkdir($path . 'lib/actions'); // backend controller mkdir($path . 'lib/actions/backend'); // api if (isset($params['api'])) { mkdir($path . 'lib/api'); if ($params['api'] !== true) { mkdir($path . 'lib/api/' . $params['api']); } else { mkdir($path . 'lib/api/v1'); } } // cli if (isset($params['cli'])) { mkdir($path . 'lib/cli'); } mkdir($path . 'lib/classes'); mkdir($path . 'lib/models'); // config mkdir($path . 'lib/config'); // app description $app = array('name' => empty($params['name']) ? ucfirst($app_id) : $params['name'], 'icon' => 'img/' . $app_id . '.gif', 'version' => $version = empty($params['version']) ? '0.1' : $params['version'], 'vendor' => $vendor = empty($params['vendor']) ? '--' : $params['vendor']); if (isset($params['frontend'])) { $app['frontend'] = true; if (isset($params['themes'])) { $app['themes'] = true; } $routing = array('*' => 'frontend'); waUtils::varExportToFile($routing, $path . 'lib/config/routing.php'); // frontend controller mkdir($path . 'lib/actions/frontend'); } // plugins if (isset($params['plugins'])) { $app['plugins'] = true; mkdir($path . 'plugins'); } waUtils::varExportToFile($app, $path . 'lib/config/app.php'); // templates mkdir($path . 'templates'); waFiles::protect($path . 'templates'); mkdir($path . 'templates/actions'); mkdir($path . 'templates/actions/backend'); // backend template if (isset($params['frontend'])) { // frontend template mkdir($path . 'templates/actions/frontend'); } // locale mkdir($path . 'locale'); waFiles::protect($path . 'locale'); if (isset($params['frontend']) && isset($params['themes'])) { // themes mkdir($path . 'themes'); mkdir($path . 'themes/default'); $theme = new waTheme('default', $app_id, true); $theme->name = 'Default theme'; $theme->description = 'Auto generated default theme'; $theme->vendor = $vendor; $theme->system = 1; $theme->addFile('index.html', 'Frontend index file'); touch($path . 'themes/default/index.html'); $theme->addFile('default.css', 'Frontend CSS file'); touch($path . 'themes/default/default.css'); $theme->version = $version; $theme->save(); waFiles::move($theme->path . '/theme.xml', $path . 'themes/default/theme.xml'); } $report .= <<<REPORT App with id "{$app_id}" created! Useful commands: #generate app's database description file db.php php wa.php generateDb {$app_id} #generate app's locale files php wa-system/locale/locale.php {$app_id} REPORT; if (isset($params['plugins'])) { $report .= "\n\n" . <<<REPORT #create a plugin with specified 'plugin_id' for your app php wa.php createPlugin {$app_id} plugin_id REPORT; } //TODO add hint about compress command } else { $report .= <<<REPORT App with id "{$app_id}" already exists. REPORT; } print $report . "\n"; }
/** * Set template directory and global valiables. * * @param waTheme $theme Instance of theme object * @param string $template Path to template or resource string specifying template * @return bool */ public function setThemeTemplate($theme, $template) { $this->assign('wa_active_theme_path', $theme->path); $this->assign('wa_active_theme_url', $theme->url); $this->assign('wa_theme_version', $theme->version()); $theme_settings = $theme->getSettings(true); $locales = $theme->getLocales(); $file = $theme->getFile($template); if ($parent_theme = $theme->parent_theme) { if (!empty($file['parent'])) { $theme = $parent_theme; } $this->assign('wa_parent_theme_url', $parent_theme->url); $this->assign('wa_parent_theme_path', $parent_theme->path); if ($parent_settings = $parent_theme->getSettings(true)) { $theme_settings = $theme_settings + $parent_settings; } if ($parent_theme->getLocales()) { $locales += $parent_theme->getLocales(); } } waLocale::setStrings($locales); $this->assign('theme_settings', $theme_settings); $this->assign('wa_theme_url', $theme->url); $this->setTemplateDir($theme->path); return file_exists($theme->path . '/' . $template); }
/** * Returns id of design theme used in current frontend page. * * @return string */ public static function getTheme() { $app_id = wa()->getConfig()->getApplication(); $key = wa()->getRouting()->getDomain() . '/theme'; if (($theme_hash = self::get('theme_hash')) && ($theme = self::get('set_force_theme')) !== null) { $app_settings_model = new waAppSettingsModel(); $hash = $app_settings_model->get($app_id, 'theme_hash'); $global_hash = $app_settings_model->get('webasyst', 'theme_hash'); if ($theme_hash == md5($hash)) { if ($theme && waTheme::exists($theme)) { wa()->getStorage()->set($app_id . '/' . $key, $theme); return $theme; } else { wa()->getStorage()->del($app_id . '/' . $key); } } elseif ($global_hash && $theme_hash == md5($global_hash)) { if ($theme && waTheme::exists($theme)) { wa()->getStorage()->set($key, $theme); return $theme; } else { wa()->getStorage()->del($key); } } } elseif ((($theme = wa()->getStorage()->get($app_id . '/' . $key)) || ($theme = wa()->getStorage()->get($key))) && waTheme::exists($theme)) { return $theme; } if (self::isMobile()) { return self::param('theme_mobile', 'default'); } return self::param('theme', 'default'); }
/** * Returns the list of previously added JavaScript file URLs. * * @param bool $html Determines whether method must return an HTML string for including JavaScript files or an array of URLs * @param bool $strict Determines whether XHTML format must be used instead of default HTML * @return string|array HTML string or array of URLs */ public function getJs($html = true, $strict = false) { if (!$html) { return $this->js; } $result = ''; foreach ($this->js as $url) { $result .= '<script' . ($strict ? ' type="text/javascript"' : '') . ' src="' . $url . '"></script>' . PHP_EOL; } if (wa()->getEnv() == 'frontend') { $app_id = wa()->getApp(); $key = wa()->getRouting()->getDomain() . '/theme'; $hash = false; if (waRequest::get('theme_hash') && ($theme = waRequest::get('set_force_theme')) !== null) { $hash = waRequest::get('theme_hash'); } elseif (($theme = wa()->getStorage()->get($app_id . '/' . $key)) || ($theme = wa()->getStorage()->get($key))) { $app_settings_model = new waAppSettingsModel(); $hash = $app_settings_model->get($app_id, 'theme_hash'); if (!$hash) { $hash = $app_settings_model->get('webasyst', 'theme_hash'); } if ($hash) { $hash = md5($hash); } } if (!$hash || !$theme || !waTheme::exists($theme)) { return $result; } $theme = new waTheme($theme, $app_id); $theme = $theme['name']; $url = '?theme_hash=' . $hash . '&set_force_theme='; $result .= ' <script type="text/javascript"> $(function () { var div = $("<div></div>"); div.css({ position: "fixed", bottom: 0, left: 0, right: 0, opacity: 0.9, padding: "15px", "text-align": "center", background: "#ffd", "border-top": "4px solid #eea", "border-image": "url(\'' . wa()->getUrl() . 'wa-content/img/recovery-mode-background.png\') 10 10 10 10 repeat", "font-family": "Lucida Grande", "font-size": "14px", "z-index": 100500, }); div.html("' . sprintf(_ws('<strong>%s</strong> theme preview in action'), $theme) . '");'; if (wa()->getUser()->isAuth() && wa()->getUser()->getRights('shop')) { $result .= ' div.prepend(\'<a href="' . $url . '" style="float: right;">' . _ws('Stop preview session') . '</a>\'); div.find("a").click(function () { $("body").append($(\'<iframe style="display:none" src="\' + $(this).attr("href") + \'" />\').load(function () { $(this).remove(); div.remove(); if (location.href.indexOf("theme_hash") != -1) { location.href = location.href.replace(/(theme_hash|set_force_theme)=[^&]*&?/g, ""); } })); return false; });'; } $result .= ' $("body").append(div); }); </script>'; } return $result; }
protected function create($params = array()) { //TODO layout|ajax|simple mode $structure = array("css/{$this->app_id}.css", "js/{$this->app_id}.js", "img/", "img/{$this->app_id}48.png" => $this->root_path . 'wa-content/img/dummy-app-icon-48.png', "img/{$this->app_id}96.png" => $this->root_path . 'wa-content/img/dummy-app-icon-96.png', "lib/", "lib/actions/backend/", "lib/actions/backend/{$this->app_id}Backend.action.php" => $this->getActionCode(), "templates/actions/backend/Backend.html" => $this->getDefaultTemplate(), "lib/classes/", "lib/models/", "lib/config/", "locale/"); $features = array_map('trim', preg_split('@[,\\s]+@', ifset($params['features'], $this->getDefaults('features')))); // api if (in_array('api', $features, true)) { $structure = array_merge($structure, array("lib/api/v1/")); } if (in_array('cli', $features, true)) { $structure = array_merge($structure, array("lib/cli/", "lib/cli/{$this->app_id}Example.cli.php" => $this->getCliController())); } $protect = array('lib', 'templates'); // app description $app = array('name' => empty($params['name']) ? ucfirst($this->app_id) : $params['name'], 'icon' => array(48 => "img/{$this->app_id}48.png", 96 => "img/{$this->app_id}96.png"), 'version' => ifempty($params['version'], $this->getDefaults('version')), 'vendor' => ifempty($params['vendor'], $this->getDefaults('vendor'))); if (isset($params['frontend'])) { $app['frontend'] = true; if ($params['frontend'] == 'themes') { $app['themes'] = true; } $routing = array('*' => 'frontend'); $structure['lib/config/routing.php'] = $routing; $structure = array_merge($structure, array('lib/actions/frontend/', "lib/actions/frontend/{$this->app_id}Frontend.action.php" => $this->getActionCode('default', false, $app))); if (!empty($app['themes'])) { $structure = array_merge($structure, array('themes/.htaccess' => ' <FilesMatch "\\.(php\\d*|html?|xml)$"> Deny from all </FilesMatch> ', 'themes/default/index.html' => $this->getFrontendTemplate(), 'themes/default/css/default.css')); } else { $structure = array_merge($structure, array("templates/actions/frontend/Frontend.html" => $this->getFrontendTemplate(), "css/frontend/{$this->app_id}.css")); } } if (isset($params['plugins'])) { $structure = array_merge($structure, array("plugins/")); $app['plugins'] = true; } $structure['lib/config/app.php'] = $app; $this->createStructure($structure); $this->protect($protect); if (!empty($app['themes'])) { waFiles::delete(wa()->getDataPath('themes/default', true, $this->app_id)); $theme = new waTheme('default', $this->app_id, true); $theme->name = 'Default theme'; $theme->description = 'Auto generated default theme'; $theme->vendor = $app['vendor']; $theme->version = $app['version']; $theme->addFile('index.html', 'Frontend index file'); $theme->addFile('css/default.css', 'Frontend CSS file'); $theme->save(); waFiles::move($theme->path . '/theme.xml', $this->path . 'themes/default/theme.xml'); } if (!isset($params['disable'])) { $this->installApp(); $errors = $this->flushCache(); if ($errors) { print "Error during delete cache files:\n\t" . implode("\n\t", $errors) . "\n"; } } return $app; }