/** * list comments as successive notes in a thread * * @param resource the SQL result * @return string the rendered text **/ function layout($result) { global $context; // we return formatted text $text = ''; // empty list if (!SQL::count($result)) { return $text; } // build a list of comments while ($item = SQL::fetch($result)) { // automatic notification if ($item['type'] == 'notification') { $text = '<dd class="thread_other" style="font-style: italic;">' . ucfirst(trim($item['description'])) . '</dd>' . $text; } else { // link to user profile -- open links in separate window to enable side browsing of participant profiles if ($item['create_id']) { if ($user = Users::get($item['create_id']) && $user['full_name']) { $hover = $user['full_name']; } else { $hover = NULL; } $author = Users::get_link($item['create_name'], $item['create_address'], $item['create_id'], TRUE, $hover); } else { $author = Users::get_link($item['edit_name'], $item['edit_address'], $item['edit_id'], TRUE); } // differentiate my posts from others if (Surfer::get_id() && $item['create_id'] == Surfer::get_id()) { $style = ' class="thread_me"'; } else { $style = ' class="thread_other"'; } // a clickable label $stamp = '#'; // flag old items on same day if (!strncmp($item['edit_date'], gmstrftime('%Y-%m-%d %H:%M:%S', time()), 10)) { $stamp = Skin::build_time($item['edit_date']); } else { $stamp = Skin::build_date($item['edit_date']); } // append this at the end of the comment $stamp = ' <div style="float: right; font-size: x-small">' . Skin::build_link(Comments::get_url($item['id']), $stamp, 'basic', i18n::s('Edit')) . '</div>'; // package everything --change order to get oldest first $text = '<dt' . $style . '>' . $author . '</dt><dd' . $style . '>' . $stamp . ucfirst(trim($item['description'])) . '</dd>' . $text; } } // end of processing SQL::free($result); // finalize the returned definition list if ($text) { $text = '<dl>' . $text . '</dl>'; } // process yacs codes $text = Codes::beautify($text); return $text; }
/** * list participants * * @see overlays/overlay.php * * @param array the hosting record * @return some HTML to be inserted into the resulting page */ function &get_list_text($host = NULL) { global $context; // we return some text $text = ''; $to_avoid = NULL; if ($id = Surfer::get_id()) { $to_avoid = 'user:'******'article:' . $host['id'], 0, USERS_LIST_SIZE, 'comma', $to_avoid)) { $text = '<p class="details">' . sprintf(i18n::s('with %s'), Skin::build_list($friends, 'comma')) . '</p>'; } return $text; }
/** * retrieve endpoints of last calls * * This is useful to list all servers notified after a publication. * * @param string title of the folded box generated * @return mixed text to be integrated into the page, or array with one item per recipient, or '' */ public static function build_endpoints($title = NULL) { global $context; // nothing to show if (!Surfer::get_id() || !isset($context['servers_endpoints']) || !$context['servers_endpoints']) { return ''; } // return the bare list if (!$title) { return $context['servers_endpoints']; } // build a nice list $list = array(); foreach ($context['servers_endpoints'] as $recipient) { $list[] = htmlspecialchars($recipient); } return Skin::build_box($title, Skin::finalize_list($list, 'compact'), 'folded'); }
// common definitions and initial processing include_once '../shared/global.php'; // ensure we only provide public content through newsfeeds $context['users_without_teasers'] = 'Y'; // check network credentials, if any -- used by winamp and other media players if ($user = Users::authenticate()) { Surfer::empower($user['capability']); } // look for the id $id = NULL; if (isset($_REQUEST['id'])) { $id = $_REQUEST['id']; } elseif (isset($context['arguments'][0])) { $id = $context['arguments'][0]; } elseif (Surfer::is_logged()) { $id = Surfer::get_id(); } $id = strip_tags($id); // get the item from the database $item = Users::get($id); // associates can do what they want if (Surfer::is_associate()) { $permitted = TRUE; } elseif ($item['active'] == 'R' && Surfer::is_member()) { $permitted = TRUE; } elseif ($item['active'] == 'Y') { $permitted = TRUE; } else { $permitted = FALSE; } // load the skin
} } // archive the letter $context['text'] .= i18n::s('Archiving the new letter') . BR . "\n"; // save the letter as a published article, but don't use special categories $fields = array(); $fields['anchor'] = $anchor; $fields['title'] = $_REQUEST['letter_title']; $label = $_REQUEST['letter_recipients']; if ($_REQUEST['letter_recipients'] == 'custom' && isset($_REQUEST['mail_to'])) { $label = $_REQUEST['mail_to']; } $fields['introduction'] = sprintf(i18n::c('Sent %s to "%s"'), Skin::build_date(time(), 'full', $context['preferred_language']), $label); $fields['description'] = $_REQUEST['letter_body']; $fields['publish_name'] = Surfer::get_name(); $fields['publish_id'] = Surfer::get_id(); $fields['publish_address'] = Surfer::get_email_address(); $fields['publish_date'] = gmstrftime('%Y-%m-%d %H:%M:%S'); $fields['id'] = Articles::post($fields); // from: from configuration files if (isset($context['letter_reply_to']) && $context['letter_reply_to']) { $from = $context['letter_reply_to']; } elseif (isset($context['mail_from']) && $context['mail_from']) { $from = $context['mail_from']; } else { $from = $context['site_name']; } // to: build the list of recipients $recipients = array(); switch ($_REQUEST['letter_recipients']) { case 'all':
/** * remember that surfer is enrolled in a meeting * * @param string reference of the target page */ public static function confirm($reference) { global $context; // sanity check if (!$reference) { return; } // ensure that the joiner has been enrolled... if (!($item = enrolments::get_record($reference))) { if (Surfer::get_id()) { // fields to save $query = array(); $query[] = "anchor = '" . $reference . "'"; $query[] = "approved = 'Y'"; $query[] = "edit_date = '" . SQL::escape(gmstrftime('%Y-%m-%d %H:%M:%S')) . "'"; $query[] = "user_id = " . SQL::escape(Surfer::get_id()); $query[] = "user_email = '" . SQL::escape(Surfer::get_email_address()) . "'"; // insert a new record $query = "INSERT INTO " . SQL::table_name('enrolments') . " SET " . implode(', ', $query); SQL::query($query); } // each joiner takes one seat } else { $query = "UPDATE " . SQL::table_name('enrolments') . " SET approved = 'Y' WHERE id = " . SQL::escape($item['id']); SQL::query($query); } }
/** * remember the last action for this category * * @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 * * @see shared/anchor.php */ function touch($action, $origin = NULL, $silently = FALSE) { global $context; // don't go further on import if (preg_match('/import$/i', $action)) { return; } // no category bound if (!isset($this->item['id'])) { return; } // sanity check if (!$origin) { logger::remember('categories/category.php: unexpected NULL origin at touch()'); return; } // components of the query $query = array(); // append a reference to a new image to the description if ($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 category 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) . "'"; } } $silently = TRUE; // set an existing image as the category thumbnail } elseif ($action == 'image:set_as_thumbnail') { include_once $context['path_to_root'] . 'images/images.php'; if ($image = Images::get($origin)) { if ($url = Images::get_thumbnail_href($image)) { $query[] = "thumbnail_url = '" . SQL::escape($url) . "'"; } } $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)) { if ($url = Images::get_thumbnail_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 category 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='" . Surfer::get_name() . "'," . "edit_id=" . Surfer::get_id() . "," . "edit_address='" . Surfer::get_email_address() . "'," . "edit_action='{$action}'," . "edit_date='" . strftime('%Y-%m-%d %H:%M:%S') . "'"; } // ensure we have a valid update query if (!@count($query)) { return; } // update the anchor category $query = "UPDATE " . SQL::table_name('categories') . " SET " . implode(', ', $query) . " WHERE id = " . SQL::escape($this->item['id']); if (SQL::query($query) === FALSE) { return; } // always clear the cache, even on no update Categories::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('category:update', $this->item['id'], TRUE); } }
/** * text to come after page description * * @param array the hosting record, if any * @return some HTML to be inserted into the resulting page */ function &get_trailer_text($host = NULL) { global $context; // the text $text = ''; // actually, a menu of commands $menu = array(); // no end date if (!isset($this->attributes['end_date']) || $this->attributes['end_date'] <= NULL_DATE) { $open = TRUE; } elseif ($this->attributes['end_date'] > gmstrftime('%Y-%m-%d %H:%M:%S')) { $open = TRUE; } else { $open = FALSE; } // different for each surfer Cache::poison(); // link to vote if ($open && Surfer::get_id() && Surfer::get_id() && !Comments::count_approvals_for_anchor($this->anchor->get_reference(), Surfer::get_id())) { $menu[] = Skin::build_link(Comments::get_url($this->anchor->get_reference(), 'approve'), i18n::s('Sign this petition'), 'shortcut'); } $text = Skin::finalize_list($menu, 'menu_bar'); return $text; }
// post a new query } elseif (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST') { // protect from hackers if (isset($_REQUEST['edit_name'])) { $_REQUEST['edit_name'] = preg_replace(FORBIDDEN_IN_NAMES, '_', $_REQUEST['edit_name']); } if (isset($_REQUEST['edit_address'])) { $_REQUEST['edit_address'] = encode_link($_REQUEST['edit_address']); } // track anonymous surfers Surfer::track($_REQUEST); // this is the exact copy of what end users has typed $item = $_REQUEST; // from form fields to record columns if (!isset($_REQUEST['edit_id'])) { $_REQUEST['edit_id'] = Surfer::get_id(); } $_REQUEST['create_address'] = $_REQUEST['edit_address']; $_REQUEST['create_name'] = $_REQUEST['edit_name']; if (!$_REQUEST['create_name']) { $_REQUEST['create_name'] = $_REQUEST['create_address']; } if (!$_REQUEST['create_name']) { $_REQUEST['create_name'] =& i18n::c('(anonymous)'); } // always auto-publish queries $_REQUEST['publish_date'] = gmstrftime('%Y-%m-%d %H:%M:%S'); if (isset($_REQUEST['edit_id'])) { $_REQUEST['publish_id'] = $_REQUEST['edit_id']; } $_REQUEST['publish_address'] = $_REQUEST['edit_address'];
// post the confirmation message Mailer::notify(NULL, $item['email'], $subject, $message, $headers); // feed-back message $context['text'] .= '<p>' . i18n::s('A reminder message has been sent to you. Check your mailbox and use provided information to authenticate to this site.') . '</p>'; // back to the anchor page $links = array(); $links[] = Skin::build_link('users/login.php', i18n::s('Login')); $context['text'] .= Skin::finalize_list($links, 'assistant_bar'); } // redirect to the origin server } elseif ($origin) { Logger::error(sprintf(i18n::s('We are only keeping a shadow record for this profile. Please handle this account at %s'), Skin::build_link('http://' . $origin, $origin, 'external'))); // password is changing } elseif (isset($_REQUEST['confirm'])) { // restrictions: anyone can modify its own profile; associates can modify everything if ($item['id'] != Surfer::get_id() && !Surfer::is_associate()) { Safe::header('Status: 401 Unauthorized', TRUE, 401); Logger::error(i18n::s('You are not allowed to perform this operation.')); // passwords have to be confirmed } elseif (!isset($_REQUEST['password']) || !$_REQUEST['password'] || strcmp($_REQUEST['confirm'], $_REQUEST['password'])) { Logger::error(i18n::s('Please confirm your new password.')); $with_form = TRUE; // stop robots and replay attacks } elseif (Surfer::may_be_a_robot()) { Logger::error(i18n::s('Please prove you are not a robot.')); $with_form = TRUE; // display the form on error } elseif (!Users::put($_REQUEST)) { $with_form = TRUE; // save one click to associates } elseif (Surfer::is_associate()) {
/** * the URL to start and to join the meeting * * @see overlays/events/start.php * * @return string the URL to redirect the user to the meeting, or NULL on error */ function get_start_url() { global $context; // almost random passwords $this->initialize_passwords(); // link to authenticate $url = 'https://my.dimdim.com/api/auth/login'; // parameters to authenticate $parameters = array(); $parameters['account'] = $this->attributes['account']; $parameters['password'] = $this->attributes['password']; $parameters['group'] = 'all'; // encode in json $data = array('request' => Safe::json_encode($parameters)); // do authenticate if ($response = http::proceed($url, '', $data)) { // successful authentication $output = Safe::json_decode($response); if (isset($output['result']) && $output['result']) { // remember the authentication token $fields = array('token' => $output['response']['authToken']); $this->set_values($fields); // link to create a meeting $url = 'https://my.dimdim.com/api/conf/start_meeting'; // provide authentication token $headers = 'X-Dimdim-Auth-Token: ' . $this->attributes['token'] . CRLF; // parameters to create a meeting $parameters = array(); $parameters['authToken'] = $this->attributes['token']; $parameters['account'] = $this->attributes['account']; $parameters['clientId'] = Surfer::get_id(); $parameters['displayName'] = Surfer::get_name(); $parameters['meetingName'] = $this->anchor->get_title(); $parameters['roomName'] = $this->anchor->get_title(); $parameters['meetingLengthMinutes'] = $this->attributes['duration']; $parameters['attendeeKey'] = $this->attendee_password; $parameters['assistantEnabled'] = 'false'; // disable some features $parameters['displayDialInfo'] = 'false'; // message displayed within the BigBlueButton session $welcome = ''; // meeting title if (is_object($this->anchor)) { $welcome .= sprintf(i18n::s('%s: %s'), i18n::s('Title'), $this->anchor->get_title()) . "\n"; } // meeting date if (isset($this->attributes['date_stamp'])) { $welcome .= sprintf(i18n::s('%s: %s'), i18n::s('Date'), Skin::build_date($this->attributes['date_stamp'], 'standalone')) . "\n"; } // meeting duration if (isset($this->attributes['duration'])) { $welcome .= sprintf(i18n::s('%s: %s'), i18n::s('Duration'), $this->attributes['duration'] . ' ' . i18n::s('minutes')) . "\n"; } // build a link to the owner page, if any if (is_object($this->anchor) && ($user = Users::get($this->anchor->get_value('owner_id')))) { $welcome .= sprintf(i18n::s('%s: %s'), i18n::s('Chairman'), $user['full_name']) . "\n"; } // welcome message $parameters['agenda'] = $welcome; // return URL if (is_callable(array($this->anchor, 'get_url'))) { $parameters['returnurl'] = $context['url_to_home'] . $context['url_to_root'] . $this->anchor->get_url(); } // encode in json $data = array('request' => Safe::json_encode($parameters)); // do the transaction if ($response = http::proceed($url, $headers, $data)) { // successful transaction $output = Safe::json_decode($response); if (isset($output['result']) && $output['result']) { // redirect to the target page return 'https://my.dimdim.com/redirect?clientId=' . urlencode(Surfer::get_id()) . '&account=' . urlencode($this->attributes['account']); } } } } // don't know where to go return NULL; }
/** * post a new section * * This function populates the error context, where applicable. * * @param array an array of fields * @param boolean TRUE to update the watch list of the poster * @return the id of the new article, or FALSE on error * * @see sections/edit.php * @see sections/populate.php * @see letters/new.php * @see links/links.php * @see query.php **/ public static function post(&$fields, $watch = TRUE) { global $context; // title cannot be empty if (!isset($fields['title']) || !trim($fields['title'])) { Logger::error(i18n::s('No title has been provided.')); return FALSE; } // sanity filter $fields['title'] = strip_tags($fields['title'], '<br>'); // protect from hackers if (isset($fields['icon_url'])) { $fields['icon_url'] = encode_link($fields['icon_url']); } if (isset($fields['thumbnail_url'])) { $fields['thumbnail_url'] = encode_link($fields['thumbnail_url']); } // set default values for this editor Surfer::check_default_editor($fields); // reinforce date formats if (!isset($fields['activation_date']) || $fields['activation_date'] <= NULL_DATE) { $fields['activation_date'] = NULL_DATE; } if (!isset($fields['create_date']) || $fields['create_date'] <= NULL_DATE) { $fields['create_date'] = $fields['edit_date']; } if (!isset($fields['expiry_date']) || $fields['expiry_date'] <= NULL_DATE) { $fields['expiry_date'] = NULL_DATE; } if (!isset($fields['publish_date']) || $fields['publish_date'] <= NULL_DATE) { $fields['publish_date'] = NULL_DATE; } // set conservative default values if (!isset($fields['active_set'])) { $fields['active_set'] = 'Y'; } if (isset($fields['edit_action'])) { $fields['edit_action'] = preg_replace('/import$/i', 'update', $fields['edit_action']); } if (!isset($fields['home_panel']) || !$fields['home_panel']) { $fields['home_panel'] = 'main'; } if (!isset($fields['index_map']) || !$fields['index_map']) { $fields['index_map'] = 'Y'; } if (!isset($fields['index_news']) || !$fields['index_news']) { $fields['index_news'] = 'none'; } // save on requests if (!isset($fields['rank']) || !$fields['rank']) { $fields['rank'] = 10000; } // set layout for sections if (!isset($fields['sections_layout']) || !$fields['sections_layout'] || !preg_match('/^(accordion|carrousel|compact|custom|decorated|directory|folded|inline|jive|map|slashdot|tabs|titles|yabb|none)$/', $fields['sections_layout'])) { $fields['sections_layout'] = 'none'; } elseif ($fields['sections_layout'] == 'custom') { if (isset($fields['sections_custom_layout']) && $fields['sections_custom_layout']) { $fields['sections_layout'] = $fields['sections_custom_layout']; } else { $fields['sections_layout'] = 'none'; } } // set layout for articles if (!isset($fields['articles_layout']) || !$fields['articles_layout'] || !preg_match('/^(accordion|alistapart|carrousel|custom|compact|daily|decorated|digg|directory|hardboiled|jive|map|newspaper|none|simile|slashdot|table|tabs|tagged|threads|titles|yabb)$/', $fields['articles_layout'])) { $fields['articles_layout'] = 'decorated'; } elseif ($fields['articles_layout'] == 'custom') { if (isset($fields['articles_custom_layout']) && $fields['articles_custom_layout']) { $fields['articles_layout'] = $fields['articles_custom_layout']; } else { $fields['articles_layout'] = 'decorated'; } } // set canvas for articles if (!isset($fields['articles_canvas']) || !$fields['articles_canvas']) { $fields['articles_canvas'] = 'standard'; } // clean provided tags if (isset($fields['tags'])) { $fields['tags'] = trim($fields['tags'], " \t.:,!?"); } // cascade anchor access rights if (isset($fields['anchor']) && ($anchor = Anchors::get($fields['anchor']))) { $fields['active'] = $anchor->ceil_rights($fields['active_set']); } else { $fields['active'] = $fields['active_set']; } // always create a random handle for this section if (!isset($fields['handle']) || strlen($fields['handle']) < 32) { $fields['handle'] = md5(mt_rand()); } $handle = "handle='" . SQL::escape($fields['handle']) . "',"; // allow anonymous surfer to access this section during his session if (!Surfer::get_id()) { Surfer::add_handle($fields['handle']); } // insert a new record $query = "INSERT INTO " . SQL::table_name('sections') . " SET "; // on import if (isset($fields['id'])) { $query .= "id='" . SQL::escape($fields['id']) . "',"; } // all fields should be visible $query .= "anchor='" . SQL::escape(isset($fields['anchor']) ? $fields['anchor'] : '') . "'," . "activation_date='" . SQL::escape($fields['activation_date']) . "'," . "active='" . SQL::escape($fields['active']) . "'," . "active_set='" . SQL::escape($fields['active_set']) . "'," . "articles_canvas='" . SQL::escape(isset($fields['articles_canvas']) ? $fields['articles_canvas'] : 'null') . "'," . "articles_layout='" . SQL::escape(isset($fields['articles_layout']) ? $fields['articles_layout'] : 'decorated') . "'," . "articles_templates='" . SQL::escape(isset($fields['articles_templates']) ? $fields['articles_templates'] : '') . "'," . "behaviors='" . SQL::escape(isset($fields['behaviors']) ? $fields['behaviors'] : '') . "'," . "content_options='" . SQL::escape(isset($fields['content_options']) ? $fields['content_options'] : '') . "'," . "content_overlay='" . SQL::escape(isset($fields['content_overlay']) ? $fields['content_overlay'] : '') . "'," . "create_address='" . SQL::escape(isset($fields['create_address']) ? $fields['create_address'] : $fields['edit_address']) . "', " . "create_date='" . SQL::escape($fields['create_date']) . "'," . "create_id=" . SQL::escape(isset($fields['create_id']) ? $fields['create_id'] : $fields['edit_id']) . ", " . "create_name='" . SQL::escape(isset($fields['create_name']) ? $fields['create_name'] : $fields['edit_name']) . "', " . "description='" . SQL::escape(isset($fields['description']) ? $fields['description'] : '') . "'," . "edit_action='" . SQL::escape(isset($fields['edit_action']) ? $fields['edit_action'] : 'section:create') . "', " . "edit_address='" . SQL::escape($fields['edit_address']) . "', " . "edit_date='" . SQL::escape($fields['edit_date']) . "'," . "edit_id=" . SQL::escape($fields['edit_id']) . ", " . "edit_name='" . SQL::escape($fields['edit_name']) . "', " . "expiry_date='" . SQL::escape($fields['expiry_date']) . "'," . "extra='" . SQL::escape(isset($fields['extra']) ? $fields['extra'] : '') . "'," . "family='" . SQL::escape(isset($fields['family']) ? $fields['family'] : '') . "'," . "file_overlay='" . SQL::escape(isset($fields['file_overlay']) ? $fields['file_overlay'] : '') . "'," . $handle . "hits=" . SQL::escape(isset($fields['hits']) ? $fields['hits'] : 0) . "," . "home_panel='" . SQL::escape(isset($fields['home_panel']) ? $fields['home_panel'] : 'main') . "'," . "icon_url='" . SQL::escape(isset($fields['icon_url']) ? $fields['icon_url'] : '') . "'," . "index_map='" . SQL::escape(isset($fields['index_map']) ? $fields['index_map'] : 'Y') . "'," . "index_news='" . SQL::escape(isset($fields['index_news']) ? $fields['index_news'] : 'static') . "'," . "index_news_count=" . SQL::escape(isset($fields['index_news_count']) ? $fields['index_news_count'] : 5) . "," . "index_title='" . SQL::escape(isset($fields['index_title']) ? $fields['index_title'] : '') . "'," . "introduction='" . SQL::escape(isset($fields['introduction']) ? $fields['introduction'] : '') . "'," . "language='" . SQL::escape(isset($fields['language']) ? $fields['language'] : '') . "'," . "locked='" . SQL::escape(isset($fields['locked']) ? $fields['locked'] : 'N') . "'," . "meta='" . SQL::escape(isset($fields['meta']) ? $fields['meta'] : '') . "'," . "nick_name='" . SQL::escape(isset($fields['nick_name']) ? $fields['nick_name'] : '') . "'," . "options='" . SQL::escape(isset($fields['options']) ? $fields['options'] : '') . "'," . "overlay='" . SQL::escape(isset($fields['overlay']) ? $fields['overlay'] : '') . "'," . "overlay_id='" . SQL::escape(isset($fields['overlay_id']) ? $fields['overlay_id'] : '') . "'," . "owner_id=" . SQL::escape(isset($fields['create_id']) ? $fields['create_id'] : $fields['edit_id']) . ", " . "prefix='" . SQL::escape(isset($fields['prefix']) ? $fields['prefix'] : '') . "'," . "rank='" . SQL::escape(isset($fields['rank']) ? $fields['rank'] : 10000) . "'," . "section_overlay='" . SQL::escape(isset($fields['section_overlay']) ? $fields['section_overlay'] : '') . "'," . "sections_layout='" . SQL::escape(isset($fields['sections_layout']) ? $fields['sections_layout'] : 'map') . "'," . "suffix='" . SQL::escape(isset($fields['suffix']) ? $fields['suffix'] : '') . "'," . "tags='" . SQL::escape(isset($fields['tags']) ? $fields['tags'] : '') . "'," . "template='" . SQL::escape(isset($fields['template']) ? $fields['template'] : '') . "'," . "thumbnail_url='" . SQL::escape(isset($fields['thumbnail_url']) ? $fields['thumbnail_url'] : '') . "'," . "title='" . SQL::escape(isset($fields['title']) ? $fields['title'] : '') . "'," . "trailer='" . SQL::escape(isset($fields['trailer']) ? $fields['trailer'] : '') . "'"; // actual insert if (SQL::query($query) === FALSE) { return FALSE; } // remember the id of the new item $fields['id'] = SQL::get_last_id($context['connection']); // assign the page to related categories Categories::remember('section:' . $fields['id'], NULL_DATE, isset($fields['tags']) ? $fields['tags'] : ''); // turn author to page editor and update author's watch list if ($watch && isset($fields['edit_id']) && $fields['edit_id']) { Members::assign('user:'******'edit_id'], 'section:' . $fields['id']); Members::assign('section:' . $fields['id'], 'user:'******'edit_id']); } // clear the cache Sections::clear($fields); // return the id of the new item return $fields['id']; }
$text = ''; require_once '../canvas/' . $item['canvas'] . '.php'; // special layout for digg if (defined('DIGG')) { $text = '<div class="digg_content">' . $text . '</div>'; } // update the main content panel $context['text'] .= $text; // // extra panel // // page tools // if ($whole_rendering) { // comment this page if anchor does not prevent it --anonymous surfers will have it in main area if ($cur_article->allows('creation', 'comment') && Surfer::get_id()) { Skin::define_img('COMMENTS_ADD_IMG', 'comments/add.gif'); $context['page_tools'][] = Skin::build_link(Comments::get_url('article:' . $item['id'], 'comment'), COMMENTS_ADD_IMG . i18n::s('Post a comment'), 'basic', i18n::s('Express yourself, and say what you think.')); } // attach a file, if upload is allowed if ($cur_article->allows('creation', 'file')) { Skin::define_img('FILES_UPLOAD_IMG', 'files/upload.gif'); $context['page_tools'][] = Skin::build_link('files/edit.php?anchor=' . urlencode('article:' . $item['id']), FILES_UPLOAD_IMG . i18n::s('Add a file'), 'basic', i18n::s('Attach related files.')); } // add a link if ($cur_article->allows('creation', 'link')) { Skin::define_img('LINKS_ADD_IMG', 'links/add.gif'); $context['page_tools'][] = Skin::build_link('links/edit.php?anchor=' . urlencode('article:' . $item['id']), LINKS_ADD_IMG . i18n::s('Add a link'), 'basic', i18n::s('Contribute to the web and link to relevant pages.')); } // post an image, if upload is allowed if ($cur_article->allows('creation', 'image')) {
// create a new page if ($item['id'] = Articles::post($item)) { // also duplicate the provided overlay, if any -- re-use 'overlay_type' only $overlay = Overlay::load($item, 'article:' . $item['id']); // post an overlay, with the new article id if (is_object($overlay)) { $overlay->remember('insert', $item, 'article:' . $item['id']); } // duplicate all related items, images, etc. Anchors::duplicate_related_to($original_anchor, 'article:' . $item['id']); // if poster is a registered user if (Surfer::get_id()) { // increment the post counter of the surfer Users::increment_posts(Surfer::get_id()); // add this page to watch list Members::assign('article:' . $item['id'], 'user:'******'article:' . $item['id'], TRUE); $context['page_title'] = i18n::s('Thank you for your contribution'); // the page has been duplicated $context['text'] .= '<p>' . i18n::s('The page has been duplicated.') . '</p>'; // follow-up commands $follow_up = i18n::s('What do you want to do now?'); $menu = array(); $menu = array_merge($menu, array($article->get_url() => i18n::s('View the page'))); $menu = array_merge($menu, array($article->get_url('edit') => i18n::s('Edit the page'))); if (Surfer::may_upload()) { $menu = array_merge($menu, array('images/edit.php?anchor=' . urlencode($article->get_reference()) => i18n::s('Add an image'))); $menu = array_merge($menu, array('files/edit.php?anchor=' . urlencode($article->get_reference()) => i18n::s('Add a file'))); }
// bottom commands if (!$render_overlaid) { $menu = array(); $menu[] = Skin::build_submit_button(i18n::s('Submit'), i18n::s('Press [s] to submit data'), 's'); if (is_object($anchor) && $anchor->is_viewable()) { $menu[] = Skin::build_link($anchor->get_url(), i18n::s('Cancel'), 'span'); } $context['text'] .= Skin::finalize_list($menu, 'assistant_bar'); // optional checkboxes $context['text'] .= '<p>'; // do not process notifications for draft articles if (strncmp($anchor->get_reference(), 'article:', strlen('article:')) || $anchor->get_value('publish_date', NULL_DATE) > NULL_DATE) { // notify watchers $context['text'] .= '<input type="checkbox" name="notify_watchers" value="Y" checked="checked" /> ' . i18n::s('Notify watchers') . BR; // notify people following me if (Surfer::get_id() && !$anchor->is_hidden()) { $context['text'] .= '<input type="checkbox" name="notify_followers" value="Y" /> ' . i18n::s('Notify my followers') . BR; } } // associates may decide to not stamp changes, but only for changes -- complex command if (Surfer::is_associate() && isset($anchor) && Surfer::has_all()) { if ((Surfer::is_associate() || is_object($anchor) && $anchor->is_assigned()) && Surfer::has_all()) { $context['text'] .= '<input type="checkbox" name="silent" value="Y" /> ' . i18n::s('Do not change modification date of the main page.') . BR; } } // validate page content $context['text'] .= '<input type="checkbox" name="option_validate" value="Y" checked="checked" /> ' . i18n::s('Ensure this post is valid XHTML.') . '</p>'; } // transmit the id as a hidden field if (isset($item['id']) && $item['id']) { $context['text'] .= '<input type="hidden" name="id" value="' . $item['id'] . '" />';
// [article.description=id] $context['text'] .= '[title]' . i18n::s('Page') . ' [escape][article.description=<id>][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape][article.description=' . $article_id . '][/escape]</td>' . '<td>[article.description=' . $article_id . ']</td></tr>' . Skin::table_suffix(); // [previous=id] $context['text'] .= '[title]' . i18n::s('Previous page') . ' [escape][previous=<id>] [previous=<id>, <label>][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape][previous=' . $article_id . '][/escape]</td>' . '<td>[previous=' . $article_id . ']</td></tr>' . Skin::table_suffix(); // [next=id] $context['text'] .= '[title]' . i18n::s('Next page') . ' [escape][next=<id>] [next=<id>, <label>][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape][next=' . $article_id . '][/escape]</td>' . '<td>[next=' . $article_id . ']</td></tr>' . Skin::table_suffix(); // [random=section:id] $context['text'] .= '[title]' . i18n::s('Random') . ' [escape][random] [random=section:<id>][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape][random] [random=section:' . $section_id . '][/escape]</td>' . '<td>[random] [random=section:' . $section_id . ']</td></tr>' . Skin::table_suffix(); // [section=id] $context['text'] .= '[title]' . i18n::s('Section shortcut') . ' [escape][section=<id>] [section=<id>, <label>][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape]' . sprintf(i18n::s('Have a look at %s'), '[section=' . $section_id . ']') . '[/escape]</td>' . '<td>' . sprintf(i18n::s('Have a look at %s'), '[section=' . $section_id . ']') . '</td></tr>' . Skin::table_suffix(); // [category=id] $context['text'] .= '[title]' . i18n::s('Category shortcut') . ' [escape][category=<id>] [category=<id>, <label>][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape]' . sprintf(i18n::s('Have a look at %s'), '[category=featured]') . '[/escape]</td>' . '<td>' . sprintf(i18n::s('Have a look at %s'), '[category=featured]') . '</td></tr>' . Skin::table_suffix(); // [category.description=id] $context['text'] .= '[title]' . i18n::s('Category') . ' [escape][category.description=<id>][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape][category.description=featured][/escape]</td>' . '<td>[category.description=featured]</td></tr>' . Skin::table_suffix(); // [user=id] $context['text'] .= '[title]' . i18n::s('User shortcut') . ' [escape][user=<id>] [user=<id>, <label>][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape]' . sprintf(i18n::s('Have a look at %s'), '[user='******']') . '[/escape]</td>' . '<td>' . sprintf(i18n::s('Have a look at %s'), '[user='******']') . '</td></tr>' . Skin::table_suffix(); // [server=id] $context['text'] .= '[title]' . i18n::s('Server shortcut') . ' [escape][server=<id>] [server=<id>, <label>][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape]' . i18n::s('Click to view the page of [server=2, this server]') . '[/escape]</td>' . '<td>' . i18n::s('Click to view the page of [server=2, this server]') . '</td></tr>' . Skin::table_suffix(); // [file=id] $context['text'] .= '[title]' . i18n::s('File shortcut') . ' [escape][file=<id>] [file=<id>, <label>][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape]' . sprintf(i18n::s('Have a look at %s'), '[file=' . $file_id . ']') . '[/escape]</td>' . '<td>' . sprintf(i18n::s('Have a look at %s'), '[file=' . $file_id . ']') . '</td></tr>' . Skin::table_suffix(); // [download=id] $context['text'] .= '[title]' . i18n::s('Download shortcut') . ' [escape][download=<id>] [download=<id>, <label>][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape]' . sprintf(i18n::s('Click to %s'), '[download=' . $file_id . ', ' . i18n::s('download the file') . ']') . '[/escape]</td>' . '<td>' . sprintf(i18n::s('Click to %s'), '[download=' . $file_id . ', ' . i18n::s('download the file') . ']') . '</td></tr>' . Skin::table_suffix(); // [clicks=id] $context['text'] .= '[title]' . i18n::s('Member clicks') . ' [escape][clicks=<id>][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape][clicks=' . $file_id . '][/escape]</td>' . '<td>[clicks=' . $file_id . ']</td></tr>' . Skin::table_suffix(); // [action=id] $context['text'] .= '[title]' . i18n::s('Action shortcut') . ' [escape][action=<id>] [action=<id>, <label>][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape]' . i18n::s('Click to view the page of [action=2, this action]') . '[/escape]</td>' . '<td>' . i18n::s('Click to view the page of [action=2, this action]') . '</td></tr>' . Skin::table_suffix(); // [comment=id] $context['text'] .= '[title]' . i18n::s('Comment shortcut') . ' [escape][comment=<id>] [comment=<id>, <label>][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape]' . i18n::s('Click to view the page of [comment=2, this comment]') . '[/escape]</td>' . '<td>' . i18n::s('Click to view the page of [comment=2, this comment]') . '</td></tr>' . Skin::table_suffix(); // [script]index.php[/script] $context['text'] .= '[title]' . i18n::s('Script shortcut') . ' [escape][script]<path/script.php>[/script][/escape][/title]' . Skin::table_prefix('wide') . Skin::table_row(array(i18n::s('Example'), i18n::s('Rendering')), 'header') . '<tr><td class="sample">[escape]' . i18n::s('You can access the documentation for the script [script]shared/codes.php[/script]') . '[/escape]</td>' . '<td>' . i18n::s('You can access the documentation for the script [script]shared/codes.php[/script]') . '</td></tr>' . Skin::table_suffix(); // [search=yacs]
// clear assignment information if (Files::assign($item['id'], NULL)) { // inform surfer $context['text'] .= '<p>' . i18n::s('You have released this file, and other surfers can reserve it for revision.') . '</p>'; // help the surfer } else { Logger::error(i18n::s('Operation has failed.')); } // follow-up commands $context['text'] .= Skin::build_block(Skin::build_link($anchor->get_url('files'), i18n::s('Done'), 'button'), 'bottom'); // file has not been assigned, and surfer has not confirmed the detach yet } elseif ($action == 'reserve' && (!isset($item['assign_id']) || !$item['assign_id']) && Surfer::get_id()) { // change page title $context['page_title'] = sprintf(i18n::s('%s: %s'), i18n::s('Reserve'), $context['page_title']); // assign the file to this surfer $user = array('nick_name' => Surfer::get_name(), 'id' => Surfer::get_id(), 'email' => Surfer::get_email_address()); if (Files::assign($item['id'], $user)) { // inform surfer $context['text'] .= '<p>' . sprintf(i18n::s('You have reserved this file, and you are encouraged to %s as soon as possible, or to %s.'), Skin::build_link(Files::get_url($item['id'], 'edit'), i18n::s('upload an updated version'), 'basic'), Skin::build_link(Files::get_url($item['id'], 'fetch', 'release'), i18n::s('release reservation'), 'basic')) . '</p>'; // help the surfer } else { Logger::error(i18n::s('Operation has failed.')); } // follow-up commands $context['text'] .= Skin::build_block(Skin::build_link($anchor->get_url('files'), i18n::s('Done'), 'button'), 'bottom'); // file has been reserved, and surfer is not owner } elseif ($action != 'confirm' && isset($item['assign_id']) && $item['assign_id'] && !Surfer::is($item['assign_id'])) { // inform surfer $context['text'] .= Skin::build_block(sprintf(i18n::s('This file has been assigned to %s %s, and it is likely that an updated version will be made available soon.'), Users::get_link($item['assign_name'], $item['assign_address'], $item['assign_id']), Skin::build_date($item['assign_date'])), 'caution'); // commands $menu = array();
} else { $context['path_bar'] = array('users/' => i18n::s('People')); } // an anchor is mandatory if (!is_object($anchor)) { Logger::error(i18n::s('No anchor has been found.')); } elseif (!$permitted) { Safe::header('Status: 401 Unauthorized', TRUE, 401); Logger::error(i18n::s('You are not allowed to perform this operation.')); // please suppress editor rights to this item } elseif (isset($_REQUEST['action']) && $_REQUEST['action'] == 'leave') { // break an assignment, and also purge the watch list Members::free('user:'******'t break symetric connections from another user if ($anchor->get_type() != 'user') { Members::free($anchor->get_reference(), 'user:'******'section') { $label = i18n::s('a section'); } else { $label = i18n::s('a page'); } $context['page_title'] = sprintf(i18n::s('You have left %s'), $label); // splash message $context['text'] .= '<p>' . sprintf(i18n::s('The operation has completed, and you have no specific access rights to %s.'), Skin::build_link($anchor->get_url(), $anchor->get_title())) . '</p>'; // back to the anchor page $links = array(); $url = Surfer::get_permalink(); $links[] = Skin::build_link($url, i18n::s('Done'), 'button');
// look for some notification } elseif (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') { // change session data to extend life of related file if (!isset($_SESSION['heartbit'])) { $_SESSION['heartbit'] = 0; } $_SESSION['heartbit']++; // refresh the watchdog $_SESSION['watchdog'] = time(); // update surfer presence $query = "UPDATE " . SQL::table_name('users') . " SET click_date='" . gmstrftime('%Y-%m-%d %H:%M:%S') . "'" . " WHERE (id = " . SQL::escape(Surfer::get_id()) . ")"; SQL::query($query, FALSE, $context['users_connection']); // assign article for more time if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'edit' && isset($_REQUEST['reference']) && !strncmp($_REQUEST['reference'], 'article:', 8)) { // refresh record of this article $query = "UPDATE " . SQL::table_name('articles') . " SET " . " assign_date = '" . SQL::escape(gmstrftime('%Y-%m-%d %H:%M:%S')) . "'" . " WHERE (id = " . SQL::escape(substr($_REQUEST['reference'], 8)) . ") AND (assign_id = " . SQL::escape(Surfer::get_id()) . ")"; SQL::query($query); } // look for one notification -- script will be be killed if none is available $response = Notifications::pull(); // encode result in JSON $output = json_encode($response); // allow for data compression render_raw('application/json; charset=' . $context['charset']); // actual transmission except on a HEAD request if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') { echo $output; } // the post-processing hook, then exit finalize_page(TRUE); }
/** * 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); } }
} } // capture first comment too if (isset($_REQUEST['first_comment']) && $_REQUEST['first_comment']) { include_once $context['path_to_root'] . 'comments/comments.php'; $fields = array(); $fields['anchor'] = 'article:' . $_REQUEST['id']; $fields['description'] = $_REQUEST['first_comment']; Comments::post($fields); } // post an overlay, with the new article id --don't stop on error if (is_object($overlay)) { $overlay->remember('insert', $_REQUEST, 'article:' . $_REQUEST['id']); } // increment the post counter of the surfer Users::increment_posts(Surfer::get_id()); // do whatever is necessary on page publication if (isset($_REQUEST['publish_date']) && $_REQUEST['publish_date'] > NULL_DATE) { Articles::finalize_publication($anchor, $_REQUEST, $overlay, isset($_REQUEST['silent']) && $_REQUEST['silent'] == 'Y', isset($_REQUEST['notify_followers']) && $_REQUEST['notify_followers'] == 'Y'); // else do whatever is necessary on page submission } else { Articles::finalize_submission($anchor, $_REQUEST, $overlay); } // get the new item $article = Anchors::get('article:' . $_REQUEST['id'], TRUE); // list persons that have been notified $context['text'] .= Mailer::build_recipients('article:' . $_REQUEST['id']); // list endpoints that have been notified $context['text'] .= Servers::build_endpoints(i18n::s('Servers that have been notified')); // follow-up commands $follow_up = i18n::s('What do you want to do now?');
*/ // common definitions and initial processing include_once '../shared/global.php'; // users are assigned to this anchor, passed as member $anchor = NULL; if (isset($_REQUEST['member'])) { $anchor = Anchors::get($_REQUEST['member']); } elseif (isset($_REQUEST['anchor'])) { $anchor = Anchors::get($_REQUEST['anchor']); } // only looking at watchers if (isset($_REQUEST['anchor']) && !isset($_REQUEST['action'])) { $permitted = 'watchers'; } elseif (Surfer::is_associate()) { $permitted = 'all'; } elseif (is_object($anchor) && Surfer::get_id() && $anchor->get_reference() == 'user:'******'all'; } elseif (Surfer::is_logged() && is_object($anchor) && $anchor->is_owned()) { $permitted = 'all'; } elseif (is_object($anchor) && $anchor->is_viewable()) { $permitted = 'editors'; } else { $permitted = FALSE; } // load the skin, maybe with a variant load_skin('users', $anchor); // the path to this page if (is_object($anchor) && $anchor->is_viewable()) { $context['path_bar'] = $anchor->get_path_bar(); } else { $context['path_bar'] = array('users/' => i18n::s('People'));
$id = $context['arguments'][0]; } $id = strip_tags($id); // get the item from the database $item = Locations::get($id); // get the related anchor, if any $anchor = NULL; if (isset($item['anchor']) && $item['anchor']) { $anchor = Anchors::get($item['anchor']); } // associates and authenticated editors can do what they want if (Surfer::is_associate() || Surfer::is_member() && is_object($anchor) && $anchor->is_assigned()) { $permitted = TRUE; } elseif (is_object($anchor) && !$anchor->is_viewable()) { $permitted = FALSE; } elseif (Surfer::is_member() && !strcmp($item['anchor'], 'user:'******'edit_id']) && Surfer::is($item['edit_id'])) { $permitted = TRUE; } else { $permitted = FALSE; } // load the skin, mabe with a variant load_skin('locations', $anchor); // the path to this page if (is_object($anchor)) { $context['path_bar'] = $anchor->get_path_bar(); } else { $context['path_bar'] = array('locations/' => i18n::s('Locations')); } // the title of the page
// protect from hackers if (isset($_REQUEST['edit_name'])) { $_REQUEST['edit_name'] = preg_replace(FORBIDDEN_IN_NAMES, '_', $_REQUEST['edit_name']); } if (isset($_REQUEST['edit_address'])) { $_REQUEST['edit_address'] = encode_link($_REQUEST['edit_address']); } // append to previous comment during 10 minutes $continuity_limit = gmstrftime('%Y-%m-%d %H:%M:%S', time() - 600); // this is the first contribution to the thread if (!($item = Comments::get_newest_for_anchor($anchor->get_reference()))) { $fields = array(); $fields['anchor'] = $anchor->get_reference(); $fields['description'] = $_REQUEST['message']; // this is a continuated contribution from this authenticated surfer } elseif ($item['type'] != 'notification' && Surfer::get_id() && (isset($item['create_id']) && Surfer::get_id() == $item['create_id']) && $continuity_limit < $item['edit_date']) { $item['description'] .= BR . $_REQUEST['message']; $fields = $item; // else process the contribution as a new comment } else { $fields = array(); $fields['anchor'] = $anchor->get_reference(); $fields['description'] = $_REQUEST['message']; } // actual database update if (!($fields['id'] = Comments::post($fields))) { Safe::header('Status: 500 Internal Error', TRUE, 500); die(i18n::s('Your contribution has not been posted.')); } // touch the related anchor, but don't notify watchers $anchor->touch('comment:thread', $fields['id']);
/** * list users * * @param resource the SQL result * @return string the rendered text * * @see layouts/layout.php **/ function layout($result) { global $context; // we return some text $text = ''; // empty list if (!($count = SQL::count($result))) { return $text; } // allow for several lists in the same page static $serial; if (isset($serial)) { $serial++; } else { $serial = 1; } // don't blast too many people if ($count > 100) { $checked = ''; } elseif (isset($this->layout_variant) && $this->layout_variant == 'unchecked') { $checked = ''; } else { $checked = ' checked="checked"'; } // div prefix $text .= '<div id="users_as_mail_panel_' . $serial . '">'; // allow to select/deslect multiple rows at once $text .= '<input type="checkbox" class="row_selector" onclick="check_user_as_mail_panel_' . $serial . '(\'div#users_as_mail_panel_' . $serial . '\', this);"' . $checked . ' /> ' . i18n::s('Select all/none') . BR; // process all items in the list $count = 0; while ($item = SQL::fetch($result)) { // we need some address if (!$item['email']) { continue; } // do not write to myself if ($item['id'] == Surfer::get_id()) { continue; } // get the related overlay, if any $overlay = Overlay::load($item, 'user:'******'id']); // column to select the row $text .= '<input type="checkbox" name="selected_users[]" class="row_selector" value="' . encode_field($item['email']) . '"' . $checked . ' />'; // signal restricted and private users if ($item['active'] == 'N') { $text .= PRIVATE_FLAG; } elseif ($item['active'] == 'R') { $text .= RESTRICTED_FLAG; } // the url to view this item $url = Users::get_permalink($item); // use the title to label the link if (is_object($overlay)) { $title = Codes::beautify_title($overlay->get_text('title', $item)); } else { $title = Codes::beautify_title($item['full_name']); } // sanity check if (!$title) { $title = $item['nick_name']; } // link to this page $text .= Skin::build_link($url, $title, 'user'); // the introductory text if ($item['introduction']) { $text .= '<span class="tiny"> - ' . Codes::beautify_introduction($item['introduction']) . '</span>'; } // insert overlay data, if any if (is_object($overlay)) { $text .= $overlay->get_text('list', $item); } // display all tags if ($item['tags']) { $text .= ' <span class="tags">' . Skin::build_tags($item['tags'], 'user:'******'id']) . '</span>'; } // append the row $text .= BR; $count++; } // the script used to check all items at once Page::insert_script('function check_user_as_mail_panel_' . $serial . '(scope, handle) {' . "\n" . ' $(scope + " input[type=\'checkbox\'].row_selector").each(' . "\n" . ' function() { $(this).attr("checked", $(handle).is(":checked"));}' . "\n" . ' );' . "\n" . '}' . "\n"); // div suffix $text .= '</div>'; // no valid account has been found if (!$count) { $text = ''; } // end of processing SQL::free($result); return $text; }
$owner = ''; if ($user_id == $item['owner_id']) { $owner = CHECKED_IMG; } $editor = ''; $watcher = CHECKED_IMG; $rows[$user_id] = array($user_label, $watcher, $editor, $owner); } } } // count if ($users_count) { $box['bar'] += array('_count' => sprintf(i18n::ns('%d participant', '%d participants', $users_count), $users_count)); } // add to the watch list -- $in_watch_list is set in sections/view.php if (Surfer::get_id() && $in_watch_list == 'N') { Skin::define_img('TOOLS_WATCH_IMG', 'tools/watch.gif'); $box['bar'] += array(Users::get_url('section:' . $item['id'], 'track') => TOOLS_WATCH_IMG . i18n::s('Watch this section')); } // invite participants, for owners if (Sections::is_owned($item, $anchor, TRUE) && isset($context['with_email']) && $context['with_email'] == 'Y') { Skin::define_img('SECTIONS_INVITE_IMG', 'sections/invite.gif'); $box['bar'] += array(Sections::get_url($item['id'], 'invite') => SECTIONS_INVITE_IMG . i18n::s('Invite participants')); } // notify participants if ($count > 1 && Sections::allow_message($item, $anchor) && isset($context['with_email']) && $context['with_email'] == 'Y') { Skin::define_img('SECTIONS_EMAIL_IMG', 'sections/email.gif'); $box['bar'] += array(Sections::get_url($item['id'], 'mail') => SECTIONS_EMAIL_IMG . i18n::s('Notify participants')); } // manage editors, for owners if (Sections::is_owned($item, $anchor, TRUE) || Surfer::is_associate()) {
// next url $next = ''; if (isset($_REQUEST['next'])) { $next = $_REQUEST['next']; } if (isset($context['arguments'][2])) { $next = $context['arguments'][2]; } $next = strip_tags($next); // // is this surfer allowed to browse the resulting page? // // associates and editors can do what they want if (Surfer::is_associate() || Articles::is_assigned($id) || is_object($anchor) && $anchor->is_assigned()) { $permitted = TRUE; } elseif (Surfer::get_id() && isset($item['create_id']) && $item['create_id'] == Surfer::get_id()) { $permitted = TRUE; } elseif (is_object($anchor) && !$anchor->is_viewable()) { $permitted = FALSE; } elseif (isset($item['active']) && $item['active'] == 'R' && Surfer::is_member()) { $permitted = TRUE; } elseif (isset($item['active']) && $item['active'] == 'Y') { $permitted = TRUE; } else { $permitted = FALSE; } // load the skin, maybe with a variant load_skin('polls', $anchor); // the path to this page $context['path_bar'] = Surfer::get_path_bar($anchor); // the title of the page
$input .= '/> ' . i18n::s('Community - Access is granted to any identified surfer') . ' ' . BR . '<input type="radio" name="active" value="N"'; if (isset($item['active']) && $item['active'] == 'N') { $input .= ' checked="checked"'; } $input .= '/> ' . i18n::s('Private - Access is restricted to selected persons'); $fields[] = array($label, $input); // actually build the form $context['text'] .= Skin::build_form($fields); $fields = array(); // // bottom commands // $menu = array(); // the submit button $menu[] = Skin::build_submit_button(i18n::s('Submit'), i18n::s('Press [s] to submit data'), 's'); // cancel button if (Surfer::get_id()) { $menu[] = Skin::build_link(Users::get_url(Surfer::get_id()), i18n::s('Back to my profile'), 'span'); } // insert the menu in the page $context['text'] .= Skin::finalize_list($menu, 'assistant_bar'); // end of the form $context['text'] .= '</div></form>'; // append the script used for data checking on the browser Page::insert_script('func' . 'tion validateDocumentPost(container) {' . "\n" . ' if(!container.title.value) {' . "\n" . ' alert("' . i18n::s('Please provide a meaningful title.') . '");' . "\n" . ' Yacs.stopWorking();' . "\n" . ' return false;' . "\n" . ' }' . "\n" . ' return true;' . "\n" . '}' . "\n" . 'func' . 'tion detectChanges() {' . "\n" . ' $("form#main_form input").each(function () {' . "\n" . ' $(this).change(function() { $("#preferred_editor").attr("disabled", true); });' . "\n" . ' });' . "\n" . "\n" . ' $("form#main_form textarea").each(function () {;' . "\n" . ' $(this).change(function() { $("#preferred_editor").attr("disabled", true); });' . "\n" . ' });' . "\n" . "\n" . ' $("form#main_form select").each(function () {;' . "\n" . ' $(this).change(function() { $("#preferred_editor").attr("disabled", true); });' . "\n" . ' });' . "\n" . '}' . "\n" . "\n" . '$(document).ready( detectChanges);' . "\n" . "\n" . '$("#title").focus();' . "\n"); // general help on this form $help = '<p>' . sprintf(i18n::s('%s and %s are available to enhance text rendering.'), Skin::build_link('codes/', 'YACS codes', 'open'), Skin::build_link('smileys/', 'smileys', 'open')) . '</p>'; $context['components']['boxes'] = Skin::build_box(i18n::s('Help'), $help, 'boxes', 'help'); } // render the skin render_skin();
/** * render a compact list of voted pages * * @param string the anchor (e.g. 'section:123') * @param string layout to use * @return string the rendered text **/ public static function render_voted($anchor = '', $layout = 'simple') { global $context; // we return some text; $text = ''; // number of items to display $count = COMPACT_LIST_SIZE; if (($position = strpos($anchor, ',')) !== FALSE) { $count = (int) trim(substr($anchor, $position + 1)); if (!$count) { $count = COMPACT_LIST_SIZE; } $anchor = trim(substr($anchor, 0, $position)); } // scope is limited to current surfer if ($anchor == 'self' && Surfer::get_id()) { $anchor = 'user:'******'section:') === 0) { // look at this branch of the content tree $anchors = Sections::get_branch_at_anchor($anchor); // query the database and layout that stuff $text =& Articles::list_for_anchor_by('rating', $anchors, 0, $count, $layout); // scope is limited to pages of one surfer } elseif (strpos($anchor, 'user:'******'rating', substr($anchor, 5), 0, $count, $layout); } else { $text =& Articles::list_by('rating', 0, $count, $layout); } // we have an array to format if (is_array($text)) { $text =& Skin::build_list($text, $layout); } // job done return $text; }
/** * check that the surfer is allowed to display the anchor * * This function is used to control the authority delegation from the anchor. * * To be overloaded into derived class if field has a different name * * @param int optional reference to some user profile * @return TRUE or FALSE */ function is_viewable($user_id = NULL) { global $context; // we need some data to proceed if (!isset($this->item['id'])) { return FALSE; } // surfer is a trusted host if (Surfer::is_trusted()) { return TRUE; } // section is public if (isset($this->item['active']) && $this->item['active'] == 'Y') { return TRUE; } // id of requesting user if (!$user_id) { $user_id = Surfer::get_id(); } // anonymous is allowed if (!$user_id) { $user_id = 0; } // section is opened to members if ($user_id && isset($this->item['active']) && $this->item['active'] == 'R') { return TRUE; } // anchor has to be assigned return $this->is_assigned($user_id) || Surfer::is_associate(); }