public function execute()
 {
     $cache = null;
     if ($cache_time = $this->getConfig()->getOption('cache_time')) {
         //$cache = new waSerializeCache('pages/'.$domain.$url.'page');
     }
     $page = array();
     if ($cache && $cache->isCached()) {
         $page = $cache->get();
     } else {
         $site = new siteFrontend();
         if (waRequest::param('error')) {
             $page = array();
         } else {
             $page = $site->getPage(waRequest::param('url', ''));
         }
         if ($page && $cache) {
             $cache->set($page);
         }
     }
     if (!waRequest::isXMLHttpRequest()) {
         $this->setLayout(new siteFrontendLayout());
     }
     try {
         $this->executeAction(new siteFrontendAction($page));
     } catch (Exception $e) {
         if (waSystemConfig::isDebug()) {
             echo $e;
         } else {
             waSystem::setActive('site');
             $this->executeAction(new siteFrontendAction($e));
         }
     }
 }
 public static function getPhotoUrl($id, $ts, $width = null, $height = null)
 {
     if ($width === 'original') {
         $size = 'original';
     } else {
         if ($width && !$height) {
             $size = $width . 'x' . $width;
         } else {
             if (!$width) {
                 $width = 96;
                 $size = '96x96';
             } else {
                 $size = $width . 'x' . $height;
             }
         }
     }
     if ($ts) {
         if (waSystemConfig::systemOption('mod_rewrite')) {
             return wa()->getDataUrl('photo/' . $id . '/' . $ts . '.' . $size . '.jpg', true, 'contacts');
         } else {
             if (file_exists(wa()->getDataPath('photo/' . $id . '/' . $ts . '.' . $size . '.jpg', true, 'contacts'))) {
                 return wa()->getDataUrl('photo/' . $id . '/' . $ts . '.' . $size . '.jpg', true, 'contacts');
             } else {
                 return wa()->getDataUrl('photo/thumb.php/' . $id . '/' . $ts . '.' . $size . '.jpg', true, 'contacts');
             }
         }
     } else {
         $size = (int) $width;
         if (!in_array($size, array(20, 32, 50, 96))) {
             $size = 96;
         }
         return wa()->getRootUrl() . 'wa-content/img/userpic' . $size . '.jpg';
     }
 }
 protected function writeToFile($file, $v)
 {
     if (!file_exists($file) && is_writable(dirname($file)) || is_writable($file)) {
         return file_put_contents($file, "<?php\nreturn " . var_export($v, true) . ";");
     } elseif (waSystemConfig::isDebug()) {
         throw new waException("Cannot write to cache file " . $file, 601);
     }
 }
 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');
     }
 }
 public function decorate($response)
 {
     if (is_array($response)) {
         $response = $this->parseArray($response);
     }
     if (waSystemConfig::isDebug() && version_compare(PHP_VERSION, '5.4.0') >= 0) {
         return json_encode($response, JSON_PRETTY_PRINT);
     } else {
         return json_encode($response);
     }
 }
 protected function writeToFile($file, $v)
 {
     $data = serialize(array('time' => time(), 'ttl' => $this->ttl, 'value' => $v));
     if (!file_exists($file) || is_writable($file)) {
         $r = @file_put_contents($file, $data);
         if ($r) {
             @chmod($file, 0664);
         }
         return $r;
     } elseif (waSystemConfig::isDebug()) {
         throw new waException("Cannot write to cache file " . $file, 601);
     }
 }
Example #7
0
 public static function getPhotoUrlTemplate($photo, $absolute = false)
 {
     $path = self::getPhotoFolder($photo['id']) . '/' . $photo['id'];
     if ($photo['status'] <= 0 && !empty($photo['hash'])) {
         $path .= '.' . $photo['hash'];
     }
     $path .= '/' . $photo['id'] . '.%size%.' . $photo['ext'];
     if (waSystemConfig::systemOption('mod_rewrite')) {
         return wa()->getDataUrl($path, true, 'photos', $absolute);
     } else {
         return wa()->getDataUrl('thumb.php/' . $path, true, 'photos', $absolute);
     }
 }
 public function display($clear_assign = true)
 {
     if (waSystemConfig::isDebug()) {
         return parent::display($clear_assign);
     }
     try {
         return parent::display($clear_assign);
     } catch (SmartyCompilerException $e) {
         $message = preg_replace('/(on\\sline\\s[0-9]+).*$/i', '$1', $e->getMessage());
         $message = str_replace($this->getConfig()->getRootPath(), '', $message);
         throw new SmartyCompilerException($message, $e->getCode());
     }
 }
 public static function getAppConfig($application, $environment = null, $root_path = null, $locale = null)
 {
     //hook creating app's config and create proxy config over siteConfig
     if ($application == 'site') {
         if ($root_path === null) {
             $root_path = realpath(dirname(__FILE__) . '/..');
         }
         if ($environment === null) {
             $environment = waSystem::getInstance()->getEnv();
         }
         return new mySiteConfig($environment, $root_path, $application, $locale);
     }
     return parent::getAppConfig($application, $environment, $root_path, $locale);
 }
 public function execute()
 {
     $message = '';
     if (!wa()->getUser()->getRights('webasyst', 'backend')) {
         $message = _w('Coding sandbox is available for Webasyst admin users only.');
     }
     if (!waSystemConfig::isDebug()) {
         $message = _w('Coding sandbox works only if Debug mode is enabled in the Installer app.');
     }
     // !!! only allow access from localhost?
     if ($message) {
         $this->setTemplate('string:<div class="tripple-padded block"><h2 style="color:red">{$message|escape}</h2></div>');
         $this->view->assign('message', $message);
     }
 }
 public function execute()
 {
     // Access control
     $message = '';
     if (!wa()->getUser()->getRights('webasyst', 'backend')) {
         $message = _w('This application is available for Webasyst admin users only.');
     }
     if (!waSystemConfig::isDebug()) {
         $message = _w('This application works only when Debug mode is enabled in the Installer app.');
     }
     if ($message) {
         throw new waRightsException($message);
     }
     // !!! TODO: only allow access from localhost?
     eval(waRequest::post('code'));
     // Welcome to the dark side!
 }
 public function execute()
 {
     $comment_id = (int) waRequest::post('spam');
     $comment_model = new blogCommentModel();
     $comment = $comment_model->getById($comment_id);
     $this->response['status'] = null;
     if ($comment) {
         $comment_model->updateById($comment_id, array('akismet_spam' => 1, 'status' => blogCommentModel::STATUS_DELETED));
         $this->response['status'] = blogCommentModel::STATUS_DELETED;
         $blog_plugin = wa()->getPlugin('akismet');
         $akismet = new Akismet(wa()->getRouting()->getUrl('blog', array(), true), $blog_plugin->getSettingValue('api_key'));
         $akismet->setCommentAuthor($comment['name']);
         $akismet->setCommentAuthorEmail($comment['email']);
         $akismet->setCommentContent($comment['text']);
         if (!waSystemConfig::isDebug() && $blog_plugin->getSettingValue('send_spam')) {
             $akismet->submitSpam();
         }
     }
 }
