/** * reference another page at this site * * The function transforms a local reference (e.g;, [code][user=2][/code]) * to an actual link relative to the YACS directory (e.g., [code]users/view.php/2[/code]), * adds a title and, sometimes, set a description as well. * * @param string any string, maybe with a local reference in it * @return an array($url, $title, $description) or NULL * * @see images/view.php * @see links/edit.php * @see shared/codes.php */ public static function transform_reference($text) { global $context; // translate this reference to an internal link if (preg_match("/^\\[(article|section|file|image|category|user)=(.+?)\\]/i", $text, $matches)) { switch ($matches[1]) { // article link case 'article': if ($item = Articles::get($matches[2])) { return array(Articles::get_permalink($item), $item['title'], $item['introduction']); } return array('', $text, ''); // section link // section link case 'section': if ($item = Sections::get($matches[2])) { return array(Sections::get_permalink($item), $item['title'], $item['introduction']); } return array('', $text, ''); // file link // file link case 'file': if ($item = Files::get($matches[2])) { return array(Files::get_url($matches[2]), $item['title'] ? $item['title'] : str_replace('_', ' ', ucfirst($item['file_name']))); } return array('', $text, ''); // image link // image link case 'image': include_once $context['path_to_root'] . 'images/images.php'; if ($item = Images::get($matches[2])) { return array(Images::get_url($matches[2]), $item['title'] ? $item['title'] : str_replace('_', ' ', ucfirst($item['image_name']))); } return array('', $text, ''); // category link // category link case 'category': if ($item = Categories::get($matches[2])) { return array(Categories::get_permalink($item), $item['title'], $item['introduction']); } return array('', $text, ''); // user link // user link case 'user': if ($item = Users::get($matches[2])) { return array(Users::get_permalink($item), $item['full_name'] ? $item['full_name'] : $item['nick_name']); } return array('', $text, ''); } } return array('', $text, ''); }
if (isset($_REQUEST['id'])) { $id = $_REQUEST['id']; } elseif (isset($context['arguments'][0])) { $id = $context['arguments'][0]; } $id = strip_tags($id); // additional action, if any $action = NULL; if (isset($_REQUEST['action'])) { $action = $_REQUEST['action']; } elseif (isset($context['arguments'][1])) { $action = $context['arguments'][1]; } $action = strip_tags($action); // get the item from the database $item = Files::get($id); // get the related anchor, if any $anchor = NULL; if (isset($item['anchor']) && $item['anchor']) { $anchor = Anchors::get($item['anchor']); } // get related behaviors, if any $behaviors = NULL; include_once '../behaviors/behaviors.php'; if (isset($item['id'])) { $behaviors = new Behaviors($item, $anchor); } // change default behavior if (isset($item['id']) && is_object($behaviors) && !$behaviors->allow('files/fetch.php', 'file:' . $item['id'])) { $permitted = FALSE; } elseif (Files::allow_access($item, $anchor)) {
/** * render a sound object with dewplayer * * @global type $context * @param type $id * @return string */ public static function render_sound($id) { global $context; // maybe an alternate title has been provided $attributes = preg_split("/\\s*,\\s*/", $id, 2); $id = $attributes[0]; $flashvars = ''; if (isset($attributes[1])) { $flashvars = $attributes[1]; } // get the file if (!($item = Files::get($id))) { $output = '[sound=' . $id . ']'; return $output; } // where to get the file if (isset($item['file_href']) && $item['file_href']) { $url = $item['file_href']; } else { $url = $context['url_to_home'] . $context['url_to_root'] . 'files/' . str_replace(':', '/', $item['anchor']) . '/' . rawurlencode($item['file_name']); } // several ways to play flash switch (strtolower(substr(strrchr($url, '.'), 1))) { // stream a sound file case 'mp3': // a flash player to stream a sound $dewplayer_url = $context['url_to_root'] . 'included/browser/dewplayer.swf'; if ($flashvars) { $flashvars = 'son=' . $url . '&' . $flashvars; } else { $flashvars = 'son=' . $url; } $output = '<div id="sound_' . $item['id'] . '" class="no_print">Flash plugin or Javascript are turned off. Activate both and reload to view the object</div>' . "\n"; Page::insert_script('var params = {};' . "\n" . 'params.base = "' . dirname($url) . '/";' . "\n" . 'params.quality = "high";' . "\n" . 'params.wmode = "transparent";' . "\n" . 'params.menu = "false";' . "\n" . 'params.flashvars = "' . $flashvars . '";' . "\n" . 'swfobject.embedSWF("' . $dewplayer_url . '", "sound_' . $item['id'] . '", "200", "20", "6", "' . $context['url_to_home'] . $context['url_to_root'] . 'included/browser/expressinstall.swf", false, params);' . "\n"); return $output; // link to file page // link to file page default: // link label $text = Skin::strip($item['title'] ? $item['title'] : str_replace('_', ' ', $item['file_name'])); // make a link to the target page $url = Files::get_download_url($item); // return a complete anchor $output =& Skin::build_link($url, $text, 'basic'); return $output; } }
/** * remember the last action for this article * * This function is called by related items. What does it do? * - On image creation, the adequate code is added to the description field to let the image be displayed inline * - On icon selection, the icon field is updated * - On thumbnail image selection, the thumbnail image field is updated * - On location creation, some code is inserted in the description field to display location name inline * - On table creation, some code is inserted in the description field to display the table inline * * @see articles/article.php * @see articles/edit.php * @see shared/anchor.php * * @param string one of the pre-defined action code * @param string the id of the item related to this update * @param boolean TRUE to not change the edit date of this anchor, default is FALSE */ function touch($action, $origin = NULL, $silently = FALSE) { global $context; // we make extensive use of comments below include_once $context['path_to_root'] . 'comments/comments.php'; // don't go further on import if (preg_match('/import$/i', $action)) { return; } // no article bound if (!isset($this->item['id'])) { return; } // delegate to overlay if (is_object($this->overlay) && $this->overlay->touch($action, $origin, $silently) === false) { return; // stop on false } // clear floating objects if ($action == 'clear') { $this->item['description'] .= ' [clear]'; $query = "UPDATE " . SQL::table_name('articles') . " SET description='" . SQL::escape($this->item['description']) . "'" . " WHERE id = " . SQL::escape($this->item['id']); SQL::query($query); return; } // get the related overlay, if any if (!isset($this->overlay)) { $this->overlay = NULL; if (isset($this->item['overlay'])) { $this->overlay = Overlay::load($this->item, 'article:' . $this->item['id']); } } // components of the query $query = array(); // a new comment has been posted if ($action == 'comment:create') { // purge oldest comments Comments::purge_for_anchor('article:' . $this->item['id']); // file upload } elseif ($action == 'file:create' || $action == 'file:upload') { // actually, several files have been added $label = ''; if (!$origin) { // only when comments are allowed if (!Articles::has_option('no_comments', $this->anchor, $this->item)) { // remember this as an automatic notification $fields = array(); $fields['anchor'] = 'article:' . $this->item['id']; $fields['description'] = i18n::s('Several files have been added'); $fields['type'] = 'notification'; Comments::post($fields); } // one file has been added } elseif (!Codes::check_embedded($this->item['description'], 'embed', $origin) && ($item = Files::get($origin, TRUE))) { // this file is eligible for being embedded in the page if (isset($item['file_name']) && Files::is_embeddable($item['file_name'])) { // the overlay may prevent embedding if (is_object($this->overlay) && !$this->overlay->should_embed_files()) { } else { $label = '[embed=' . $origin . ']'; } // else add a comment to take note of the upload } else { // only when comments are allowed if (!Articles::has_option('no_comments', $this->anchor, $this->item)) { // remember this as an automatic notification $fields = array(); $fields['anchor'] = 'article:' . $this->item['id']; if ($action == 'file:create') { $fields['description'] = '[file=' . $item['id'] . ',' . $item['file_name'] . ']'; } else { $fields['description'] = '[download=' . $item['id'] . ',' . $item['file_name'] . ']'; } Comments::post($fields); } } } // we are in some interactive thread if ($origin && $this->has_option('view_as_chat')) { // default is to download the file if (!$label) { $label = '[download=' . $origin . ']'; } // this is the first contribution to the thread if (!($comment = Comments::get_newest_for_anchor('article:' . $this->item['id']))) { $fields = array(); $fields['anchor'] = 'article:' . $this->item['id']; $fields['description'] = $label; // this is a continuated contribution from this authenticated surfer } elseif ($comment['type'] != 'notification' && Surfer::get_id() && (isset($comment['create_id']) && Surfer::get_id() == $comment['create_id'])) { $comment['description'] .= BR . $label; $fields = $comment; // else process the contribution as a new comment } else { $fields = array(); $fields['anchor'] = 'article:' . $this->item['id']; $fields['description'] = $label; } // only when comments are allowed if (!Articles::has_option('no_comments', $this->anchor, $this->item)) { Comments::post($fields); } // include flash videos in a regular page } elseif ($origin && $label) { $query[] = "description = '" . SQL::escape($this->item['description'] . ' ' . $label) . "'"; } // suppress references to a deleted file } elseif ($action == 'file:delete' && $origin) { // suppress reference in main description field $text = Codes::delete_embedded($this->item['description'], 'download', $origin); $text = Codes::delete_embedded($text, 'embed', $origin); $text = Codes::delete_embedded($text, 'file', $origin); // save changes $query[] = "description = '" . SQL::escape($text) . "'"; // append a reference to a new image to the description } elseif ($action == 'image:create' && $origin) { if (!Codes::check_embedded($this->item['description'], 'image', $origin)) { // the overlay may prevent embedding if (is_object($this->overlay) && !$this->overlay->should_embed_files()) { } else { // list has already started if (preg_match('/\\[image=[^\\]]+?\\]\\s*$/', $this->item['description'])) { $this->item['description'] .= ' [image=' . $origin . ']'; } else { $this->item['description'] .= "\n\n" . '[image=' . $origin . ']'; } $query[] = "description = '" . SQL::escape($this->item['description']) . "'"; } } // also use it as thumnail if none has been defined yet if (!isset($this->item['thumbnail_url']) || !trim($this->item['thumbnail_url'])) { include_once $context['path_to_root'] . 'images/images.php'; if (($image = Images::get($origin)) && ($url = Images::get_thumbnail_href($image))) { $query[] = "thumbnail_url = '" . SQL::escape($url) . "'"; } } // refresh stamp only if image update occurs within 6 hours after last edition if (SQL::strtotime($this->item['edit_date']) + 6 * 60 * 60 < time()) { $silently = TRUE; } // suppress a reference to an image that has been deleted } elseif ($action == 'image:delete' && $origin) { // suppress reference in main description field $query[] = "description = '" . SQL::escape(Codes::delete_embedded($this->item['description'], 'image', $origin)) . "'"; // suppress references as icon and thumbnail as well include_once $context['path_to_root'] . 'images/images.php'; if ($image = Images::get($origin)) { if ($url = Images::get_icon_href($image)) { if ($this->item['icon_url'] == $url) { $query[] = "icon_url = ''"; } if ($this->item['thumbnail_url'] == $url) { $query[] = "thumbnail_url = ''"; } } if ($url = Images::get_thumbnail_href($image)) { if ($this->item['icon_url'] == $url) { $query[] = "icon_url = ''"; } if ($this->item['thumbnail_url'] == $url) { $query[] = "thumbnail_url = ''"; } } } // set an existing image as the article icon } elseif ($action == 'image:set_as_icon' && $origin) { include_once $context['path_to_root'] . 'images/images.php'; if ($image = Images::get($origin)) { if ($url = Images::get_icon_href($image)) { $query[] = "icon_url = '" . SQL::escape($url) . "'"; } // also use it as thumnail if none has been defined yet if (!(isset($this->item['thumbnail_url']) && trim($this->item['thumbnail_url'])) && ($url = Images::get_thumbnail_href($image))) { $query[] = "thumbnail_url = '" . SQL::escape($url) . "'"; } } // set an existing image as the article thumbnail } elseif ($action == 'image:set_as_thumbnail' && $origin) { include_once $context['path_to_root'] . 'images/images.php'; if ($image = Images::get($origin)) { // use the thumbnail for large files, or the image itself for smaller files if ($image['image_size'] > $context['thumbnail_threshold']) { $url = Images::get_thumbnail_href($image); } else { $url = Images::get_icon_href($image); } $query[] = "thumbnail_url = '" . SQL::escape($url) . "'"; } elseif ($origin) { $query[] = "thumbnail_url = '" . SQL::escape($origin) . "'"; } // do not remember minor changes $silently = TRUE; // append a new image, and set it as the article thumbnail } elseif ($action == 'image:set_as_both' && $origin) { if (!Codes::check_embedded($this->item['description'], 'image', $origin)) { $query[] = "description = '" . SQL::escape($this->item['description'] . ' [image=' . $origin . ']') . "'"; } include_once $context['path_to_root'] . 'images/images.php'; if ($image = Images::get($origin)) { // use the thumbnail for large files, or the image itself for smaller files if ($image['image_size'] > $context['thumbnail_threshold']) { $url = Images::get_thumbnail_href($image); } else { $url = Images::get_icon_href($image); } $query[] = "thumbnail_url = '" . SQL::escape($url) . "'"; } elseif ($origin) { $query[] = "thumbnail_url = '" . SQL::escape($origin) . "'"; } // do not remember minor changes $silently = TRUE; // add a reference to a location in the article description } elseif ($action == 'location:create' && $origin) { if (!Codes::check_embedded($this->item['description'], 'location', $origin)) { $query[] = "description = '" . SQL::escape($this->item['description'] . ' [location=' . $origin . ']') . "'"; } // suppress a reference to a location that has been deleted } elseif ($action == 'location:delete' && $origin) { $query[] = "description = '" . SQL::escape(Codes::delete_embedded($this->item['description'], 'location', $origin)) . "'"; // add a reference to a new table in the article description } elseif ($action == 'table:create' && $origin) { if (!Codes::check_embedded($this->item['description'], 'table', $origin)) { $query[] = "description = '" . SQL::escape($this->item['description'] . "\n" . '[table=' . $origin . ']' . "\n") . "'"; } // suppress a reference to a table that has been deleted } elseif ($action == 'table:delete' && $origin) { $query[] = "description = '" . SQL::escape(Codes::delete_embedded($this->item['description'], 'table', $origin)) . "'"; } // stamp the update if (!$silently) { $query[] = "edit_name='" . SQL::escape(Surfer::get_name()) . "'," . "edit_id=" . SQL::escape(Surfer::get_id()) . "," . "edit_address='" . SQL::escape(Surfer::get_email_address()) . "'," . "edit_action='" . SQL::escape($action) . "'," . "edit_date='" . gmstrftime('%Y-%m-%d %H:%M:%S') . "'"; } // update the database if (count($query)) { $query = "UPDATE " . SQL::table_name('articles') . " SET " . implode(', ', $query) . " WHERE id = " . SQL::escape($this->item['id']); SQL::query($query); } // add this page to the watch list of the contributor, on any action if (Surfer::get_id()) { Members::assign('article:' . $this->item['id'], 'user:'******'article:' . $this->item['id'], $this->item['active']); // always clear the cache, even on no update Articles::clear($this->item); // get the parent if (!$this->anchor) { $this->anchor = Anchors::get($this->item['anchor']); } // propagate the touch upwards if (is_object($this->anchor)) { $this->anchor->touch('article:update', $this->item['id'], TRUE); } }
/** * remember the last action for this section * * @see articles/article.php * @see shared/anchor.php * * @param string the description of the last action * @param string the id of the item related to this update * @param boolean TRUE to not change the edit date of this anchor, default is FALSE */ function touch($action, $origin = NULL, $silently = FALSE) { global $context; // we make extensive use of comments below include_once $context['path_to_root'] . 'comments/comments.php'; // don't go further on import if (preg_match('/import$/i', $action)) { return; } // no section bound if (!isset($this->item['id'])) { return; } // delegate to overlay if (is_object($this->overlay) && $this->overlay->touch($action, $origin, $silently) === false) { return; // stop on false } // sanity check if (!$origin) { logger::remember('sections/section.php: unexpected NULL origin at touch()'); return; } // components of the query $query = array(); // a new page has been added to the section if ($action == 'article:publish' || $action == 'article:submit') { // limit the number of items attached to this section if (isset($this->item['maximum_items']) && $this->item['maximum_items'] > 10) { Articles::purge_for_anchor('section:' . $this->item['id'], $this->item['maximum_items']); } // a new comment has been posted } elseif ($action == 'comment:create') { // purge oldest comments Comments::purge_for_anchor('section:' . $this->item['id']); // file upload } elseif ($action == 'file:create' || $action == 'file:upload') { // actually, several files have been added $label = ''; if (!$origin) { $fields = array(); $fields['anchor'] = 'section:' . $this->item['id']; $fields['description'] = i18n::s('Several files have been added'); $fields['type'] = 'notification'; Comments::post($fields); // one file has been added } elseif (!Codes::check_embedded($this->item['description'], 'embed', $origin) && ($item = Files::get($origin, TRUE))) { // this file is eligible for being embedded in the page if (isset($item['file_name']) && Files::is_embeddable($item['file_name'])) { // the overlay may prevent embedding if (is_object($this->overlay) && !$this->overlay->should_embed_files()) { } else { $label = '[embed=' . $origin . ']'; } // else add a comment to take note of the upload } elseif (Comments::allow_creation($this->item, null, 'section')) { $fields = array(); $fields['anchor'] = 'section:' . $this->item['id']; if ($action == 'file:create') { $fields['description'] = '[file=' . $item['id'] . ',' . $item['file_name'] . ']'; } else { $fields['description'] = '[download=' . $item['id'] . ',' . $item['file_name'] . ']'; } Comments::post($fields); } } // include flash videos in a regular page if ($label) { $query[] = "description = '" . SQL::escape($this->item['description'] . ' ' . $label) . "'"; } // suppress references to a deleted file } elseif ($action == 'file:delete') { // suppress reference in main description field $text = Codes::delete_embedded($this->item['description'], 'download', $origin); $text = Codes::delete_embedded($text, 'embed', $origin); $text = Codes::delete_embedded($text, 'file', $origin); // save changes $query[] = "description = '" . SQL::escape($text) . "'"; // append a reference to a new image to the description } elseif ($action == 'image:create') { if (!Codes::check_embedded($this->item['description'], 'image', $origin)) { // the overlay may prevent embedding if (is_object($this->overlay) && !$this->overlay->should_embed_files()) { } else { // list has already started if (preg_match('/\\[image=[^\\]]+?\\]\\s*$/', $this->item['description'])) { $query[] = "description = '" . SQL::escape($this->item['description'] . ' [image=' . $origin . ']') . "'"; } else { $query[] = "description = '" . SQL::escape($this->item['description'] . "\n\n" . '[image=' . $origin . ']') . "'"; } } } // also use it as thumnail if none has been defined yet if (!isset($this->item['thumbnail_url']) || !trim($this->item['thumbnail_url'])) { include_once $context['path_to_root'] . 'images/images.php'; if (($image = Images::get($origin)) && ($url = Images::get_thumbnail_href($image))) { $query[] = "thumbnail_url = '" . SQL::escape($url) . "'"; } } // refresh stamp only if image update occurs within 6 hours after last edition if (SQL::strtotime($this->item['edit_date']) + 6 * 60 * 60 < time()) { $silently = TRUE; } // suppress a reference to an image that has been deleted } elseif ($action == 'image:delete') { // suppress reference in main description field $query[] = "description = '" . SQL::escape(Codes::delete_embedded($this->item['description'], 'image', $origin)) . "'"; // suppress references as icon and thumbnail as well include_once $context['path_to_root'] . 'images/images.php'; if ($image = Images::get($origin)) { if ($url = Images::get_icon_href($image)) { if ($this->item['icon_url'] == $url) { $query[] = "icon_url = ''"; } if ($this->item['thumbnail_url'] == $url) { $query[] = "thumbnail_url = ''"; } } if ($url = Images::get_thumbnail_href($image)) { if ($this->item['icon_url'] == $url) { $query[] = "icon_url = ''"; } if ($this->item['thumbnail_url'] == $url) { $query[] = "thumbnail_url = ''"; } } } // set an existing image as the section icon } elseif ($action == 'image:set_as_icon') { include_once $context['path_to_root'] . 'images/images.php'; if ($image = Images::get($origin)) { if ($url = Images::get_icon_href($image)) { $query[] = "icon_url = '" . SQL::escape($url) . "'"; } // also use it as thumnail if none has been defined yet if (!(isset($this->item['thumbnail_url']) && trim($this->item['thumbnail_url'])) && ($url = Images::get_thumbnail_href($image))) { $query[] = "thumbnail_url = '" . SQL::escape($url) . "'"; } } elseif ($origin) { $query[] = "icon_url = '" . SQL::escape($origin) . "'"; } $silently = TRUE; // set an existing image as the section thumbnail } elseif ($action == 'image:set_as_thumbnail') { include_once $context['path_to_root'] . 'images/images.php'; if ($image = Images::get($origin)) { // use the thumbnail for large files, or the image itself for smaller files if ($image['image_size'] > $context['thumbnail_threshold']) { $url = Images::get_thumbnail_href($image); } else { $url = Images::get_icon_href($image); } $query[] = "thumbnail_url = '" . SQL::escape($url) . "'"; } elseif ($origin) { $query[] = "thumbnail_url = '" . SQL::escape($origin) . "'"; } $silently = TRUE; // append a new image, and set it as the article thumbnail } elseif ($action == 'image:set_as_both') { if (!Codes::check_embedded($this->item['description'], 'image', $origin)) { $query[] = "description = '" . SQL::escape($this->item['description'] . ' [image=' . $origin . ']') . "'"; } include_once $context['path_to_root'] . 'images/images.php'; if ($image = Images::get($origin)) { // use the thumbnail for large files, or the image itself for smaller files if ($image['image_size'] > $context['thumbnail_threshold']) { $url = Images::get_thumbnail_href($image); } else { $url = Images::get_icon_href($image); } $query[] = "thumbnail_url = '" . SQL::escape($url) . "'"; } elseif ($origin) { $query[] = "thumbnail_url = '" . SQL::escape($origin) . "'"; } // do not remember minor changes $silently = TRUE; // add a reference to a new table in the section description } elseif ($action == 'table:create') { if (!Codes::check_embedded($this->item['description'], 'table', $origin)) { $query[] = "description = '" . SQL::escape($this->item['description'] . ' [table=' . $origin . ']') . "'"; } // suppress a reference to a table that has been deleted } elseif ($action == 'table:delete') { $query[] = "description = '" . SQL::escape(Codes::delete_embedded($this->item['description'], 'table', $origin)) . "'"; } // stamp the update if (!$silently) { $query[] = "edit_name='" . SQL::escape(Surfer::get_name()) . "'," . "edit_id=" . SQL::escape(Surfer::get_id()) . "," . "edit_address='" . SQL::escape(Surfer::get_email_address()) . "'," . "edit_action='{$action}'," . "edit_date='" . SQL::escape(gmstrftime('%Y-%m-%d %H:%M:%S')) . "'"; } // update the database if (@count($query)) { $query = "UPDATE " . SQL::table_name('sections') . " SET " . implode(', ', $query) . " WHERE id = " . SQL::escape($this->item['id']); SQL::query($query); } // always clear the cache, even on no update Sections::clear($this->item); // get the parent if (!$this->anchor) { $this->anchor = Anchors::get($this->item['anchor']); } // propagate the touch upwards silently -- we only want to purge the cache if (is_object($this->anchor)) { $this->anchor->touch('section:touch', $this->item['id'], TRUE); } }
/** * load the related item * * @param int the id of the record to load * @param boolean TRUE to always fetch a fresh instance, FALSE to enable cache * * @see shared/anchor.php */ function load_by_id($id, $mutable = FALSE) { $this->item = Files::get($id, $mutable); }
/** * process uploaded file * * This function processes files from the temporary directory, and put them at their definitive * place. * * It returns FALSE if there is a disk error, or if some virus has been detected, or if * the operation fails for some other reason (e.g., file size). * * @param array usually, $_FILES['upload'] * @param string target location for the file * @param mixed reference to the target anchor, of a function to parse every file individually * @return mixed file name or array of file names or FALSE if an error has occured */ public static function upload($input, $file_path, $target = NULL, $overlay = NULL) { global $context, $_REQUEST; // size exceeds php.ini settings -- UPLOAD_ERR_INI_SIZE if (isset($input['error']) && $input['error'] == 1) { Logger::error(i18n::s('The size of this file is over limit.')); } elseif (isset($input['error']) && $input['error'] == 2) { Logger::error(i18n::s('The size of this file is over limit.')); } elseif (isset($input['error']) && $input['error'] == 3) { Logger::error(i18n::s('No file has been transmitted.')); } elseif (isset($input['error']) && $input['error'] == 4) { Logger::error(i18n::s('No file has been transmitted.')); } elseif (!$input['size']) { Logger::error(i18n::s('No file has been transmitted.')); } // do we have a file? if (!isset($input['name']) || !$input['name'] || $input['name'] == 'none') { return FALSE; } // access the temporary uploaded file $file_upload = $input['tmp_name']; // $_FILES transcoding to utf8 is not automatic $input['name'] = utf8::encode($input['name']); // enhance file name $file_name = $input['name']; $file_extension = ''; $position = strrpos($input['name'], '.'); if ($position !== FALSE) { $file_name = substr($input['name'], 0, $position); $file_extension = strtolower(substr($input['name'], $position + 1)); } $input['name'] = $file_name; if ($file_extension) { $input['name'] .= '.' . $file_extension; } // ensure we have a file name $file_name = utf8::to_ascii($input['name']); // uploads are not allowed if (!Surfer::may_upload()) { Logger::error(i18n::s('You are not allowed to perform this operation.')); } elseif (!Files::is_authorized($input['name'])) { Logger::error(i18n::s('This type of file is not allowed.')); } elseif ($file_path && !Safe::is_uploaded_file($file_upload)) { Logger::error(i18n::s('Possible file attack.')); } else { // create folders if ($file_path) { Safe::make_path($file_path); } // sanity check if ($file_path && $file_path[strlen($file_path) - 1] != '/') { $file_path .= '/'; } // move the uploaded file if ($file_path && !Safe::move_uploaded_file($file_upload, $context['path_to_root'] . $file_path . $file_name)) { Logger::error(sprintf(i18n::s('Impossible to move the upload file to %s.'), $file_path . $file_name)); } else { // process the file where it is if (!$file_path) { $file_path = str_replace($context['path_to_root'], '', dirname($file_upload)); $file_name = basename($file_upload); } // check against viruses $result = Files::has_virus($context['path_to_root'] . $file_path . '/' . $file_name); // no virus has been found in this file if ($result == 'N') { $context['text'] .= Skin::build_block(i18n::s('No virus has been found.'), 'note'); } // this file has been infected! if ($result == 'Y') { // delete this file immediately Safe::unlink($file_path . '/' . $file_name); Logger::error(i18n::s('This file has been infected by a virus and has been rejected!')); return FALSE; } // explode a .zip file include_once $context['path_to_root'] . 'shared/zipfile.php'; if (preg_match('/\\.zip$/i', $file_name) && isset($_REQUEST['explode_files'])) { $zipfile = new zipfile(); // check files extracted from the archive file function explode_callback($name) { global $context; // reject all files put in sub-folders if (($path = substr($name, strlen($context['uploaded_path'] . '/'))) && strpos($path, '/') !== FALSE) { Safe::unlink($name); } elseif (!Files::is_authorized($name)) { Safe::unlink($name); } else { // make it easy to download $ascii = utf8::to_ascii(basename($name)); Safe::rename($name, $context['uploaded_path'] . '/' . $ascii); // remember this name $context['uploaded_files'][] = $ascii; } } // extract archive components and save them in mentioned directory $context['uploaded_files'] = array(); $context['uploaded_path'] = $file_path; if (!($count = $zipfile->explode($context['path_to_root'] . $file_path . '/' . $file_name, $file_path, '', 'explode_callback'))) { Logger::error(sprintf('Nothing has been extracted from %s.', $file_name)); return FALSE; } // one single file has been uploaded } else { $context['uploaded_files'] = array($file_name); } // ensure we know the surfer Surfer::check_default_editor($_REQUEST); // post-process all uploaded files foreach ($context['uploaded_files'] as $file_name) { // this will be filtered by umask anyway Safe::chmod($context['path_to_root'] . $file_path . $file_name, $context['file_mask']); // invoke post-processing function if ($target && is_callable($target)) { call_user_func($target, $file_name, $context['path_to_root'] . $file_path); // we have to update an anchor page } elseif ($target && is_string($target)) { $fields = array(); // update a file with the same name for this anchor if ($matching =& Files::get_by_anchor_and_name($target, $file_name)) { $fields['id'] = $matching['id']; } elseif (isset($input['id']) && ($matching = Files::get($input['id']))) { $fields['id'] = $matching['id']; // silently delete the previous version of the file if (isset($matching['file_name'])) { Safe::unlink($file_path . '/' . $matching['file_name']); } } // prepare file record $fields['file_name'] = $file_name; $fields['file_size'] = filesize($context['path_to_root'] . $file_path . $file_name); $fields['file_href'] = ''; $fields['anchor'] = $target; // change title if (isset($_REQUEST['title'])) { $fields['title'] = $_REQUEST['title']; } // change has been documented if (!isset($_REQUEST['version']) || !$_REQUEST['version']) { $_REQUEST['version'] = ''; } else { $_REQUEST['version'] = ' - ' . $_REQUEST['version']; } // always remember file uploads, for traceability $_REQUEST['version'] = $fields['file_name'] . ' (' . Skin::build_number($fields['file_size'], i18n::s('bytes')) . ')' . $_REQUEST['version']; // add to file history $fields['description'] = Files::add_to_history($matching, $_REQUEST['version']); // if this is an image, maybe we can derive a thumbnail for it? if (Files::is_image($file_name)) { include_once $context['path_to_root'] . 'images/image.php'; Image::shrink($context['path_to_root'] . $file_path . $file_name, $context['path_to_root'] . $file_path . 'thumbs/' . $file_name); if (file_exists($context['path_to_root'] . $file_path . 'thumbs/' . $file_name)) { $fields['thumbnail_url'] = $context['url_to_home'] . $context['url_to_root'] . $file_path . 'thumbs/' . rawurlencode($file_name); } } // change active_set if (isset($_REQUEST['active_set'])) { $fields['active_set'] = $_REQUEST['active_set']; } // change source if (isset($_REQUEST['source'])) { $fields['source'] = $_REQUEST['source']; } // change keywords if (isset($_REQUEST['keywords'])) { $fields['keywords'] = $_REQUEST['keywords']; } // change alternate_href if (isset($_REQUEST['alternate_href'])) { $fields['alternate_href'] = $_REQUEST['alternate_href']; } // overlay, if any if (is_object($overlay)) { // allow for change detection $overlay->snapshot(); // update the overlay from form content $overlay->parse_fields($_REQUEST); // save content of the overlay in this item $fields['overlay'] = $overlay->save(); $fields['overlay_id'] = $overlay->get_id(); } // create the record in the database if (!($fields['id'] = Files::post($fields))) { return FALSE; } // record surfer activity Activities::post('file:' . $fields['id'], 'upload'); } } // so far so good if (count($context['uploaded_files']) == 1) { return $context['uploaded_files'][0]; } else { return $context['uploaded_files']; } } } // some error has occured return FALSE; }
/** * render a link to an object * * Following types are supported: * - article - link to an article page * - category - link to a category page * - comment - link to a comment page * - download - link to a download page * - file - link to a file page * - flash - display a file as a native flash object, or play a flash video * - go * - image - display an in-line image * - next - link to an article page * - previous - link to an article page * - section - link to a section page * - server - link to a server page * - user - link to a user page * * @param string the type * @param string the id, with possible options or variant * @return string the rendered text **/ public static function render_object($type, $id) { global $context; $id = Codes::fix_tags($id); // depending on type switch ($type) { // link to an article case 'article': // maybe an alternate title has been provided $attributes = preg_split("/\\s*,\\s*/", $id, 2); $id = $attributes[0]; // load the record from the database if (!($item = Articles::get($id))) { $output = '[article=' . $id . ']'; } else { // ensure we have a label for this link if (isset($attributes[1])) { $text = $attributes[1]; $type = 'basic'; } else { $text = Skin::strip($item['title']); } // make a link to the target page $url = Articles::get_permalink($item); // return a complete anchor $output =& Skin::build_link($url, $text, $type); } return $output; // insert article description // insert article description case 'article.description': // maybe an alternate title has been provided $attributes = preg_split("/\\s*,\\s*/", $id, 2); $id = $attributes[0]; // load the record from the database if (!($item = Articles::get($id))) { $output = '[article.description=' . $id . ']'; } else { // ensure we have a label for this link if (isset($attributes[1])) { $text = $attributes[1]; $type = 'basic'; } else { $text = Skin::strip($item['title']); } // make a link to the target page $url = Articles::get_permalink($item); // return a complete anchor $output =& Skin::build_link($url, $text, 'article'); // the introduction text, if any $output .= BR . Codes::beautify($item['introduction']); // load overlay, if any if (isset($item['overlay']) && $item['overlay']) { $overlay = Overlay::load($item, 'article:' . $item['id']); // get text related to the overlay, if any if (is_object($overlay)) { $output .= $overlay->get_text('view', $item); } } // the description, which is the actual page body $output .= '<div>' . Codes::beautify($item['description']) . '</div>'; } return $output; // link to a category // link to a category case 'category': // maybe an alternate title has been provided $attributes = preg_split("/\\s*,\\s*/", $id, 2); $id = $attributes[0]; // load the record from the database if (!($item = Categories::get($id))) { $output = '[category=' . $id . ']'; } else { // ensure we have a label for this link if (isset($attributes[1])) { $text = $attributes[1]; $type = 'basic'; } else { $text = Skin::strip($item['title']); } // make a link to the target page $url = Categories::get_permalink($item); // return a complete anchor $output =& Skin::build_link($url, $text, $type); } return $output; // insert category description // insert category description case 'category.description': // maybe an alternate title has been provided $attributes = preg_split("/\\s*,\\s*/", $id, 2); $id = $attributes[0]; // load the record from the database if (!($item = Categories::get($id))) { $output = '[category.description=' . $id . ']'; } else { // ensure we have a label for this link if (isset($attributes[1])) { $text = $attributes[1]; $type = 'basic'; } else { $text = Skin::strip($item['title']); } // make a link to the target page $url = Categories::get_permalink($item); // return a complete anchor $output =& Skin::build_link($url, $text, 'category'); // the introduction text, if any $output .= BR . Codes::beautify($item['introduction']); // load overlay, if any if (isset($item['overlay']) && $item['overlay']) { $overlay = Overlay::load($item, 'category:' . $item['id']); // get text related to the overlay, if any if (is_object($overlay)) { $output .= $overlay->get_text('view', $item); } } // the description, which is the actual page body $output .= '<div>' . Codes::beautify($item['description']) . '</div>'; } return $output; // link to a comment // link to a comment case 'comment': include_once $context['path_to_root'] . 'comments/comments.php'; // maybe an alternate title has been provided $attributes = preg_split("/\\s*,\\s*/", $id, 2); $id = $attributes[0]; // load the record from the database if (!($item = Comments::get($id))) { $output = '[comment=' . $id . ']'; } else { // ensure we have a label for this link if (isset($attributes[1])) { $text = $attributes[1]; } else { $text = i18n::s('View this comment'); } // make a link to the target page $url = $context['url_to_home'] . $context['url_to_root'] . Comments::get_url($item['id']); // return a complete anchor $output =& Skin::build_link($url, $text, 'basic'); } return $output; // link to a download // link to a download case 'download': // maybe an alternate title has been provided $attributes = preg_split("/\\s*,\\s*/", $id, 2); $id = $attributes[0]; // load the record from the database if (!($item = Files::get($id))) { // file does not exist anymore if (isset($attributes[1]) && $attributes[1]) { $output = $attributes[1] . '<p class="details">' . i18n::s('[this file has been deleted]') . '</p>'; } else { $output = '[download=' . $id . ']'; } } else { // label for this file $prefix = $text = $suffix = ''; // signal restricted and private files if ($item['active'] == 'N') { $prefix .= PRIVATE_FLAG; } elseif ($item['active'] == 'R') { $prefix .= RESTRICTED_FLAG; } // ensure we have a label for this link if (isset($attributes[1]) && $attributes[1]) { $text .= $attributes[1]; // this may describe a previous file, which has been replaced if ($item['edit_action'] != 'file:create' && $attributes[1] != $item['file_name']) { $text .= ' <p class="details">' . i18n::s('[this file has been replaced]') . '</p>'; $output = $prefix . $text . $suffix; return $output; } } else { $text = Skin::strip($item['title'] ? $item['title'] : str_replace('_', ' ', $item['file_name'])); } // flag files uploaded recently if ($item['create_date'] >= $context['fresh']) { $suffix .= NEW_FLAG; } elseif ($item['edit_date'] >= $context['fresh']) { $suffix .= UPDATED_FLAG; } // always download the file $url = $context['url_to_home'] . $context['url_to_root'] . Files::get_url($item['id'], 'fetch', $item['file_name']); // return a complete anchor $output = $prefix . Skin::build_link($url, $text, 'file') . $suffix; } return $output; // link to a file // link to a file case 'file': // maybe an alternate title has been provided $attributes = preg_split("/\\s*,\\s*/", $id, 2); $id = $attributes[0]; // load the record from the database --ensure we get a fresh copy of the record, not a cached one if (!($item = Files::get($id, TRUE))) { // file does not exist anymore if (isset($attributes[1]) && $attributes[1]) { $output = $attributes[1] . '<p class="details">' . i18n::s('[this file has been deleted]') . '</p>'; } else { $output = '[file=' . $id . ']'; } } else { // maybe we want to illustrate this file if ($item['edit_action'] != 'file:create' && isset($attributes[1]) && $attributes[1] || !($output = Files::interact($item))) { // label for this file $output = $prefix = $text = $suffix = ''; // signal restricted and private files if ($item['active'] == 'N') { $prefix .= PRIVATE_FLAG; } elseif ($item['active'] == 'R') { $prefix .= RESTRICTED_FLAG; } // ensure we have a label for this link if (isset($attributes[1]) && $attributes[1]) { $text .= $attributes[1]; // this may describe a previous file, which has been replaced if ($item['edit_action'] != 'file:create' && $attributes[1] != $item['file_name']) { $text .= '<p class="details">' . i18n::s('[this file has been replaced]') . '</p>'; $output = $prefix . $text . $suffix; return $output; } } else { $text .= Skin::strip($item['title'] ? $item['title'] : str_replace('_', ' ', $item['file_name'])); } // flag files uploaded recently if ($item['create_date'] >= $context['fresh']) { $suffix .= NEW_FLAG; } elseif ($item['edit_date'] >= $context['fresh']) { $suffix .= UPDATED_FLAG; } // make a link to the target page $url = Files::get_download_url($item); // return a complete anchor $output .= $prefix . Skin::build_link($url, $text, 'basic') . $suffix; } } return $output; // invoke the selector // invoke the selector case 'go': // extract the label, if any $attributes = preg_split("/\\s*,\\s*/", $id, 2); $name = $attributes[0]; // ensure we have a label for this link if (isset($attributes[1])) { $text = $attributes[1]; } else { $text = $name; } // return a complete anchor $output = Skin::build_link($context['url_to_home'] . $context['url_to_root'] . normalize_shortcut($name), $text, 'basic'); return $output; // embed an image // embed an image case 'image': include_once $context['path_to_root'] . 'images/images.php'; // get the variant, if any $attributes = preg_split("/\\s*,\\s*/", $id, 2); $id = $attributes[0]; if (isset($attributes[1])) { $variant = $attributes[1]; } else { $variant = 'inline'; } // get the image record if (!($image = Images::get($id))) { $output = '[image=' . $id . ']'; return $output; } // a title for the image --do not force a title if (isset($image['title'])) { $title = $image['title']; } else { $title = ''; } // provide thumbnail if not defined, or forced, or for large images if (!$image['use_thumbnail'] || $image['use_thumbnail'] == 'A' || $image['use_thumbnail'] == 'Y' && $image['image_size'] > $context['thumbnail_threshold']) { // not inline anymore, but thumbnail --preserve other variants if ($variant == 'inline') { $variant = 'thumbnail'; } // where to fetch the image file $href = Images::get_thumbnail_href($image); // to drive to plain image $link = Images::get_icon_href($image); // add an url, if any } elseif ($image['link_url']) { // flag large images if ($image['image_size'] > $context['thumbnail_threshold']) { $variant = rtrim('large ' . $variant); } // where to fetch the image file $href = Images::get_icon_href($image); // transform local references, if any include_once $context['path_to_root'] . '/links/links.php'; $attributes = Links::transform_reference($image['link_url']); if ($attributes[0]) { $link = $context['url_to_root'] . $attributes[0]; } else { $link = $image['link_url']; } // get the <img ... /> element } else { // do not append poor titles to inline images if ($variant == 'inline') { $title = ''; } // flag large images if ($image['image_size'] > $context['thumbnail_threshold']) { $variant = rtrim('large ' . $variant); } // where to fetch the image file $href = Images::get_icon_href($image); // no link $link = ''; } // use the skin if (Images::allow_modification($image['anchor'], $id)) { // build editable image $output =& Skin::build_image($variant, $href, $title, $link, $id); } else { $output =& Skin::build_image($variant, $href, $title, $link); } return $output; // embed a stack of images // embed a stack of images case 'images': include_once $context['path_to_root'] . 'images/images.php'; // get the list of ids $ids = preg_split("/\\s*,\\s*/", $id); if (!count($ids)) { $output = '[images=id1, id2, ...]'; return $output; } // build the list of images $items = array(); foreach ($ids as $id) { // get the image record if ($image = Images::get($id)) { // a title for the image --do not force a title if (isset($image['title'])) { $title = $image['title']; } else { $title = ''; } // provide thumbnail if not defined, or forced, or for large images $variant = 'inline'; if (!$image['use_thumbnail'] || $image['use_thumbnail'] == 'A' || $image['use_thumbnail'] == 'Y' && $image['image_size'] > $context['thumbnail_threshold']) { // not inline anymore, but thumbnail $variant = 'thumbnail'; // where to fetch the image file $href = Images::get_thumbnail_href($image); // to drive to plain image $link = $context['url_to_root'] . Images::get_url($id); // add an url, if any } elseif ($image['link_url']) { // flag large images if ($image['image_size'] > $context['thumbnail_threshold']) { $variant = rtrim('large ' . $variant); } // where to fetch the image file $href = Images::get_icon_href($image); // transform local references, if any include_once $context['path_to_root'] . '/links/links.php'; $attributes = Links::transform_reference($image['link_url']); if ($attributes[0]) { $link = $context['url_to_root'] . $attributes[0]; } else { $link = $image['link_url']; } // get the <img ... /> element } else { // flag large images if ($image['image_size'] > $context['thumbnail_threshold']) { $variant = rtrim('large ' . $variant); } // where to fetch the image file $href = Images::get_icon_href($image); // no link $link = ''; } // use the skin $label =& Skin::build_image($variant, $href, $title, $link); // add item to the stack $items[] = $label; } } // format the list $output = ''; if (count($items)) { // stack items $output = Skin::finalize_list($items, 'stack'); // rotate items $output = Skin::rotate($output); } // done return $output; // link to the next article // link to the next article case 'next': // maybe an alternate title has been provided $attributes = preg_split("/\\s*,\\s*/", $id, 2); $id = $attributes[0]; // load the record from the database if (!($item = Articles::get($id))) { $output = '[next=' . $id . ']'; } else { // ensure we have a label for this link if (isset($attributes[1])) { $text = $attributes[1]; } else { $text = Skin::strip($item['title']); } // make a link to the target page $url = Articles::get_permalink($item); // return a complete anchor $output =& Skin::build_link($url, $text, 'next'); } return $output; // link to the previous article // link to the previous article case 'previous': // maybe an alternate title has been provided $attributes = preg_split("/\\s*,\\s*/", $id, 2); $id = $attributes[0]; // load the record from the database if (!($item = Articles::get($id))) { $output = '[previous=' . $id . ']'; } else { // ensure we have a label for this link if (isset($attributes[1])) { $text = $attributes[1]; } else { $text = Skin::strip($item['title']); } // make a link to the target page $url = Articles::get_permalink($item); // return a complete anchor $output =& Skin::build_link($url, $text, 'previous'); } return $output; // link to a section // link to a section case 'section': // maybe an alternate title has been provided $attributes = preg_split("/\\s*,\\s*/", $id, 2); $id = $attributes[0]; // load the record from the database if (!($item = Sections::get($id))) { $output = '[section=' . $id . ']'; } else { // ensure we have a label for this link if (isset($attributes[1])) { $text = $attributes[1]; $type = 'basic'; } else { $text = Skin::strip($item['title']); } // make a link to the target page $url = Sections::get_permalink($item); // return a complete anchor $output =& Skin::build_link($url, $text, $type); } return $output; // link to a server // link to a server case 'server': include_once $context['path_to_root'] . 'servers/servers.php'; // maybe an alternate title has been provided $attributes = preg_split("/\\s*,\\s*/", $id, 2); $id = $attributes[0]; // load the record from the database if (!($item = Servers::get($id))) { $output = '[server=' . $id . ']'; } else { // ensure we have a label for this link if (isset($attributes[1])) { $text = $attributes[1]; $type = 'basic'; } else { $text = Skin::strip($item['title']); } // make a link to the target page $url = $context['url_to_home'] . $context['url_to_root'] . Servers::get_url($id); // return a complete anchor $output =& Skin::build_link($url, $text, $type); } return $output; // link to a user // link to a user case 'user': // maybe an alternate title has been provided $attributes = preg_split("/\\s*,\\s*/", $id, 2); $id = $attributes[0]; // load the record from the database if (!($item = Users::get($id))) { $output = '[user='******']'; } else { // ensure we have a label for this link if (isset($attributes[1])) { $text = $attributes[1]; $type = 'basic'; } elseif (isset($item['full_name']) && $item['full_name']) { $text = ucfirst($item['full_name']); } else { $text = ucfirst($item['nick_name']); } // make a link to the target page $url = Users::get_permalink($item); // return a complete anchor $output =& Skin::build_link($url, $text, $type); } return $output; // invalid type // invalid type default: $output = '[' . $type . ']'; return $output; } }