/** * Сверяет введённое значение с сохранённым в сессии. */ protected function validate($value) { if (!($good = mcms::session('captcha:' . $this->value)) or $good != $value) { throw new ValidationException($this->label, t('Вы неверно ввели символы с картинки. Похоже, вы — робот, рассылающий спам!')); } mcms::session('captcha:' . $this->value, null); }
/** * @mcms_message ru.molinos.cms.hook.node */ public static function hookNodeUpdate(Context $ctx, Node $node, $op) { switch ($op) { case 'delete': $node->onSave("UPDATE `node` SET `deleted` = 1 WHERE `class` = 'comment' AND `id` IN (SELECT `nid` FROM `node__rel` WHERE `tid` = %ID%"); break; case 'erase': $node->onSave("DELETE FROM `node` WHERE `class` = 'comment' AND `id` IN (SELECT `nid` FROM `node__rel` WHERE `tid` = %ID%)"); break; case 'create': if (!empty($node->doc) and is_numeric($nid = Node::_id($node->doc))) { // Собираем прикреплённых пользователей. $l1 = $node->getDB()->getResultsV("nid", "SELECT `nid` " . "FROM `node__rel` WHERE `tid` = ? AND `nid` IN (SELECT `id` " . "FROM `node` WHERE `class` = 'user')", array($nid)); // Собираем пользователей, комментировавших ранее $l2 = $node->getDB()->getResultsV("uid", "SELECT `n`.`uid` " . "FROM `node` `n` " . "INNER JOIN `node__rel` `r` ON `r`.`nid` = `n`.`id` " . "WHERE `r`.`tid` = ? AND `n`.`class` = 'comment'", array($nid)); $uids = array_diff(array_unique(array_merge($l1, $l2)), array($ctx->user->id)); $body = mcms::render(__CLASS__, array('mode' => 'new', 'comment' => $node->getRaw())); if (!empty($body) and !empty($uids)) { foreach ($uids as $uid) { if (empty($node->doc)) { $subject = t('Новый комментарий'); } else { $subject = t('Новый комментарий [%id]', array('%id' => Node::_id($node->doc))); } mcms::mail(null, $uid, $subject, $body); } } } } }
/** * @mcms_message ru.molinos.cms.hook.node */ public static function on_node_change(Context $ctx, $node, $op) { try { list($sql, $params) = sql::getInsert('node__log', array('nid' => $node->id, 'uid' => $ctx->user->id, 'username' => $ctx->user->getNode()->getName(), 'operation' => $op, 'ip' => $_SERVER['REMOTE_ADDR'], 'timestamp' => mcms::now(), 'name' => $node->name)); $ctx->db->exec($sql, $params); } catch (TableNotFoundException $e) { } }
public static function rpc_purge(Context $ctx) { $filter = array('class' => 'message', 're' => $ctx->user->id); $ids = join(', ', array_keys(Node::find($ctx->db, $filter))); if (!empty($ids)) { $ctx->db->exec("DELETE FROM `node` WHERE `id` IN ({$ids})"); mcms::flush(); } }
private function setFont($font) { try { $fNode = Node::load(array('id' => $font, 'class' => 'file')); } catch (ObjectNotFoundException $e) { throw new PageNotFoundException(t('Шрифт с идентификатором %id не найден.', array('%id' => $font))); } $this->font = mcms::config('filestorage') . DIRECTORY_SEPARATOR . $fNode->filepath; }
/** * @mcms_message ru.molinos.cms.log.access */ public static function on_log(Context $ctx, Node $node) { try { $ctx->db->beginTransaction(); $ctx->db->exec("INSERT INTO `node__astat` (`nid`, `timestamp`) VALUES (?, ?)", array($node->id, mcms::now())); $ctx->db->commit(); } catch (TableNotFoundException $e) { } }
/** * Поиск доступного обновления. * * @return string номер доступной версии. */ private static function getAvailable() { $release = mcms::version(mcms::VERSION_RELEASE); $content = http::fetch('http://code.google.com/p/molinos-cms' . '/downloads/list?q=label:R' . $release, http::CONTENT); if (preg_match($re = "@http://molinos-cms\\.googlecode\\.com/files/molinos-cms-({$release}\\.[0-9]+)\\.zip@", $content, $m)) { return $m[1]; } else { return $version; } }
public static function decrypt($input) { $input = base64_decode(rawurldecode($input)); if (function_exists('mcrypt_create_iv') and $key = mcms::config('guid')) { $securekey = hash('sha256', $key, true); $iv = mcrypt_create_iv(32); $input = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $securekey, $input, MCRYPT_MODE_ECB, $iv); } return $input; }
protected static function getSchema($mode) { switch ($mode) { case 'update': return new Schema(array('info' => array('type' => 'InfoControl', 'text' => t('Система полностью обновлена (наличие обновлений проверяется в фоновом режиме, по расписанию).')), 'submit' => array('type' => 'SubmitControl', 'text' => t('Проверить наличие обновлений')))); case 'upgrade': return new Schema(array('modules' => array('type' => 'ModManControl', 'label' => t('Доступные обновления'), 'columns' => array('check', 'name', 'version', 'available'), 'disable_required' => false), 'submit' => array('type' => 'SubmitControl', 'text' => t('Обновить отмеченные')))); default: mcms::debug($mode); } }
/** * Вызов api/ads/get.xml * * Возвращает случайные баннеры. * * @route GET//api/ads/get.xml */ public static function on_get_banners(Context $ctx) { $limit = intval($ctx->get('limit', 1)); $sql = "SELECT `node`.`id`, `xml` FROM `node` " . "INNER JOIN `node__banners` ON `node__banners`.`id` = `node`.`id` " . "WHERE `class` = 'banner' AND `deleted` = 0 AND `published` = 1 " . "AND (`time_limit` IS NULL OR `time_limit` < ?) " . "AND (`display_limit` IS NULL OR `display_count` IS NULL OR `display_count` < `display_limit`) " . "ORDER BY RAND() LIMIT " . $limit; $data = $ctx->db->getResultsKV("id", "xml", $sql, array(mcms::now())); $params = array(); $ctx->db->beginTransaction(); $ctx->db->exec("UPDATE `node__banners` SET `display_count` = 0 WHERE `display_count` IS NULL"); $ctx->db->exec("UPDATE `node__banners` SET `display_count` = `display_count` + 1 WHERE `id` " . sql::in(array_keys($data), $params), $params); $ctx->db->commit(); return new Response(html::em('nodes', implode('', $data)), 'text/xml'); }
public function run(array $args) { try { $this->prepare($args); $this->process(); $this->cleanup(); } catch (Exception $e) { mcms::fatal($e); $this->log("Error: " . rtrim($e->getMessage(), '.')); exit(1); } }
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; }
/** * Добавление файлов с FTP (форма). */ public static function on_get_ftp_form(Context $ctx) { if (!($files = self::getFtpFiles($ctx))) { throw new PageNotFoundException(); } $options = array('name' => 'addfile', 'title' => t('Добавление <a href="@url">файлов</a>, загруженных по FTP', array('@url' => 'admin/content/files')), 'mode' => 'ftp', 'target' => 'admin/create/file/ftp?destination=' . urlencode($ctx->get('destination')), 'back' => $ctx->get('destination')); $content = ''; foreach ($files as $file) { $content .= html::em('file', array('name' => basename($file), 'size' => filesize($file), 'sizeh' => mcms::filesize(filesize($file)), 'time' => mcms::now(filemtime($file)))); } $content .= self::get_modes($ctx, 'ftp'); return html::em('content', $options, $content); }
/** * Выход, завершение сеанса. * * @param Context $ctx * @return Response */ public static function rpc_get_logout(Context $ctx) { $uid = null; $stack = (array) mcms::session('uidstack'); $uid = array_pop($stack); mcms::session('uidstack', $stack); if (empty($uid)) { $ctx->user->logout(); } else { self::login($uid); } $next = $uid ? $ctx->get('from', '') : ''; return $ctx->getRedirect($next); }
private static function checkDbAccess(Context $ctx) { if (null !== ($file = $ctx->db->getDbFile())) { if (0 === strpos(realpath($file), MCMS_ROOT . DIRECTORY_SEPARATOR)) { $url = $ctx->url()->getBase($ctx) . os::webpath($file); if (false !== ($headers = (array) @get_headers($url, 1))) { if (3 == count($parts = explode(' ', $headers[0]))) { if (200 == $parts[1]) { return t('Файл базы данных доступен веб серверу, любой желающий может <a href=\'@url\'>скачать его</a>. Пожалуйста, вынесите его в папку, недоступную веб серверу, и измените путь в конфигурационном файле (%config).', array('@url' => $url, '%config' => mcms::config('fullpath'))); } } } } } }
/** * Форматирует содержимое стэка. */ public static function backtrace($stack = null, $condition = null) { $output = ''; if (null !== $condition and !defined($condition)) { return; } if ($stack instanceof Exception) { $tmp = $stack->getTrace(); array_unshift($tmp, array('file' => $stack->getFile(), 'line' => $stack->getLine(), 'function' => sprintf('throw new %s', get_class($stack)))); $stack = $tmp; } elseif (null === $stack or !is_array($stack)) { $stack = debug_backtrace(); array_shift($stack); } $libdir = 'lib' . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR; $idx = 1; foreach ($stack as $k => $v) { /* if (!empty($v['file'])) $v['file'] = preg_replace('@.*'. preg_quote($libdir) .'@', $libdir, $v['file']); if (!empty($v['class'])) $func = $v['class'] .$v['type']. $v['function']; else $func = $v['function']; */ if (empty($v['file'])) { continue; } $output .= sprintf("%2d. ", $idx++); if (class_exists('mcms')) { $output .= mcms::formatStackElement($v); } /* if (!empty($v['file']) and !empty($v['line'])) $output .= sprintf('%s(%d) — ', ltrim(str_replace(MCMS_ROOT, '', $v['file']), '/'), $v['line']); else $output .= '??? — '; $output .= $func .'()'; */ $output .= "\n"; } return $output; }
protected function getRequestOptions(Context $ctx, array $params) { $options = parent::getRequestOptions($ctx, $params); if ($params['section'] or $params['document']) { mcms::debug("Виджет {$this->getInstanceName()} не может работать на страницах, параметризуемых кодом раздела или документа."); throw new WidgetHaltedException(); } if (count($ctx->apath) == 1) { $options['user'] = $ctx->apath[0]; } elseif (count($ctx->apath) > 1) { throw new PageNotFoundException(); } else { $options['user'] = null; } $options['limit'] = $this->limit ? $this->limit : 10; $options['page'] = $this->get('page', 1); return $options; }
protected function getData() { switch ($this->preset) { case 'pages': $data = self::getNodeTree(); if (empty($data)) { $url = 'admin/create/' . $this->type; if ($parent_id = $this->getParentId()) { $url .= '/' . $parent_id; } $url .= '?destination=CURRENT'; $r = new Redirect($url); $r->send(); } return $data; default: mcms::debug($this->ctx->get('preset'), $this->ctx); } }
/** * Вывод содержимого объекта. */ public static function on_get_dump(Context $ctx) { $filter = array('id' => $ctx->get('node')); if (!$ctx->canDebug()) { $filter['deleted'] = 0; } if ($ctx->get('raw')) { $node = Node::load($filter, $ctx->db); $temp = $node->{'never should this field exist'}; mcms::debug($node); } else { $xml = Node::findXML($filter, $ctx->db); if (empty($xml)) { throw new RuntimeException(t('Для этого документа нет XML представления (такого быть не должно), см. <a href="@url">сырой вариант</a>.', array('@url' => '?q=node/' . $filter['id'] . '/dump&raw=1'))); } $res = new Response('<?xml version="1.0"?>' . $xml, 'text/xml'); $res->send(); } throw new ForbiddenException(); }
/** * 发表文章 */ public function pub() { $c = $this->post_uint('c'); $content = $this->post('content'); $title = $this->post('title'); if ($c && $title && $content) { $is = false; foreach (mcms::get_category() as $cat) { if (intval($cat['id']) === $c) { $is = true; break; } } if ($is === false) { return; } mcms::add_content($c, $title, $content); } view::assign('category', mcms::get_category()); }
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 function __construct(Context $ctx) { // Если кроме id аттачмента ничего не задали, ругаемся if (null == $ctx->get('fid', null) or null == $ctx->get('scale', null)) { $this->sendError(500, 'usage: ?q=imgtoolkit.rpc&fid=attachment[&operation=parameter...]'); } foreach ($this->options as $k => $v) { if ($p = $ctx->get($k)) { if (in_array($k, array('noshow', 'merge', 'fid', 'mirrorH', 'mirrorV'))) { $this->options[$k] = $p; } else { $this->options[$k] = floatval($p); } } // Формируем имя файла-ссылки для кэша $outfile .= "{$this->options[$k]},"; } $outfile = trim($outfile, ','); $node = Node::load(array('class' => 'file', 'id' => $this->options['fid'])); if (empty($node)) { self::sendError(404, 'attachment not found.'); } if (null === ($storage = mcms::config('filestorage'))) { $storage = 'storage'; } $this->node = $node; $this->filename = $node->filename; $this->folder = $storage; $this->sourceDir = $storage; $this->source = $storage . '/' . $node->filepath; $this->output = $this->folder . '/' . $outfile; if (null != $this->options['merge']) { $this->mergeNode = Node::load(array('class' => 'file', 'id' => $this->options['merge'])); if (empty($this->mergeNode)) { self::sendError(404, 'merge attachment not found.'); } } }
public function set($value, &$node) { $result = array(); foreach (preg_split('/[\\r\\n]+/', $value) as $line) { if (count($parts = preg_split('/\\s+/', $line, 2, PREG_SPLIT_NO_EMPTY))) { $link = array(); if ($tmp = array_shift($parts)) { $link['href'] = $tmp; } if ($tmp = array_shift($parts)) { $link['name'] = $tmp; } if (!empty($link['href'])) { $link['host'] = url::host($link['href']); } try { $head = http::head($link['href']); if (200 == ($link['status'] = $head['_status'])) { if (!empty($head['Content-Type'])) { $link['type'] = $head['Content-Type']; } if (!empty($head['Content-Length'])) { $link['size'] = intval($head['Content-Length']); $link['sizefm'] = mcms::filesize($link['size']); } } } catch (Exception $e) { } $result[] = $link; } } if (empty($result)) { unset($node->{$this->value}); } else { $node->{$this->value} = $result; } }
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 getContent() { $content = $this->content; if ('text/html' == $this->type) { $content = str_replace(array('$request_time', '$peak_memory'), array(microtime(true) - MCMS_START_TIME, mcms::filesize(memory_get_peak_usage())), $content); if (!empty($_GET['__cleanurls'])) { $re = '@(href|src|action)=([\'"])\\?q=([^&"\']+)\\&\\;+@'; $content = preg_replace($re, '\\1=\\2\\3?', $content); $re = '@(href|src|action)=([\'"])\\?q=([^&"\']+)([\'"])+@'; $content = preg_replace($re, '\\1=\\2\\3\\4', $content); } } return $content; }
/** * Return the contents of the session in array form. */ function contents() { mcms::session()->raw(); }
/** * Возвращает список источников обновлений. */ public static function getSources() { if (!is_array($urls = mcms::config('sources'))) { $urls = array(); } $default = 'http://molinos-cms.googlecode.com/svn/dist/' . mcms::version(mcms::VERSION_RELEASE) . '/modules.ini'; if (!in_array($default, $urls)) { $urls[] = $default; } asort($urls); return $urls; }
private function checkUserHasVote(array $options) { $skey = 'already_voted_with_' . $this->getInstanceName() . "_{$options['node']}"; $rate = (array) mcms::session('rate'); // Мы кэшируем состояние в сессии для всех пользователей, поэтому проверяем в первую очередь. if (!empty($rate[$skey])) { return true; } // Анонимных пользователей считаем по IP, зарегистрированных -- по идентификатору. if ($this->user->id == 0) { $status = 0 != $this->ctx->db->getResult("SELECT COUNT(*) FROM `node__rating` WHERE `nid` = :nid AND `uid` = 0 AND `ip` = :ip", array(':nid' => $this->ctx->document->id, ':ip' => $_SERVER['REMOTE_ADDR'])); } else { $status = 0 != $this->ctx->db->getResult("SELECT COUNT(*) FROM `node__rating` WHERE `nid` = :nid AND `uid` = :uid", array(':nid' => $this->ctx->document->id, ':uid' => $this->user->id)); } // Сохраняем в сессии для последующего быстрого доступа. $rate[$skey] = $status; mcms::session('rate', $rate); return $status; }
public static function listDrivers() { return array_diff(PDO::getAvailableDrivers(), mcms::config('runtime.db.drivers.disable', array())); }
/** * Заглушка для неверных вызовов. */ private final function __call($method, $args) { mcms::debug('Bad method call', $method); throw new RuntimeException(t('Метод %class::%method() не существует.', array('%class' => get_class($this), '%method' => $method))); }