Example #13
0
 public function add($action, $params = null, $subject_contact_id = null, $contact_id = null)
 {
     /**
      * @var waSystem
      */
     $system = waSystem::getInstance();
     /**
      * @var waAppConfig
      */
     $config = $system->getConfig();
     if ($config instanceof waAppConfig) {
         // Get actions of current application available to log
         $actions = $config->getLogActions();
         // Check action
         if (!isset($actions[$action])) {
             if (waSystemConfig::isDebug()) {
                 throw new waException('Unknown action for log ' . $action);
             } else {
                 return false;
             }
         }
         if ($actions[$action] === false) {
             return false;
         }
         $app_id = $system->getApp();
     } else {
         $app_id = 'wa-system';
     }
     // Save to database
     $data = array('app_id' => $app_id, 'contact_id' => $contact_id === null ? $system->getUser()->getId() : $contact_id, 'datetime' => date("Y-m-d H:i:s"), 'action' => $action, 'subject_contact_id' => $subject_contact_id);
     if ($params !== null) {
         if (is_array($params)) {
             $params = json_encode($params);
         }
         $data['params'] = $params;
     }
     return $this->insert($data);
 }
Example #14
0
 public function getApps($system = false)
 {
     if (self::$apps === null) {
         $locale = $this->getUser()->getLocale();
         $file = $this->config->getPath('cache', 'config/apps' . $locale);
         if (!file_exists($this->getConfig()->getPath('config', 'apps'))) {
             self::$apps = array();
             throw new waException('File wa-config/apps.php not found.', 600);
         }
         if (!file_exists($file) || filemtime($file) < filemtime($this->getConfig()->getPath('config', 'apps')) || waSystemConfig::isDebug()) {
             waFiles::create($this->getConfig()->getPath('cache') . '/config');
             $all_apps = (include $this->getConfig()->getPath('config', 'apps'));
             $all_apps['webasyst'] = true;
             self::$apps = array();
             foreach ($all_apps as $app => $enabled) {
                 if ($enabled) {
                     waLocale::loadByDomain($app, $locale);
                     $app_config = $this->getAppPath('lib/config/app.php', $app);
                     if (!file_exists($app_config)) {
                         if (false && SystemConfig::isDebug()) {
                             throw new waException("Config not found. Create config by path " . $app_config);
                         }
                         continue;
                     }
                     $app_info = (include $app_config);
                     $build_file = $app_config = $this->getAppPath('lib/config/build.php', $app);
                     if (file_exists($build_file)) {
                         $app_info['build'] = (include $build_file);
                     } else {
                         if (SystemConfig::isDebug()) {
                             $app_info['build'] = time();
                         } else {
                             $app_info['build'] = 0;
                         }
                     }
                     $app_info['id'] = $app;
                     $app_info['name'] = _wd($app, $app_info['name']);
                     if (isset($app_info['icon'])) {
                         if (is_array($app_info['icon'])) {
                             foreach ($app_info['icon'] as $size => $url) {
                                 $app_info['icon'][$size] = 'wa-apps/' . $app . '/' . $url;
                             }
                         } else {
                             $app_info['icon'] = array(48 => 'wa-apps/' . $app . '/' . $app_info['icon']);
                         }
                     } else {
                         $app_info['icon'] = array();
                     }
                     if (isset($app_info['img'])) {
                         $app_info['img'] = 'wa-apps/' . $app . '/' . $app_info['img'];
                     } else {
                         $app_info['img'] = isset($app_info['icon'][48]) ? $app_info['icon'][48] : 'wa-apps/' . $app . '/img/' . $app . ".png";
                     }
                     if (!isset($app_info['icon'][48])) {
                         $app_info['icon'][48] = $app_info['img'];
                     }
                     if (!isset($app_info['icon'][24])) {
                         $app_info['icon'][24] = $app_info['icon'][48];
                     }
                     if (!isset($app_info['icon'][16])) {
                         $app_info['icon'][16] = $app_info['icon'][24];
                     }
                     self::$apps[$app] = $app_info;
                 }
             }
             if (!file_exists($file) || filemtime($file) < filemtime($this->getConfig()->getPath('config', 'apps'))) {
                 waUtils::varExportToFile(self::$apps, $file);
             }
         } else {
             self::$apps = (include $file);
             waLocale::loadByDomain('webasyst');
         }
     }
     if ($system) {
         return self::$apps;
     } else {
         $apps = self::$apps;
         unset($apps['webasyst']);
         return $apps;
     }
 }
 public function checkUpdates()
 {
     try {
         $app_settings_model = new waAppSettingsModel();
         $time = $app_settings_model->get($this->application, 'update_time');
     } catch (waDbException $e) {
         // Can't connect to MySQL server
         if ($e->getCode() == 2002) {
             throw $e;
         } elseif (!empty($app_settings_model)) {
             $time = null;
             $row = $app_settings_model->getByField(array('app_id' => $this->application, 'name' => 'update_time'));
             if ($row) {
                 $time = $row['value'];
             }
         } elseif ($this->application != 'webasyst' && $this->environment == 'frontend') {
             wa('webasyst');
         }
     } catch (waException $e) {
         return;
     }
     if (empty($time)) {
         try {
             $this->install();
         } catch (waException $e) {
             waLog::log($e->__toString());
             throw $e;
         }
         $ignore_all = true;
         $time = null;
     } else {
         $ignore_all = false;
     }
     if (!self::isDebug()) {
         $cache = new waVarExportCache('updates', 0, $this->application);
         if ($cache->isCached() && $cache->get() <= $time) {
             return;
         }
     }
     $path = $this->getAppPath() . '/lib/updates';
     $cache_database_dir = $this->getPath('cache') . '/db';
     if (file_exists($path)) {
         $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
         $files = array();
         foreach ($iterator as $file) {
             /**
              * @var SplFileInfo $file
              */
             if ($file->isFile() && preg_match('/^[0-9]+\\.php$/', $file->getFilename())) {
                 $t = substr($file->getFilename(), 0, -4);
                 if ($t > $time) {
                     $files[$t] = $file->getPathname();
                 }
             }
         }
         ksort($files);
         if (!self::isDebug()) {
             // get last time
             if ($files) {
                 $keys = array_keys($files);
                 $cache->set(end($keys));
             } else {
                 $cache->set($time ? $time : 1);
             }
         }
         foreach ($files as $t => $file) {
             try {
                 if (!$ignore_all) {
                     $this->includeUpdate($file);
                     waFiles::delete($cache_database_dir);
                     $app_settings_model->set($this->application, 'update_time', $t);
                 }
             } catch (Exception $e) {
                 if (waSystemConfig::isDebug()) {
                     echo $e;
                 }
                 // log errors
                 waLog::log($e->__toString());
                 break;
             }
         }
     } else {
         $t = 1;
     }
     if ($ignore_all) {
         if (!isset($t) || !$t) {
             $t = 1;
         }
         if (!isset($app_settings_model)) {
             $app_settings_model = new waAppSettingsModel();
         }
         $app_settings_model->set($this->application, 'update_time', $t);
     }
     if (isset($this->info['edition']) && $this->info['edition']) {
         if (!isset($app_settings_model)) {
             $app_settings_model = new waAppSettingsModel();
         }
         if (!$app_settings_model->get($this->application, 'edition')) {
             $app_settings_model->set($this->application, 'edition', $this->info['edition']);
         }
     }
 }
