Ejemplo n.º 1
0
 public static function navMenu(&$user, $level = 1)
 {
     // FIXME: add exact match boolean for url/context checking
     $menu = array();
     $context = null;
     $matches = array();
     $requestUri = isset($_GET['uri']) ? $_GET['uri'] : isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : null;
     preg_match('#(/(.*))/((.*)(\\.php)?)#', $requestUri, $matches);
     $active = null;
     if (count($matches)) {
         $context = $matches[2];
         $active = $matches[4];
     }
     $paths = explode("/", $context);
     $db = Core::getDb();
     $qLevel = $db->escape($level);
     $qContext = $db->escape($context);
     if ($context) {
         $q = "select title, url, level, admin, class, icon from menu_items where level={$qLevel} and ('{$qContext}' like concat('%', context, '%') or context is null) order by sortorder asc";
     } else {
         $q = "select title, url, level, admin, class, icon from menu_items where level={$qLevel} and context is null order by sortorder asc";
     }
     $rs = $db->query($q);
     if ($rs && $db->numRows($rs)) {
         while ($o = $db->fetchObject($rs)) {
             $menuItem = Boilerplate::navMenuItem($user, $o);
             if ($menuItem) {
                 $menu[] = $menuItem;
             }
         }
     }
     return $menu;
 }
Ejemplo n.º 2
0
 public function __construct($name, $logFacility = LOG_DAEMON)
 {
     $this->db = Core::getDb();
     $this->name = $name;
     $this->logFacility = $logFacility;
     $this->pid = getmypid();
     openlog("{$name}", LOG_PID, $this->logFacility);
 }
Ejemplo n.º 3
0
 public static function store(&$email, $priority = 10)
 {
     $db = Core::getDb();
     $q = $db->buildQuery("insert into mail_queue (msg_id, ctime, mtime, lock_id, priority, sent, subject, `from`, `to`, headers, body) values ('%s', now(), now(), null, %d, false, '%s', '%s', '%s', '%s', '%s')", $email->msgId(), $priority, $email->subject(), $email->from(), $email->to(), $email->headers(), $email->body());
     $rs = $db->query($q);
     $id = $db->lastInsertId($rs);
     return $id;
 }
Ejemplo n.º 4
0
 public static function show($objectId, $jsonLast = null)
 {
     $db = Core::getDb();
     $user = Core::getUser();
     $comments = array();
     $qLast = $jsonLast ? "and c.id>" . $db->escape($jsonLast) : "";
     $q = $db->buildQuery("SELECT c.id, c.body, o.ctime, u.id as local_user_id, o.user_id, c.user_connection_id, con.service, con.external_id\n      FROM comments c\n      LEFT JOIN objects o ON o.object_id=c.object_id\n      LEFT JOIN connections con ON c.user_connection_id=con.id\n\t\t\tLEFT JOIN users u ON u.id=o.user_id\n      WHERE c.in_reply_to_id=%d {$qLast}\n      ORDER BY o.ctime ASC", $objectId);
     $rs = $db->query($q);
     if ($rs && $db->numrows($rs)) {
         while ($o = $db->fetchObject($rs)) {
             $commentAuthor = ObjectCache::getByType('\\Kiki\\User', $o->user_id ? $o->user_id : $o->local_user_id);
             if ($commentAuthor) {
                 if ($o->external_id) {
                     // HACK: should not always have to load this, but this is quicker than getStoredConnections for User 0
                     $connection = User\Factory::getInstance($o->service, $o->external_id, 0);
                     // $connection = $commentAuthor->getConnection($o->service. "_". $o->external_id, true);
                     if ($connection) {
                         $serviceName = $connection->serviceName();
                         $name = $connection->name();
                         $pic = $connection->picture();
                     } else {
                         $serviceName = 'None';
                         // SNH
                         $name = $commentAuthor->name();
                         $pic = $commentAuthor->picture();
                     }
                 } else {
                     $serviceName = 'None';
                     // Kiki
                     $name = $commentAuthor->name();
                     $pic = $commentAuthor->picture();
                 }
             } else {
                 $serviceName = 'None';
                 $name = "Anonymous";
                 $pic = null;
             }
             if ($jsonLast !== null) {
                 $comments[] = Comments::showSingle($objectId, $o->id, $name, $pic, $serviceName, $o->body, $o->ctime);
             } else {
                 $comment = array('objectId' => $objectId, 'id' => $o->id, 'name' => $name, 'pic' => $pic, 'type' => $serviceName, 'body' => $o->body, 'ctime' => $o->ctime, 'dateTime' => date("c", strtotime($o->ctime)), 'relTime' => Misc::relativeTime($o->ctime));
                 $comments[] = $comment;
             }
         }
     } else {
         if ($jsonLast === null) {
             $comments[] = Comments::showDummy($objectId);
         }
     }
     if ($jsonLast !== null) {
         return $comments;
     }
     $template = new Template('parts/comments');
     $template->assign('objectId', $objectId);
     $template->assign('comments', $comments);
     return $template->fetch();
 }
