/** * list sections * * @param resource the SQL result * @return an array of $url => (NULL, $title, NULL, 'section_123', NULL, 'visit this section') * * @see layouts/layout.php **/ function layout($result) { global $context; // empty list if (!SQL::count($result)) { $output = array(); return $output; } // hovering label $href_title = i18n::s('View the section'); // we return an array of ($url => $attributes) $items = array(); // process all items in the list while ($item = SQL::fetch($result)) { // the url to view this item $url = Sections::get_permalink($item); // initialize variables $prefix = $suffix = ''; // list all components for this item $items[$url] = array($prefix, ucfirst(Skin::strip($item['title'], 30)), $suffix, 'section_' . $item['id'], NULL, $href_title); } // end of processing SQL::free($result); return $items; }
/** * preserve content across page modification * * @see overlays/overlay.php * * @param the hosting attributes * @return a list of ($label, $input, $hint) */ function get_fields($host, $field_pos = NULL) { global $context; // form fields $fields = array(); // item identifier if (!isset($this->attributes['overlay_id'])) { $this->attributes['overlay_id'] = ''; } // only associates can change the overlay id if (Surfer::is_associate()) { // isset($host['anchor']) && ($parent =& Anchors::get($host['anchor'])) && $parent->is_assigned()) { $label = i18n::s('Overlay identifier'); $input = '<input type="text" name="overlay_id" value="' . encode_field($this->attributes['overlay_id']) . '" />'; } else { $label = 'hidden'; $input = '<input type="hidden" name="overlay_id" value="' . encode_field($this->attributes['overlay_id']) . '" />'; } // hidden attributes foreach ($this->attributes as $name => $value) { if (preg_match('/_content$/', $name)) { $input .= '<input type="hidden" name="' . encode_field($name) . '" value="' . encode_field($value) . '" />'; } } // we do have something to preserve $fields[] = array($label, $input); // job done return $fields; }
/** * list links * * @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; } // process all items in the list while ($item = SQL::fetch($result)) { // get the main anchor $anchor = Anchors::get($item['anchor']); // url is the link itself -- hack for xhtml compliance $url = str_replace('&', '&', $item['link_url']); // initialize variables $prefix = $suffix = ''; // flag links that are dead, or created or updated very recently if ($item['edit_date'] >= $context['fresh']) { $suffix = NEW_FLAG; } // make a label $label = Links::clean($item['title'], $item['link_url']); // the main anchor link if (is_object($anchor)) { $suffix .= ' - <span class="details">' . sprintf(i18n::s('in %s'), Skin::build_link($anchor->get_url(), ucfirst($anchor->get_title()))) . '</span>'; } // list all components for this item $items[$url] = array($prefix, $label, $suffix, 'basic', NULL); } // end of processing SQL::free($result); return $items; }
function check_file($node) { global $context; global $footprints; $key = substr($node, strlen($context['path_to_root'])); // no extension to check if (strpos($key, '.') === FALSE) { } elseif (!strncmp($node, 'scripts/staging', 16)) { } elseif (!strcmp($key, 'footprints.php')) { } elseif (!strncmp(substr($key, -9), 'index.php', 9) && ($content = Safe::file_get_contents($node)) && !strcmp($content, Safe::mkdir_index_content())) { } elseif (!strncmp($key, 'temporary/cache_i18n_locale_', 28)) { } elseif (!strncmp(substr($key, -4), '.php', 4)) { // one of the parameter files created by yacs if (preg_match('/parameters\\/(agents|control|feeds|files|hooks|letters|root|scripts|services|skins|users|virtual_.+)\\.include\\.php$/i', $key)) { } elseif (isset($footprints[$key])) { $expected = $footprints[$key]; $actual = Scripts::hash($node); if ($expected[0] != $actual[0] || $expected[1] != $actual[1]) { $context['text'] .= sprintf(i18n::s('ERROR: File %s is missing or corrupted.'), $key) . BR . "\n"; } } else { $context['text'] .= sprintf(i18n::s('File %s is not part of Yacs.'), $key) . BR . "\n"; } // not a safe file } elseif (!preg_match('/\\.(bak|bat|css|done|dtd|fdb|flv|gif|ico|jpeg|jpg|js|jsmin|htc|htm|html|mo|off|on|pdf|png|po|pot|reg|sh|sql|swf|tgz|txt|xml|zip)$/i', $key)) { $context['text'] .= sprintf(i18n::s('File %s is not part of Yacs.'), $key) . BR . "\n"; } }
/** * display content below main panel * * Everything is in a separate panel * * @param array the hosting record, if any * @return some HTML to be inserted into the resulting page */ function &get_trailer_text($host = NULL) { $text = ''; // display the following only if at least one comment has been attached to this page if (is_object($this->anchor) && !Comments::count_for_anchor($this->anchor->get_reference())) { return $text; } // ask the surfer if he has not answered yet, and if the page has not been locked $ask = TRUE; if (isset($_COOKIE['rating_' . $host['id']])) { $ask = FALSE; } elseif (isset($host['locked']) && $host['locked'] == 'Y') { $ask = FALSE; } // ask the surfer if ($ask) { $text = '<p style="line-height: 2.5em;">' . i18n::s('Has this page been useful to you?') . ' ' . Skin::build_link(Articles::get_url($host['id'], 'like'), i18n::s('Yes'), 'button') . ' ' . Skin::build_link(Articles::get_url($host['id'], 'dislike'), i18n::s('No'), 'button') . '</p>'; // or report on results } elseif ($host['rating_count']) { $text = '<p>' . Skin::build_rating_img((int) round($host['rating_sum'] / $host['rating_count'])) . ' ' . sprintf(i18n::ns('%d rating', '%d ratings', $host['rating_count']), $host['rating_count']) . '</p>'; } // add a title if ($text) { $text = Skin::build_box(i18n::s('Feed-back'), $text); } // done return $text; }
/** * list versions * * @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 = '_' . $item['id']; // Versions::get_url($item['id']); // version description $label = sprintf(i18n::s('edited by %s %s'), ucfirst($item['edit_name']), Skin::build_date($item['edit_date'])); // command to view this version $suffix .= ' ' . Skin::build_link(Versions::get_url($item['id'], 'view'), i18n::s('compare to current version'), 'button'); // list all components for this item $items[$url] = array($prefix, $label, $suffix, 'version', $icon); } // end of processing SQL::free($result); return $items; }
/** * list articles * * @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 (!SQL::count($result)) { return $text; } // clear flows $text .= '<br style="clear: left" />'; // process all items in the list while ($item = SQL::fetch($result)) { // get the related overlay $overlay = Overlay::load($item, 'article:' . $item['id']); // the url to view this item $url = Articles::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['title']); } // the hovering title if ($item['introduction'] && $context['skins_with_details'] == 'Y') { $hover = strip_tags(Codes::beautify_introduction($item['introduction'])); } else { $hover = i18n::s('View the page'); } // title is a link to the target article $title =& Skin::build_link($url, $title, 'basic', $hover); // use the thumbnail for this article if ($icon = trim($item['thumbnail_url'])) { // fix relative path if (!preg_match('/^(\\/|http:|https:|ftp:)/', $icon)) { $icon = $context['url_to_root'] . $icon; } // use parameter of the control panel for this one $options = ''; if (isset($context['classes_for_thumbnail_images'])) { $options = 'class="' . $context['classes_for_thumbnail_images'] . '" '; } // build the complete HTML element $icon = '<img src="' . $icon . '" alt="" title="' . encode_field($hover) . '" ' . $options . ' />'; // use default icon if nothing to display } else { $icon = MAP_IMG; } // use the image as a link to the target page $icon =& Skin::build_link($url, $icon, 'basic', $hover); // add a floating box $text .= Skin::build_box($title, $icon, 'floating'); } // clear flows $text .= '<br style="clear: left" />'; // end of processing SQL::free($result); return $text; }
/** * 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; }
/** * 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 files * * @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 = 'full'; } // process all items in the list while ($item = SQL::fetch($result)) { // get the main anchor $anchor = Anchors::get($item['anchor']); // download the file directly $url = Files::get_url($item['id'], 'fetch', $item['file_name']); // initialize variables $prefix = $suffix = ''; // flag files that are dead, or created or updated very recently if ($item['create_date'] >= $context['fresh']) { $suffix .= NEW_FLAG; } elseif ($item['edit_date'] >= $context['fresh']) { $suffix .= UPDATED_FLAG; } // 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'])); } // the main anchor link, except on user profiles if (is_object($anchor) && $anchor->get_reference() != $this->focus) { $suffix .= ' - <span class="details">' . sprintf(i18n::s('in %s'), Skin::build_link($anchor->get_url(), ucfirst($anchor->get_title()))) . '</span>'; } // list all components for this item $items[$url] = array($prefix, $label, $suffix, 'basic', NULL); } // end of processing SQL::free($result); return $items; }
/** * 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; }
/** * render an iframe * * @param string URL to be embedded * @param string iframe parameters * @return string the rendered text **/ public static function render_iframe($url, $variant) { global $context; // split parameters $attributes = preg_split("/\\s*,\\s*/", $variant, 2); // set a default size if (!isset($attributes[0])) { $attributes[0] = 320; } if (!isset($attributes[1])) { $attributes[1] = 240; } $text = '<iframe src="' . $url . '" style="width: ' . $attributes[0] . 'px; height: ' . $attributes[1] . 'px" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" vspace="0" hspace="0">' . "\n" . i18n::s('Your browser does not accept iframes') . '</iframe>'; return $text; }
/** * login * * The script checks provided name and password against remote server. * * This is done by transmitting the user name and the password * while opening a FTP session to the server. * * @param string the nickname of the user * @param string the submitted password * @return TRUE on succesful authentication, FALSE othewise */ function login($name, $password) { global $context; // we need some parameters if (!isset($this->attributes['authenticator_parameters']) || !$this->attributes['authenticator_parameters']) { Logger::error(i18n::s('Please provide parameters to the authenticator.')); return FALSE; } // prepare network parameters $server = $this->attributes['authenticator_parameters']; if (strstr($server, ':')) { list($server, $port) = explode(':', $server, 2); } else { $port = 21; } // open network socket if (!($handle = Safe::fsockopen($server, $port))) { Logger::error(sprintf(i18n::s('Impossible to connect to %.'), $this->attributes['authenticator_parameters'])); return FALSE; } // read welcome banner if (!($line = fgets($handle, 256)) || !strstr($line, '2')) { fclose($handle); Logger::error(sprintf(i18n::s('Invalid banner message from %s.'), $this->attributes['authenticator_parameters'])); return FALSE; } // submit name fputs($handle, "USER {$username}\r\n"); if (!($line = fgets($handle, 256)) || !strstr($line, '3')) { fclose($handle); Logger::error(sprintf(i18n::s('Impossible to submit name to %s.'), $this->attributes['authenticator_parameters'])); return FALSE; } // submit password fputs($handle, "PASS {$password}\r\n"); if (!($line = fgets($handle, 256)) || !strstr($line, '2')) { fclose($handle); Logger::error(sprintf(i18n::s('Impossible to submit password to %s.'), $this->attributes['authenticator_parameters'])); return FALSE; } // close ftp session fputs($handle, "QUIT\r\n"); fclose($handle); // this is a valid user return TRUE; }
/** * check access rights * * @param string script name * @paral string target anchor, if any * @return boolean FALSE if access is denied, TRUE otherwise */ function allow($script, $anchor = NULL) { global $context; // limit the scope of our check if ($script != 'files/view.php' && $script != 'files/fetch.php' && $script != 'files/fetch_all.php' && $script != 'files/stream.php') { return TRUE; } // sanity check if (!$anchor) { die(i18n::s('No anchor has been found.')); } // stop here if the agreement has been gathered previously if (isset($_SESSION['agreements']) && is_array($agreements = $_SESSION['agreements'])) { foreach ($agreements as $agreement) { if ($agreement == $anchor) { return TRUE; } } } // which agreement? if (!$this->parameters) { die(sprintf(i18n::s('No parameter has been provided to %s'), 'behaviors/agree_on_file_access')); } // do we have a related file to display? if (!is_readable($context['path_to_root'] . 'behaviors/agreements/' . $this->parameters)) { die(sprintf(i18n::s('Bad parameter to behavior <code>%s %s</code>'), 'agree_on_file_access', $this->parameters)); } // splash message $context['text'] .= '<p class="agreement">' . i18n::s('Before moving forward, please read following text and express yourself at the end of the page.') . '</p><hr/>' . "\n"; // load and display the file to be displayed $context['text'] .= Codes::beautify(Safe::file_get_contents($context['path_to_root'] . 'behaviors/agreements/' . $this->parameters)); // target link to record agreement if ($context['with_friendly_urls'] == 'Y') { $agree_link = 'behaviors/agreements/agree.php/' . rawurlencode($anchor); } else { $agree_link = 'behaviors/agreements/agree.php?id=' . urlencode($anchor); } // display confirmation buttons at the end of the agreement $context['text'] .= '<hr/><p class="agreement">' . i18n::s('Do you agree?'); $context['text'] .= ' ' . Skin::build_link($agree_link, i18n::s('Yes'), 'button'); $context['text'] .= ' ' . Skin::build_link('behaviors/agreements/deny.php', i18n::s('No'), 'button') . '</p>' . "\n"; // render the skin based only on text provided by this behavior render_skin(); exit; }
public function render($matches) { $count = isset($matches[0]) ? $matches[0] : 20; // sanity check if (!(int) $count) { $count = 20; } // query the database and layout that stuff if (!($text = Members::list_categories_by_count_for_anchor(NULL, 0, $count, 'cloud'))) { $text = '<p>' . i18n::s('No item has been found.') . '</p>'; } // we have an array to format if (is_array($text)) { $text = Skin::build_list($text, '2-columns'); } // job done return $text; }
/** * get next and previous items, if any * * @param string the item type (eg, 'image', 'file', etc.) * @param array the anchored item asking for neighbours * @return an array($previous_url, $previous_label, $next_url, $next_label, $option_url, $option_label), or NULL * * @see shared/anchor.php */ function get_neighbours($type, $item) { global $context; // no item bound if (!isset($this->item['id'])) { return NULL; } // initialize components $previous_url = $previous_label = $next_url = $next_label = $option_url = $option_label = ''; // previous and next images if ($type == 'image') { // load the adequate library include_once $context['path_to_root'] . 'images/images.php'; // extract all images references from the description preg_match_all('/\\[image=(\\d+)/', $this->item['description'], $matches); // locate the previous image, if any $previous = NULL; reset($matches[1]); $index = 0; while (list($key, $value) = each($matches[1])) { $index++; if ($item['id'] == $value) { break; } $previous = $value; } // make a link to the previous image if ($previous) { $previous_url = Images::get_url($previous); $previous_label = i18n::s('Previous image'); } // locate the next image, if any if (!(list($key, $next) = each($matches[1]))) { $next = NULL; } else { $next_url = Images::get_url($next); $next_label = i18n::s('Next image'); } // add a label $option_label = sprintf(i18n::s('Image %d of %d'), $index, count($matches[1])); } // return navigation info return array($previous_url, $previous_label, $next_url, $next_label, $option_url, $option_label); }
/** * list files * * @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; } // process all items in the list while ($item = SQL::fetch($result)) { // download the file directly $url = Files::get_url($item['id'], 'fetch', $item['file_name']); // initialize variables $prefix = $suffix = ''; // flag files that are dead, or created or updated very recently if ($item['create_date'] >= $context['fresh']) { $suffix .= NEW_FLAG; } elseif ($item['edit_date'] >= $context['fresh']) { $suffix .= UPDATED_FLAG; } // 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'])); } // with hits if ($item['hits'] > 1) { $suffix .= ' <span class="details">- ' . Skin::build_number($item['hits'], i18n::s('downloads')) . '</span>'; } // list all components for this item $items[$url] = array($prefix, $label, $suffix, 'basic', NULL); } // end of processing SQL::free($result); return $items; }
/** * extend the page menu * * @param string script name * @param string target anchor, if any * @param array current menu * @return array updated menu */ function add_commands($script, $anchor, $menu = array()) { global $context; // limit the scope of our check to viewed pages if (!preg_match('/articles\\/view/', $script)) { return $menu; } // surfer has to be authenticated if (!Surfer::is_logged()) { return $menu; } // sanity checks if (!$anchor) { Logger::error(i18n::s('No anchor has been found.')); } elseif (!($target = Anchors::get($anchor))) { Logger::error(i18n::s('No anchor has been found.')); } elseif (!$this->parameters) { Logger::error(sprintf(i18n::s('No parameter has been provided to %s'), 'behaviors/move_on_article_access')); } else { // look at parent container if possible if (!($origin = Anchors::get($target->get_parent()))) { $origin = $target; } // only container editors can proceed if ($origin->is_assigned() || Surfer::is_associate()) { // load target section $tokens = explode(' ', $this->parameters, 2); if ($section = Anchors::get('section:' . $tokens[0])) { // make a label if (count($tokens) < 2) { $tokens[1] = sprintf(i18n::s('Move to %s'), $section->get_title()); } // the target link to move the page $link = Articles::get_url(str_replace('article:', '', $anchor), 'move', str_replace('section:', '', $section->get_reference())); // make a sub-menu $menu = array_merge(array($link => array('', $tokens[1], '', 'button')), $menu); } } } return $menu; }
/** * list files * * @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; } // process all items in the list while ($item = SQL::fetch($result)) { // download the file directly $url = Files::get_url($item['id'], 'fetch', $item['file_name']); // file title or file name $label = Codes::beautify_title($item['title']); if (!$label) { $label = ucfirst(str_replace(array('%20', '-', '_'), ' ', $item['file_name'])); } // initialize variables $prefix = $suffix = ''; $contributor = Users::get_link($item['create_name'], $item['create_address'], $item['create_id']); $flag = ''; if ($item['create_date'] >= $context['fresh']) { $flag = NEW_FLAG; } elseif ($item['edit_date'] >= $context['fresh']) { $flag = UPDATED_FLAG; } $suffix .= '<span class="details"> - ' . sprintf(i18n::s('By %s'), $contributor) . ' ' . Skin::build_date($item['create_date']) . $flag . '</span>'; // signal restricted and private files if ($item['active'] == 'N' && defined('PRIVATE_FLAG')) { $prefix .= PRIVATE_FLAG; } elseif ($item['active'] == 'R' && defined('RESTRICTED_FLAG')) { $prefix .= RESTRICTED_FLAG; } // list all components for this item $items[$url] = array($prefix, $label, $suffix, 'file', NULL); } // end of processing SQL::free($result); return $items; }
/** * get form fields to change the day * * @see overlays/overlay.php * * @param array hosting attributes * @return a list of ($label, $input, $hint) */ function get_fields($host, $field_pos = NULL) { global $context; $options = '<input type="hidden" name="time_stamp" value="12:00" />' . '<input type="hidden" name="duration" value="1440" />'; // default value is now if (!isset($this->attributes['date_stamp']) || $this->attributes['date_stamp'] <= NULL_DATE) { $this->attributes['date_stamp'] = gmstrftime('%Y-%m-%d %H:%M', time() + Surfer::get_gmt_offset() * 3600); } else { $this->attributes['date_stamp'] = Surfer::from_GMT($this->attributes['date_stamp']); } // split date from time list($date, $time) = explode(' ', $this->attributes['date_stamp']); // event time $label = i18n::s('Date'); $input = Skin::build_input_time('date_stamp', $date, 'date') . $options; $hint = i18n::s('Use format YYYY-MM-DD'); $fields[] = array($label, $input, $hint); // ensure that we do have a date Page::insert_script('func' . 'tion validateOnSubmit(container) {' . "\n" . "\n" . ' if(!Yacs.trim(container.date_stamp.value)) {' . "\n" . ' alert("' . i18n::s('Please provide a date.') . '");' . "\n" . ' container.date_stamp.focus();' . "\n" . ' Yacs.stopWorking();' . "\n" . ' return false;' . "\n" . ' }' . "\n\n" . ' return true;' . "\n" . '}' . "\n"); return $fields; }
/** * create a new authenticator instance * * This function creates an instance of the Authenticator class based on the given type. * For the type '[code]foo[/code]', the script file '[code]users/authenticators/foo.php[/code]' is loaded. * * Example: * [php] * // create a new authenticator * $authenticator = Authenticator::bind('ldap'); * [/php] * * The provided string may include parameters after the type. * These parameters, if any, are saved along authenticator attributes. * * @param string authenticator type, followed by parameters if any * @return a brand new instance * */ public static function bind($type = '') { global $context; // stop hackers, if any $type = preg_replace(FORBIDDEN_IN_PATHS, '', strip_tags($type)); // remove side spaces $type = trim($type); // sanity check if (!$type) { Logger::error(i18n::s('Invalid authenticator type.')); return NULL; } // localize authenticators strings i18n::bind('users'); // extract parameters, if any $parameters = ''; if (strlen($type) > 1 && ($separator = strpos($type, ' ', 1)) !== FALSE) { $parameters = substr($type, $separator + 1); $type = substr($type, 0, $separator); } // load the authenticator class file $file = $context['path_to_root'] . 'users/authenticators/' . $type . '.php'; if (is_readable($file)) { include_once $file; } // create the instance $class_auth = $type . AUTH_CLASS_SUFFIX; if (class_exists(class_auth)) { $authenticator = new $class_auth(); $authenticator->attributes = array(); $authenticator->attributes['authenticator_type'] = $class_auth; $authenticator->attributes['authenticator_parameters'] = $parameters; return $authenticator; } // houston, we've got a problem Logger::error(sprintf(i18n::s('Unknown authenticator type %s'), $type)); return NULL; }
/** * list images * * @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)) { // url to view the image $url = Images::get_url($item['id']); // initialize variables $prefix = $suffix = ''; // flag new images if ($item['edit_date'] >= $context['fresh']) { $suffix .= NEW_FLAG; } // image title or image name $label = Skin::strip($item['title'], 10); if (!$label) { $name_as_title = TRUE; $label = ucfirst($item['image_name']); } $label = str_replace('_', ' ', str_replace('%20', ' ', $label)); // with hits if ($item['hits'] > 1) { $suffix .= ' ' . Skin::build_number($item['hits'], i18n::s('hits')); } // list all components for this item $items[$url] = array($prefix, $label, $suffix, 'basic', NULL); } // end of processing SQL::free($result); return $items; }
/** * login * * The script checks provided name and password against remote server. * * This is done by transmitting the user name and the password to the origin server, * through a XML-RPC call ([code]drupal.login[/code]). * On success the origin server will provide the original id for the user profile. * Else a null id will be returned. * * @link http://drupal.org/node/312 Using distributed authentication (drupal.org) * * @param string the nickname or the email address of the user * @param string the submitted password * @return TRUE on succesful authentication, FALSE othewise */ function login($name, $password) { global $context; // we need some parameters if (!isset($this->attributes['authenticator_parameters']) || !$this->attributes['authenticator_parameters']) { Logger::error(i18n::s('Please provide parameters to the authenticator.')); return FALSE; } // submit credentials to the authenticating server include_once $context['path_to_root'] . 'services/call.php'; $result = Call::invoke($this->attributes['authenticator_parameters'], 'drupal.login', array($name, $password), 'XML-RPC'); // invalid result if (!$result || @count($result) < 2) { Logger::error(sprintf(i18n::s('Impossible to complete XML-RPC call to %s.'), $this->attributes['authenticator_parameters'])); return FALSE; } // successful authentication if ($result[0] && $result[1] > 0) { return TRUE; } // failed authentication return FALSE; }
/** * list comments * * @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 (!SQL::count($result)) { return $text; } // process all items in the list include_once $context['path_to_root'] . 'comments/comments.php'; while ($item = SQL::fetch($result)) { // automatic notification if ($item['type'] == 'notification') { $text .= '<dd style="font-style: italic; font-size: smaller;">' . ucfirst(trim($item['description'])) . ' <span class="details">' . Skin::build_date($item['create_date']) . '</span></dd>'; } else { // the title as the label if ($item['create_name']) { $label = ucfirst($item['create_name']); } else { $label = i18n::s('anonymous'); } // expand a definition list $text .= '<dt>' . $label . '</dt>' . '<dd>' . $item['description'] . ' <span class="details">' . Skin::build_date($item['create_date']) . '</span></dd>' . "\n"; } } // finalize the definition list if ($text) { $text = '<dl class="comments">' . $text . '</dl>'; } // process yacs codes at once $text = Codes::beautify($text); // end of processing SQL::free($result); return $text; }
$where .= " OR categories.active='R'"; } if (Surfer::is_associate()) { $where .= " OR categories.active='N'"; } // only consider live categories $where = '(' . $where . ')' . ' AND ((categories.expiry_date is NULL)' . "\tOR (categories.expiry_date <= '" . NULL_DATE . "') OR (categories.expiry_date > '" . $context['now'] . "'))"; // limit the query to top level only $query = "SELECT categories.id, categories.title " . " FROM " . SQL::table_name('categories') . " AS categories " . " WHERE (" . $where . ") AND (categories.anchor='category:" . $category_id . "')" . " ORDER BY categories.title"; $result = SQL::query($query); $sub_categories = array(); while ($result && ($option = SQL::fetch($result))) { $sub_categories['category:' . $option['id']] = $option['title']; } if (count($sub_categories)) { $suffix .= '<form method="post" action="' . $context['script_url'] . '"><div>' . i18n::s('More specific:') . ' <select name="anchor">'; foreach ($sub_categories as $option_reference => $option_label) { $suffix .= '<option value="' . $option_reference . '">' . $option_label . "</option>\n"; } $suffix .= '</select>' . ' ' . Skin::build_submit_button(" >> ") . '<input type="hidden" name="member" value="' . $member . '">' . '<input type="hidden" name="father" value="category:' . $category_id . '">' . '</div></form>' . "\n"; } // format the item $new_categories[$url] = array($prefix, $label, $suffix, $type, $icon); } // display attached categories with unlink buttons $context['text'] .= Skin::build_list($new_categories, 'decorated'); } // insert anchor suffix if (is_object($anchor)) { $context['text'] .= $anchor->get_suffix(); }
if ($file == 'index.php') { continue; } if ($file == 'behavior.php') { continue; } if ($file == 'behaviors.php') { continue; } if (!preg_match('/(.*)\\.php$/i', $file, $matches)) { continue; } $behaviors[] = $matches[1]; } Safe::closedir($dir); if (@count($behaviors)) { natsort($behaviors); foreach ($behaviors as $behavior) { $context['text'] .= '<li>' . $behavior . "</li>\n"; } } } $context['text'] .= '</ul>'; // how to use behaviors if (Surfer::is_associate()) { $context['text'] .= '<p>' . sprintf(i18n::s('For example, if you want to apply the behavior <code>foo</code>, go to the %s , and select a target section, or add a new one.'), Skin::build_link('sections/', i18n::s('site map'), 'shortcut')) . '</p>' . '<p>' . i18n::s('In the form used to edit the section, type the keyword <code>foo</code> in the behavior field, then save changes.') . '</p>'; } // referrals, if any $context['components']['referrals'] =& Skin::build_referrals('behaviors/index.php'); // render the skin render_skin();
/** * layout one recent article * * @param array the article * @return an array ($prefix, $label, $suffix) **/ function layout_recent($item) { global $context; // permalink $url = Articles::get_permalink($item); // get the related overlay, if any $overlay = Overlay::load($item, 'article:' . $item['id']); // get the anchor $anchor = Anchors::get($item['anchor']); // 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['title']); } // reset everything $prefix = $suffix = ''; // signal restricted and private articles if ($item['active'] == 'N') { $prefix .= PRIVATE_FLAG; } elseif ($item['active'] == 'R') { $prefix .= RESTRICTED_FLAG; } // rating if ($item['rating_count']) { $suffix .= Skin::build_link(Articles::get_url($item['id'], 'like'), Skin::build_rating_img((int) round($item['rating_sum'] / $item['rating_count'])), 'basic'); } // the introductory text $introduction = ''; if (is_object($overlay)) { $introduction = $overlay->get_text('introduction', $item); } elseif ($item['introduction']) { $introduction = $item['introduction']; } if ($introduction) { $suffix .= ' - ' . Codes::beautify_introduction($introduction); } // other details $details = array(); // the author $author = ''; if (isset($context['with_author_information']) && $context['with_author_information'] == 'Y') { $author = sprintf(i18n::s('by %s'), $item['create_name']) . ' '; } // date $details[] = $author . Skin::build_date($item['publish_date']); // info on related files if ($count = Files::count_for_anchor('article:' . $item['id'], TRUE)) { $details[] = Skin::build_link($url . '#_attachments', sprintf(i18n::ns('%d file', '%d files', $count), $count), 'basic'); } // info on related comments $link = Comments::get_url('article:' . $item['id'], 'list'); if ($count = Comments::count_for_anchor('article:' . $item['id'], TRUE)) { $details[] = Skin::build_link($link, sprintf(i18n::ns('%d comment', '%d comments', $count), $count), 'basic'); } // discuss if (Comments::allow_creation($item, $anchor)) { $details[] = Skin::build_link(Comments::get_url('article:' . $item['id'], 'comment'), i18n::s('Discuss'), 'basic'); } // info on related links if ($count = Links::count_for_anchor('article:' . $item['id'], TRUE)) { $details[] = Skin::build_link($url . '#_attachments', sprintf(i18n::ns('%d link', '%d links', $count), $count), 'basic'); } // append a menu $suffix .= Skin::finalize_list($details, 'menu'); // display all tags if ($item['tags']) { $suffix .= ' <p class="tags" style="margin-top: 3px;">' . Skin::build_tags($item['tags'], 'article:' . $item['id']) . '</p>'; } // insert an array of links return array($prefix, $title, $suffix); }
/** * update a link * * @param array an array of fields * @return boolean TRUE on success, FALSE on error **/ public static function put(&$fields) { global $context; // id cannot be empty if (!isset($fields['id']) || !is_numeric($fields['id'])) { Logger::error(i18n::s('No item has the provided id.')); return FALSE; } // no link if (!$fields['link_url']) { Logger::error(i18n::s('No link URL has been provided.')); return FALSE; } // no anchor reference if (!$fields['anchor']) { Logger::error(i18n::s('No anchor has been found.')); return FALSE; } // set default values for this editor Surfer::check_default_editor($fields); // update the existing record $query = "UPDATE " . SQL::table_name('links') . " SET " . "anchor='" . SQL::escape($fields['anchor']) . "', " . "anchor_id=SUBSTRING_INDEX('" . SQL::escape($fields['anchor']) . "', ':', -1)," . "anchor_type=SUBSTRING_INDEX('" . SQL::escape($fields['anchor']) . "', ':', 1)," . "link_url='" . SQL::escape($fields['link_url']) . "', " . "link_target='" . SQL::escape(isset($fields['link_target']) ? $fields['link_target'] : '') . "', " . "link_title='" . SQL::escape(isset($fields['link_title']) ? $fields['link_title'] : '') . "', " . "title='" . SQL::escape(isset($fields['title']) ? $fields['title'] : '') . "', " . "description='" . SQL::escape(isset($fields['description']) ? $fields['description'] : '') . "'"; // 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='link:update', " . "edit_date='" . SQL::escape($fields['edit_date']) . "'"; } // update only one record $query .= " WHERE id = " . SQL::escape($fields['id']); // do the job if (!SQL::query($query)) { return FALSE; } // clear the cache for links Links::clear($fields); // report on result return TRUE; }
} else { // if the server is currently switched off if (file_exists($context['path_to_root'] . 'parameters/switch.off')) { // server status Logger::error(i18n::s('The server is currently switched off. All users are redirected to the closed page.')); // the confirmation question $context['text'] .= '<b>' . i18n::s('You are about to open the server again. Are you sure?') . "</b>\n"; // the menu for this page $context['text'] .= '<form method="post" action="' . $context['script_url'] . '"><p>' . Skin::build_submit_button(i18n::s('Yes, I do want to switch this server on')) . '<input type="hidden" name="action" value="on" />' . '</p></form>' . "\n"; // else the server is currently switched on } else { // server status $context['text'] .= '<p>' . i18n::s('The server is currently switched on. Pages are provided normally to surfers.') . "</p>\n"; // the confirmation question $context['text'] .= '<p><b>' . i18n::s('You are about to close the server. Are you sure?') . "</b></p>\n"; // the menu for this page $context['text'] .= '<form method="post" action="' . $context['script_url'] . '"><div>' . Skin::build_submit_button(i18n::s('Yes, I do want to switch this server off')) . '<input type="hidden" name="action" value="off" />'; // redirect $label = i18n::s('Option: redirect requests to the following address'); $input = '<input type="text" name="switch_target" size="45" maxlength="255" />'; $context['text'] .= '<p>' . $label . BR . $input . "</p>\n"; // contact information $label = i18n::s('Option: contact information, such as an email address'); $input = '<input type="text" name="switch_contact" size="45" maxlength="255" />'; $context['text'] .= '<p>' . $label . BR . $input . "</p>\n"; // end of the form $context['text'] .= '</div></form>' . "\n"; } } // render the skin render_skin();
/** * login * * The script checks provided name and password against remote server. * * This is done by transmitting the user name and the password * to the directory. * * @param string the nickname of the user * @param string the submitted password * @return TRUE on successful authentication, FALSE othewise */ function login($name, $password) { global $context; // we need some parameters if (!isset($this->attributes['authenticator_parameters']) || !$this->attributes['authenticator_parameters']) { Logger::error(i18n::s('Please provide parameters to the authenticator.')); return FALSE; } // tokenize enclosed parameters $tokens = preg_split('/(")/', $this->attributes['authenticator_parameters'], -1, PREG_SPLIT_DELIM_CAPTURE); $outside = TRUE; $parameters = array(); foreach ($tokens as $token) { // sanity check --PREG_SPLIT_NO_EMPTY does not work if (!trim($token)) { // catch "" arguments (used for example as an empty password) if (!$outside) { $parameters[] = ""; } continue; } // begin or end of a token if ($token == '"') { $outside = !$outside; continue; } // outside, each word is a token if ($outside) { $parameters = array_merge($parameters, explode(' ', trim($token))); } else { $parameters[] = trim($token); } } // ensure a minimum number of parameters if (count($parameters) < 1) { Logger::error(i18n::s('Provide at least server name to the LDAP authenticator.')); return FALSE; } // prepare network parameters $server = $parameters[0]; if (strstr($server, ':')) { list($server, $port) = explode(':', $server, 2); } else { $port = 389; } // distinguished name used for bind $bind_dn = ''; if (isset($parameters[1])) { $bind_dn = str_replace('%u', $name, $parameters[1]); } // password used for bind $bind_password = ''; if (isset($parameters[2])) { $bind_password = str_replace('%p', $password, $parameters[2]); } // distinguished name used for search $search_dn = ''; if (isset($parameters[3])) { $search_dn = $parameters[3]; } // encode provided parameters to avoid LDAP injections $name = preg_replace('/([^a-zA-Z0-9\' ])/e', "chr(92).bin2hex('\$1')", $name); $password = preg_replace('/([^a-zA-Z0-9\' ])/e', "chr(92).bin2hex('\$1')", $password); // search expression $search_filter = ''; if (isset($parameters[4])) { $search_filter = str_replace(array('%u', '%p'), array($name, $password), $parameters[4]); } // parse options $opt_deref = LDAP_DEREF_NEVER; $opt_protocol_version = 3; $opt_sizelimit = 0; $opt_timelimit = 0; $opt_ldap_search_func = "ldap_search"; if (isset($parameters[5])) { $tokens = preg_split('/,/', $parameters[5], -1, PREG_SPLIT_NO_EMPTY); foreach ($tokens as $token) { $argerror = $valerror = 0; $argerror_s = $argerror_c = ''; list($key, $val) = explode('=', $token, 2); if (!strcasecmp($key, "DEREF")) { if (!strcasecmp($val, "never")) { $opt_deref = LDAP_DEREF_NEVER; } elseif (!strcasecmp($val, "always")) { $opt_deref = LDAP_DEREF_ALWAYS; } else { $valerror = 1; } } elseif (!strcasecmp($key, "PROTOCOL_VERSION")) { if ($val == 2 || $val == 3) { $opt_protocol_version = $val; } else { $valerror = 1; } } elseif (!strcasecmp($key, "SCOPE")) { if (!strcasecmp($val, "one")) { $opt_ldap_search_func = "ldap_list"; } elseif (!strcasecmp($val, "sub")) { $opt_ldap_search_func = "ldap_search"; } else { $valerror = 1; } } elseif (!strcasecmp($key, "SIZELIMIT")) { if (ctype_digit($val)) { $opt_sizelimit = $val; } else { $valerror = 1; } } elseif (!strcasecmp($key, "TIMELIMIT")) { if (ctype_digit($val)) { $opt_timelimit = $val; } else { $valerror = 1; } } else { $argerror_s = sprintf(i18n::s("Unknown LDAP option %s."), $key); $argerror_c = sprintf(i18n::c("Unknown LDAP option %s."), $key); $argerror = 1; } // a wrong value must trigger an error message if ($valerror) { $argerror_s = sprintf(i18n::s("LDAP %s: bad value '%s'."), $key, $val); $argerror_c = sprintf(i18n::c("LDAP %s: bad value '%s'."), $key, $val); $argerror = 1; } // print any error message raised while parsing the option if ($argerror) { Logger::error($argerror_s); if ($context['with_debug'] == 'Y') { Logger::remember('users/authenticators/ldap.php: ' . $argerror_c, '', 'debug'); } return FALSE; } } } // ensure we can move forward if (!is_callable('ldap_connect')) { Logger::error(i18n::s('Please activate the LDAP library.')); if ($context['with_debug'] == 'Y') { Logger::remember('users/authenticators/ldap.php: ' . i18n::c('Please activate the LDAP library.'), '', 'debug'); } return FALSE; } // open network socket if (!($handle = @ldap_connect($server, $port))) { Logger::error(sprintf(i18n::s('Impossible to connect to %.'), $server)); if ($context['with_debug'] == 'Y') { Logger::remember('users/authenticators/ldap.php: ' . sprintf(i18n::c('Impossible to connect to %.'), $server . ':' . $port), '', 'debug'); } return FALSE; } // set desired options @ldap_set_option($handle, LDAP_OPT_PROTOCOL_VERSION, $opt_protocol_version); @ldap_set_option($handle, LDAP_OPT_DEREF, $opt_deref); @ldap_set_option($handle, LDAP_OPT_SIZELIMIT, $opt_sizelimit); @ldap_set_option($handle, LDAP_OPT_TIMELIMIT, $opt_timelimit); // bind to directory, namely or anonymously if ($bind_dn && @ldap_bind($handle, $bind_dn, $bind_password)) { } elseif (!$bind_dn && @ldap_bind($handle)) { } else { Logger::error(sprintf(i18n::s('Impossible to bind to LDAP server %s.'), $server) . BR . ldap_errno($handle) . ': ' . ldap_error($handle)); if ($context['with_debug'] == 'Y') { Logger::remember('users/authenticators/ldap.php: ' . sprintf(i18n::c('Impossible to bind to LDAP server %s.'), $server . ' ' . $bind_dn . ' ' . $bind_password), ldap_errno($handle) . ': ' . ldap_error($handle), 'debug'); } ldap_close($handle); return FALSE; } // stop on successful bind if (!trim($search_filter)) { ldap_close($handle); return TRUE; } // search the directory if (!($result = @call_user_func($opt_ldap_search_func, $handle, $search_dn, $search_filter, array('cn')))) { Logger::error(sprintf(i18n::s('Impossible to search in LDAP server %s.'), $server) . BR . ldap_errno($handle) . ': ' . ldap_error($handle)); if ($context['with_debug'] == 'Y') { Logger::remember('users/authenticators/ldap.php: ' . sprintf(i18n::c('Impossible to search in LDAP server %s.'), $server), ldap_errno($handle) . ': ' . ldap_error($handle), 'debug'); } ldap_close($handle); return FALSE; } // successful match if (@ldap_first_entry($handle, $result) !== FALSE) { ldap_free_result($result); ldap_close($handle); return TRUE; } // authentication has failed if ($context['with_debug'] == 'Y') { Logger::remember('users/authenticators/ldap.php: ' . sprintf(i18n::c('No match for %s.'), $search_filter), '', 'debug'); } ldap_free_result($result); ldap_close($handle); return FALSE; }