Example #16
0
    public function __toString()
    {
        try {
            $wa = wa();
            $additional_info = '';
        } catch (Exception $e) {
            $wa = null;
            $additional_info = $e->getMessage();
        }
        $message = nl2br($this->getMessage());
        if ($wa && waSystem::getApp()) {
            $app = $wa->getAppInfo();
            $backend_url = $wa->getConfig()->getBackendUrl(true);
        } else {
            $app = array();
        }
        if (!waSystemConfig::isDebug() && $wa) {
            $env = $wa->getEnv();
            $file = $code = $this->getCode();
            if (!$code || !file_exists(dirname(__FILE__) . '/data/' . $code . '.php')) {
                $file = 'error';
            }
            include dirname(__FILE__) . '/data/' . $file . '.php';
            exit;
        }
        if ($wa && $wa->getEnv() == 'cli' || !$wa && php_sapi_name() == 'cli') {
            return date("Y-m-d H:i:s") . " php " . implode(" ", waRequest::server('argv')) . "\n" . "Error: {$this->getMessage()}\nwith code {$this->getCode()} in '{$this->getFile()}' around line {$this->getLine()}:{$this->getFileContext()}\n" . $this->getTraceAsString() . "\n" . ($additional_info ? "Error while initializing waSystem during error generation: " . $additional_info . "\n" : '');
        } elseif ($this->code == 404) {
            $response = new waResponse();
            $response->setStatus(404);
            $response->sendHeaders();
        }
        $request = htmlentities(var_export($_REQUEST, true), ENT_NOQUOTES, 'utf-8');
        $params = htmlentities(var_export(waRequest::param(), true), ENT_NOQUOTES, 'utf-8');
        $context = htmlentities($this->getFileContext(), ENT_NOQUOTES, 'utf-8');
        $trace = htmlentities($this->getTraceAsString(), ENT_NOQUOTES, 'utf-8');
        $result = <<<HTML
<div style="width:99%; position:relative; text-align: left;">
\t<h2 id='Title'>{$message}</h2>
\t<div id="Context" style="display: block;">
\t\t<h3>Error with code {$this->getCode()} in '{$this->getFile()}' around line {$this->getLine()}:</h3>
\t\t<pre>{$context}</pre>
\t</div>
\t<div id="Trace">
\t\t<h2>Call stack</h2>
\t\t<pre>{$trace}</pre>
\t</div>
\t<div id="Request">
\t\t<h2>Request</h2>
\t\t<pre>{$request}</pre>
    </div>
</div>
<div style="text-align: left;">
    <h2>Params</h2>
    <pre>{$params}</pre>
</div>
HTML;
        if ($additional_info) {
            $additional_info = htmlentities($additional_info, ENT_NOQUOTES, 'utf-8');
            $result .= <<<HTML

<div style="text-align: left;">
    <h2>Error while initializing waSystem during error generation</h2>
    <pre>{$additional_info}</pre>
</div>
HTML;
        }
        return $result;
    }