Ejemplo n.º 5
0
 public function __construct($id = 0, $objectId = 0)
 {
     $this->db = Core::getDb();
     $this->id = $id;
     $this->objectId = $objectId;
     if ($this->id || $this->objectId) {
         $this->load();
     } else {
         $this->reset();
     }
 }
Ejemplo n.º 6
0
 public function __construct(array $_data = array())
 {
     if (!isset(self::$db)) {
         self::$db = Core::getDb();
     }
     if (!isset(self::$request)) {
         self::$request = Core::$request;
     }
     if (!isset(self::$profile)) {
         self::$profile = Auth::$profile;
         self::$uid = self::$profile->user_id;
     }
     if (isset($_data)) {
         $this->_data = $_data;
     }
 }
Ejemplo n.º 7
0
 public function __construct($template = null)
 {
     $this->db = Core::getDb();
     $this->template = $template;
     $data = Core::getTemplateData();
     // @deprecated Assign into global namespace. For backwards compatibility
     // with <= 0.0.32, when the namespace kiki was introduced and populated
     // but not yet ported and used.  Compatibility will be removed in future
     // 0.1.0 (the this is getting somewhere update, which seems to be
     // approaching).
     foreach ($data as $key => $value) {
         switch ($key) {
             case 'config':
                 break;
             default:
                 $this->data[$key] = $value;
         }
     }
     // Assign to {$kiki} namespace.
     $this->data['kiki'] = $data;
 }
Ejemplo n.º 8
0
 public static function articles($sectionId)
 {
     $db = Core::getDb();
     $content = null;
     $articles = array();
     $q = $db->buildQuery("select id from articles a LEFT JOIN objects o ON o.object_id=a.object_id where featured=true and visible=true and ctime<=now() and section_id=%d order by ctime desc limit 4", $sectionId);
     $rs = $db->query($q);
     if ($rs && ($count = $db->numRows($rs))) {
         while ($o = $db->fetchObject($rs)) {
             $article = new Article($o->id);
             $articles[] = $article;
         }
     } else {
         return $content;
     }
     $widths = array();
     $widths[1] = array(780);
     $widths[2] = array(520, 260);
     $widths[3] = array(390, 195, 195);
     $widths[4] = array(195, 195, 195, 195);
     list($articles) = array_chunk($articles, 4);
     $count = count($articles);
     if (!$count) {
         return null;
     }
     $content .= "<div class=\"banner\">\n";
     foreach ($articles as $id => $article) {
         $width = $widths[$count][$id];
         $img = Storage::url($article->topImage());
         list($base, $ext) = Storage::splitExtension($img);
         $img = "{$base}.{$width}x250.c.{$ext}";
         $content .= "<div class=\"bannerItem\" style=\"width: {$width}px; background-image: url({$img});\">\n";
         $content .= "<a href=\"" . $article->url() . "\">" . $article->title() . "</a>";
         $content .= "</div>\n";
     }
     $content .= "<br class=\"spacer\">";
     $content .= "</div>\n";
     return $content;
 }
