/** * __construct() * * @access public * @param {class} $os The os. */ public function __construct(os $os) { if (!$os->session_exists()) { die('Session does not exist!'); } $this->os = $os; }
/** * __construct() * * @access public * @param {class} $os The os. */ public function __construct(os $os) { if (!$os->session_exists()) { die('Session does not exist!'); } $this->document_root = $os->get_document_root(); $this->library_dir = $os->get_library_dir(); $this->os = $os; }
/** * __construct() * * @access public * @param {class} $os The os. */ public function __construct(os $os) { if (!$os->session_exists()) { die('Session does not exist!'); } $this->member_id = $os->get_member_id(); $this->group_id = $os->get_group_id(); if (!isset($this->member_id, $this->group_id)) { die('Member/Group not found!'); } $this->os = $os; $this->member_info = $this->get_member_info(); $this->preferences = $this->get_preferences(); }
/** * @mcms_message ru.molinos.cms.cron */ public static function taskRun(Context $ctx) { $types = $ctx->config->get('modules/subscription/types', array()); $xsl = $ctx->config->get('modules/subscription/stylesheet', os::path('lib', 'modules', 'subscription', 'message.xsl')); $sub = $ctx->config->get('modules/subscription/subject', 'Новости сайта %host'); if (empty($types)) { return; } $ctx->db->beginTransaction(); $users = Node::find(array('class' => 'subscription', 'deleted' => 0, 'published' => 1, '#sort' => 'name'), $ctx->db); // Обрабатываем активных пользователей. foreach ($users as $user) { $olast = $last = intval($user->last); if ($sections = (array) $user->tags) { list($sql, $params) = Query::build(array('class' => $types, 'tags' => $sections, 'published' => 1, 'deleted' => 0, 'id' => array('>' . ($olast + 1))))->getSelect(array('id', 'xml')); $nodes = $ctx->db->getResultsKV('id', 'xml', $sql, $params); // Отправляем документы. foreach ($nodes as $nid => $node) { $xml = html::em('message', array('mode' => 'regular', 'unsubscribe' => 'subscription.rpc?action=remove&name=' . urlencode($user->name) . '&id=' . $user->id, 'base' => $ctx->url()->getBase($ctx), 'host' => MCMS_HOST_NAME), $node); $body = xslt::transform($xml, $xsl, null); $subject = t($sub, array('%host' => $ctx->url()->host())); BebopMimeMail::send(null, $user->name, $subject, $body); $last = max($last, $nid); } // Запоминаем последнее отправленное сообщение. $user->last = $last; $user->save(); } } $ctx->db->commit(); }
public function __construct(array $conf) { $this->dbfile = $this->dbname = MCMS_SITE_FOLDER . DIRECTORY_SEPARATOR . $conf['name']; if (':memory:' != $this->dbfile and !file_exists($this->dbfile)) { os::copy(os::path('lib', 'modules', 'pdo', 'default.sqlite'), $this->dbfile); } $dsn = 'sqlite:' . $this->dbfile; if (':memory:' != $this->dbfile) { if (!file_exists(realpath($this->dbfile))) { throw new NotInstalledException('db'); } } try { parent::__construct($dsn, '', ''); } catch (PDOException $e) { if (!in_array('sqlite', PDO::getAvailableDrivers())) { throw new NotInstalledException('driver'); } elseif (file_exists($conf['name'])) { throw new RuntimeException(t('Не удалось открыть базу данных.')); } else { throw new NotInstalledException('connection'); } } $this->dbtype = 'SQLite'; }
public function render(Context $ctx, array $options = array()) { $options = array_merge(array('name' => 'custom', 'title' => MCMS_HOST_NAME, 'xsl' => os::path('lib', 'modules', 'rss', 'default.xsl'), 'base' => $ctx->url()->getBase($ctx), 'description' => 'News from ' . MCMS_HOST_NAME, 'language' => 'ru', 'url' => 'http://' . MCMS_HOST_NAME . $ctx->url()->string()), $options); $content = html::wrap('nodes', Node::findXML($this->filter, $ctx->db)); $content = html::em('rss', $options, $content); return xslt::transform($content, $options['xsl'], 'text/xml'); }
/** * Возвращает список скриптов и стилей для использования на сайте. * * @mcms_message ru.molinos.cms.compressor.enumXXX */ public static function on_compressor_enum(Context $ctx, $mode = 'website') { $result = array(); $conf = $ctx->config->get('modules/tinymce'); $conf['gzip'] = false; if (empty($conf['gzip'])) { $result[] = array('script', 'lib/modules/tinymce/editor/tiny_mce.js'); } else { $result[] = array('script', 'lib/modules/tinymce/editor/tiny_mce_gzip.js'); } $initializer = empty($conf['initializer']) ? '' : $conf['initializer'] . ', '; $initializer .= 'document_base_url: "http://' . MCMS_HOST_NAME . $ctx->folder() . '/", '; $initializer .= 'tiny_mce_path: "lib/modules/tinymce/editor"'; $text = 'tinyMCE_initializer = {' . $initializer . '};'; os::write($path = os::path($ctx->config->getPath('main/tmpdir'), 'tinymce_initializer.js'), $text); $result[] = array('script', os::localpath($path)); $theme = empty($conf['theme']) ? 'simple' : $conf['theme']; if (!empty($conf['gzip'])) { if (file_exists($path = os::path('lib', 'modules', 'tinymce', 'editor', 'template_' . $theme . '_gzip.js'))) { $result[] = array('script', os::webpath($path)); } } if (file_exists($path = os::path('lib', 'modules', 'tinymce', 'editor', 'template_' . $theme . '.js'))) { $result[] = array('script', os::webpath($path)); } return $result; }
public static function rpc_post_subscribe(Context $ctx) { $data = $ctx->post; if (empty($data['sections'])) { throw new InvalidArgumentException("Не выбраны разделы для подписки."); } if (false === strpos($data['email'], '@')) { throw new InvalidArgumentException(t('Введённый email не похож на email.')); } // В массиве могут быть и другие данные, поэтому мы // выбираем только то, что нам нужно завернуть. $bulk = array('email' => $data['email'], 'sections' => $data['sections']); $link = new url(array('args' => array('q' => 'subscription.rpc', 'action' => 'confirm', 'code' => base64_encode(serialize($bulk))))); $sections = Node::findXML(array('class' => 'tag', 'deleted' => 0, 'published' => 1, 'id' => $data['sections'], '#sort' => 'name'), $ctx->db, 'section'); if (empty($sections)) { throw new InvalidArgumentException("Выбраны несуществующие разделы для подписки."); } $xml = html::em('message', array('mode' => 'confirm', 'host' => MCMS_HOST_NAME, 'email' => $data['email'], 'base' => $ctx->url()->getBase($ctx), 'confirmLink' => $link->string()), html::em('sections', $sections)); $xsl = $ctx->config->get('modules/subscription/stylesheet', os::path('lib', 'modules', 'subscription', 'message.xsl')); if (false === ($body = xslt::transform($xml, $xsl, null))) { throw new RuntimeException(t('Возникла ошибка при форматировании почтового сообщения.')); } $subject = t('Подписка на новости сайта %host', array('%host' => MCMS_HOST_NAME)); // mcms::debug($data['email'], $subject, $body); BebopMimeMail::send(null, $data['email'], $subject, $body); }
/** * Вывод формы авторизации. * @route GET//login */ public static function on_get_login_form(Context $ctx) { if ($ctx->user->id and !$ctx->get('stay')) { return $ctx->getRedirect(); } if (class_exists('APIStream')) { APIStream::init($ctx); } $handler = array('theme' => $ctx->config->get('modules/auth/login_theme')); $content = ''; foreach ((array) $ctx->registry->poll('ru.molinos.cms.page.head', array($ctx, $handler, null), true) as $block) { if (!empty($block['result'])) { $content .= $block['result']; } } $content .= self::getXML($ctx); $xml = html::em('page', array('status' => 401, 'base' => $ctx->url()->getBase($ctx), 'host' => MCMS_HOST_NAME, 'prefix' => os::webpath(MCMS_SITE_FOLDER, 'themes'), 'back' => urlencode(MCMS_REQUEST_URI), 'next' => $ctx->get('destination'), 'api' => APIStream::getPrefix(), 'query' => $ctx->query()), $content); if (file_exists($xsl = os::path(MCMS_SITE_FOLDER, 'themes', $handler['theme'], 'templates', 'login.xsl'))) { try { return xslt::transform($xml, $xsl); } catch (Exception $e) { } } return xslt::transform($xml, 'lib/modules/auth/xsl/login.xsl'); }
/** * Возвращает экземпляр типографа. Кэширует его, для быстрого применения к нескольким полям. * * @static * @access private * @return Pride_Typograph */ private static function getTypo() { if (self::$typo === null) { $options = array('array_regex_array' => require os::path('lib', 'modules', 'pridetypograph', 'resources', 'RulesRegex.php'), 'array_replace_array' => require os::path('lib', 'modules', 'pridetypograph', 'resources', 'RulesReplace.php'), 'array_clean_array' => require os::path('lib', 'modules', 'pridetypograph', 'resources', 'CleanHtml.php')); self::$typo = Pride_Typograph::factory('array', $options); } return self::$typo; }
public static function rpc_get_default(Context $ctx) { if ($ctx->config->isOk()) { $ctx->redirect('admin'); } $xml = self::listDriversXML(); $xsl = os::path('lib', 'modules', 'install', 'template.xsl'); return xslt::transform(html::em('installer', array('base' => $ctx->url()->getBase($ctx), 'dirname' => $ctx->config->getDirName()), $xml), $xsl); }
/** * Возвращает RSS комментариев. * @route GET//comments.rss */ public static function on_get_rss(Context $ctx) { if (!class_exists('RSSFeed')) { throw new PageNotFoundException(t('Модуль rss не установлен.')); } $filter = array('class' => 'comment', 'deleted' => 0, 'published' => 1, '#limit' => 20, '#sort' => '-id'); $title = t('Комментарии на %host', array('%host' => MCMS_HOST_NAME)); $feed = new RSSFeed($filter); return $feed->render($ctx, array('title' => $title, 'description' => $title . '.', 'xsl' => os::path('lib', 'modules', 'comment', 'rss.xsl'))); }
public static function on_download(Context $ctx) { zip::fromFolder($zipFile = os::path($ctx->config->getPath('main/tmpdir'), 'backup.zip'), MCMS_ROOT, realpath($ctx->config->getPath('main/tmpdir'))); $filename = $ctx->host() . '-' . date('YmdHi', time() - date('Z', time())) . '.zip'; header('Content-Type: application/zip'); header('Content-Length: ' . filesize($zipFile)); header('Content-Disposition: attachment; filename="' . $filename . '"'); readfile($zipFile); unlink($zipFile); die; }
/** * @mcms_message ru.molinos.cms.compressor.enum */ public static function on_compressor_enum(Context $ctx) { $libs = array(); if ($version = $ctx->config->get('modules/jquery/jsversion', '1.2.6')) { $libs[] = array('script', os::path('lib', 'modules', 'jquery', 'jquery-' . $version . '.min.js')); } if ($ctx->config->get('modules/jquery/ui')) { $libs[] = array('script', os::path('lib', 'modules', 'jquery', 'jquery-ui-1.5.3.min.js')); } return $libs; }
/** * Вывод списка файлов. */ public static function on_get_list(Context $ctx) { try { $options = array('#raw' => true, 'name' => 'list', 'title' => t('Файловый архив'), 'path' => os::webpath(MCMS_SITE_FOLDER, $ctx->config->get('modules/files/storage')), 'advsearch' => true, 'canedit' => true, 'mode' => $ctx->get('mode', 'table'), 'scope' => $ctx->get('scope'), 'type' => 'file'); $tmp = new FileList($ctx, $options['scope']); return $tmp->getHTML('files', $options); } catch (TableNotFoundException $e) { if ($e->getTableName() != 'node__idx_filetype') { throw $e; } throw new Exception(t('Отсутствует индекс по полю filetype, <a href="@url">исправьте это</a> и возвращайтесь.', array('@url' => 'admin/structure/fields/edit?type=file&field=filetype&destination=' . urlencode(MCMS_REQUEST_URI)))); } }
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); }
/** * @mcms_message ru.molinos.cms.admin.form.modman */ public static function getAdminFormXML(Context $ctx) { $ctx->theme = os::path('lib', 'modules', 'modman', 'template.xsl'); switch ($ctx->get('mode')) { case 'addremove': return self::getInstallForm($ctx); case 'config': return self::getConfigForm($ctx); case 'upgrade': return self::getUpgradeForm($ctx); default: return self::getSettingsForm($ctx); } }
public function __construct($keyStr) { $iniParams = ini::read(os::path('lib', 'modules', 'captcha', 'config.ini')); foreach ($iniParams as $k => $v) { $this->{$k} = $v; } // CAPTCHA image colors (RGB, 0-255) // $this->foreground_color = array(0, 0, 0); // $this->background_color = array(220, 230, 255); $this->foreground_color = array(mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100)); $this->background_color = array(mt_rand(200, 255), mt_rand(200, 255), mt_rand(200, 255)); // Что надо нарисовать $this->keyString = $keyStr; }
public static function rpc_rebuild(Context $ctx) { // Обновление БД. foreach (os::find('lib/modules/*/*.yml') as $fileName) { $schema = Spyc::YAMLLoad($fileName); Logger::log('applying ' . $fileName, 'module'); if (!empty($schema['tables'])) { foreach ($schema['tables'] as $tableName => $tableInfo) { TableInfo::check($tableName, $tableInfo); } } } $ctx->registry->rebuild(); $ctx->registry->broadcast('ru.molinos.cms.install', array($ctx)); }
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'))); } } } } } }
/** * Добавление скриптов к странице. * @mcms_message ru.molinos.cms.page.head */ public static function on_get_head(Context $ctx, array $pathinfo) { if ($query = $ctx->get('query') and $key = $ctx->config->get('modules/search/gas_key')) { $query = str_replace('"', "'", $query); $paths = array(os::path(MCMS_SITE_FOLDER, 'gas.js'), os::path('lib', 'modules', 'search', 'gas.js')); $output = ''; foreach ($paths as $path) { if (file_exists($path)) { $js = str_replace('QUERY', $query, file_get_contents($path)); $js = str_replace('HOSTNAME', url::host($_SERVER['HTTP_HOST']), $js); $output = '<script type="text/javascript" src="http://www.google.com/jsapi?key=' . $key . '"></script>' . '<script type="text/javascript">' . $js . '</script>'; return html::wrap('head', html::cdata($output), array('module' => 'search')); } } } }
public static function trace($message) { $trace = debug_backtrace(); if ($message instanceof Exception) { $trace = $message->getTrace(); array_unshift($trace, array('file' => $message->getFile(), 'line' => $message->getLine(), 'class' => 'throw', 'type' => ' new ', 'function' => get_class($message))); $message = get_class($message) . ': ' . $message->getMessage(); } error_log($message, 0); foreach ($trace as $line) { if (!empty($line['class']) and !empty($line['function'])) { $file = empty($line['file']) ? '???' : os::localpath($line['file']) . ' @' . $line['line']; error_log(" -- {$line['class']}{$line['type']}{$line['function']}() — {$file}", 0); } } error_log(' -- ' . MCMS_REQUEST_URI, 0); }
/** * Вывод административной страницы. Вызывает обработчик, указанный в next, * предварительно проверив права пользователя. */ public static function serve(Context $ctx, $path, array $pathinfo) { if (class_exists('APIStream')) { APIStream::init($ctx); } try { self::checkperm($ctx, $pathinfo); if (!$ctx->user->id and empty($pathinfo['anonymous'])) { throw new UnauthorizedException(); } if (empty($pathinfo['next'])) { if (!empty($pathinfo['xsl'])) { $pathinfo['next'] = 'AdminPage::xsltonly'; } else { throw new RuntimeException(t('Не указан обработчик для страницы %path (параметр <tt>next</tt>).', array('%path' => $path))); } } if (!is_callable($pathinfo['next'])) { throw new RuntimeException(t('Неверный обработчик для страницы %path (<tt>%next()</tt>).', array('%path' => $path, '%next' => $pathinfo['next']))); } $args = func_get_args(); $output = call_user_func_array($pathinfo['next'], $args); if (!$output instanceof Response) { $xsl = empty($pathinfo['xsl']) ? null : implode(DIRECTORY_SEPARATOR, explode('/', $pathinfo['xsl'])); $tmp = new AdminPage($output, $xsl); $output = $tmp->getResponse($ctx); } return $output; } catch (NotConnectedException $e) { Logger::trace($e); if (is_dir(os::path('lib', 'modules', 'install'))) { $ctx->redirect('install?destination=' . urlencode(MCMS_REQUEST_URI)); } else { throw new RuntimeException('Система не проинсталлирована и модуля install нет.'); } } catch (Exception $e) { Logger::trace($e); $data = array('status' => 500, 'error' => get_class($e), 'message' => $e->getMessage(), 'version' => MCMS_VERSION, 'release' => MCMS_RELEASE, 'base' => $ctx->url()->getBase($ctx), 'prefix' => MCMS_SITE_FOLDER . '/themes', 'back' => urlencode(MCMS_REQUEST_URI), 'next' => urlencode($ctx->get('destination')), 'clean' => !empty($_GET['__cleanurls'])); if ($e instanceof UserErrorException) { $data['status'] = $e->getCode(); } $xsl = os::path('lib', 'modules', 'admin', 'template.xsl'); xslt::transform(html::em('page', $data), $xsl)->send(); } }
/** * Возвращает содержимое файла для текущего домена. * @route GET//robots.txt */ public static function on_get_robots(Context $ctx) { $content = ""; foreach ($ctx->registry->poll('ru.molinos.cms.robots.txt', array($ctx)) as $tmp) { if (!empty($tmp['result'])) { $content .= trim($tmp['result']) . "\n"; } } if (!empty($content)) { $content .= "\n"; } $content .= "User-agent: *\n" . "Disallow: /admin\n" . "Disallow: /api/\n" . "Disallow: /doc/\n" . "Disallow: /lib/\n" . "Disallow: /sites/\n" . "Disallow: /download/\n"; if (file_exists($path = os::path(MCMS_SITE_FOLDER, 'robots.txt'))) { $content .= trim(file_get_contents($path)) . "\n"; } header('Content-Type: text/plain; charset=utf-8'); header('Content-Length: ' . strlen($content)); die($content); }
/** * Запись файла с поддержкой секций. */ public static function write($filename, array $data, $header = null) { $output = null === $header ? "" : trim($header) . "\n\n"; // Сначала пишет простые значения $output .= self::write_keys($data); // Теперь сохраняем секции. foreach ($data as $k => $v) { if (is_array($v) and !empty($v)) { if (!empty($output)) { $output .= "\n"; } $output .= sprintf("[%s]\n", $k); $output .= self::write_keys($v, true); } } if (file_exists($filename)) { rename($filename, $filename . '~'); } os::write($filename, $output); }
/** * Восстановление пароля. * * @param Context $ctx * @param array $params * @return void * @mcms_message ru.molinos.cms.auth.process.basicpw */ public static function on_register(Context $ctx, array $params) { if (false === strpos($params['email'], '@')) { throw new BadRequestException(t('Неверно введён почтовый адрес.')); } $node = Node::load(array('class' => 'user', 'name' => $params['email'])); if ($node->deleted) { throw new ForbiddenException(t('Этот пользователь был удалён.')); } elseif (!$node->published) { throw new ForbiddenException(t('Этот пользователь заблокирован.')); } $salt = md5($_SERVER['REMOTE_ADDR'] . microtime(true) . $node->name . rand()); $node->otp = $salt; $ctx->db->beginTransaction(); $node->save(); $ctx->db->commit(); $xml = html::em('request', array('email' => $node->name, 'host' => MCMS_HOST_NAME, 'base' => $ctx->url()->getBase($ctx), 'link' => 'authbasic/restore.rpc?email=' . urlencode($node->name) . '&otp=' . urlencode($salt))); $xsl = $ctx->config->get('modules/authbasic/restoretpl', os::path('lib', 'modules', 'authbasic', 'restore.xsl')); $html = xslt::transform($xml, $xsl, null); BebopMimeMail::send(null, $node->name, t('Восстановление пароля'), $html); }
/** * Вытаскивает таблицу маршрутизации из .ini файла, если не находит — возвращает пустой массив. */ private function load_ini(Context $ctx) { $raw = array(); foreach ($ctx->config->get('routes', array()) as $k => $v) { $raw['GET/' . $k] = $v; } foreach (os::find('lib', 'modules', '*', 'route.ini') as $iniFile) { foreach (ini::read($iniFile) as $k => $v) { if (is_array($v)) { $raw[$k] = $v; $raw[$k]['static'] = true; } elseif ('dynamic' == $k and false !== strpos($v, '::')) { list($class, $method) = explode('::', $v); if (method_exists($class, $method)) { try { if (is_array($tmp = call_user_func(array($class, $method), $ctx))) { foreach ($tmp as $k => $v) { $raw[$k] = $v; } } } catch (Exception $e) { Logger::log(get_class($e) . ' in ' . $v . '()'); } } } } } // Опрос динамических маршрутов. foreach ((array) $ctx->registry->poll('ru.molinos.cms.route.poll') as $tmp) { if (!empty($tmp['result'])) { foreach ($tmp['result'] as $k => $v) { $raw[$k] = $v; } } } return $raw; }
public static function suite() { ini_set('display_errors', 1); $suite = new PHPUnit_Framework_TestSuite('PHPUnit Framework'); $mask = realpath(dirname(__FILE__) . '/../modules') . '/*/{tests,class.*.test}.php'; foreach (glob($mask, GLOB_BRACE) as $file) { $module = basename(dirname($file)); if ('.test.php' == substr(basename($file), -9)) { $class = ucfirst(substr(basename($file), 6, -9)) . 'Tests'; } else { $class = ucfirst($module) . 'ModuleTests'; } require_once $file; if (class_exists($class, false)) { printf("%s => %s\n", os::localPath($file), $class); $suite->addTestSuite($class); } else { die("Class {$class} not found in {$file}.\n"); } } ini_set('error_log', dirname(__FILE__) . '/tests.log'); ini_set('display_errors', 1); return $suite; }
/** * Форматирование элемента стэка. */ public static function formatStackElement(array $em) { $output = ''; if (!empty($em['file'])) { $output .= os::localPath($em['file']) . '(' . $em['line'] . ') — '; } $caller = empty($em['class']) ? '' : $em['class']; $caller .= empty($em['type']) ? '' : $em['type']; if (!empty($em['function'])) { $caller .= $em['function'] . '('; if (!empty($em['args'])) { $args = array(); foreach ($em['args'] as $arg) { if (is_array($arg)) { $args[] = 'array'; } elseif (is_object($arg)) { $args[] = get_class($arg); } elseif (true === $arg) { $args[] = 'true'; } elseif (false === $arg) { $args[] = 'false'; } elseif (null === $arg) { $args[] = 'null'; } elseif (is_string($arg)) { $tmp = '"'; $tmp .= mb_strlen($arg) > 10 ? mb_substr($arg, 0, 10) . '...' : $arg; $tmp .= '"'; $args[] = $tmp; } else { $args[] = $arg; } } $caller .= join(', ', $args); } $caller .= ');'; } $output .= $caller; return $output; }
<?php require_once '../../../../server/os.php'; $os = new os(); if (!$os->session_exists()) { die('No existe sesión!'); } function selectCanal() { global $os; $os->db->conn->query("SET NAMES 'utf8'"); $sql = "SELECT * FROM xmltv_canal ORDER BY id"; $result = $os->db->conn->query($sql); $data = array(); while ($row = $result->fetch(PDO::FETCH_ASSOC)) { $data[] = $row; } echo json_encode(array("success" => true, "data" => $data)); } function insertCanal() { global $os; $os->db->conn->query("SET NAMES 'utf8'"); $data = json_decode(stripslashes($_POST["data"])); $sql = "INSERT INTO xmltv_canal(nombre , descripcion , icono)\n\tvalues('{$data->nombre}', '{$data->descripcion}', '{$data->icono}');"; $sql = $os->db->conn->prepare($sql); $sql->execute(); echo json_encode(array("success" => $sql->errorCode() == 0, "msg" => $sql->errorCode() == 0 ? "insertado exitosamente" : $sql->errorCode(), "data" => array(array("id" => $os->db->conn->lastInsertId(), "nombre" => $data->nombre, "descripcion" => $data->descripcion, "icono" => $data->icono)))); } function updateCanal() {