Example #17
0
 /**
  * Returns URL of a product image. 
  * 
  * @param array $image Key-value image data object
  * @param string $size Size value string (e.g., '200x0', '96x96', etc.)
  * @param bool $absolute Whether absolute URL must be returned
  * @return string
  */
 public static function getUrl($image, $size = null, $absolute = false)
 {
     $path = shopProduct::getFolder($image['product_id']) . "/{$image['product_id']}/images/{$image['id']}/{$image['id']}.{$size}.{$image['ext']}";
     if (waSystemConfig::systemOption('mod_rewrite')) {
         return wa()->getDataUrl($path, true, 'shop', $absolute);
     } else {
         if (file_exists(wa()->getDataPath($path, true, 'shop'))) {
             return wa()->getDataUrl($path, true, 'shop', $absolute);
         } else {
             $path = str_replace('products/', 'products/thumb.php/', $path);
             return wa()->getDataUrl($path, true, 'shop', $absolute);
         }
     }
 }
 protected function checkUpdates()
 {
     try {
         $app_settings_model = new waAppSettingsModel();
         $time = $app_settings_model->get($this->application, 'update_time');
     } catch (waDbException $e) {
         if ($e->getCode() == 2002 && !waSystemConfig::isDebug()) {
             return;
         } else {
             // table doesn't exist
             $time = null;
         }
     } catch (waException $e) {
         return;
     }
     if (!$time) {
         try {
             $this->install();
         } catch (waException $e) {
             waLog::log($e->__toString());
             throw $e;
         }
         $ignore_all = true;
     } else {
         $ignore_all = false;
     }
     if (!self::isDebug()) {
         $cache = new waVarExportCache('updates', 0, $this->application);
         if ($cache->isCached() && $cache->get() <= $time) {
             return;
         }
     }
     $path = $this->getAppPath() . '/lib/updates';
     $cache_database_dir = $this->getPath('cache') . '/db';
     if (file_exists($path)) {
         $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
         $files = array();
         foreach ($iterator as $file) {
             /**
              * @var SplFileInfo $file
              */
             if ($file->isFile() && preg_match('/^[0-9]+\\.php$/', $file->getFilename())) {
                 $t = substr($file->getFilename(), 0, -4);
                 if ($t > $time) {
                     $files[$t] = $file->getPathname();
                 }
             }
         }
         ksort($files);
         if (!self::isDebug()) {
             // get last time
             if ($files) {
                 $keys = array_keys($files);
                 $cache->set(end($keys));
             } else {
                 $cache->set($time ? $time : 1);
             }
         }
         foreach ($files as $t => $file) {
             try {
                 if (!$ignore_all) {
                     include $file;
                     waFiles::delete($cache_database_dir);
                     $app_settings_model->set($this->application, 'update_time', $t);
                 }
             } catch (Exception $e) {
                 if (waSystemConfig::isDebug()) {
                     echo $e;
                 }
                 // log errors
                 waLog::log($e->__toString());
                 break;
             }
         }
     } else {
         $t = 1;
     }
     if ($ignore_all) {
         if (!isset($t) || !$t) {
             $t = 1;
         }
         if (!isset($app_settings_model)) {
             $app_settings_model = new waAppSettingsModel();
         }
         $app_settings_model->set($this->application, 'update_time', $t);
     }
     if (isset($this->info['edition']) && $this->info['edition']) {
         if (!isset($app_settings_model)) {
             $app_settings_model = new waAppSettingsModel();
         }
         if (!$app_settings_model->get($this->application, 'edition')) {
             $file_sql = $this->getAppPath('lib/config/app.' . $this->info['edition'] . '.sql');
             if (file_exists($file_sql)) {
                 self::executeSQL($file_sql, 1);
             }
             $app_settings_model->set($this->application, 'edition', $this->info['edition']);
         }
     }
 }
 /**
  * Trigger event with given $name from current active application.
  *
  * @param  string    $name        Event name.
  * @param  mixed     $params      Parameters passed to event handlers.
  * @param  string[]  $array_keys  Array of expected template items for UI events.
  * @return  array  app_id or plugin_id => data returned from handler (unless null is returned)
  */
 public function event($name, &$params = null, $array_keys = null)
 {
     $result = array();
     if (is_array($name)) {
         $event_app_id = $name[0];
         $event_system = self::getInstance($event_app_id);
         $name = $name[1];
     } else {
         $event_app_id = $this->getConfig()->getApplication();
         $event_system = $this;
     }
     $event_prefix = wa($event_app_id)->getConfig()->getPrefix();
     if (!isset(self::$handlers['apps'])) {
         self::$handlers['apps'] = array();
         $cache_file = $this->config->getPath('cache', 'config/handlers');
         if (!waSystemConfig::isDebug() && file_exists($cache_file)) {
             self::$handlers['apps'] = (include $cache_file);
         }
         if (!self::$handlers['apps'] || !is_array(self::$handlers['apps'])) {
             $apps = $this->getApps();
             $path = $this->getConfig()->getPath('apps');
             foreach ($apps as $app_id => $app_info) {
                 $files = waFiles::listdir($path . '/' . $app_id . '/lib/handlers/');
                 foreach ($files as $file) {
                     if (substr($file, -12) == '.handler.php') {
                         $file = explode('.', substr($file, 0, -12), 2);
                         self::$handlers['apps'][$file[0]][$file[1]][] = $app_id;
                     }
                 }
             }
             if (!waSystemConfig::isDebug()) {
                 waUtils::varExportToFile(self::$handlers['apps'], $cache_file);
             }
         }
     }
     if (!isset(self::$handlers['plugins'][$event_app_id])) {
         self::$handlers['plugins'][$event_app_id] = array();
         $plugins = $event_system->getConfig()->getPlugins();
         foreach ($plugins as $plugin_id => $plugin) {
             if (!empty($plugin['handlers'])) {
                 foreach ($plugin['handlers'] as $handler_event => $handler_method) {
                     self::$handlers['plugins'][$event_app_id][$handler_event][$plugin_id] = $handler_method;
                 }
             }
         }
     }
     if (isset(self::$handlers['apps'][$event_app_id][$name])) {
         $path = $this->getConfig()->getPath('apps');
         foreach (self::$handlers['apps'][$event_app_id][$name] as $app_id) {
             $file_path = $path . '/' . $app_id . '/lib/handlers/' . $event_prefix . "." . $name . ".handler.php";
             if (!file_exists($file_path)) {
                 continue;
             }
             wa($app_id);
             include_once $file_path;
             $class_name = $name;
             if (strpos($name, '.') !== false) {
                 $class_name = strtok($class_name, '.') . ucfirst(strtok(''));
             }
             $class_name = $app_id . ucfirst($event_prefix) . ucfirst($class_name) . "Handler";
             /**
              * @var $handler waEventHandler
              */
             $handler = new $class_name();
             try {
                 $r = $handler->execute($params);
                 if ($r !== null) {
                     $result[$app_id] = $r;
                 }
             } catch (Exception $e) {
                 waLog::log('Event handling error in ' . $file_path . ': ' . $e->getMessage());
             }
         }
     }
     if (isset(self::$handlers['plugins'][$event_app_id][$name])) {
         $plugins = $event_system->getConfig()->getPlugins();
         foreach (self::$handlers['plugins'][$event_app_id][$name] as $plugin_id => $method) {
             if (!isset($plugins[$plugin_id])) {
                 continue;
             }
             $plugin = $plugins[$plugin_id];
             self::pushActivePlugin($plugin_id, $event_prefix);
             $class_name = $event_app_id . ucfirst($plugin_id) . 'Plugin';
             try {
                 $class = new $class_name($plugin);
                 // Load plugin locale if it exists
                 $locale_path = $this->getAppPath('plugins/' . $plugin_id . '/locale', $event_app_id);
                 if (is_dir($locale_path)) {
                     waLocale::load($this->getLocale(), $locale_path, self::getActiveLocaleDomain(), false);
                 }
                 if (method_exists($class, $method) && null !== ($r = $class->{$method}($params))) {
                     if ($array_keys && is_array($r)) {
                         foreach ($array_keys as $k) {
                             if (!isset($r[$k])) {
                                 $r[$k] = '';
                             }
                         }
                     }
                     $result[$plugin_id . '-plugin'] = $r;
                 }
             } catch (Exception $e) {
                 waLog::log('Event handling error in ' . $class_name . '->' . $name . '(): ' . $e->getMessage());
             }
             self::popActivePlugin();
         }
     }
     return $result;
 }
