/** * list servers * * @param resource the SQL result * @return string the rendered text * * @see layouts/layout.php **/ function layout($result) { global $context; // empty list if (!SQL::count($result)) { $output = array(); return $output; } // we return an array of ($url => $attributes) $items = array(); // process all items in the list while ($item = SQL::fetch($result)) { // initialize variables $prefix = $suffix = $icon = ''; // the url to view this item $url = Servers::get_url($item['id']); // use the title as a label $label = Skin::strip($item['title'], 10); // flag files uploaded recently if ($item['edit_date'] >= $context['fresh']) { $prefix = NEW_FLAG . $prefix; } // description if ($item['description']) { $suffix .= ' ' . ucfirst(trim($item['description'])); } // the menu bar for associates and poster if (Surfer::is_empowered() || Surfer::is($item['edit_id'])) { $menu = array(Servers::get_url($item['id'], 'edit') => i18n::s('Edit'), Servers::get_url($item['id'], 'delete') => i18n::s('Delete')); $suffix .= ' ' . Skin::build_list($menu, 'menu'); } // add a separator if ($suffix) { $suffix = ' - ' . $suffix; } // append details to the suffix $suffix .= BR . '<span class="details">'; // details $details = array(); // item poster if ($item['edit_name']) { $details[] = sprintf(i18n::s('edited by %s %s'), Users::get_link($item['edit_name'], $item['edit_address'], $item['edit_id']), Skin::build_date($item['edit_date'])); } // the edition date $details[] = Skin::build_date($item['edit_date']); // all details if (count($details)) { $suffix .= ucfirst(implode(', ', $details)) . "\n"; } // end of details $suffix .= '</span>'; // list all components for this item $items[$url] = array($prefix, $label, $suffix, 'server', $icon); } // end of processing SQL::free($result); return $items; }
/** * check if a surfer owns a section * * @param array section attributes * @param object parent anchor, if any * @param boolean FALSE if the surfer can be an editor of parent section * @param int optional reference to some user profile * @return TRUE or FALSE */ public static function is_owned($item = NULL, $anchor = NULL, $strict = FALSE, $user_id = NULL) { global $context; // id of requesting user if (!$user_id) { if (!Surfer::get_id()) { return FALSE; } $user_id = Surfer::get_id(); } // surfer owns this section if (isset($item['owner_id']) && $item['owner_id'] == $user_id) { return TRUE; } // do not look upwards if (!$anchor || !is_object($anchor)) { return FALSE; } // associates can do what they want if (Surfer::is($user_id) && Surfer::is_associate()) { return TRUE; } // we are owning one of the parents if ($anchor->is_owned($user_id)) { return TRUE; } // surfer is a member assigned to one of the parents if (!$strict && Surfer::is_member() && is_object($anchor) && !$anchor->is_hidden() && $anchor->is_assigned($user_id)) { return TRUE; } // sorry return FALSE; }
// re-enforce the canonical link } elseif (!$zoom_type && $page == 1 && $context['self_url'] && $whole_rendering && strncmp($context['self_url'], $context['page_link'], strlen($context['page_link']))) { Safe::header('Status: 301 Moved Permanently', TRUE, 301); Safe::header('Location: ' . $context['page_link']); Logger::error(Skin::build_link($context['page_link'])); // display the article } else { // behaviors can change page menu if (is_object($behaviors)) { $context['page_menu'] = $behaviors->add_commands('articles/view.php', 'article:' . $item['id'], $context['page_menu']); } // remember surfer visit Surfer::is_visiting(Articles::get_permalink($item), Codes::beautify_title($item['title']), 'article:' . $item['id'], $item['active']); // increment silently the hits counter if not robot, nor associate, nor owner, nor at follow-up page if (Surfer::is_crawler() || Surfer::is_associate()) { } elseif (isset($item['owner_id']) && Surfer::is($item['owner_id'])) { } elseif (!$zoom_type) { $item['hits'] = isset($item['hits']) ? $item['hits'] + 1 : 1; Articles::increment_hits($item['id']); } // initialize the rendering engine Codes::initialize(Articles::get_permalink($item)); // neighbours information $neighbours = NULL; if (Articles::has_option('with_neighbours', $anchor, $item) && is_object($anchor)) { $neighbours = $anchor->get_neighbours('article', $item); } // // set page image -- $context['page_image'] // // the article or the anchor icon, if any
/** * put an updated user profile in the database * * If present, only the password is changed. Or other fields except the password are modified. * * To change a password, set fields 'id', 'password' and 'confirm' * * @param array an array of fields * @return TRUE on success, FALSE otherwise * * @see users/edit.php * @see users/password.php * @see users/select_avatar.php **/ public static function put(&$fields) { global $context; // load the record $item = Users::get($fields['id']); if (!isset($item['id']) || !$item['id']) { Logger::error(i18n::s('No item has the provided id.')); return FALSE; } // remember who is changing this record Surfer::check_default_editor($fields); // if a password change if (isset($fields['password'])) { // ensure that the password has been provided twice if (!isset($fields['confirm']) || $fields['confirm'] != $fields['password']) { Logger::error(i18n::s('New password has to be confirmed.')); return FALSE; } // hash password, we are coming from an interactive form $fields['password'] = md5($fields['password']); // else if a regular profile update } else { // nick_name is required if (!isset($fields['nick_name']) || !trim($fields['nick_name'])) { Logger::error(i18n::s('Please indicate a nick name.')); return FALSE; } // some weird users put spaces around $fields['nick_name'] = trim($fields['nick_name']); // nick_name may be already used if (($used = Users::get($fields['nick_name'])) && $used['id'] != $fields['id']) { Logger::error(i18n::s('Another member already has this nick name. Please select a different one.')); return FALSE; } // ensure we have a full name if (!isset($fields['full_name']) || !trim($fields['full_name'])) { $fields['full_name'] = $fields['nick_name']; } // protect from hackers if (isset($fields['avatar_url'])) { $fields['avatar_url'] = encode_link($fields['avatar_url']); } // set default values if (!isset($fields['active']) || !$fields['active']) { $fields['active'] = 'Y'; } if (isset($fields['selected_editor'])) { $fields['editor'] = $fields['selected_editor']; } elseif (isset($context['users_default_editor'])) { $fields['editor'] = $context['users_default_editor']; } else { $fields['editor'] = 'yacs'; } if (!isset($fields['interface']) || $fields['interface'] != 'C') { $fields['interface'] = 'I'; } if (!isset($fields['with_newsletters']) || $fields['with_newsletters'] != 'Y') { $fields['with_newsletters'] = 'N'; } if (!isset($fields['without_alerts']) || $fields['without_alerts'] != 'N') { $fields['without_alerts'] = 'Y'; } if (!isset($fields['without_confirmations']) || $fields['without_confirmations'] != 'N') { $fields['without_confirmations'] = 'Y'; } if (!isset($fields['without_messages']) || $fields['without_messages'] != 'N') { $fields['without_messages'] = 'Y'; } if (!isset($fields['birth_date']) || !$fields['birth_date']) { $fields['birth_date'] = NULL_DATE; } // clean provided tags if (isset($fields['tags'])) { $fields['tags'] = trim($fields['tags'], " \t.:,!?"); } // save new settings in session and in cookie if (Surfer::is($fields['id'])) { // change preferred editor $_SESSION['surfer_editor'] = $fields['editor']; Safe::setcookie('surfer_editor', $fields['editor'], NULL, '/'); // change preferred language if (isset($fields['language']) && $_SESSION['surfer_language'] != $fields['language']) { $_SESSION['surfer_language'] = $fields['language']; $_SESSION['l10n_modules'] = array(); } } } // update an existing record $query = "UPDATE " . SQL::table_name('users') . " SET "; // change only the password if (isset($fields['password'])) { $query .= "password='******'password']) . "'"; } else { $query .= "email='" . SQL::escape(isset($fields['email']) ? $fields['email'] : '') . "', " . "aim_address='" . SQL::escape(isset($fields['aim_address']) ? $fields['aim_address'] : '') . "', " . "alternate_number='" . SQL::escape(isset($fields['alternate_number']) ? $fields['alternate_number'] : '') . "', " . "avatar_url='" . SQL::escape(isset($fields['avatar_url']) ? $fields['avatar_url'] : '') . "', " . "birth_date='" . SQL::escape($fields['birth_date']) . "', " . "description='" . SQL::escape(isset($fields['description']) ? $fields['description'] : '') . "', " . "editor='" . SQL::escape($fields['editor']) . "', " . "from_where='" . SQL::escape(isset($fields['from_where']) ? $fields['from_where'] : '') . "', " . "full_name='" . SQL::escape(isset($fields['full_name']) ? $fields['full_name'] : '') . "', " . "icq_address='" . SQL::escape(isset($fields['icq_address']) ? $fields['icq_address'] : '') . "', " . "interface='" . SQL::escape($fields['interface']) . "', " . "introduction='" . SQL::escape(isset($fields['introduction']) ? $fields['introduction'] : '') . "', " . "irc_address='" . SQL::escape(isset($fields['irc_address']) ? $fields['irc_address'] : '') . "', " . "jabber_address='" . SQL::escape(isset($fields['jabber_address']) ? $fields['jabber_address'] : '') . "', " . "language='" . SQL::escape(isset($fields['language']) ? $fields['language'] : 'none') . "', " . "msn_address='" . SQL::escape(isset($fields['msn_address']) ? $fields['msn_address'] : '') . "', " . "nick_name='" . SQL::escape($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'] : '') . "'," . "pgp_key='" . SQL::escape(isset($fields['pgp_key']) ? $fields['pgp_key'] : '') . "', " . "phone_number='" . SQL::escape(isset($fields['phone_number']) ? $fields['phone_number'] : '') . "', " . "signature='" . SQL::escape(isset($fields['signature']) ? $fields['signature'] : '') . "', " . "skype_address='" . SQL::escape(isset($fields['skype_address']) ? $fields['skype_address'] : '') . "', " . "tags='" . SQL::escape(isset($fields['tags']) ? $fields['tags'] : '') . "', " . "twitter_address='" . SQL::escape(isset($fields['twitter_address']) ? $fields['twitter_address'] : '') . "', " . "vcard_agent='" . SQL::escape(isset($fields['vcard_agent']) ? $fields['vcard_agent'] : '') . "', " . "vcard_label='" . SQL::escape(isset($fields['vcard_label']) ? $fields['vcard_label'] : '') . "', " . "vcard_organization='" . SQL::escape(isset($fields['vcard_organization']) ? $fields['vcard_organization'] : '') . "', " . "vcard_title='" . SQL::escape(isset($fields['vcard_title']) ? $fields['vcard_title'] : '') . "', " . "web_address='" . SQL::escape(isset($fields['web_address']) ? $fields['web_address'] : '') . "', " . "with_newsletters='" . $fields['with_newsletters'] . "', " . "without_alerts='" . $fields['without_alerts'] . "', " . "without_confirmations='" . $fields['without_confirmations'] . "', " . "without_messages='" . $fields['without_messages'] . "', " . "yahoo_address='" . SQL::escape(isset($fields['yahoo_address']) ? $fields['yahoo_address'] : '') . "'"; // fields set only by associates -- see users/edit.php if (Surfer::is_associate()) { $query .= ", " . "capability='" . SQL::escape($fields['capability']) . "', " . "active='" . SQL::escape($fields['active']) . "'"; } } // maybe a silent update if (!isset($fields['silent']) || $fields['silent'] != 'Y') { $query .= ", " . "edit_name='" . SQL::escape($fields['edit_name']) . "', " . "edit_id=" . SQL::escape($fields['edit_id']) . ", " . "edit_address='" . SQL::escape($fields['edit_address']) . "', " . "edit_action='user:update', " . "edit_date='" . SQL::escape($fields['edit_date']) . "'"; } // actual update query $query .= " WHERE id = " . SQL::escape($item['id']); SQL::query($query, FALSE, $context['users_connection']); // list the user in categories if (isset($fields['tags']) && $fields['tags']) { Categories::remember('user:'******'id'], NULL_DATE, $fields['tags']); } // clear all the cache on profile update, because of avatars, etc. $fields['id'] = $item['id']; Users::clear($fields); // send a confirmation message on password change if (isset($context['with_email']) && $context['with_email'] == 'Y' && isset($fields['confirm']) && $item['email'] && $item['without_confirmations'] != 'Y') { // message title $subject = sprintf(i18n::s('Your account at %s'), strip_tags($context['site_name'])); // message body $message = '<p>' . sprintf(i18n::s('This message has been automatically sent to you to confirm a change of your profile at %s.'), '<a href="' . $context['url_to_master'] . $context['url_to_root'] . '">' . strip_tags($context['site_name']) . '</a>') . '</p>' . '<p>' . sprintf(i18n::s('Your nick name is %s'), $item['nick_name']) . BR . sprintf(i18n::s('Authenticate with password %s'), $fields['confirm']) . '</p>' . '<p>' . sprintf(i18n::s('On-line help is available at %s'), '<a href="' . $context['url_to_home'] . $context['url_to_root'] . 'help/' . '">' . $context['url_to_home'] . $context['url_to_root'] . 'help/' . '</a>') . '</p>' . '<p>' . sprintf(i18n::s('Thank you for your interest into %s.'), '<a href="' . $context['url_to_master'] . $context['url_to_root'] . '">' . strip_tags($context['site_name']) . '</a>') . '</p>'; // enable threading $headers = Mailer::set_thread('user:'******'id']); // post the confirmation message Mailer::notify(NULL, $item['email'], $subject, $message, $headers); } // update user session if (isset($fields['nick_name']) && Surfer::get_id() && $fields['id'] == Surfer::get_id() && is_callable(array('Surfer', 'set'))) { Surfer::set($fields); } // end of job return TRUE; }
} // page details if (is_array($details)) { $context['text'] .= '<p class="details">' . ucfirst(implode(', ', $details)) . "</p>\n"; } // insert anchor suffix if (is_object($anchor)) { $context['text'] .= $anchor->get_suffix(); } // back to the anchor page if (is_object($anchor) && $anchor->is_viewable()) { $menu = array(Skin::build_link($anchor->get_url(), i18n::s('Back to main page'), 'button')); $context['text'] .= Skin::build_block(Skin::finalize_list($menu, 'menu_bar'), 'bottom'); } // // populate the extra panel // // commands for associates and editors if (Surfer::is_associate() || is_object($anchor) && $anchor->is_assigned()) { $context['page_tools'][] = Skin::build_link(Locations::get_url($id, 'edit'), i18n::s('Edit')); $context['page_tools'][] = Skin::build_link(Locations::get_url($id, 'delete'), i18n::s('Delete')); // commands for the author } elseif (Surfer::is($item['edit_id'])) { $context['page_tools'][] = Skin::build_link(Locations::get_url($item['id'], 'edit'), i18n::s('Edit')); } // referrals, if any, in a sidebar // $context['components']['referrals'] =& Skin::build_referrals(Locations::get_url($item['id'])); } // render the skin render_skin();
/** * list links * * Recognize following variants: * - 'no_anchor' to list items attached to one particular anchor * - 'no_author' to list items attached to one user prolink * * @param resource the SQL result * @return array of resulting items, or NULL * * @see layouts/layout.php **/ function layout($result) { global $context; // we return an array of ($url => $attributes) $items = array(); // empty list if (!SQL::count($result)) { return $items; } // sanity check if (!isset($this->layout_variant)) { $this->layout_variant = 'no_anchor'; } // process all items in the list while ($item = SQL::fetch($result)) { // get the main anchor $anchor = Anchors::get($item['anchor']); // initialize variables $prefix = $suffix = $icon = ''; // make a label $label = Links::clean($item['title'], $item['link_url']); // flag links uploaded recently if ($item['edit_date'] >= $context['fresh']) { $prefix = NEW_FLAG . $prefix; } // the number of clicks if ($item['hits'] > 1) { $suffix .= ' (' . Skin::build_number($item['hits'], i18n::s('clicks')) . ') '; } // add a separator if ($suffix) { $suffix = ' - ' . $suffix; } // details $details = array(); // item poster if ($item['edit_name'] && $this->layout_variant != 'no_author') { if (Surfer::is_member() || (!isset($context['content_without_details']) || $context['content_without_details'] != 'Y') || is_object($anchor) && $anchor->has_option('with_details')) { $details[] = sprintf(i18n::s('edited by %s %s'), Users::get_link($item['edit_name'], $item['edit_address'], $item['edit_id']), Skin::build_date($item['edit_date'])); } } // show an anchor link if ($this->layout_variant != 'no_anchor' && $this->layout_variant != 'no_author' && $item['anchor'] && ($anchor = Anchors::get($item['anchor']))) { $anchor_url = $anchor->get_url(); $anchor_label = ucfirst($anchor->get_title()); $details[] = sprintf(i18n::s('in %s'), Skin::build_link($anchor_url, $anchor_label, 'article')); } // the menu bar for associates and poster if (Surfer::is_empowered() || Surfer::is($item['edit_id'])) { $details[] = Skin::build_link('links/edit.php?id=' . $item['id'], i18n::s('edit'), 'span'); $details[] = Skin::build_link('links/delete.php?id=' . $item['id'], i18n::s('delete'), 'span'); } // append details to the suffix if (count($details)) { $suffix .= BR . Skin::finalize_list($details, 'menu'); } // description if ($item['description']) { $suffix .= BR . Codes::beautify($item['description']); } // build the actual link to check it if ($this->layout_variant == 'review') { $icon = $item['link_url']; } // url is the link itself -- hack for xhtml compliance $url = str_replace('&', '&', $item['link_url']); // let the rendering engine guess the type of link $link_type = NULL; // except if we want to stay within this window if (isset($item['link_target']) && $item['link_target'] != 'I') { $link_type = 'external'; } // hovering title $link_title = NULL; if (isset($item['link_title']) && $item['link_title']) { $link_title = $item['link_title']; } // pack everything $items[$url] = array($prefix, $label, $suffix, $link_type, $icon, $link_title); } // end of processing SQL::free($result); return $items; }
/** * check that the surfer owns an anchor * * To be overloaded into derived class if attribute has a different name than 'owner_id'. * * @param int optional reference to some user profile * @param boolean FALSE to not cascade the check to parent containers * @return TRUE or FALSE */ function is_owned($user_id = NULL, $cascade = TRUE) { global $context; // id of requesting user if (!$user_id) { if (!Surfer::get_id()) { return FALSE; } $user_id = Surfer::get_id(); } // surfer owns this item if (isset($this->item['owner_id']) && $user_id == $this->item['owner_id']) { return TRUE; } // do not cascade if (!$cascade) { return FALSE; } // associates can always do it, except if not cascading if (Surfer::is($user_id) && Surfer::is_associate()) { return TRUE; } // if surfer manages parent container it's ok too if (isset($this->item['anchor'])) { // save requests if (!isset($this->anchor) || !$this->anchor) { $this->anchor = Anchors::get($this->item['anchor']); } // test strict ownership if (is_object($this->anchor) && $this->anchor->is_owned($user_id)) { return TRUE; } } // sorry return FALSE; }
$context['components']['boxes'] = Skin::build_box(i18n::s('Help'), $help, 'boxes', 'help'); } // adding followers } else { if (Surfer::may_mail()) { $help = i18n::s('Each new person will be notified that you are following him.'); // in a side box $context['components']['boxes'] = Skin::build_box(i18n::s('Help'), $help, 'boxes', 'help'); } } // list editors } elseif ($permitted == 'editors') { // the title of the page if (is_object($anchor)) { if (!strncmp($anchor->get_reference(), 'user:'******'page_title'] = i18n::s('Persons that I am following'); } else { $context['page_title'] = sprintf(i18n::s('Persons followed by %s'), $anchor->get_title()); } } elseif (!strncmp($anchor->get_reference(), 'category:', 9)) { $context['page_title'] = sprintf(i18n::s('Members of %s'), $anchor->get_title()); } else { $context['page_title'] = i18n::s('Editors'); } } // look for the user through his nick name if (isset($_REQUEST['assigned_name']) && ($user = Users::get($_REQUEST['assigned_name']))) { $_REQUEST['anchor'] = 'user:'******'id']; } // the current list of category members
/** * check if a surfer owns a page * * @param array page attributes * @param object cascade to parent if set * @param boolean FALSE if the surfer can be an editor of parent section * @param int optional reference to some user profile * @return TRUE or FALSE */ public static function is_owned($item = NULL, $anchor = NULL, $strict = FALSE, $user_id = NULL) { global $context; // ownership requires to be authenticated if (!$user_id) { if (!Surfer::get_id()) { return FALSE; } $user_id = Surfer::get_id(); } // surfer owns this page if (isset($item['owner_id']) && $item['owner_id'] == $user_id) { return TRUE; } // do not look upwards if (!$anchor || !is_object($anchor)) { return FALSE; } // associates can do what they want if (Surfer::is($user_id) && Surfer::is_associate()) { return TRUE; } // surfer owns parent container if ($anchor->is_owned($user_id)) { return TRUE; } // page has not been created yet, section is not private, and surfer is member --not subscriber // Alexis => desactivated cause it's rejected later //if(!$strict && !isset($item['id']) && Surfer::is_member() && is_object($anchor) && !$anchor->is_hidden()) // return TRUE; // page is not private, and surfer is editor --not subscriber-- of parent container if (!$strict && isset($item['active']) && $item['active'] != 'N' && Surfer::is_member() && is_object($anchor) && $anchor->is_assigned($user_id)) { return TRUE; } // sorry return FALSE; }
// change avatar if (Surfer::is_empowered() && isset($item['avatar_url']) && $item['avatar_url']) { Skin::define_img('IMAGES_ADD_IMG', 'images/add.gif'); $label = i18n::s('Change picture'); $context['page_tools'][] = Skin::build_link(Users::get_url($item['id'], 'select_avatar'), IMAGES_ADD_IMG . $label, 'basic'); } // modify this page Skin::define_img('USERS_EDIT_IMG', 'users/edit.gif'); $context['page_tools'][] = Skin::build_link(Users::get_url($item['id'], 'edit'), USERS_EDIT_IMG . i18n::s('Edit this profile'), 'basic', i18n::s('Press [e] to edit'), FALSE, 'e'); // change password if (!isset($context['users_authenticator']) || !$context['users_authenticator']) { Skin::define_img('USERS_PASSWORD_IMG', 'users/password.gif'); $context['page_tools'][] = Skin::build_link(Users::get_url($item['id'], 'password'), USERS_PASSWORD_IMG . i18n::s('Change password'), 'basic'); } // only associates can delete user profiles; self-deletion may also be allowed if (isset($item['id']) && !$zoom_type && $permitted && (Surfer::is_associate() || Surfer::is($item['id']) && (!isset($context['users_without_self_deletion']) || $context['users_without_self_deletion'] != 'Y'))) { Skin::define_img('USERS_DELETE_IMG', 'users/delete.gif'); $context['page_tools'][] = Skin::build_link(Users::get_url($item['id'], 'delete'), USERS_DELETE_IMG . i18n::s('Delete this profile')); } } // associates can transfer ownership if (Surfer::is_associate()) { Skin::define_img('USERS_TRANSFER_IMG', 'users/transfer.gif'); $context['page_tools'][] = Skin::build_link(Users::get_url($item['id'], 'transfer'), USERS_TRANSFER_IMG . i18n::s('Transfer ownership')); } // user profile aside $context['components']['profile'] = Skin::build_profile($item, 'extra'); // add extra information from the overlay, if any if (is_object($overlay)) { $context['components']['overlay'] = $overlay->get_text('extra', $item); }
/** * list files for search requests * * @param resource the SQL result * @return array of resulting items ($score, $summary), or NULL * * @see layouts/layout.php **/ function layout($result) { global $context; // we return an array of array($score, $summary) $items = array(); // empty list if (!SQL::count($result)) { return $items; } // process all items in the list while ($item = SQL::fetch($result)) { // one box at a time $box = ''; // get the main anchor $anchor = Anchors::get($item['anchor']); $prefix = $suffix = ''; // stream the file if (Files::is_stream($item['file_name'])) { $url = Files::get_url($item['id'], 'stream', $item['file_name']); } else { $url = Files::get_url($item['id'], 'fetch', $item['file_name']); } // absolute url $url = $context['url_to_home'] . $context['url_to_root'] . $url; // signal restricted and private files if ($item['active'] == 'N') { $prefix .= PRIVATE_FLAG; } elseif ($item['active'] == 'R') { $prefix .= RESTRICTED_FLAG; } // file title or file name $label = Codes::beautify_title($item['title']); if (!$label) { $label = ucfirst(str_replace(array('%20', '-', '_'), ' ', $item['file_name'])); } // show a reference to the file for members $hover = i18n::s('Get the file'); if (Surfer::is_member()) { $hover .= ' [file=' . $item['id'] . ']'; } // flag files uploaded recently if ($item['create_date'] >= $context['fresh']) { $suffix .= NEW_FLAG; } elseif ($item['edit_date'] >= $context['fresh']) { $suffix .= UPDATED_FLAG; } // one line of text $box .= $prefix . Skin::build_link($url, $label, 'basic', $hover) . $suffix; // side icon if ($item['thumbnail_url']) { $icon = $item['thumbnail_url']; } else { $icon = $context['url_to_root'] . Files::get_icon_url($item['file_name']); } // build the complete HTML element $icon = '<img src="' . $icon . '" alt="" title="' . encode_field(strip_tags($label)) . '" />'; // make it a clickable link $icon = Skin::build_link($url, $icon, 'basic'); // first line of details $details = array(); // file poster and last action $details[] = sprintf(i18n::s('shared by %s %s'), Users::get_link($item['edit_name'], $item['edit_address'], $item['edit_id']), Skin::build_date($item['edit_date'])); // downloads if ($item['hits'] > 1) { $details[] = Skin::build_number($item['hits'], i18n::s('downloads')); } // file size if ($item['file_size'] > 1) { $details[] = Skin::build_number($item['file_size'], i18n::s('bytes')); } // file has been detached if (isset($item['assign_id']) && $item['assign_id']) { // who has been assigned? if (Surfer::is($item['assign_id'])) { $details[] = DRAFT_FLAG . sprintf(i18n::s('reserved by you %s'), Skin::build_date($item['assign_date'])); } else { $details[] = DRAFT_FLAG . sprintf(i18n::s('reserved by %s %s'), Users::get_link($item['assign_name'], $item['assign_address'], $item['assign_id']), Skin::build_date($item['assign_date'])); } } // the main anchor link if (is_object($anchor)) { $details[] = sprintf(i18n::s('in %s'), Skin::build_link($anchor->get_url(), ucfirst($anchor->get_title()), 'article')); } // append details if (count($details)) { $box .= '<p class="details">' . Skin::finalize_list($details, 'menu') . '</p>'; } // layout this item if ($icon) { $list = array(array($box, $icon)); $items[] = array($item['score'], Skin::finalize_list($list, 'decorated')); // put the item in a division } else { $items[] = array($item['score'], '<div style="margin: 0 0 1em 0">' . $box . '</div>'); } } // end of processing SQL::free($result); return $items; }
/** * list blogmarks * * @param resource the SQL result * @return string resulting text **/ function layout($result) { global $context; // we return a string $text = ''; // empty list if (!SQL::count($result)) { return $text; } // start in north $in_north = TRUE; // define allowed HTML tags for the cover page define('ALLOWED_HTML_TAGS', '<a><b><br><h1><h2><h3><i><img><li><ol><p><ul>'); // build a list of articles $box = array(); $box['content'] = ''; $previous_date = NULL; while ($item = SQL::fetch($result)) { // not the same date $current_date = substr($item['edit_date'], 0, 10); if ($previous_date != $current_date) { // insert a complete box for the previous date if ($box['content']) { if ($in_north) { $text .= '<div class="newest">' . "\n"; } $text .= Skin::build_box($box['title'], $box['content']); if ($in_north) { $text .= '</div>' . "\n"; } $in_north = FALSE; } // prepare a box for a new date $previous_date = $current_date; $box['title'] = Skin::build_date($item['edit_date'], 'no_hour'); $box['content'] = ''; } $box['content'] .= '<br clear="both" />'; // time $box['content'] .= '<span class="details">' . substr($item['edit_date'], 11, 5) . '</span> '; // make a label $label = Links::clean($item['title'], $item['link_url']); $box['content'] .= Skin::build_link($item['link_url'], $label); // flag links updated recently if ($item['edit_date'] >= $context['fresh']) { $box['content'] .= ' ' . NEW_FLAG; } // the description if (trim($item['description'])) { $box['content'] .= "\n<br/>" . Skin::cap(Codes::beautify($item['description']), 500) . "\n"; } // the menu bar for associates and poster if (Surfer::is_empowered() || Surfer::is($item['edit_id'])) { $menu = array('links/edit.php?id=' . $item['id'] => i18n::s('Edit'), 'links/delete.php?id=' . $item['id'] => i18n::s('Delete')); $box['content'] .= ' ' . Skin::build_list($menu, 'menu'); } // append details to the suffix $box['content'] .= BR . '<span class="details">'; // details $details = array(); // item poster if (Surfer::is_member()) { if ($item['edit_name']) { $details[] = sprintf(i18n::s('edited by %s %s'), Users::get_link($item['edit_name'], $item['edit_address'], $item['edit_id']), Skin::build_date($item['edit_date'])); } } else { $details[] = Anchors::get_action_label($item['edit_action']); } // show an anchor link if ($item['anchor'] && ($anchor = Anchors::get($item['anchor']))) { $anchor_url = $anchor->get_url(); $anchor_label = ucfirst($anchor->get_title()); $details[] = sprintf(i18n::s('in %s'), Skin::build_link($anchor_url, $anchor_label)); } // all details $box['content'] .= ucfirst(trim(implode(' ', $details))) . "\n"; // end of details $box['content'] .= '</span><br/><br/>'; } // close the on-going box if ($in_north) { $text .= '<div class="newest">' . "\n"; } $text .= Skin::build_box($box['title'], $box['content']); if ($in_north) { $text .= '</div>' . "\n"; } // end of processing SQL::free($result); return $text; }
} elseif (isset($_REQUEST['anchor'])) { $link = 'articles/edit.php?anchor=' . $_REQUEST['anchor']; } else { $link = 'articles/edit.php'; } Safe::redirect($context['url_to_home'] . $context['url_to_root'] . 'users/login.php?url=' . urlencode($link)); } // permission denied to authenticated user Safe::header('Status: 401 Unauthorized', TRUE, 401); Logger::error(i18n::s('You are not allowed to perform this operation.')); // an error occured } elseif (count($context['error'])) { $item = $_REQUEST; $with_form = TRUE; // page has been assigned to another person during the last 5 minutes } elseif (isset($item['assign_id']) && $item['assign_id'] && !Surfer::is($item['assign_id']) && SQL::strtotime($item['assign_date']) + 5 * 60 >= time()) { // permission denied to authenticated user Safe::header('Status: 401 Unauthorized', TRUE, 401); $context['text'] .= Skin::build_block(sprintf(i18n::s('This page is currently edited by %s. You have to wait for a new version to be released.'), Users::get_link($item['assign_name'], $item['assign_address'], $item['assign_id'])), 'caution'); // process uploaded data } 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); // set options
} elseif (isset($item['id']) && Articles::is_assigned($item['id']) && Surfer::is_logged()) { Surfer::empower('S'); } elseif (isset($item['options']) && $item['options'] && preg_match('/\\banonymous_edit\\b/i', $item['options'])) { Surfer::empower(); } elseif (Surfer::is_member() && isset($item['options']) && $item['options'] && preg_match('/\\bmembers_edit\\b/i', $item['options'])) { Surfer::empower(); } elseif (isset($item['handle']) && Surfer::may_handle($item['handle'])) { Surfer::empower(); } // // is this surfer allowed to browse the page? // // associates, editors and readers can read this page if (Surfer::is_empowered('S')) { $permitted = TRUE; } elseif (isset($item['create_id']) && Surfer::is($item['create_id'])) { $permitted = TRUE; } elseif (is_object($anchor) && !$anchor->is_viewable()) { $permitted = FALSE; } elseif (isset($item['active']) && $item['active'] == 'R' && Surfer::is_logged()) { $permitted = TRUE; } elseif (isset($item['active']) && $item['active'] == 'Y') { $permitted = TRUE; } else { $permitted = FALSE; } // load localized strings i18n::bind('overlays'); // load the skin, maybe with a variant load_skin('articles', $anchor, isset($item['options']) ? $item['options'] : ''); // clear the tab we are in
/** * check if a file can be deleted * * This function returns TRUE if the file can be deleted, * and FALSE otherwise. * * @param array a set of item attributes, aka, the target file * @param object an instance of the Anchor interface * @return TRUE or FALSE */ public static function allow_deletion($item, $anchor) { global $context; // sanity check if (!isset($item['id'])) { return FALSE; } // surfer is an associate if (Surfer::is_associate()) { return TRUE; } // surfer owns the container if (is_object($anchor) && $anchor->is_owned()) { return TRUE; } // allow container editors --not subscribers-- to manage content, except on private sections if (Surfer::is_member() && is_object($anchor) && !$anchor->is_hidden() && $anchor->is_assigned()) { return TRUE; } // the file is anchored to the profile of this member if (Surfer::get_id() && is_object($anchor) && !strcmp($anchor->get_reference(), 'user:'******'create_id']) && Surfer::is($item['create_id'])) { return TRUE; } // surfer has changed the file if (isset($item['edit_id']) && Surfer::is($item['edit_id'])) { return TRUE; } // default case return FALSE; }
} else { $context['path_bar'] = array('files/' => i18n::s('Files')); } // the title of the page if (isset($item['file_name'])) { $context['page_title'] = sprintf(i18n::s('%s: %s'), i18n::s('Delete'), $item['file_name']); } // not found if (!isset($item['id'])) { include '../error.php'; // permission denied } elseif (!$permitted) { Safe::header('Status: 401 Unauthorized', TRUE, 401); Logger::error(i18n::s('You are not allowed to perform this operation.')); // file has been reserved } elseif (isset($item['assign_id']) && $item['assign_id'] && !Surfer::is($item['assign_id'])) { // prevent updates $context['text'] .= Skin::build_block(sprintf(i18n::s('This file has been reserved by %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'); // follow-up commands $menu = array(); $menu[] = Skin::build_link($anchor->get_url('files'), i18n::s('Done'), 'button'); $menu[] = Skin::build_link(Files::get_url($item['id'], 'release'), i18n::s('Release reservation'), 'span'); $context['text'] .= Skin::build_block(Skin::finalize_list($menu, 'menu_bar'), 'bottom'); // deletion is confirmed } elseif (isset($_REQUEST['confirm']) && $_REQUEST['confirm'] == 'yes') { // touch the related anchor before actual deletion, since the file has to be accessible at that time if (is_object($anchor)) { $anchor->touch('file:delete', $item['id']); } // if no error, back to the anchor or to the index page if (Files::delete($item['id'])) {
/** * check if comments can be modified * * This function returns TRUE if comments can be edited to some place, * and FALSE otherwise. * * @param object an instance of the Anchor interface, if any * @param array a set of item attributes, if any * @return TRUE or FALSE */ public static function allow_modification($anchor, $item) { global $context; // associates can do what they want if (Surfer::is_associate()) { return TRUE; } // the item is anchored to the profile of this member // if(Surfer::is_member() && isset($item['anchor']) && !strcmp($item['anchor'], 'user:'******'create_id']) && Surfer::is($item['create_id']) && is_object($anchor) && !$anchor->has_option('locked')) { return TRUE; } // owner if (is_object($anchor) && $anchor->is_owned()) { return TRUE; } // editor of a public page if (is_object($anchor) && !$anchor->is_hidden() && $anchor->is_assigned()) { return TRUE; } // the default is to not allow modifications return FALSE; }
/** * add text to the bottom of the page * * This is where video streams from OpenTok are included * * @see overlays/event.php * * @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; // meeting is not on-going $text = ''; if ($this->attributes['status'] != 'started') { return $text; } // use services/configure.php to activate OpenTok if (!isset($context['opentok_api_key']) || !$context['opentok_api_key']) { return $text; } // no session id! if (!isset($this->attributes['session_id']) || !$this->attributes['session_id']) { Logger::error(sprintf('OpenTok error: %s', 'no session id has been found')); return $text; } // prepare the authentication token $credentials = 'session_id=' . $this->attributes['session_id'] . '&create_time=' . time() . '&role=publisher' . '&nonce=' . microtime(true) . mt_rand(); // hash credentials using secret $hash = hash_hmac('sha1', $credentials, $context['opentok_api_secret']); // finalize the authentication token expected by OpenTok $token = 'T1==' . base64_encode('partner_id=' . $context['opentok_api_key'] . '&sig=' . $hash . ':' . $credentials); // delegate audio processing to OpenTok too $with_audio = 'true'; // except if twilio has been activated instead if (isset($context['twilio_account_sid']) && $context['twilio_account_sid']) { $with_audio = 'false'; } // load the OpenTok javascript library in shared/global.php $context['javascript']['opentok'] = TRUE; // interface with the OpenTok API $js_script = 'var OpenTok = {' . "\n" . "\n" . ' apiKey: ' . $context['opentok_api_key'] . ',' . "\n" . ' sessionId: "' . $this->attributes['session_id'] . '",' . "\n" . ' tokenString: "' . $token . '",' . "\n" . "\n" . ' deviceManager: null,' . "\n" . ' publisher: null,' . "\n" . ' session: null,' . "\n" . ' subscribers: {},' . "\n" . ' tentatives: 3,' . "\n" . ' watchdog: null,' . "\n" . ' withAudio: ' . $with_audio . ',' . "\n" . "\n" . ' // user has denied access to the camera from Flash' . "\n" . ' accessDeniedHandler: function() {' . "\n" . ' $("#opentok .me").empty();' . "\n" . ' },' . "\n" . "\n" . ' // attempt to reconnect to the server' . "\n" . ' connectAgain: function() {' . "\n" . ' OpenTok.growl("' . i18n::s('Connecting again to OpenTok') . '");' . "\n" . ' OpenTok.session.connect(OpenTok.apiKey, OpenTok.tokenString);' . "\n" . ' },' . "\n" . "\n" . ' // successful detection of local devices' . "\n" . ' devicesDetectedHandler: function(event) {' . "\n" . "\n" . ' // no adequate hardware to move forward' . "\n" . ' if(event.cameras.length == 0) {' . "\n" . ' OpenTok.growl("' . i18n::s('A webcam is required to be visible') . '");' . "\n" . "\n" . ' // at least one camera is available' . "\n" . ' } else {' . "\n" . "\n" . ' // create one placeholder div for my own camera' . "\n" . ' OpenTok.growl("' . i18n::s('Adding local video stream') . '");' . "\n" . ' $("#opentok .me").append(\'<div class="frame subscriber"><div id="placeholder"></div></div>\');' . "\n" . "\n" . ' // bind this div with my own camera' . "\n" . ' var streamProps = {width: 120, height: 90,' . "\n" . ' publishAudio: false, publishVideo: true, name: "' . str_replace('"', "'", Surfer::get_name()) . '" };' . "\n" . ' OpenTok.publisher = OpenTok.session.publish("placeholder", streamProps);' . "\n" . "\n" . ' // monitor the publishing session' . "\n" . ' OpenTok.publisher.addEventListener("accessDenied", OpenTok.accessDeniedHandler);' . "\n" . ' OpenTok.publisher.addEventListener("deviceInactive", OpenTok.deviceInactiveHandler);' . "\n" . "\n" . ' }' . "\n" . "\n" . ' },' . "\n" . "\n" . ' // for some reason the user is not publishing anymore' . "\n" . ' deviceInactiveHandler: function(event) {' . "\n" . ' if(event.camera) {' . "\n" . ' OpenTok.growl("' . i18n::s('You are not visible') . '");' . "\n" . ' }' . "\n" . ' if(event.microphone) {' . "\n" . ' OpenTok.growl("' . i18n::s('You have been muted') . '");' . "\n" . ' $("#opentok .me .frame").removeClass("talker");' . "\n" . ' }' . "\n" . ' },' . "\n" . "\n" . ' // we have been killed by an asynchronous exception' . "\n" . ' exceptionHandler: function(event) {' . "\n" . "\n" . ' OpenTok.growl(event.code + " " + event.title + " - " + event.message);' . "\n" . "\n" . ' OpenTok.tentatives--;' . "\n" . ' if((OpenTok.tentatives > 0) && (event.code === 1006 || event.code === 1008 || event.code === 1014)) {' . "\n" . ' OpenTok.session.connecting = false;' . "\n" . ' window.setTimeout("OpenTok.connectAgain()", 3000);' . "\n" . ' }' . "\n" . ' },' . "\n" . "\n" . ' // display a message for some seconds' . "\n" . ' growl: function(message) {' . "\n" . ' if(typeof OpenTok.growlId != "number") {' . "\n" . ' OpenTok.growlId = 1;' . "\n" . ' } else {' . "\n" . ' OpenTok.growlId++;' . "\n" . ' }' . "\n" . ' var myId = OpenTok.growlId++;' . "\n" . ' $("#opentok .growl").append(\'<span id="growl\'+myId+\'">\'+message+"</span>");' . "\n" . ' window.setTimeout("$(\'#growl"+myId+"\').fadeOut(\'slow\')", 5000);' . "\n" . ' },' . "\n" . "\n" . ' // launch the video chat based on OpenTok' . "\n" . ' initialize: function() {' . "\n" . "\n" . ' // report on error, if any' . "\n" . ' TB.setLogLevel(TB.DEBUG);' . "\n" . ' TB.addEventListener("exception", OpenTok.exceptionHandler);' . "\n" . "\n" . ' // check system capabilities before activating the service' . "\n" . ' if(TB.checkSystemRequirements() == TB.HAS_REQUIREMENTS) {' . "\n" . "\n" . ' // slide to page bottom, because this is not obvious to end-user' . "\n" . ' OpenTok.growl("' . i18n::s('Connecting to OpenTok') . '");' . "\n" . "\n" . ' // bind to local hardware via a device manager' . "\n" . ' OpenTok.deviceManager = TB.initDeviceManager(OpenTok.apiKey);' . "\n" . ' OpenTok.deviceManager.addEventListener("devicesDetected", OpenTok.devicesDetectedHandler);' . "\n" . "\n" . ' // bind to the API via a session' . "\n" . ' OpenTok.session = TB.initSession(OpenTok.sessionId);' . "\n" . ' OpenTok.session.addEventListener("sessionConnected", OpenTok.sessionConnectedHandler);' . "\n" . ' OpenTok.session.addEventListener("signalReceived", OpenTok.signalReceivedHandler);' . "\n" . ' OpenTok.session.addEventListener("streamCreated", OpenTok.streamCreatedHandler);' . "\n" . ' OpenTok.session.addEventListener("streamDestroyed", OpenTok.streamDestroyedHandler);' . "\n" . ' OpenTok.session.addEventListener("streamPropertyChanged", OpenTok.streamPropertyChangedHandler);' . "\n" . "\n" . ' // connect to back-end servers' . "\n" . ' OpenTok.session.connect(OpenTok.apiKey, OpenTok.tokenString);' . "\n" . "\n" . ' // no way to use the service' . "\n" . ' } else {' . "\n" . ' OpenTok.growl("' . i18n::s('This system is not supported by OpenTok') . '");' . "\n" . ' }' . "\n" . ' },' . "\n" . "\n" . ' // successful connection to the OpenTok back-end servers' . "\n" . ' sessionConnectedHandler: function(event) {' . "\n" . "\n" . ' // display streams already attached to this session' . "\n" . ' OpenTok.subscribeToStreams(event.streams);' . "\n" . "\n" . ' // attach the local webcam and microphone if detected' . "\n" . ' OpenTok.deviceManager.detectDevices();' . "\n" . ' },' . "\n" . "\n" . ' // send a signal to other parties' . "\n" . ' signal: function() {' . "\n" . ' if(OpenTok.session)' . "\n" . ' OpenTok.session.signal();' . "\n" . ' },' . "\n" . "\n" . ' // signal received, refresh the page' . "\n" . ' signalReceivedHandler: function(event) {' . "\n" . "\n" . ' // refresh the chat area' . "\n" . ' if(typeof Comments == "object")' . "\n" . ' Comments.subscribe();' . "\n" . ' },' . "\n" . "\n" . ' // i start to talk' . "\n" . ' startTalking: function() {' . "\n" . ' for(var i = 0; i < OpenTok.subscribers.length; i++) {' . "\n" . ' OpenTok.subscribers[i].subscribeToAudio(false);' . "\n" . ' }' . "\n" . ' OpenTok.publisher.publishAudio(true);' . "\n" . "\n" . ' document.getElementById("pushToTalk").onclick = OpenTok.stopTalking;' . "\n" . ' document.getElementById("pushToTalk").value = "' . i18n::s('Stop talking') . '";' . "\n"; // identify the chairman or, if unknown, the owner of this page $chairman = array(); if (isset($this->attributes['chairman']) && $this->attributes['chairman']) { $chairman = Users::get($this->attributes['chairman']); } if (!isset($chairman['id']) && ($owner = $this->anchor->get_value('owner_id'))) { $chairman = Users::get($owner); } // if this surfer is the chairman of this meeting, he will take over after three seconds of silence if (isset($chairman['id']) && Surfer::is($chairman['id'])) { $js_script .= 'OpenTok.watchdog = setInterval(function () {' . 'if(!$("#opentok .talker").length) {OpenTok.startTalking();}' . '}, 3000);' . "\n"; } // end of javascript snippet $js_script .= ' },' . "\n" . "\n" . ' // i am back to listening mode' . "\n" . ' stopTalking: function() {' . "\n" . ' if(OpenTok.watchdog) { clearInterval(OpenTok.watchdog); OpenTok.watchdog = null; }' . "\n" . ' OpenTok.publisher.publishAudio(false);' . "\n" . ' for(var i = 0; i < OpenTok.subscribers.length; i++) {' . "\n" . ' OpenTok.subscribers[i].subscribeToAudio(true);' . "\n" . ' }' . "\n" . "\n" . ' document.getElementById("pushToTalk").onclick = OpenTok.startTalking;' . "\n" . ' document.getElementById("pushToTalk").value = "' . i18n::s('Start talking') . '";' . "\n" . ' },' . "\n" . "\n" . ' // display new streams on people arrival' . "\n" . ' streamCreatedHandler: function(event) {' . "\n" . ' OpenTok.subscribeToStreams(event.streams);' . "\n" . ' },' . "\n" . "\n" . ' // remove a stream that has been destroyed' . "\n" . ' streamDestroyedHandler: function(event) {' . "\n" . ' for(i = 0; i < event.streams.length; i++) {' . "\n" . ' var stream = event.streams[i];' . "\n" . ' $("#opentok_"+stream.streamId).remove();' . "\n" . ' }' . "\n" . ' },' . "\n" . "\n" . ' // a stream has started or stopped' . "\n" . ' streamPropertyChangedHandler: function(event) {' . "\n" . ' switch(event.changedProperty) {' . "\n" . ' case "hasAudio":' . "\n" . ' if(event.newValue) {' . "\n" . ' OpenTok.growl("' . i18n::s("%s is talking") . '".replace(/%s/, event.stream.name));' . "\n" . ' if(event.stream.connection.connectionId != OpenTok.session.connection.connectionId) {' . "\n" . ' $("#opentok_"+event.stream.streamId).addClass("talker");' . "\n" . ' OpenTok.stopTalking();' . "\n" . ' } else {' . "\n" . ' $("#opentok .me .frame").addClass("talker");' . "\n" . ' }' . "\n" . ' } else {' . "\n" . ' OpenTok.growl("' . i18n::s("%s is listening") . '".replace(/%s/, event.stream.name));' . "\n" . ' if(event.stream.connection.connectionId != OpenTok.session.connection.connectionId) {' . "\n" . ' $("#opentok_"+event.stream.streamId).removeClass("talker");' . "\n" . ' } else {' . "\n" . ' $("#opentok .me .frame").removeClass("talker");' . "\n" . ' }' . "\n" . ' }' . "\n" . ' break;' . "\n" . ' case "hasVideo":' . "\n" . ' if(!event.newValue) {' . "\n" . ' OpenTok.growl("' . i18n::s("%s is not visible") . '".replace(/%s/, event.stream.name));' . "\n" . ' }' . "\n" . ' break;' . "\n" . ' }' . "\n" . ' },' . "\n" . "\n" . ' // add new streams to the user interface' . "\n" . ' subscribeToStreams: function(streams) {' . "\n" . "\n" . ' // some remote stream in the list?' . "\n" . ' for(i = 0; i < streams.length; i++) {' . "\n" . ' if(streams[i].connection.connectionId != OpenTok.session.connection.connectionId) {' . "\n" . ' OpenTok.growl("' . i18n::s('Adding remote video streams') . '");' . "\n" . ' break;' . "\n" . ' }' . "\n" . ' }' . "\n" . "\n" . ' for(i = 0; i < streams.length; i++) {' . "\n" . ' var stream = streams[i];' . "\n" . "\n" . ' // subscribe to all streams, except my own camera' . "\n" . ' if(stream.connection.connectionId != OpenTok.session.connection.connectionId) {' . "\n" . "\n" . ' // create one div per subscribed stream and give it the id of the stream' . "\n" . ' $("#opentok .others").append(\'<span id="opentok_\'+stream.streamId+\'"><span id="placeholder"></span></span>\');' . "\n" . ' $("#opentok_"+stream.streamId).addClass("ibox subscriber").css({width: 120, height: 90 });' . "\n" . "\n" . ' // bind the stream to this div' . "\n" . ' var streamProps = {width: 120, height: 90, subscribeToAudio: true, subscribeToVideo: true};' . "\n" . ' OpenTok.subscribers[stream.streamId] = OpenTok.session.subscribe(stream, "placeholder", streamProps);' . "\n" . "\n" . ' // the remote stream is active' . "\n" . ' if(stream.hasAudio) {' . "\n" . ' OpenTok.growl("' . i18n::s("%s is talking") . '".replace(/%s/, stream.name));' . "\n" . ' $("#opentok_"+stream.streamId).addClass("talker");' . "\n" . ' }' . "\n" . "\n" . ' // the default is to push to talk' . "\n" . ' } else if(OpenTok.withAudio) {' . "\n" . ' $("#opentok .me").append(\'<div style="text-align: center; padding: 2px 0;">' . '<input type="button" id="pushToTalk" value="' . i18n::s('Start talking') . '" onClick="OpenTok.startTalking()" />' . '</div>\');' . "\n" . ' OpenTok.growl("' . i18n::s("Click on the button before talking") . '");' . "\n" . ' }' . "\n" . ' }' . "\n" . ' $("#opentok .me .frame").addClass("subscriber").css({width: 120, height: 90});' . "\n" . ' $("#description").focus();' . "\n" . ' }' . "\n" . "\n" . '}' . "\n" . "\n" . '// bind to OpenTok' . "\n" . '$(document).ready(OpenTok.initialize);' . "\n" . "\n"; Page::insert_script($js_script); // video streams are put above the chat area $text = '<div id="opentok">' . '<div class="growl" style="height: 1.6em;" > </div>' . '<table class="layout"><tr>' . '<td class="me"></td>' . '<td class="others"></td>' . '</tr></table>' . '</div>' . "\n"; return $text; }
} } // file history $history = ''; // file has been assigned if (isset($item['assign_id']) && $item['assign_id']) { if (Surfer::is($item['assign_id'])) { $label = i18n::s('you'); } else { $label = $item['assign_name']; } $history .= DRAFT_FLAG . sprintf(i18n::s('reserved by %s %s'), Users::get_link($label, $item['assign_address'], $item['assign_id']), Skin::build_date($item['assign_date'])) . BR; } // file uploader if (isset($item['create_name'])) { if (Surfer::is($item['create_id'])) { $label = i18n::s('you'); } else { $label = $item['create_name']; } $history .= sprintf(i18n::s('shared by %s %s'), Users::get_link($label, $item['create_address'], $item['create_id']), Skin::build_date($item['create_date'])); } // display the full text if ($item['description']) { $history .= Skin::build_box(i18n::s('More information'), $item['description'], 'folded'); } // past of this file if ($history) { $rows[] = array(i18n::s('History'), $history); } // display the source
} 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(); $menu[] = Skin::build_submit_button(i18n::s('Download this file'), NULL, NULL, 'confirmed', 'no_spin_on_click'); $menu[] = Skin::build_link($anchor->get_url('files'), i18n::s('Cancel'), 'span'); // to get the actual file $target_href = $context['url_to_home'] . $context['url_to_root'] . Files::get_url($item['id'], 'fetch', $item['file_name']); // render commands $context['text'] .= '<form method="post" action="' . $context['script_url'] . '" id="main_form"><div>' . "\n" . Skin::finalize_list($menu, 'assistant_bar') . '<input type="hidden" name="id" value="' . $item['id'] . '" />' . "\n" . '<input type="hidden" name="action" value="confirm" />' . "\n" . '</div></form>' . "\n"; // set the focus Page::insert_script('$("#confirmed").focus();'); //actual transfer } elseif ($item['id'] && $item['anchor']) { // increment the count of downloads
if (Users::delete($item['id'])) { // log item deletion $label = sprintf(i18n::c('Deletion: %s'), strip_tags($item['nick_name'])); $description = Users::get_permalink($item); Logger::remember('users/delete.php: ' . $label, $description); // this can appear anywhere Cache::clear(); // back to the index page Safe::redirect($context['url_to_home'] . $context['url_to_root'] . 'users/'); } // deletion has to be confirmed } elseif (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST') { Logger::error(i18n::s('The action has not been confirmed.')); } else { // the submit button if (Surfer::is($item['id'])) { $label = i18n::s('Yes, I want to suppress my own profile from this server and log out.'); } else { $label = i18n::s('Yes, I want to suppress this user'); } $context['text'] .= '<form method="post" action="' . $context['script_url'] . '" id="main_form"><p>' . "\n" . Skin::build_submit_button($label, NULL, NULL, 'confirmed') . "\n" . '<input type="hidden" name="id" value="' . $item['id'] . '" />' . "\n" . '<input type="hidden" name="confirm" value="yes" />' . "\n" . '</p></form>' . "\n"; // set the focus Page::insert_script('$("#confirmed").focus();'); // user nick name if ($item['nick_name']) { $context['text'] .= Skin::build_block($item['nick_name'], 'title'); } // user full name if ($item['full_name']) { $context['text'] .= '<p>' . $item['full_name'] . "</p>\n"; }
/** * list files * * Recognize following variants: * - 'section:123' to list items attached to one particular anchor * - 'no_author' to list items attached to one user profile * * @param resource the SQL result * @return string HTML text to be displayed, or NULL * * @see layouts/layout.php **/ function layout($result) { global $context; // we return some text $text = ''; // empty list if (!SQL::count($result)) { return $text; } // sanity check if (!isset($this->focus)) { $this->focus = ''; } // process all items in the list $items = array(); while ($item = SQL::fetch($result)) { // one box at a time $box = ''; // get the main anchor $anchor = Anchors::get($item['anchor']); // we feature only the head of the list, if we are at the origin page if (!count($items) && $anchor && is_string($this->focus) && $this->focus == $anchor->get_reference()) { $box .= Codes::render_object('file', $item['id']); // no side icon $icon = ''; // we are listing various files from various places } else { $prefix = $suffix = ''; // stream the file if (Files::is_stream($item['file_name'])) { $url = Files::get_url($item['id'], 'stream', $item['file_name']); } else { $url = Files::get_url($item['id'], 'fetch', $item['file_name']); } // absolute url $url = $context['url_to_home'] . $context['url_to_root'] . $url; // signal restricted and private files if ($item['active'] == 'N') { $prefix .= PRIVATE_FLAG; } elseif ($item['active'] == 'R') { $prefix .= RESTRICTED_FLAG; } // file title or file name $label = Codes::beautify_title($item['title']); if (!$label) { $label = ucfirst(str_replace(array('%20', '-', '_'), ' ', $item['file_name'])); } // show a reference to the file for members $hover = i18n::s('Get the file'); if (Surfer::is_member()) { $hover .= ' [file=' . $item['id'] . ']'; } // flag files uploaded recently if ($item['create_date'] >= $context['fresh']) { $suffix .= NEW_FLAG; } elseif ($item['edit_date'] >= $context['fresh']) { $suffix .= UPDATED_FLAG; } // one line of text $box .= $prefix . Skin::build_link($url, $label, 'basic', $hover) . $suffix; // side icon if ($item['thumbnail_url']) { $icon = $item['thumbnail_url']; } else { $icon = $context['url_to_root'] . Files::get_icon_url($item['file_name']); } // build the complete HTML element $icon = '<img src="' . $icon . '" alt="" title="' . encode_field(strip_tags($label)) . '" />'; // make it a clickable link $icon = Skin::build_link($url, $icon, 'basic'); } // first line of details $details = array(); // file poster and last action if ($this->layout_variant != 'no_author') { $details[] = sprintf(i18n::s('shared by %s %s'), Users::get_link($item['edit_name'], $item['edit_address'], $item['edit_id']), Skin::build_date($item['edit_date'])); } else { $details[] = Skin::build_date($item['edit_date']); } // downloads if ($item['hits'] > 1) { $details[] = Skin::build_number($item['hits'], i18n::s('downloads')); } // file size if ($item['file_size'] > 1) { $details[] = Skin::build_number($item['file_size'], i18n::s('bytes')); } // anchor link if ($anchor && is_string($this->focus) && $this->focus != $anchor->get_reference()) { $anchor_url = $anchor->get_url(); $anchor_label = ucfirst($anchor->get_title()); $details[] = sprintf(i18n::s('in %s'), Skin::build_link($anchor_url, $anchor_label, 'article')); } $box .= '<p class="details">' . Skin::finalize_list($details, 'menu') . '</p>'; // append details $details = array(); // view the file $details[] = Skin::build_link(Files::get_permalink($item), i18n::s('details'), 'basic'); // file has been detached if (isset($item['assign_id']) && $item['assign_id']) { // who has been assigned? if (Surfer::is($item['assign_id'])) { $details[] = DRAFT_FLAG . sprintf(i18n::s('reserved by you %s'), Skin::build_date($item['assign_date'])); } else { $details[] = DRAFT_FLAG . sprintf(i18n::s('reserved by %s %s'), Users::get_link($item['assign_name'], $item['assign_address'], $item['assign_id']), Skin::build_date($item['assign_date'])); } } // detach or edit the file if (Files::allow_modification($item, $anchor)) { if (!isset($item['assign_id']) || !$item['assign_id']) { $details[] = Skin::build_link(Files::get_url($item['id'], 'reserve'), i18n::s('reserve'), 'basic', i18n::s('Prevent other persons from changing this file until you update it')); } // release reservation if (isset($item['assign_id']) && $item['assign_id'] && (Surfer::is($item['assign_id']) || is_object($anchor) && $anchor->is_owned())) { $details[] = Skin::build_link(Files::get_url($item['id'], 'release'), i18n::s('release reservation'), 'basic', i18n::s('Allow other persons to update this file')); } if (!isset($item['assign_id']) || !$item['assign_id'] || Surfer::is($item['assign_id']) || is_object($anchor) && $anchor->is_owned()) { $details[] = Skin::build_link(Files::get_url($item['id'], 'edit'), i18n::s('update'), 'basic', i18n::s('Share a new version of this file, or change details')); } } // delete the file if (Files::allow_deletion($item, $anchor)) { $details[] = Skin::build_link(Files::get_url($item['id'], 'delete'), i18n::s('delete'), 'basic'); } // append details if (count($details)) { $box .= '<p class="details">' . Skin::finalize_list($details, 'menu') . '</p>'; } // insert item icon if ($icon) { $list = array(array($box, $icon)); $items[] = Skin::finalize_list($list, 'decorated'); // put the item in a division } else { $items[] = '<div style="margin: 0 0 1em 0">' . $box . '</div>'; } } // stack all items in a single column $text = Skin::finalize_list($items, 'rows'); // end of processing SQL::free($result); return $text; }
/** * list locations * * Recognize following variants: * - 'no_anchor' to list items attached to one particular anchor * - 'no_author' to list items attached to one user prolocation * * @param resource the SQL result * @return string the rendered text * * @see layouts/layout.php **/ function layout($result) { global $context; // empty list if (!SQL::count($result)) { $output = array(); return $output; } // we return an array of ($url => $attributes) $items = array(); // process all items in the list while ($item = SQL::fetch($result)) { // initialize variables $prefix = $suffix = $icon = ''; // the url to view this item $url = Locations::get_url($item['id']); // build a valid label if ($item['geo_place_name']) { $label = Skin::strip($item['geo_place_name'], 10); } else { $label = $item['latitude'] . ', ' . $item['longitude']; } // description if ($item['description']) { $suffix .= ' ' . ucfirst(trim($item['description'])); } // the menu bar for associates and poster if (Surfer::is_empowered() || Surfer::is($item['edit_id'])) { $menu = array(Locations::get_url($item['id'], 'edit') => i18n::s('Edit'), Locations::get_url($item['id'], 'delete') => i18n::s('Delete')); $suffix .= ' ' . Skin::build_list($menu, 'menu'); } // add a separator if ($suffix) { $suffix = ' - ' . $suffix; } // append details to the suffix $suffix .= BR . '<span class="details">'; // details $details = array(); // item poster if (isset($this->layout_variant) && $this->layout_variant != 'no_author') { if ($item['edit_name']) { $details[] = sprintf(i18n::s('edited by %s %s'), Users::get_link($item['edit_name'], $item['edit_address'], $item['edit_id']), Skin::build_date($item['edit_date'])); } } else { $details[] = Anchors::get_action_label($item['edit_action']); } // show an anchor location if (isset($this->layout_variant) && $this->layout_variant != 'no_anchor' && $item['anchor'] && ($anchor = Anchors::get($item['anchor']))) { $anchor_url = $anchor->get_url(); $anchor_label = ucfirst($anchor->get_title()); $details[] = sprintf(i18n::s('in %s'), Skin::build_link($anchor_url, $anchor_label, 'article')); } // all details if (count($details)) { $suffix .= ucfirst(implode(', ', $details)) . "\n"; } // end of details $suffix .= '</span>'; // list all components for this item $items[$url] = array($prefix, $label, $suffix, 'location', $icon); } // end of processing SQL::free($result); return $items; }
// 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 (isset($item['id']) && Surfer::is($item['id'])) { $permitted = TRUE; } else { $permitted = FALSE; } // load the skin load_skin('users'); // the path to this page $context['path_bar'] = array('users/' => i18n::s('People')); // the title of the page if (isset($item['nick_name'])) { $context['page_title'] = sprintf(i18n::s('Select a picture for %s'), $item['nick_name']); } // stop crawlers if (Surfer::is_crawler()) { Safe::header('Status: 401 Unauthorized', TRUE, 401);
/** * list images * * Recognize following variants: * - 'compact' - to build short lists in boxes and sidebars * - '<a valid anchor>' - example: 'section:123' - to list images attached to an anchor page * * @param resource the SQL result * @return array one item per image * * @see layouts/layout.php **/ function layout($result) { global $context; // empty list if (!SQL::count($result)) { $output = array(); return $output; } if (!isset($this->layout_variant)) { $this->layout_variant = ''; } // we return an array of ($url => $attributes) $items = array(); // process all items in the list while ($item = SQL::fetch($result)) { // initialize variables $prefix = $suffix = $icon = ''; // the url to view this item $url = Images::get_url($item['id']); $label = '_'; // the title if ($item['title']) { $suffix .= Skin::strip($item['title'], 10) . BR; } // there is an anchor if ($item['anchor'] && ($anchor = Anchors::get($item['anchor']))) { // codes to embed this image if ($this->focus == $anchor->get_reference()) { // help to insert in textarea // if(!isset($_SESSION['surfer_editor']) || ($_SESSION['surfer_editor'] == 'yacs')) // $suffix .= '<a onclick="edit_insert(\'\', \' [image='.$item['id'].']\');return false;" title="insert" tabindex="2000">[image='.$item['id'].']</a>' // .' <a onclick="edit_insert(\'\', \' [image='.$item['id'].', left]\');return false;" title="insert" tabindex="2000">[image='.$item['id'].',left]</a>' // .' <a onclick="edit_insert(\'\', \' [image='.$item['id'].', right]\');return false;" title="insert" tabindex="2000">[image='.$item['id'].',right]</a>' // .' <a onclick="edit_insert(\'\', \' [image='.$item['id'].', center]\');return false;" title="insert" tabindex="2000">[image='.$item['id'].',center]</a>'; // // else $suffix .= '[image=' . $item['id'] . ']' . ' [image=' . $item['id'] . ',left]' . ' [image=' . $item['id'] . ',right]' . ' [image=' . $item['id'] . ',center]'; $suffix .= BR; // show an anchor link } else { $anchor_url = $anchor->get_url(); $anchor_label = ucfirst($anchor->get_title()); $suffix .= sprintf(i18n::s('In %s'), Skin::build_link($anchor_url, $anchor_label)) . BR; } } // details $details = array(); // file name if ($item['image_name']) { $details[] = $item['image_name']; } // file size if ($item['image_size'] > 1) { $details[] = number_format($item['image_size']) . ' ' . i18n::s('bytes'); } // poster if ($item['edit_name']) { $details[] = sprintf(i18n::s('edited by %s %s'), Users::get_link($item['edit_name'], $item['edit_address'], $item['edit_id']), Skin::build_date($item['edit_date'])); } // append details if (count($details)) { $suffix .= '<span class="details">' . ucfirst(implode(', ', $details)) . '</span>' . BR; } // the menu bar $menu = array(); // change the image if (Surfer::is_empowered() || Surfer::is($item['edit_id'])) { $menu = array_merge($menu, array(Images::get_url($item['id'], 'edit') => i18n::s('Update this image'))); } // use the image if (Surfer::is_empowered() && Surfer::is_member()) { if (preg_match('/\\buser\\b/', $this->layout_variant)) { $menu = array_merge($menu, array(Images::get_url($item['id'], 'set_as_thumbnail') => i18n::s('Set as profile picture'))); } elseif (preg_match('/\\b(article|category|section)\\b/', $this->layout_variant)) { $menu = array_merge($menu, array(Images::get_url($item['id'], 'set_as_icon') => i18n::s('Set as page image'))); $menu = array_merge($menu, array(Images::get_url($item['id'], 'set_as_thumbnail') => i18n::s('Set as page thumbnail'))); } } // delete the image if (Surfer::is_empowered() || Surfer::is($item['edit_id'])) { $menu = array_merge($menu, array(Images::get_url($item['id'], 'delete') => i18n::s('Delete this image'))); } if (count($menu)) { $suffix .= Skin::build_list($menu, 'menu'); } // link to the thumbnail image, if any $icon = '<span class="small_image"><img src="' . Images::get_thumbnail_href($item) . '" title="' . encode_field(strip_tags($item['title'])) . '" alt="" /></span>'; // list all components for this item $items[$url] = array($prefix, $label, $suffix, 'image', $icon); } // end of processing SQL::free($result); return $items; }