Ejemplo n.º 9
0
 public static function find($type = '', array $options = array())
 {
     $where = $order = $joins = '';
     if ($type && is_numeric($type)) {
         $options['conditions'] = ['id' => (int) $type];
         $type = 'first';
     }
     if (Core::$cache->exists('collections_' . get_called_class(), json_encode($options))) {
         // check if cached
         $result = Core::$cache->get('collections_' . get_called_class(), json_encode($options));
     } else {
         $table = isset(static::$source) ? static::$source : strtolower(get_called_class());
         if (isset($options['conditions']) && is_array($options['conditions'])) {
             $conditions = self::_mapConditions(self::_cleanOperators($options['conditions']), $table);
             $ac = [];
             foreach ($conditions as $k => $v) {
                 if ($k === 'AND') {
                     $ac['AND'][] = '(' . implode(' AND ', $v) . ')';
                 } else {
                     if ($k === 'OR' && count($v) === 1) {
                         $ac['OR'][] = "OR {$v['0']}";
                     } else {
                         if ($k === 'OR') {
                             $ac['AND'][] = '(' . implode(' OR ', $v) . ')';
                         } else {
                             if ($k === 'MATCH' && count($v) === 1) {
                                 $ac['MATCH'][] = "{$v['0']}";
                             } else {
                                 if ($k === 'MATCH') {
                                     $ac['MATCH'][] = implode(' AND ', $v);
                                 } else {
                                     $ac['AND'][] = implode(' AND ', $v);
                                 }
                             }
                         }
                     }
                 }
             }
             if (!empty($ac)) {
                 $where = ' WHERE';
             }
             if (!empty($ac['MATCH'])) {
                 $where .= ' ' . implode(' AND ', $ac['MATCH']) . ' AND';
             }
             if (!empty($ac['AND'])) {
                 $where .= ' ' . implode(' AND ', $ac['AND']);
             }
             if (!empty($ac['OR'])) {
                 $where .= ' ' . implode(' OR ', $ac['OR']);
             }
         }
         if ($type == 'count') {
             $fields = 'COUNT(*) as count';
         } else {
             $fields = '*';
             if (isset($options['fields']) && is_array($options['fields'])) {
                 $fields = [];
                 foreach ($options['fields'] as $field) {
                     $fields[] = strpos('.', $field) === false ? $table . '.' . $field : $field;
                 }
                 $fields = implode(",", $fields);
             }
             if (isset($options['order'])) {
                 if (is_array($options['order'])) {
                     $arr = [];
                     foreach ($options['order'] as $key => $val) {
                         if ($find = ucfirst(stristr($key, '.', true))) {
                             $ok = class_exists($find) && isset($find::$source) ? $find::$source . stristr($key, '.') : strtolower($find) . stristr($key, '.');
                         } else {
                             $ok = $table . '.' . $key;
                             // default class name is table name
                         }
                         $arr[] = $ok . ' ' . $val;
                     }
                     $order = ' ORDER BY ' . implode(',', $arr);
                 }
             }
             $limit = isset($options['limit']) && is_numeric($options['limit']) ? ' LIMIT ' . (int) $options['limit'] : ($type == 'first' ? ' LIMIT 1' : '');
             $offset = isset($options['offset']) && is_numeric($options['offset']) && !empty($limit) ? ' OFFSET ' . (int) $options['offset'] : '';
         }
         if (isset($options['joins']) && is_array($options['joins'])) {
             $joins = [];
             foreach ($options['joins'] as $model => $opts) {
                 $model = property_exists($model, 'source') && isset($model::$source) ? $model::$source : strtolower($model);
                 $constraints = self::_mapJoins(self::_mapConditions(self::_cleanOperators($opts['constraints']), $model));
                 $joins[] = ' INNER JOIN ' . $model . ' ' . $model . ' ON ' . $constraints;
             }
             $joins = implode(' ', $joins);
         }
         $sql = sprintf("SELECT %s FROM %s %s%s%s%s%s%s", $fields, $table, $table, $joins, $where, $order, $limit, $offset);
         error_log("sql: {$sql}");
         if (isset($options['objects']) && $options['objects'] == false) {
             $result = Core::getDb()->sqlFetchAll($sql);
         } else {
             $rows = Core::getDb()->sqlFetchAll($sql);
             if (!empty($rows)) {
                 $class = get_called_class();
                 if (count($rows) === 1) {
                     // return 1 object
                     $result = $class::create($rows[0]);
                 } else {
                     // return array of objects
                     $result = [];
                     foreach ($rows as $data) {
                         $result[] = $class::create($data);
                     }
                 }
             }
         }
         Core::$cache->add('collections_' . get_called_class(), json_encode($options), $result);
         // cache it
     }
     return $result;
 }