Example #20
0
 public function getRootUrl($absolute = false, $script = false)
 {
     if (!self::$root_url) {
         if (isset($_SERVER['SCRIPT_NAME']) && $_SERVER['SCRIPT_NAME']) {
             self::$root_url = $_SERVER['SCRIPT_NAME'];
         } elseif (isset($_SERVER['PHP_SELF']) && $_SERVER['PHP_SELF']) {
             self::$root_url = $_SERVER['PHP_SELF'];
         } else {
             self::$root_url = '/';
         }
         self::$root_url = preg_replace('!/[^/]*$!', '/', self::$root_url);
     }
     if ($absolute) {
         $url = $this->getHostUrl();
         return $url . self::$root_url . ($script && !$this->getSystemOption('mod_rewrite') ? 'index.php/' : '');
     }
     return self::$root_url . ($script && !$this->getSystemOption('mod_rewrite') ? 'index.php/' : '');
 }
Example #21
0
 public function execute()
 {
     $fm = new shopFollowupModel();
     $opm = new shopOrderParamsModel();
     $asm = new waAppSettingsModel();
     $olm = new shopOrderLogModel();
     $cm = new shopCustomerModel();
     $om = new shopOrderModel();
     $asm->set('shop', 'last_followup_cli', time());
     $view = wa()->getView();
     $empty_customer = $cm->getEmptyRow();
     $general = wa('shop')->getConfig()->getGeneralSettings();
     foreach ($fm->getAllEnabled() as $f) {
         $between_from = date('Y-m-d', strtotime($f['last_cron_time']) - 24 * 3600);
         $between_to = date('Y-m-d 23:59:59', time() - $f['delay'] - 10 * 3600);
         $orders = $om->where('paid_date >= ? AND paid_date < ?', $between_from, $between_to)->fetchAll('id');
         if ($orders) {
             $f_param_key = 'followup_' . $f['id'];
             // Params for all orders with one query
             $params = $opm->get(array_keys($orders));
             // Customer data for all orders with one query
             $cids = array();
             foreach ($orders as $o) {
                 $cids[] = $o['contact_id'];
             }
             $customers = $cm->getById($cids);
             $sent_count = 0;
             foreach ($orders as $o) {
                 try {
                     // Is there a recipient in the first place?
                     if (empty($o['contact_id'])) {
                         if (waSystemConfig::isDebug()) {
                             waLog::log("Unable to send follow-up #{$f['id']} for order #{$o['id']}: no contact_id");
                         }
                         continue;
                     }
                     // Check that this is the first order of this customer
                     if ($f['first_order_only']) {
                         $first_order_id = $om->select('MIN(id)')->where('contact_id=? AND paid_date IS NOT NULL', $o['contact_id'])->fetchField();
                         if ($first_order_id != $o['id']) {
                             if (waSystemConfig::isDebug()) {
                                 waLog::log("Skipping follow-up #{$f['id']} for order #{$o['id']}: not the first order of a customer.");
                             }
                             continue;
                         }
                     }
                     $o['params'] = ifset($params[$o['id']], array());
                     $source = 'backend';
                     if (!empty($o['params']['storefront'])) {
                         $source = rtrim($o['params']['storefront'], '/') . '/*';
                     }
                     if ($f['source'] && $f['source'] != $source) {
                         continue;
                     }
                     // Make sure we have not send follow-up for this order yet
                     if (isset($o['params'][$f_param_key])) {
                         if (waSystemConfig::isDebug()) {
                             waLog::log("Skipping follow-up #{$f['id']} for order #{$o['id']}: already sent before.");
                         }
                         continue;
                     }
                     shopHelper::workupOrders($o, true);
                     // Recipient info
                     $customer = ifset($customers[$o['contact_id']], $empty_customer);
                     $contact = new shopCustomer($o['contact_id']);
                     $email = $contact->get('email', 'default');
                     // this with throw exception if contact does not exist; that's ok
                     if (!$email) {
                         if (waSystemConfig::isDebug()) {
                             waLog::log("Unable to send follow-up #{$f['id']} for order #{$o['id']}: contact has no email");
                         }
                         continue;
                     }
                     $to = array($email => $contact->getName());
                     if (self::sendOne($f, $o, $customer, $contact, $to, $view, $general)) {
                         $sent_count++;
                         // Write to order log
                         $olm->add(array('order_id' => $o['id'], 'contact_id' => null, 'action_id' => '', 'text' => sprintf_wp("Follow-up <strong>%s</strong> (%s) sent to customer.", htmlspecialchars($f['name']), $f['id']), 'before_state_id' => $o['state_id'], 'after_state_id' => $o['state_id']));
                         // Write to order params
                         $opm->insert(array('order_id' => $o['id'], 'name' => $f_param_key, 'value' => date('Y-m-d H:i:s')));
                     } else {
                         waLog::log("Unable to send follow-up #{$f['id']} for order #{$o['id']}: waMessage->send() returned FALSE.");
                     }
                 } catch (Exception $e) {
                     waLog::log("Unable to send follow-up #{$f['id']} for order #{$o['id']}:\n" . $e);
                 }
             }
             /**
              * Notify plugins about sending followup
              * @event followup_send
              * @param array[string]int $params['sent_count'] number of emails successfully sent
              * @param array[string]int $params['id'] followup_id
              * @return void
              */
             $event_params = $f;
             $event_params['sent_count'] = $sent_count;
             wa()->event('followup_send', $event_params);
         }
         $fm->updateById($f['id'], array('last_cron_time' => $between_to));
     }
 }
