public function __construct() { $conf = Context::last()->config->get('modules/drawtext'); if (isset($conf['font'])) { $this->setFont($conf['font']); } }
/** * Загружает файл в S3. */ public static function moveFileToS3($fileName, $mimeType = null, $baseName = null) { self::checkEnv($ctx = Context::last()); $conf = $ctx->config->get('modules/s3'); $s3 = new S3($conf['accesskey'], $conf['secretkey']); if (!($bucketName = trim($ctx->config->get('modules/s3/bucket', 'files'), '/'))) { throw new RuntimeException(t('Модуль s3 не настроен (bucket).')); } if ($folderName = $ctx->config->get('module/s3/folder', 'files')) { $folderName .= '/'; } /* if (!in_array($bucketName, $s3->listBuckets())) throw new RuntimeException(t('Нет такой папки: ' . $bucketName)); */ if ($f = fopen($fileName, 'rb')) { if (null === $baseName) { $baseName = basename($fileName); } if (!($r = S3::inputResource($f, filesize($fileName)))) { throw new RuntimeException(t('Не удалось создать ресурс из файла %filename.', array('%filename' => $fileName))); } if (!($response = S3::putObject($r, $bucketName, $folderName . $baseName, S3::ACL_PUBLIC_READ))) { throw new RuntimeException(t('Не удалось загрузить файл %filename в папку %bucket.', array('%filename' => $fileName, '%bucket' => $bucketName))); } $url = 'http://' . $bucketName . '.s3.amazonaws.com/' . $folderName . $baseName; Logger::log('S3: ' . $url); return $url; } }
/** * Клонирование прав при клонировании объекта. * @mcms_message ru.molinos.cms.node.clone */ public static function on_clone(Node $node) { if ($node instanceof UserNode) { $node->name .= '/tmp' . rand(); } $node->uid = Context::last()->user->getNode(); }
/** * Форматирование значения. Вызывает обработчики вроде типографа. */ public function format(Node $node, $em) { $value = $node->{$this->value}; $ctx = Context::last(); $ctx->registry->broadcast('ru.molinos.cms.format.text', array($ctx, $this->value, &$value)); return html::wrap($em, html::cdata($value)); }
/** * @mcms_message ru.molinos.cms.module.settings.drawtext */ public static function on_get_settings(Context $ctx) { $fonts = array(); foreach (Node::find(Context::last()->db, array('class' => 'file', 'filetype' => 'application/x-font-ttf')) as $n) { $fonts[$n->id] = isset($n->name) ? $n->name : $n->filename; } return new Schema(array('font' => array('type' => 'EnumControl', 'label' => t('Шрифт по умолчанию'), 'default' => t('(не использовать)'), 'options' => $fonts, 'description' => t('Вы можете <a href=\'@url\'>загрузить новый шрифт</a> в файловый архив.', array('@url' => '?q=admin/content/create&type=file&destination=CURRENT'))))); }
public function getSelected($data) { if (null === ($email = $this->findEmail($data))) { return array(); } $tags = Context::last()->db->getResultsV("tid", "SELECT tid FROM node__rel WHERE nid IN (SELECT id FROM node WHERE class = 'subscription' AND deleted = 0 AND name = ?)", array($email)); return is_array($tags) ? $tags : array(); }
public function getEnabledSections() { $conf = Context::last()->config->get('modules/subscription'); if (!array_key_exists('sections', $conf)) { return array(); } return $conf['sections']; }
private function isActive($data) { if ($data->id) { return false; } $ctx = Context::last(); if ($ctx->user->id and !$this->required) { return false; } return true; }
public function checkPermission($perm) { $user = Context::last()->user; mcms::debug($this->uid, $this->re); if ($this->cmp($this->uid, $user->id)) { return true; } if ($this->cmp($this->re, $user->id)) { return true; } return false; }
public function __construct($url = '', $code = 302) { if ('POST' == $_SERVER['REQUEST_METHOD']) { $code = self::OTHER; } $u = new url($url); $url = $u->getAbsolute(Context::last()); $this->url = $url; $message = t('<html><head><title>Redirecting</title>' . '<meta http-equiv=\'refresh\' content=\'0; url=@url\' />' . '</head><body>' . '<h1>Redirecting</h1><p>Redirecting to <a href=\'@url\'>a new location</a>.</p>' . '</body></html>', array('@url' => $url)); $this->headers[] = 'Location: ' . $this->url; parent::__construct($message, 'text/html', $code); }
private static function getProfileFields() { $result = array(); foreach (Schema::load(Context::last()->db, 'user') as $k => $v) { $result[$k] = $v->label; } if (isset($result['groups'])) { unset($result['groups']); } asort($result); return $result; }
/** * Добавляет в комментарий информацию о ноде. */ public function getExtraXMLContent() { $content = parent::getExtraXMLContent(); $db = Context::last()->db; $node = $this->node ? $this->node : $db->fetch("SELECT `tid` FROM `node__rel` WHERE `nid` = ? LIMIT 1", array($this->id)); if ($node) { if ($data = $db->getResults("SELECT id, class, name FROM node WHERE id = ?", array($node))) { $content .= html::em('node', $data[0]); } } return $content; }
/** * Переключается в указанного пользователя, проверяет его статус. */ private static function login($uid) { if ($uid) { $data = Context::last()->db->fetch("SELECT `id`, `published` FROM `node` WHERE `class` = 'user' AND `deleted` = 0 AND `id` = ?", array($uid)); if (empty($data)) { throw new ForbiddenException(t('Нет такого пользователя.')); } elseif (empty($data['published'])) { throw new ForbiddenException(t('Ваш профиль заблокирован.')); } } User::storeSessionData($uid); }
public function format(Node $node, $em) { $result = ''; $value = $node->{$this->value}; if (!empty($value) and is_array($value)) { $params = array(); $data = (array) Context::last()->db->getResults($sql = "SELECT `id`, `published`, `name` FROM `node` WHERE `class` = 'label' AND `deleted` = 0 AND `id` " . sql::in(array_keys($value), $params), $params); foreach ($data as $row) { $result .= html::em('label', array('id' => $row['id'], 'published' => (bool) $row['published']), html::cdata($row['name'])); } } return html::wrap($em, $result); }
private function getProductLink(array $item) { $ctx = Context::last(); if (empty($item['id'])) { return htmlspecialchars($item['name']); } if (0 === strpos($ctx->query(), 'admin/')) { $url = '?q=admin/edit/' . $item['id'] . '&destination=admin'; } else { $url = '?q=nodeapi.rpc&action=locate&node=' . $item['id']; } return html::link($url, html::plain($item['name'])); }
public function format(Node $node, $em) { $value = $node->{$this->value}; include_once os::path(dirname(__FILE__), 'markdown.php'); $output = Markdown($value); $ctx = Context::last(); $ctx->registry->broadcast('ru.molinos.cms.format.text', array($ctx, $this->value, &$output)); $attrs = array(); if (!($sniplen = $this->sniplen)) { $sniplen = 50; } $attrs['snippet'] = mb_strimwidth(strip_tags($output), 0, $sniplen, '…'); return html::wrap($em, html::cdata(trim($output)), $attrs); }
private static function getUid($re) { if (empty($re)) { return Context::last()->user->id; } elseif ($re instanceof Node) { return $re->id; } elseif (is_numeric($re)) { return intval($re); } if (is_array($re) and count($re) == 1) { return self::getUid(array_shift($re)); } throw new InvalidArgumentException(t('Получатель сообщения должен быть указан числом или объектом Node.')); }
protected function getData() { $data = Node::find(array('class' => 'type', 'deleted' => 0, '#sort' => '-published name'), Context::last()->db); $counts = $this->ctx->db->getResultsKV("name", "count", "SELECT `class` AS `name`, COUNT(*) AS `count` FROM `node` WHERE `deleted` = 0 GROUP BY `class`"); $nodes = ''; foreach ($data as $node) { if (!$node->isdictionary) { $tmp = Node::create($node->name); $attrs = array('id' => $node->id, 'name' => $node->name, 'title' => $node->title, 'list' => $tmp->getListURL(), 'published' => (bool) $node->published, 'dynamic' => $tmp->canEditFields()); $attrs['count'] = array_key_exists($node->name, $counts) ? $counts[$node->name] : 0; $nodes .= html::em('node', $attrs); } } return html::wrap('data', $nodes); }
protected function sendEmail($to, $mode) { if (empty($to)) { Logger::log($mode . ' not sent: email not found', 'cart'); return; } if (!($xslt = Context::last()->config->get("modules/cart/{$mode}_templates"))) { Logger::log($mode . ' not sent: XSLT file not set', 'cart'); return; } if ($html = xslt::process($this->getXML(), $xslt)) { $subject = t('Заказ на %host', array('%host' => MCMS_HOST_NAME)); BebopMimeMail::send(null, $to, $subject, $html); } }
/** * Сохранение введённого значения. * * Если объект не новый — у него есть id — ничего не происходит. Для новых * объектов сохраняется информация о пользователе только если он не попросил * анонимности. */ public function set($value, &$node) { if ($node->id) { return; } $user = Context::last()->user; // Анонимность разрешена и запрошена. if (!$this->required and $user->id and $value) { return; } // Сохраняем информацию. if ($user->id) { $node->{$this->value} = $user->id; } elseif ($value) { $node->{$this->value . ':name'} = $value; } }
private static function fixhtml($html) { $re = '@<a(\\s+([a-z]+)=([\'"]([^\'"]+)[\'"]))+\\s*>@i'; if (preg_match_all($re, $html, $m)) { foreach ($m[4] as $idx => $href) { if (false !== strpos($href, '://')) { continue; } if (false !== strpos($href, 'mailto:')) { continue; } $ctx = Context::last(); $new = $ctx->url()->getBase($ctx) . $href; $new = str_replace($href, $new, $m[0][$idx]); $html = str_replace($m[0][$idx], $new, $html); } } return $html; }
/** * Сохранение значения. */ public function set($value, &$node) { $node->{$this->value} = null; if (!empty($value)) { if (preg_match('/^[0-9\\.\\,]+$/', $value)) { list($lat, $lon) = explode(',', $value); } elseif ($key = Context::last()->config->get('modules/googlemaps/key')) { $url = 'http://maps.google.com/maps/geo?q=' . urlencode(trim($value)) . '&output=csv&oe=utf8&sensor=false&key=' . urlencode($key); if ($data = http::fetch($url, http::CONTENT)) { list($status, $accuracy, $lat, $lon) = explode(',', $data); if (200 != $status) { return; } } else { return; } } else { return; } $node->{$this->value} = array('query' => $value, 'lat' => $lat, 'lon' => $lon); } }
private function notify($isnew) { if ($this->to and $this->to == Context::last()->user->id) { return; } $data = array('mode' => 'mail', 'node' => $this->getRaw()); $data['node']['uid'] = Node::load(array('class' => 'user', 'id' => $this->uid))->getRaw(); $message = bebop_render_object('mail', 'todo', null, $data, __CLASS__); if (!empty($message)) { if ($isnew) { if ($this->to) { mcms::mail(null, $this->to, t('Новое напоминание'), $message); } } elseif (!$isnew) { if ($this->closed) { mcms::mail(null, $this->uid, t('Напоминание удалено'), $message); } elseif ($this->to) { mcms::mail(null, $this->to, t('Напоминание реактивировано'), $message); } } } }
public static function run() { try { self::setup(); $ctx = Context::last(); if ('admin/install' != $ctx->query() and !$ctx->config->isOk()) { $ctx->redirect('admin/install'); } $router = new Router(); $result = $router->poll($ctx)->dispatch($ctx); if ($result instanceof Response) { $result->send(); } elseif (false === $result) { header('HTTP/1.1 404 Not Found'); header('Content-Type: text/plain; charset=utf-8'); die('Route Not Found.'); } else { list($handler, $args) = $router->find($ctx); if (false === $handler) { $method = '?unknown?'; } elseif (is_array($handler['call'])) { $method = implode('::', $handler['call']); } else { $method = $handler['call']; } $message = t('<h1>Внутренняя ошибка</h1><p>Обработчик пути <tt>%path</tt> (<tt>%func</tt>) должен был вернуть объект класса <a href="@class">Response</a>, а вернул %type.</p><hr/><a href="@home">Molinos CMS v%version</a>', array('%path' => $ctx->query(), '%type' => gettype($result), '%func' => $method, '@class' => 'http://code.google.com/p/molinos-cms/wiki/Response_Class', '%version' => MCMS_VERSION, '@home' => 'http://molinos-cms.googlecode.com/')); header('HTTP/1.1 500 Internal Server Error'); header('Content-Type: text/html; charset=utf-8'); die($message); } } catch (Exception $e) { Logger::trace($e); header('HTTP/1.1 500 FUBAR'); header('Content-Type: text/plain; charset=utf-8'); die(sprintf('%s: %s.', get_class($e), rtrim($e->getMessage(), '.'))); } }
public static function getSignature(Context $ctx = null, $full = false) { $result = array('version' => mcms::version(), 'client' => $_SERVER['REMOTE_ADDR']); try { if (null === $ctx) { $ctx = Context::last(); } $result['at'] = $ctx->host() . $ctx->folder(); $result['version_link'] = 'http://code.google.com/p/molinos-cms/wiki/ChangeLog_' . str_replace('.', '_', mcms::version(mcms::VERSION_STABLE)); if ($full) { $options = array(); if (count($parts = explode(':', mcms::config('db')))) { if (in_array($parts[0], Database::listDrivers())) { $options[] = $parts[0]; } } $options[] = str_replace('_provider', '', get_class(cache::getInstance())); $options[] = ini_get('memory_limit'); $result['options'] = join('+', $options); } } catch (Exception $e) { } return $result; }
protected function getRequestOptions(Context $ctx, array $params) { $options = array('uid' => Context::last()->user->id, 'mode' => $this->mode ? $this->mode : $this->get('mode', 'inbox'), 'limit' => $this->limit); return $options; }
/** * Отправляет сообщение об ошибке куда следует. */ private static function send_error($message = "undefined", $extra = null) { Logger::trace($message); if (class_exists('BebopMimeMail')) { $message = wordwrap(strip_tags($message), 75, "\n "); $referer = empty($_SERVER['HTTP_REFERER']) ? null : "Referer: {$_SERVER['HTTP_REFERER']}\n"; $subject = "Error at " . MCMS_HOST_NAME; $content = "<pre>Message: {$message}\nMethod: {$_SERVER['REQUEST_METHOD']}\n" . "URL: http://" . MCMS_HOST_NAME . MCMS_REQUEST_URI . "\n{$extra}\n{$referer}" . "Backtrace follows.\n\n" . Logger::backtrace() . '</pre>'; BebopMimeMail::send(null, Context::last()->config->get('main/errors/mail'), $subject, $content); } }
public static function getAccessible($mode = ACL::READ) { $ctx = Context::last(); $result = array(); foreach (Node::find(array('class' => 'type', 'deleted' => 0), $ctx->db) as $type) { if (null === $mode or $ctx->user->hasAccess(ACL::READ, $type->name)) { $result[$type->name] = empty($type->title) ? $type->name : $type->title; } } asort($result); return $result; }
/** * Сбрасывает права для указанных объектов. */ public static function resetNode(array $nodeIds) { $params = array(); Context::last()->db->exec("DELETE FROM `node__access` WHERE `nid` " . sql::in($nodeIds, $params), $params); self::flush(); }
/** * Сохранение объекта. Добавляет индексацию. */ public function save() { if ($this->dirty) { $ctx = Context::last(); // Публикация при создании, если есть права. // TODO: вынести в отдельный модуль? if ($this->isNew() and $this->checkPermission(ACL::PUBLISH)) { $this->data['published'] = true; } $ctx->registry->broadcast('ru.molinos.cms.hook.node.before', array($ctx, $this, $this->isNew() ? 'create' : 'update')); $this->realSave(); $ctx->registry->broadcast('ru.molinos.cms.hook.node', array($ctx, $this, $this->isNew() ? 'create' : 'update')); } return $this; }