Ejemplo n.º 10
0
 /**
  * @return string database version or null when no value could be retrieved from the database.
  */
 public static function dbVersion()
 {
     $db = Core::getDb();
     $q = "select value from config where `key`='dbVersion'";
     return $db->getSingleValue($q);
 }
Ejemplo n.º 11
0
 /**
  * Stores a resource.
  *
  * @param string $fileName original filename
  * @param string $data file data
  * @return int ID of the database entry created
  */
 public static function save($fileName, $data)
 {
     $db = Core::getDb();
     $fileName = strtolower($fileName);
     // FIXME: care about actual mimetypes, not extensions
     $extension = self::getExtension($fileName);
     $hash = sha1(uniqid() . $data);
     $qHash = $db->escape($hash);
     $qName = $db->escape($fileName);
     $qExt = $db->escape($extension);
     $qSize = $db->escape(sizeof($data));
     $q = "insert into storage(hash, original_name, extension, size) values('{$qHash}', '{$qName}', '{$qExt}', {$qSize})";
     $rs = $db->query($q);
     $id = $db->lastInsertId($rs);
     $fileName = self::localFile($id);
     file_put_contents($fileName, $data);
     chmod($fileName, 0644);
     return $id;
 }
Ejemplo n.º 12
0
 public function __construct()
 {
     $this->db = Core::getDb();
 }
Ejemplo n.º 13
0
 /**
  * Finds an album by title. Optionally creates a new album if none exists
  * by that title.
  *
  * @bug Only allows one album by title globally, this should be (at least)
  * on a per-user basis.
  *
  * @param string $title title of the album
  * @param boolean $create (optional) create a new album if none found,
  * defaults to false
  *
  * @return Album loaded instance when found/created, otherwise a bare
  * instance
  */
 public static function findByTitle($title, $create = false)
 {
     $db = Core::getDb();
     // Find
     $qTitle = $db->escape($title);
     $q = "select id from albums where title='{$qTitle}'";
     $id = $db->getSingleValue($q);
     // Create if it doesn't exist
     if (!$id && $create) {
         $album = new Album();
         $album->setTitle($title);
         $album->save();
         return $album;
     }
     return new Album($id);
 }
Ejemplo n.º 14
0
 /**
  * Retrieves the type of an object from the database.
  *
  * @param int $objectId
  * @return string Type (class name) of the object
  */
 private static function getType($objectId)
 {
     $db = Core::getDb();
     $q = $db->buildQuery("select type from objects where object_id=%d", $objectId);
     $type = $db->getSingleValue($q);
     // TODO: remove backwards compatibility
     return preg_match("/^Kiki\\\\/", $type) ? $type : 'Kiki\\' . $type;
 }