Example #22
0
 public function debug()
 {
     return waSystemConfig::isDebug();
 }
Example #23
0
<?php

if (!isset($argc)) {
    die("Run from CLI only!");
}
require_once dirname(__FILE__) . '/../wa-config/SystemConfig.class.php';
if (count($argv) < 3) {
    die("Use\r\n" . realpath(dirname(__FILE__) . '/../') . "/cli.php  APP CLASS PARAMS\r\n");
}
try {
    $config = new SystemConfig('cli');
    waSystem::getInstance(null, $config)->dispatchCli($argv);
} catch (Exception $e) {
    waLog::log($e, "cli.log");
    if (waSystemConfig::isDebug()) {
        echo $e;
    }
}
Example #24
0
function smarty_block_wa_js($params, $content, &$smarty)
{
    if (!$content) {
        return '';
    }
    // jquery ui custom bundle
    $ui_custom = array('core' => 0, 'widget' => 0, 'mouse' => 0, 'draggable' => 0, 'droppable' => 0, 'sortable' => 0, 'datepicker' => 1);
    $files = explode("\n", $content);
    $wa = waSystem::getInstance();
    $jquery_ui_path = "wa-content/js/jquery-ui/jquery.ui.";
    $jquery_ui_path_n = strlen($jquery_ui_path);
    $n = strlen($wa->getRootUrl());
    $locale = $wa->getLocale();
    //
    // Non-debug mode: merge all files into one cache
    //
    if (!SystemConfig::isDebug() && isset($params['file'])) {
        $root_path = $wa->getConfig()->getRootPath();
        $app_path = $wa->getConfig()->getAppPath();
        $result = '';
        $files_combine = array();
        $mtime = file_exists($app_path . '/' . $params['file']) ? filemtime($app_path . '/' . $params['file']) : 0;
        $r = true;
        foreach ($files as $f) {
            $f = trim($f);
            $f = substr($f, $n);
            if ($f) {
                if (substr($f, 0, $jquery_ui_path_n) == $jquery_ui_path) {
                    $jquery_f = substr($f, $jquery_ui_path_n);
                    if (substr($jquery_f, -7) == '.min.js') {
                        $jquery_f = substr($jquery_f, 0, -7);
                    }
                    if (isset($ui_custom[$jquery_f])) {
                        if (!$result) {
                            $result = '<script type="text/javascript" src="' . $wa->getRootUrl() . 'wa-content/js/jquery-ui/jquery-ui.custom.min.js"></script>' . "\n";
                        }
                        // include locale
                        if ($ui_custom[$jquery_f] && $locale != 'en_US') {
                            $result .= '<script type="text/javascript" src="' . $wa->getRootUrl() . 'wa-content/js/jquery-ui/i18n/jquery.ui.' . $jquery_f . '-' . $locale . '.js"></script>' . "\n";
                        }
                        continue;
                    }
                }
                if (!file_exists($f)) {
                    $r = false;
                    break;
                }
                $files_combine[] = $f;
                if ($mtime && filemtime($root_path . '/' . $f) > $mtime) {
                    $mtime = 0;
                }
            }
        }
        if ($files_combine) {
            if ($r && !$mtime && waFiles::create($app_path . '/' . $params['file'])) {
                // check Google Closure Compiler
                // https://developers.google.com/closure/compiler/docs/gettingstarted_app
                if ($compiler = waSystemConfig::systemOption('js_compiler')) {
                    $cmd = 'java -jar "' . $compiler . '"';
                    foreach ($files_combine as $file) {
                        $cmd .= ' --js "' . $root_path . '/' . $file . '"';
                    }
                    $cmd .= ' --js_output_file "' . $app_path . '/' . $params['file'] . '"';
                    system($cmd, $res);
                    $r = !$res;
                    if (!$r) {
                        waLog::log("Error occured while compress files:\n\t" . implode("\n\t", $files_combine) . "\n\t{$params['file']}\n\ncommand:\n{$cmd}", __FUNCTION__ . '.log');
                    }
                } else {
                    $r = false;
                }
                if (!$r) {
                    $data = "";
                    foreach ($files_combine as $file) {
                        $data .= file_get_contents($root_path . '/' . $file) . ";\n";
                    }
                    $r = @file_put_contents($app_path . '/' . $params['file'], $data);
                    if (!$r) {
                        waLog::log("Error occured while compress files:\n\t" . implode("\n\t", $files_combine) . "\n\t{$params['file']}", __FUNCTION__ . '.log');
                    }
                }
            }
        }
        if ($r) {
            if ($files_combine) {
                $result .= '<script type="text/javascript" src="' . $wa->getAppStaticUrl() . $params['file'] . '?v' . $wa->getVersion() . '"></script>' . "\n";
            }
            return $result;
        }
    }
    //
    // Debug mode (or no file specified): include all files separately
    //
    $result = "";
    foreach ($files as $f) {
        $f = trim($f);
        if ($f) {
            // Add ?version to circumvent browser caching
            if (substr($f, $n, 10) !== 'wa-content') {
                $f .= '?v' . $wa->getVersion();
            }
            $result .= '<script type="text/javascript" src="' . $f . '"></script>' . "\n";
            // Add datepicker localization automatically
            // !!! This is not really a good idea since it will break in non-debug mode anyways
            if (substr($f, $n) == $jquery_ui_path . 'datepicker.min.js' && $locale != 'en_US') {
                $result .= '<script type="text/javascript" src="' . $wa->getRootUrl() . 'wa-content/js/jquery-ui/i18n/jquery.ui.datepicker-' . $locale . '.js"></script>' . "\n";
            }
        }
    }
    return $result;
}
Example #25
0
 /**
  * Reads file contents and outputs it to browser with appropriate headers.
  *
  * @param string $file File to path
  * @param string|null $attach Name, which will be suggested to user when he requests to download the file.
  *     If not specified, browser's auto-suggestion will be used.
  * @param bool $exit Flag requiring to send file transfer headers to user's browser. By default (true) headers are sent.
  * @param bool $md5 Flag requiring to send the Content-MD5 header. By default (false) this header is not sent.
  * @throws waException If file does not exist
  */
 public static function readFile($file, $attach = null, $exit = true, $md5 = false)
 {
     if (file_exists($file)) {
         $response = wa()->getResponse();
         $file_type = self::getMimeType($attach ? $attach : $file);
         if ($md5) {
             $md5 = base64_encode(pack('H*', md5_file($file)));
         }
         @ini_set('async_send', 1);
         wa()->getStorage()->close();
         if ($attach !== null) {
             $send_as = str_replace('"', '\\"', is_string($attach) ? $attach : basename($file));
             $send_as = preg_replace('~[\\n\\r]+~', ' ', $send_as);
             $x_accel_redirect = waSystemConfig::systemOption('x_accel_redirect');
             $file_size = filesize($file);
             $response->setStatus(200);
             if (empty($x_accel_redirect)) {
                 $from = $to = false;
                 if ($http_range = waRequest::server('HTTP_RANGE')) {
                     // multi range support incomplete
                     list($dimension, $range) = explode("=", $http_range, 2);
                     $ranges = explode(',', $range);
                     $intervals = array();
                     foreach ($ranges as $range) {
                         $range = trim($range);
                         if (preg_match('/^(\\d+)-(\\d+)$/', $range, $matches)) {
                             $intervals[] = array('from' => intval($matches[1]), 'to' => intval($matches[2]));
                         } elseif (preg_match('/^(\\d+)-$/', $range, $matches)) {
                             $intervals[] = array('from' => intval($matches[1]), 'to' => $file_size - 1);
                         } elseif (preg_match('/^-(\\d+)$/', $range, $matches)) {
                             $intervals[] = array('from' => $file_size - intval($matches[1]), 'to' => $file_size - 1);
                         } else {
                             throw new waException('Requested range not satisfiable', 416);
                         }
                     }
                     foreach ($intervals as $interval) {
                         if ($from === false) {
                             $from = $interval['from'];
                         }
                         if ($to === false) {
                             $to = $interval['to'];
                         } else {
                             if ($to + 1 == $interval['from']) {
                                 $to = $interval['to'];
                             } else {
                                 //hole at interval
                                 throw new waException('Requested range not satisfiable', 416);
                             }
                         }
                     }
                     if ($from < 0 || $to + 1 > $file_size) {
                         throw new waException('Requested range not satisfiable', 416);
                     }
                     $range_length = $to - $from + 1;
                     $response->setStatus(206);
                     $response->addHeader("Content-Length", $range_length);
                     $response->addHeader("Content-Range", "bytes {$from}-{$to}/{$file_size}");
                 } else {
                     $response->addHeader("Content-Length", $file_size);
                     if ($md5) {
                         $response->addHeader("Content-MD5", $md5);
                     }
                 }
                 $response->addHeader("Cache-Control", "no-cache, must-revalidate");
                 $response->addHeader("Content-type", "{$file_type}");
                 $response->addHeader("Content-Disposition", "attachment; filename=\"{$send_as}\"");
                 $response->addHeader("Last-Modified", filemtime($file));
                 $response->addHeader("Accept-Ranges", "bytes");
                 $response->addHeader("Connection", "close");
                 $fp = fopen($file, 'rb');
                 if ($from) {
                     fseek($fp, $from);
                 }
                 $response->sendHeaders();
                 $response = null;
                 //TODO: adjust chunk size
                 $chunk = 1048576;
                 //1M
                 while (!feof($fp) && $chunk && connection_status() == 0) {
                     if ($to) {
                         $chunk = min(1 + $to - @ftell($fp), $chunk);
                     }
                     if ($chunk) {
                         print @fread($fp, $chunk);
                         @flush();
                     }
                 }
                 @fclose($fp);
             } else {
                 $response->addHeader("Content-type", $file_type);
                 //RFC 6266
                 $response->addHeader("Content-Disposition", "attachment; filename=\"{$send_as}\"");
                 $response->addHeader("Accept-Ranges", "bytes");
                 $response->addHeader("Content-Length", $file_size);
                 $response->addHeader("Expires", "0");
                 $response->addHeader("Cache-Control", "no-cache, must-revalidate", false);
                 $response->addHeader("Pragma", "public");
                 $response->addHeader("Connection", "close");
                 if ($md5) {
                     $response->addHeader("Content-MD5", $md5);
                 }
                 $response->addHeader("X-Accel-Redirect", $file);
                 $response->sendHeaders();
                 $response = null;
                 //@future
                 //$response->addHeader("X-Accel-Limit-Rate", $rate_limit);
             }
         } else {
             $response->addHeader("Content-type", $file_type);
             $response->addHeader("Last-Modified", filemtime($file));
             if ($md5) {
                 $response->addHeader("Content-MD5", $md5);
             }
             $response->sendHeaders();
             $response = null;
             @readfile($file);
         }
         if ($exit) {
             if (!empty($response)) {
                 /**
                  * @var waResponse $response
                  */
                 $response->sendHeaders();
             }
             exit;
         }
     } else {
         throw new waException("File not found", 404);
     }
 }
 protected function checkUpdates()
 {
     $app_settings_model = new waAppSettingsModel();
     $time = $app_settings_model->get(array($this->app_id, $this->id), 'update_time');
     if (!$time) {
         try {
             $this->install();
         } catch (Exception $e) {
             waLog::log($e->getMessage());
             throw $e;
         }
         $ignore_all = true;
     } else {
         $ignore_all = false;
     }
     $is_debug = waSystemConfig::isDebug();
     if (!$is_debug) {
         $cache = new waVarExportCache('updates', 0, $this->app_id . "." . $this->id);
         if ($cache->isCached() && $cache->get() <= $time) {
             return;
         }
     }
     $path = $this->path . '/lib/updates';
     $cache_database_dir = wa()->getConfig()->getPath('cache') . '/db';
     if (file_exists($path)) {
         $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
         $files = array();
         foreach ($iterator as $file) {
             /**
              * @var SplFileInfo $file
              */
             if ($file->isFile() && preg_match('/^[0-9]+\\.php$/', $file->getFilename())) {
                 $t = substr($file->getFilename(), 0, -4);
                 if ($t > $time) {
                     $files[$t] = $file->getPathname();
                 }
             }
         }
         ksort($files);
         if (!$is_debug) {
             // get last time
             if ($files) {
                 $keys = array_keys($files);
                 $cache->set(end($keys));
             } else {
                 $cache->set($time ? $time : 1);
             }
         }
         foreach ($files as $t => $file) {
             try {
                 if (!$ignore_all) {
                     include $file;
                     waFiles::delete($cache_database_dir);
                     $app_settings_model->set(array($this->app_id, $this->id), 'update_time', $t);
                 }
             } catch (Exception $e) {
                 if ($is_debug) {
                     echo $e;
                 }
                 // log errors
                 waLog::log($e->__toString());
                 break;
             }
         }
     } else {
         $t = 1;
     }
     if ($ignore_all) {
         if (!isset($t) || !$t) {
             $t = 1;
         }
         $app_settings_model->set(array($this->app_id, $this->id), 'update_time', $t);
     }
 }
Example #27
0
 public function addCss($url, $app_id = false)
 {
     if ($app_id) {
         $url = wa()->getAppStaticUrl($app_id) . $url;
         $app_info = wa()->getAppInfo($app_id === true ? null : $app_id);
         $url .= '?' . (isset($app_info['version']) ? $app_info['version'] : '0.0.1');
         if (waSystemConfig::isDebug()) {
             $url .= '.' . time();
         }
     } else {
         $url = wa()->getRootUrl() . $url;
     }
     $this->css[] = $url;
     return $this;
 }
 private function validate()
 {
     libxml_use_internal_errors(true);
     shopYandexmarketPlugin::path('shops.dtd');
     $this->loadDom($this->data['path']['offers']);
     $valid = @$this->dom->validate();
     $strict = waSystemConfig::isDebug();
     if ((!$valid || $strict) && ($r = libxml_get_errors())) {
         $this->data['error'] = array();
         $error = array();
         if ($valid) {
             $this->data['error'][] = array('level' => 'info', 'message' => 'YML-файл валиден');
         } else {
             $this->data['error'][] = array('level' => 'error', 'message' => 'YML-файл содержит ошибки');
         }
         foreach ($r as $er) {
             /**
              * @var libXMLError $er
              */
             $level_name = '';
             switch ($er->level) {
                 case LIBXML_ERR_WARNING:
                     $level_name = 'LIBXML_ERR_WARNING';
                     break;
                 case LIBXML_ERR_ERROR:
                     $level_name = 'LIBXML_ERR_ERROR';
                     break;
                 case LIBXML_ERR_FATAL:
                     $level_name = 'LIBXML_ERR_FATAL';
                     break;
             }
             if ($er->code != 505) {
                 $this->data['error'][] = array('level' => $valid ? 'warning' : 'error', 'message' => "{$level_name} #{$er->code} [{$er->line}:{$er->column}]: {$er->message}");
             }
             $error[] = "Error #{$er->code}[{$er->level}] at [{$er->line}:{$er->column}]: {$er->message}";
         }
         if ($valid && count($this->data['error']) == 1) {
             $this->data['error'] = array();
         }
         $this->error(implode("\n\t", $error));
     }
 }
 /**
  * Called when something went badly wrong so that current Runner should not continue,
  * (at least should immidiately notify a developer if in debug mode).
  * Still, not badly enough yet to break the whole long action process.
  */
 protected function runnerFatalWarning($msg)
 {
     if (waSystemConfig::isDebug()) {
         // In debug mode, better to fail fast.
         throw new waException($msg);
     } else {
         waLog::log('waLongActionController (' . get_class($this) . '): ' . $msg);
     }
 }