Ejemplo n.º 15
0
 /**
  * Creates an article edit form.
  *
  * @fixme Should be integrated into a template.
  * @todo Traditional Page class is deprecated so we can now remove the $type argument hack and have a Page/Article class both deriving from Post.
  *
  * @param User $user User object, used to show the proper connection links for publications.
  * @param boolean $hidden Hide the form initially.
  * @param string $type Defaults to 'articles'. When set to 'page', form treats this article as a page.
  *
  * @return string The form HTML.
  *
  */
 public function form($hidden = false, $type = 'articles')
 {
     $user = Core::getUser();
     $date = date("d-m-Y H:i", $this->ctime ? strtotime($this->ctime) : time());
     $class = $hidden ? "hidden" : "";
     $sections = array();
     if ($type == 'pages') {
         $sections[0] = 'top-level page';
     }
     $db = Core::getDb();
     $q = $db->buildQuery("select id,title from sections where type='%s' order by title asc", $type);
     $rs = $db->query($q);
     if ($rs && $db->numRows($rs)) {
         while ($oSection = $db->fetchObject($rs)) {
             $sections[$oSection->id] = $oSection->title;
         }
     }
     $content = Form::open("articleForm_" . $this->id, Config::$kikiPrefix . "/json/article.php", 'POST', $class, "multipart/form-data");
     $content .= Form::hidden("articleId", $this->id);
     $content .= Form::hidden("albumId", $this->albumId);
     $content .= Form::select("sectionId", $sections, "Section", $this->sectionId);
     $this->loadPublications();
     $content .= Form::text("title", $this->title, "Title");
     if (!count($this->publications)) {
         $content .= Form::text("cname", $this->cname, "URL name");
     }
     if ($type != 'pages') {
         $content .= Form::datetime("ctime", $date, "Date");
     }
     $class = Config::$clEditor ? "cleditor" : null;
     $content .= Form::textarea("body", preg_replace('~\\r?\\n~', '&#010;', htmlspecialchars($this->body)), "Body", null, 0, $class);
     if ($type != 'pages') {
         $content .= Form::checkbox("featured", $this->featured, "Featured");
     }
     $content .= Form::checkbox("visible", $this->visible, "Visible");
     $content .= "<label>Publications</label>";
     foreach ($this->publications as $publication) {
         $content .= "<a href=\"" . $publication->url() . "\" class=\"button\"><span class=\"buttonImg " . $publication->service() . "\"></span>" . $publication->service() . "</a>\n";
     }
     // TODO: Make this generic, difference with social update is the check
     // against an already stored external URL.
     foreach ($user->connections() as $connection) {
         if ($connection->serviceName() == 'Facebook') {
             // TODO: inform user that, and why, these are required.
             if (!$connection->hasPerm('publish_stream')) {
                 continue;
             }
             $content .= Form::checkbox("connections[" . $connection->uniqId() . "]", false, $connection->serviceName(), $connection->name());
         } else {
             if ($connection->serviceName() == 'Twitter') {
                 $content .= Form::checkbox("connections[" . $connection->uniqId() . "]", false, $connection->serviceName(), $connection->name());
                 $content .= Form::text("hashtags", $this->hashtags, "Hashtags");
             }
         }
     }
     $content .= Form::button("submit", "submit", "Opslaan");
     $content .= Form::close();
     return $content;
 }
Ejemplo n.º 16
0
 public static function storeBaseUri($baseUri, $title, $type, $instanceId = 0)
 {
     $db = Core::getDb();
     if ($baseUri[0] != '/') {
         $baseUri = '/' . $baseUri;
     }
     $q = $db->buildQuery("INSERT INTO sections (id, base_uri, title, type) VALUES (%d, '%s', '%s', '%s') ON DUPLICATE KEY UPDATE type='%s', title='%s'", $instanceId, $baseUri, $title, $type, $type, $title);
     $db->query($q);
 }
Ejemplo n.º 17
0
 public static function albumImage($id, $label, $albumId, $selected = 0)
 {
     $db = Core::getDb();
     $template = new Template('forms/album-selectimage');
     $imgUrl = $selected ? Storage::url($selected, 75, 75, true) : "/kiki/img/blank.gif";
     $template->assign('label', $label);
     $template->assign('imgUrl', $imgUrl);
     $images = array();
     $q = $db->buildQuery("select p.storage_id from pictures p, album_pictures ap where ap.picture_id=p.id AND ap.album_id=%d", $albumId);
     $rs = $db->query($q);
     if ($rs && $db->numRows($rs)) {
         while ($o = $db->fetchObject($rs)) {
             $url = Storage::url($o->storage_id, 75, 75, true);
             $images[] = array('storageId' => $o->storage_id, 'url' => $url);
         }
     }
     $template->assign('images', $images);
     $template->assign('id', $id);
     $template->assign('selected', $selected);
     return $template->fetch();
 }
Ejemplo n.º 18
0
 /** @TODO Figure out what the f**k I mean when I say "of note." */
 protected function disconnect()
 {
     /** @TODO Add more Core hook functionality here and elsewhere. */
     /** Check to ensure the driver has been loaded and let it connect.  */
     if (!isset($this->driver)) {
         $this->loadDriver();
     }
     /** If this model instance is not connected do nothing (may wanna log this). */
     if (!isset($this->connection)) {
         return;
     }
     /** Use the default db config unless another is defined within the model. */
     $this->db = isset($this->db) ? $this->db : Core::getDb();
     /** Return the associated connection object result. */
     $this->connection = $this->driver->disconnect($this);
 }