Example #30
0
 /**
  * Returns the photo URL of the specified contact.
  *
  * @param int $id Contact id
  * @param int $ts Contact photo id stored in contact's 'photo' property. If not specified, the URL of the default
  *     userpic is returned.
  * @param int|string|null $width Image width. Arbitrary integer value, or string value 'original', which requires
  *     that method must return the URL of the original image originally uploaded from a user's computer. Defaults to 96.
  * @param int|string|null $height Image height (integer). If not specified, the integer value specified for the
  *     $width parameter is used.
  * @param string $type
  * @param bool $retina
  * @return string
  */
 public static function getPhotoUrl($id, $ts, $width = null, $height = null, $type = 'person', $retina = null)
 {
     if ($width === 'original') {
         $size = 'original';
     } else {
         if ($width && !$height) {
             $size = $width . 'x' . $width;
         } else {
             if (!$width) {
                 $width = 96;
                 $size = '96x96';
             } else {
                 $size = $width . 'x' . $height;
             }
         }
     }
     if ($retina === null) {
         $retina = wa()->getEnv() == 'backend';
     }
     $dir = self::getPhotoDir($id, false);
     if ($ts) {
         if ($size != 'original' && $retina) {
             $size .= '@2x';
         }
         if (waSystemConfig::systemOption('mod_rewrite')) {
             return wa()->getDataUrl("photos/{$dir}{$ts}.{$size}.jpg", true, 'contacts');
         } else {
             if (file_exists(wa()->getDataPath("photos/{$dir}{$ts}.{$size}.jpg", true, 'contacts'))) {
                 return wa()->getDataUrl("photos/{$dir}{$ts}.{$size}.jpg", true, 'contacts');
             } else {
                 return wa()->getDataUrl("photos/thumb.php/{$dir}{$ts}.{$size}.jpg", true, 'contacts');
             }
         }
     } else {
         $size = (int) $width;
         if (!in_array($size, array(20, 32, 50, 96))) {
             $size = 96;
         }
         if ($retina) {
             $size .= '@2x';
         }
         if ($type == 'company') {
             return wa()->getRootUrl() . 'wa-content/img/company' . $size . '.jpg';
         } else {
             return wa()->getRootUrl() . 'wa-content/img/userpic' . $size . '.jpg';
         }
     }
 }