summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThe Great Git Migration2003-07-02 17:09:10 +0000
committerThe Great Git Migration2003-07-02 17:09:10 +0000
commit9abd98139dbcc05f7fcadcc13950540f3c8a5e59 (patch)
tree41df42f78a21e37e3e6a825bbbac8f988e0d9570
parentd017514eba70ea4041218b943f01721cfd6e9b64 (diff)
This commit was manufactured as part of Drupal's Great Git Migration to
create branch 'DRUPAL-4-2'. Sprout from master 2003-07-02 17:09:09 UTC Dries Buytaert <dries@buytaert.net> '- Improvement: made it possible to translate the forum module. Patch #53 by Stefan.' Delete: modules/aggregator.module modules/aggregator/aggregator.module modules/archive/archive.module modules/block/block.module modules/blog/blog.module modules/book/book.module modules/comment/comment.module modules/drupal/drupal.module modules/forum/forum.module modules/help/help.module modules/locale/locale.module modules/node/node.module modules/page/page.module modules/ping/ping.module modules/poll/poll.module modules/profile/profile.module modules/search/search.module modules/statistics/statistics.module modules/story/story.module modules/system/system.module modules/taxonomy/taxonomy.module modules/throttle/throttle.module modules/tracker/tracker.module modules/user/user.module modules/watchdog/watchdog.module
-rw-r--r--modules/aggregator.module825
-rw-r--r--modules/aggregator/aggregator.module825
-rw-r--r--modules/archive/archive.module247
-rw-r--r--modules/block/block.module336
-rw-r--r--modules/blog/blog.module261
-rw-r--r--modules/book/book.module787
-rw-r--r--modules/comment/comment.module1549
-rw-r--r--modules/drupal/drupal.module196
-rw-r--r--modules/forum/forum.module728
-rw-r--r--modules/help/help.module56
-rw-r--r--modules/locale/locale.module301
-rw-r--r--modules/node/node.module1481
-rw-r--r--modules/page/page.module145
-rw-r--r--modules/ping/ping.module74
-rw-r--r--modules/poll/poll.module387
-rw-r--r--modules/profile/profile.module294
-rw-r--r--modules/search/search.module395
-rw-r--r--modules/statistics/statistics.module855
-rw-r--r--modules/story/story.module84
-rw-r--r--modules/system/system.module334
-rw-r--r--modules/taxonomy/taxonomy.module817
-rw-r--r--modules/throttle/throttle.module126
-rw-r--r--modules/tracker/tracker.module93
-rw-r--r--modules/user/user.module1876
-rw-r--r--modules/watchdog/watchdog.module110
25 files changed, 0 insertions, 13182 deletions
diff --git a/modules/aggregator.module b/modules/aggregator.module
deleted file mode 100644
index 1926605..0000000
--- a/modules/aggregator.module
+++ /dev/null
@@ -1,825 +0,0 @@
-<?php
-// $Id$
-
-
-function import_help() {
- $output .= "<p>Thousands of web sites, especially news sites and weblogs, syndicate their most recent site content for others to display. The syndicated content always includes titles, also known as headlines, for the newest published stories. Each headline acts as a direct link to the stories on the remote site. Along with the headline, most sites typically provide either the first few paragraphs of the story or a short summary. Many individuals use client-based news aggregators on their personal computer to aggregate content, such as <a href=\"http://www.disobey.com/amphetadesk/\">AmphetaDesk</a>.</p>";
-
- $output .= "<p>Drupal also has a news aggregator built in as a standard feature. With it, you can subscribe to feeds from other sites and display their content for your site users. Simply enable the import module in site administration and enter the feeds that you choose.</p>";
- $output .= "<h3>What do I need to subscribe to a feed?</h3>";
- $output .= "<p>The standard method of syndication is using the XML-based <a href=\"http://groups.yahoo.com/group/rss-dev/files/specification.html\">Rich Site Summary</a> (RSS). To syndicate a site's content, obtain the full URL of the RSS page providing syndication. Common file tags for RSS pages are .rss, .xml and .rdf. Example: <a href=\"http://slashdot.org/slashdot.rdf\">http://slashdot.org/slashdot.rdf</a>.</p>";
- $output .= "<p>Most weblog sites that offer syndication will have an obvious link on the main page. Often you need only look for an xml syndication button, such as the one Drupal uses for site syndication.</p>";
- $output .= "<p>But some sites do not make their RSS feeds as easy to find. Or maybe you want to find a number of feeds on a given topic, without extensively searching the web. In that case, try an RSS syndication directory such as <a href=\"http://www.syndic8.com/\">Syndic8</a>.</p>";
- $output .= "<p>To learn much more about RSS, read Mark Pilgrim's <a href=\"http://www.xml.com/pub/a/2002/12/18/dive-into-xml.html\">What is RSS</a> and WebReference.com's <a href=\"http://www.webreference.com/authoring/languages/xml/rss/1/\">The Evolution of RSS</a>.</p>";
- $output .= "<p>NOTE: Enable your site's xml syndication button by turning on the Syndicate block in block management.</p>";
- $output .= "<h3>Configuring news feeds</h3>";
- $output .= "<p>To subscribe to an RSS feed on another site, use the <i>administer news feeds</i> shortcut at the top of the news aggregation page. The link leads directly to the news aggregation configuration section of Drupal site administration.</p>";
- $output .= "<p>Once there, select <i>add new feed</i> from the left hand menu. Drupal will then ask for the following:</p>";
- $output .= "<ul>";
- $output .= " <li><b>Title</b> -- The text entered here will be used in your news aggregator, within the administration configuration section, and as title for the news feed block. As a general rule, use the web site name from which the feed originates.</li>";
- $output .= " <li><b>URL</b> -- Here you'll enter the fully-qualified URL for the feed for the site you want to subscribe to.</li>";
- $output .= " <li><b>Attributes</b> -- Attributes are keywords which can be used to collect feeds into <i>bundles</i> (see below). Think of these as the means of classifying your feeds. Separate multiple attributes with commas. If you do not plan on using the specific feed in a bundle, this input field can be left blank.</li>";
- $output .= " <li><b>Update interval</b> -- The update interval is how often Drupal will automatically access the RSS URL for the site for fresh content. The 1 hour default is typically the minimum you will want to use. Accessing another site's RSS page more frequently can be considered impolite. After all, it does require the other site's server to handle your automatic requests. To take advantage of this feature, note that cron.php must be configured to have your feeds updated regularly. Otherwise, you'll have to manually update feeds one at a time within the news aggregation administration section by using <i>update items</i>.</li>";
- $output .= "</ul>";
- $output .= "<p>Once you submit your new feed, check to see if it is working properly. Select <i>update items </i> on the main news aggregation page. If you do not see any items listed for that feed, edit the feed and make sure that the URL was entered correctly.</p>";
- $output .= "<h3>Adding bundles</h3>";
- $output .= "<p>You may want to follow some feeds more closely than others. Or perhaps you'd like to display a select list of the titles for some feeds as a block for users. Bundles are a way of grouping your feeds into categories. Bundles look for feeds that contain at least one of the keywords, or attributes, associated with the bundle and display those feeds together.</p>";
- $output .= "<p>When adding a bundle, Drupal will ask for:</p>";
- $output .= "<ul>";
- $output .= " <li><b>Title</b> -- The title will be used in the <i>news by topics</i> listing in your news aggregator and with the customized block created for the bundle.</li>";
- $output .= " <li><b>Attributes</b> -- Enter one or more of the attributes used to categorize the news feeds already created. Separate multiple attributes with commas. Be careful to use the same spelling. Don't have any feeds with attributes for the bundle? After creating the bundle, edit existing feeds or create new ones and tag them with the attribute.</li>";
- $output .= "</ul>";
- $output .= "<h3>Using the news aggregator</h3>";
- $output .= "<p>The news aggregator has a number of ways that it displays your subscribed content:</p>";
- $output .= "<ul>";
- $output .= " <li><b>Latest news</b> -- Displays all incoming content in the order received with:";
- $output .= " <ul>";
- $output .= " <li>The title of the original post.</li>";
- $output .= " <li>The name of the source, which acts as a link to an individual feed page, listing information about that feed and incoming content for that feed only.</li>";
- $output .= " <li>A description, the first few paragraphs or summary of the originating post (if any).</li>";
- $output .= " <li>A <i>blog it</i> link. Users can select this link to have Drupal automatically prepare a blog post for the specific item.</li>";
- $output .= " <li>A <i>feed</i> link, which acts as a link to an individual feed page, listing information about that feed and incoming content for that feed only.</li>";
- $output .= " </ul>";
- $output .= " </li>";
- $output .= " <li><b>News by source -- </b>Organizes incoming content by feed, displaying titles which link to the originating post. Also has an icon which acts as blog it link.</li>";
- $output .= " <li><b>News by topic</b> -- Organizes incoming content by bundles, displaying titles which link to the originating post. Also has an icon which acts as
- blog it link.</li>";
- $output .= " <li><b>News sources</b> -- Displays an alphabetical listing of all subscribed feeds and a description. The title acts as a link to an individual feed page, listing information about that feed and incoming content for that feed only.</li>";
- $output .= "</ul>";
- $output .= "<h3>RSS feed blocks</h3>";
- $output .= "<p>In addition to providing subscribed content through the news aggregator, Drupal automatically creates a block for each subscribed feed and every bundle created. Beside each headline in each block, Drupal includes an icon which acts a blog it link. Enable any or all of the blocks using block management.</p>";
- return $output;
-}
-
-function import_system($field){
- $system["description"] = t("Used to aggregate syndicated content (RSS and RDF).");
- $system["admin_help"] = t("Drupal's news aggregator controls how many RSS/RDF items from a single source are displayed in a \"Block\", and on the page that goes with that block.");
- return $system[$field];
-}
-
-function import_settings() {
- $number = array(5 => 5, 10 => 10, 15 => 15, 20 => 20, 25 => 25, 30 => 30, 35 => 35, 40 => 40, 45 => 45, 50 => 50, 55 => 55, 60 => 60, 65 => 65, 70 => 70, 75 => 75, 80 => 80, 85 => 85, 90 => 90, 95 => 95, 100 => 100);
- $output .= form_select("Items per block", "import_block_limit", variable_get("import_block_limit", 15), $number, "The maximum number of news items displayed in one block.");
- $output .= form_select("Items per page", "import_page_limit", variable_get("import_page_limit", 75), $number, "The maximum number of news items displayed on one page.");
-
- return $output;
-}
-
-function import_perm() {
- return array("administer news feeds", "access news feeds");
-}
-
-function import_link($type) {
-
- $links = array();
-
- if ($type == "page" && user_access("access news feeds")) {
- $links[] = l(t("news feeds"), "import", array("title" => t("Read the latest news from syndicated web sites.")));
- }
-
- if ($type == "admin" && user_access("administer news feeds")) {
- $help["general"] = t("Several web sites, especially news related sites, syndicate parts of their site's content for other web sites to display. Usually, the syndicated content includes the latest headlines with a direct link to that story on the remote site. Some syndicated content also includes a description of the headline. The standard method of syndication is using the XML based Rich Site Summary (RSS). To get a feed to work you <b>must</b> run \"cron.php\". To display the feed in a block you must turn on the <a href=\"%block\">feed's block</a>. <br /><ul><li>To delete a feed choose \"edit feed\"</li><li>To clear all of the entries from a feed choose \"Remove items\"</li><li>To check whether a feed is working, and to get new items <b>now</b> click on \"update items\"</li></ul><ul><li>To delete a bundle choose \"edit bundle\".</li></ul>", array("%block" => url("admin/block")));
- $help["addfeed"] = t("Add a site to that has an RSS/RDF feed. The URL is the full path to the RSS feed file. For the feed to update you must run \"cron.php\". The \"Attributes\" are used to bundle this feed with other feeds (See <a href=\"%bundle\">add new bundle</a>, and to tag articles from this feed.<br />Note: If you already have another feed with the URL you are planning to use, the system will not accept your entry.", array("%bundle" => url("admin/syndication/news/add/bundle")));
- $help["bundles"] = t("Bundles provide a generalized way of creating composite feeds. They allow you, for example, to combine various sport-related feeds into one bundle called <i>Sport</i>. If an article from a feed has been \"tag\"-ged (See <a href=\"%tag\">tag news item</a> too look at and change tags.) with a matching \"Attribute\" then it will be added to the bundle.", array("%tag" => url("admin/syndication/news/tag")));
- $help["tag"] = t("This allows you to see and change an news item's \"tag\". All articles are originally tagged with the \"Attributes\" of their feed.");
-
- menu("admin/syndication", "content syndication", NULL, NULL, 5);
- menu("admin/syndication/news", "news aggregation", "import_admin", $help["general"]);
- menu("admin/syndication/news/add/feed", "add new feed", "import_admin", $help["addfeed"], 2);
- menu("admin/syndication/news/add/bundle", "add new bundle", "import_admin", $help["bundles"], 3);
- menu("admin/syndication/news/tag", "tag news items", "import_admin", $help["tag"], 4);
- menu("admin/syndication/news/help", "help", "import_help", NULL, 9);
- }
-
- return $links;
-}
-
-function import_cron() {
- $result = db_query("SELECT * FROM feed WHERE timestamp + refresh < ". time());
- while ($feed = db_fetch_array($result)) {
- import_refresh($feed);
- }
-}
-
-function import_update() {
- $result = db_query("SELECT * FROM feed");
- while ($feed = db_fetch_array($result)) {
- import_refresh($feed);
- }
-}
-
-function import_format_item($item, $feed = 0) {
- global $user;
-
- if ($user->uid && user_access("maintain personal blog")) {
- $output .= "<div class=\"icon\">". l("<img src=\"". theme("image", "blog.gif") ."\" alt=\"". t("blog it") ."\" title=\"". t("blog it") ."\" />", "node/add/blog&amp;iid=$item->iid", array("title" => t("Comment on this news item in your personal blog."), "class" => "blog-it")) ."</div>";
- }
-
- // external link
- $output .= "<a href=\"$item->link\">$item->title</a>";
-
- return $output;
-}
-
-function import_bundle_block($attributes) {
-
- if ($attributes) {
- $keys = explode(",", $attributes);
- foreach ($keys as $key) $where[] = "attributes LIKE '%". trim($key) ."%'";
-
- $result = db_query_range("SELECT * FROM item WHERE ". implode(" OR ", $where) ." ORDER BY iid DESC", 0, variable_get("import_block_limit", 15));
- }
-
- $items = array();
- while ($item = db_fetch_object($result)) {
- $items[] = import_format_item($item);
- }
-
- $output = "<div class=\"import-block\"><div class=\"bundle\">";
- $output .= theme("theme_item_list", $items);
- $output .= "</div></div>";
-
- return $output;
-}
-
-function import_feed_block($feed) {
- $result = db_query_range("SELECT * FROM item WHERE fid = %d ORDER BY iid DESC ", $feed->fid, 0, variable_get("import_block_limit", 15));
-
- $items = array();
- while ($item = db_fetch_object($result)) {
- $items[] = import_format_item($item);
- }
-
- $output = "<div class=\"import-block\"><div class=\"feed\">";
- $output .= theme("theme_item_list", $items);
- $output .= "</div></div>";
-
- return $output;
-}
-
-function import_block($op, $delta) {
- if ($op == "list") {
- $result = db_query("SELECT * FROM bundle ORDER BY title");
- while ($bundle = db_fetch_object($result)) {
- $block["bundle:$bundle->bid"]["info"] = "$bundle->title bundle";
- }
-
- $result = db_query("SELECT * FROM feed ORDER BY fid");
- while ($feed = db_fetch_object($result)) {
- $block["feed:$feed->fid"]["info"] = "$feed->title feed";
- }
-
- return $block;
- }
- else {
- list($type, $id) = split(":", $delta);
- switch ($type) {
- case "feed":
- $feed = db_fetch_object(db_query("SELECT * FROM feed WHERE fid = %d", $id));
- $block["subject"] = $feed->title;
- $block["content"] .= import_feed_block($feed) ."<div style=\"text-align: right;\">". l(t("more"), "import/feed/$feed->fid", array("title" => t("View this feed's recent news."))) ."</div>";
- break;
-
- case "bundle":
- $bundle = db_fetch_object(db_query("SELECT * FROM bundle WHERE bid = %d", $id));
- $block["subject"] = $bundle->title;
- $block["content"] .= import_bundle_block($bundle->attributes) ."<div style=\"text-align: right;\">". l(t("more"), "import/bundle/$bundle->bid", array("title" => t("View this bundle's recent news."))) ."</div>";
- break;
- }
-
- return $block;
- }
-}
-
-function import_get_bundles($attributes = 0) {
-
- $block = array();
-
- $result = db_query("SELECT * FROM bundle ORDER BY title");
- while ($bundle = db_fetch_object($result)) {
- $block["bundle:$bundle->bid"]["subject"] = $bundle->title;
- $block["bundle:$bundle->bid"]["content"] = import_bundle_block($bundle->attributes) ."<div style=\"text-align: right;\">".
- l(t("more"), "import/bundle/$bundle->bid", array("title" => t("View this bundle's recent news.")))
- ."</div>";
- $block["bundle:$bundle->bid"]["info"] = "$bundle->title bundle";
- }
-
- return $block;
-}
-
-function import_get_feeds($attributes = 0) {
-
- $block = array();
-
- $result = db_query("SELECT * FROM feed ORDER BY fid");
- while ($feed = db_fetch_object($result)) {
- $block["feed:$feed->fid"]["subject"] = $feed->title;
- $block["feed:$feed->fid"]["content"] = import_feed_block($feed) ."<div style=\"text-align: right;\">".
- l(t("more"), "import/feed/$feed->fid", array("title" => t("View this feed's recent news.")))
- ."</div>";
- $block["feed:$feed->fid"]["info"] = "$feed->title feed";
- }
-
- return $block;
-}
-
-function import_remove($feed) {
- db_query("DELETE FROM item WHERE fid = %d", $feed["fid"]);
- return t("removed news items from '%site'.", array("%site" => $feed["title"]));
-}
-
-// Call-back function used by XML parser:
-function import_element_start($parser, $name, $attributes) {
- global $item, $element, $tag;
-
- switch ($name) {
- case "IMAGE":
- case "TEXTINPUT":
- $element = $name;
- break;
- case "ITEM":
- $element = $name;
- $item += 1;
- }
-
- $tag = $name;
-}
-
-// Call-back function used by XML parser:
-function import_element_end($parser, $name) {
- global $element;
-
- switch ($name) {
- case "IMAGE":
- case "TEXTINPUT":
- case "ITEM":
- $element = "";
- }
-}
-
-// Call-back function used by XML parser:
-function import_element_data($parser, $data) {
- global $channel, $element, $items, $item, $tag;
-
- switch ($element) {
- case "ITEM":
- $items[$item][$tag] .= $data;
- break;
- case "IMAGE":
- case "TEXTINPUT":
- /*
- ** The sub-elements "image" and "textinput" are not supported
- ** but we have recognize them or their content will end up in
- ** the items-array.
- */
- break;
- default:
- $channel[$tag] .= $data;
- }
-}
-
-function import_refresh($feed) {
-
- // unset the global variables before we use them:
- unset($GLOBALS["channel"], $GLOBALS["element"], $GLOBALS["item"], $GLOBALS["items"], $GLOBALS["tag"]);
-
- // after we unset the variables, we can global them again:
- global $items, $channel;
-
- /*
- ** Check whether the feed is properly configured:
- */
-
- if (!ereg("^http://|ftp://", $feed["url"])) {
- return t("failed to parse RSS feed '%site': incorrect or missing URL.", array("%side" => $feed["title"]));
- }
-
- /*
- ** Grab the news items:
- */
-
- if ($fp = @fopen($feed["url"], "r")) {
- // fetch data:
- while (!feof($fp)) {
- $data .= fgets($fp, 128);
- }
- fclose($fp);
-
- // filter the input data:
- xss_check_input_data($data);
-
- // parse the data:
- $xml_parser = xml_parser_create();
- xml_set_element_handler($xml_parser, "import_element_start", "import_element_end");
- xml_set_character_data_handler($xml_parser, "import_element_data");
- xml_parser_set_option($xml_parser, XML_OPTION_TARGET_ENCODING, "utf-8");
-
- if (!xml_parse($xml_parser, $data, 1)) {
- return t("failed to parse RSS feed '%site': %error at line %line.", array("%site" => $feed["title"], "%error" => xml_error_string(xml_get_error_code($xml_parser)), "%line" => xml_get_current_line_number($xml_parser)));
- }
- xml_parser_free($xml_parser);
-
- // initialize the translation table:
- $tt = array_flip(get_html_translation_table(HTML_ENTITIES));
- $tt["&apos;"] = "'";
-
- db_query("UPDATE feed SET timestamp = %d, link = '%s', description = '%s' WHERE fid = %d", time(), $channel["LINK"], $channel["DESCRIPTION"], $feed["fid"]);
-
- /*
- ** We reverse the array such that we store the first item last,
- ** and the last item first. In the database, the newest item
- ** should be at the top.
- */
-
- $items = array_reverse($items);
-
- foreach ($items as $item) {
- unset($title, $link, $author, $description);
-
- // Prepare the item:
- foreach ($item as $key => $value) {
- $item[$key] = node_filter(strtr(trim($value), $tt));
- }
-
- if ($item["TITLE"]) {
- $title = $item["TITLE"];
- }
- else {
- /*
- ** Use up to 40 characters of the description, ending at
- ** word boundary, but don't split potential entities.
- */
- $title = preg_replace('/^(.*)[^\w;&].*?$/', "\\1", substr($item["DESCRIPTION"], 0, 40));
- }
-
- if ($item["LINK"]) {
- $link = $item["LINK"];
- }
- elseif ($item["GUID"] && (strncmp($item["GUID"], "http://", 7) == 0)) {
- $link = $item["GUID"];
- }
- else {
- $link = $feed["link"];
- }
-
- /*
- ** Save this item. Try to avoid duplicate entries as much as
- ** possible. If we find a duplicate entry, we resolve it and
- ** pass along it's ID such that we can update it if needed.
- */
-
- if ($link && $link != $feed["link"] && $link != $feed["url"]) {
- $entry = db_fetch_object(db_query("SELECT iid FROM item WHERE fid = %d AND link = '%s'", $feed["fid"], $link));
- }
- else {
- $entry = db_fetch_object(db_query("SELECT iid FROM item WHERE fid = %d AND title = '%s'", $feed["fid"], $title));
- }
-
- import_save_item(array(iid => $entry->iid, fid => $feed["fid"], title => $title, link => $link, author => $item["AUTHOR"], description => $item["DESCRIPTION"], attributes => $feed["attributes"]));
- }
-
- /*
- ** Remove all the old, expired items:
- */
-
- unset($items);
-
- $result = db_query("SELECT iid FROM item WHERE fid = %d ORDER BY timestamp", $feed["fid"]);
-
- while ($item = db_fetch_object($result)) {
- $items[] = "iid = '$item->iid'";
- }
-
- if (sizeof($items) > 50) {
- db_query("DELETE FROM item WHERE ". implode(" OR ", array_slice($items, 0, - 50)));
- }
-
- cache_clear_all();
- }
- else {
- return t("failed to parse RSS feed '%site': no data.", array("%site" => $feed["tite"]));
- }
-
- return t("syndicated content from '%site'.", array("%site" => $feed["title"]));
-}
-
-function import_save_item($edit) {
- if ($edit["iid"] && $edit["title"]) {
- db_query("UPDATE item SET title = '%s', link = '%s', author = '%s', description = '%s', attributes = '%s' WHERE iid = %d", $edit["title"], $edit["link"], $edit["author"], $edit["description"], $edit["attributes"], $edit["iid"]);
- }
- else if ($edit["iid"]) {
- db_query("DELETE FROM item WHERE iid = %d", $edit["iid"]);
- }
- else if ($edit["title"] && $edit["link"]) {
- db_query("INSERT INTO item (fid, title, link, author, description, attributes, timestamp) VALUES (%d, '%s', '%s', '%s', '%s', '%s', %d)", $edit["fid"], $edit["title"], $edit["link"], $edit["author"], $edit["description"], $edit["attributes"], time());
- }
-}
-
-function import_form_bundle($edit = array()) {
-
- $form .= form_textfield("Title", "title", $edit["title"], 50, 64, "The name of the bundle.");
- $form .= form_textfield("Attributes", "attributes", $edit["attributes"], 50, 128, "A comma-separated list of keywords describing the bundle.");
-
- $form .= form_submit("Submit");
-
- if ($edit["bid"]) {
- $form .= form_submit("Delete");
- $form .= form_hidden("bid", $edit["bid"]);
- }
-
- return form($form);
-}
-
-function import_save_bundle($edit) {
- if ($edit["bid"] && $edit["title"]) {
- db_query("UPDATE bundle SET title = '%s', attributes = '%s' WHERE bid = %d", $edit["title"], $edit["attributes"], $edit["bid"]);
- }
- else if ($edit["bid"]) {
- db_query("DELETE FROM bundle WHERE bid = %d", $edit["bid"]);
- }
- else if ($edit["title"]) {
- // a single unique id for bundles and feeds, to use in blocks
- $next_id = db_next_id("bundle_bid");
- db_query("INSERT INTO bundle (bid, title, attributes) VALUES (%d, '%s', '%s')", $next_id, $edit["title"], $edit["attributes"]);
- }
-}
-
-function import_form_feed($edit = array()) {
-
- $period = array(900 => format_interval(900), 1800 => format_interval(1800), 3600 => format_interval(3600), 7200 => format_interval(7200), 10800 => format_interval(10800), 21600 => format_interval(21600), 32400 => format_interval(32400), 43200 => format_interval(43200), 64800 => format_interval(64800), 86400 => format_interval(86400), 172800 => format_interval(172800), 259200 => format_interval(259200), 604800 => format_interval(604800), 1209600 => format_interval(1209600), 2419200 => format_interval(2419200));
-
- if ($edit["refresh"] == "") {
- $edit["refresh"] = 3600;
- }
-
- $form .= form_textfield("Title", "title", $edit["title"], 50, 64, "The name of the feed; typically the name of the web site you syndicate content from.");
- $form .= form_textfield("Url", "url", $edit["url"], 50, 128, "The fully-qualified URL of the feed.");
- $form .= form_textfield("Attributes", "attributes", $edit["attributes"], 50, 128, "A comma-separated list of keywords describing the feed.");
- $form .= form_select("Update interval", "refresh", $edit["refresh"], $period, "The refresh interval indicating how often you want to update this feed. Requires crontab.");
-
- $form .= form_submit("Submit");
-
- if ($edit["fid"]) {
- $form .= form_submit("Delete");
- $form .= form_hidden("fid", $edit["fid"]);
- }
-
- return form($form);
-}
-
-function import_save_feed($edit) {
- if ($edit["fid"] && $edit["title"]) {
- db_query("UPDATE feed SET title = '%s', url = '%s', attributes = '%s', refresh = %d WHERE fid = %d", $edit["title"], $edit["url"], $edit["attributes"], $edit["refresh"], $edit["fid"]);
- db_query("DELETE FROM item WHERE fid = %d", $edit["fid"]);
- }
- else if ($edit["fid"]) {
- db_query("DELETE FROM feed WHERE fid = %d", $edit["fid"]);
- db_query("DELETE FROM item WHERE fid = %d", $edit["fid"]);
- }
- else if ($edit["title"]) {
- // a single unique id for bundles and feeds, to use in blocks
- $next_id = db_next_id("feed_fid");
- db_query("INSERT INTO feed (fid, title, url, attributes, refresh) VALUES (%d, '%s', '%s', '%s', %d)", $next_id, $edit["title"], $edit["url"], $edit["attributes"], $edit["refresh"]);
- }
-}
-
-function import_save_attributes($edit) {
- foreach ($edit as $iid => $value) {
- db_query("UPDATE item SET attributes = '%s' WHERE iid = %d", $value, $iid);
- }
- return "attributes has been saved";
-}
-
-function import_get_feed($fid) {
- return db_fetch_array(db_query("SELECT * FROM feed WHERE fid = %d", $fid));
-}
-
-function import_get_bundle($bid) {
- return db_fetch_array(db_query("SELECT * FROM bundle WHERE bid = %d", $bid));
-}
-
-function import_view() {
- $result = db_query("SELECT f.*, COUNT(i.iid) AS items FROM feed f LEFT JOIN item i ON f.fid = i.fid GROUP BY f.fid, f.title, f.url, f.refresh, f.timestamp, f.attributes, f.link, f.description ORDER BY f.title");
-
- $output .= "<h3>Feed overview</h3>";
-
- $header = array(t("title"), t("attributes"), t("items"), t("last update"), t("next update"), array("data" => t("operations"), "colspan" => 3));
- unset($rows);
- while ($feed = db_fetch_object($result)) {
- $rows[] = array($feed->title, $feed->attributes, format_plural($feed->items, "1 item", "%count items"), ($feed->timestamp ? format_interval(time() - $feed->timestamp) ." ago" : "never"), ($feed->timestamp ? format_interval($feed->timestamp + $feed->refresh - time()) ." left" : "never"), l(t("edit feed"), "admin/syndication/news/edit/feed/$feed->fid"), l(t("remove items"), "admin/syndication/news/remove/$feed->fid"), l(t("update items"), "admin/syndication/news/update/$feed->fid"));
- }
- $output .= table($header, $rows);
-
- $result = db_query("SELECT * FROM bundle ORDER BY title");
-
- $output .= "<h3>Bundle overview</h3>";
-
- $header = array(t("title"), t("attributes"), t("operations"));
- unset($rows);
- while ($bundle = db_fetch_object($result)) {
- $rows[] = array($bundle->title, $bundle->attributes, l(t("edit bundle"), "admin/syndication/news/edit/bundle/$bundle->bid"));
- }
- $output .= table($header, $rows);
-
- return $output;
-}
-
-function import_tag() {
-
- $result = db_query_range("SELECT i.*, f.title AS feed FROM item i LEFT JOIN feed f ON i.fid = f.fid ORDER BY i.iid DESC", 0, 50);
-
- $header = array(t("date"), t("feed"), t("news item"));
- while ($item = db_fetch_object($result)) {
- $rows[] = array(array("data" => format_date($item->timestamp, "small"), "nowrap" => "nowrap", "valign" => "top"), array("data" => l($item->feed, "admin/syndication/news/edit/feed/$item->fid"), "valign" => "top"), "<a href=\"$item->link\">$item->title</a>". ($item->description ? "<br /><small><i>$item->description</i></small>" : "") ."<br /><input type=\"text\" name=\"edit[$item->iid]\" value=\"". check_form($item->attributes) ."\" size=\"50\" />");
- }
-
- $output .= table($header, $rows);
- $output .= "<input type=\"submit\" name=\"op\" value=\"Save attributes\" />\n";
-
- return form($output);
-}
-
-function import_admin() {
- $op = $_POST["op"];
- $edit = $_POST["edit"];
-
- if (user_access("administer news feeds")) {
-
- if (empty($op)) {
- $op = arg(3);
- }
-
- switch ($op) {
- case "add":
- if (arg(4) == "bundle") {
- print import_form_bundle();
- }
- else {
- print import_form_feed();
- }
- break;
- case "edit":
- if (arg(4) == "bundle") {
- print import_form_bundle(import_get_bundle(arg(5)));
- }
- else {
- print import_form_feed(import_get_feed(arg(5)));
- }
- break;
- case "remove":
- print status(import_remove(import_get_feed(arg(4))));
- print import_view();
- break;
- case "update":
- print status(import_refresh(import_get_feed(arg(4))));
- print import_view();
- break;
- case "tag":
- print import_tag();
- break;
- case "Save attributes":
- print status(import_save_attributes($edit));
- print import_tag();
- break;
- case "Delete":
- $edit["title"] = 0;
- // fall through:
- case "Submit":
- if (arg(4) == "bundle") {
- print status(import_save_bundle($edit));
- }
- else {
- print status(import_save_feed($edit));
- }
- // fall through:
- default:
- print import_view();
- }
- }
- else {
- print message_access();
- }
-}
-
-function import_page_info() {
-
-
- $links[] = l(t("latest news"), "import", array("title" => t("Read the latest news from syndicated web sites.")));
- $links[] = l(t("news by source"), "import/feeds", array("title" => t("View the latest headlines sorted by source.")));
- $links[] = l(t("news by topic"), "import/bundles", array("title" => t("View the latest headlines sorted by topic.")));
- $links[] = l(t("news sources"), "import/sources", array("title" => t("View a list of all the web sites we syndicate from.")));
-
- if (user_access("administer news feeds")) {
- $links[] = l(t("administer news feeds"), "admin/syndication/news", array("title" => t("View the news feed administrative pages.")));
- }
-
- return "<div style=\"text-align: center;\">". theme("links", $links) ."</div>";
-}
-
-function import_page_last() {
-
-
- $result = db_query_range("SELECT i.*, f.title AS ftitle, f.link AS flink FROM item i LEFT JOIN feed f ON i.fid = f.fid ORDER BY i.iid DESC", 0, variable_get("import_page_limit", 75));
-
- $output .= "<table border=\"0\" cellpadding=\"4\" cellspacing=\"2\">";
- while ($item = db_fetch_object($result)) {
- if (module_exist("blog") && user_access("maintain personal blog")) {
- $links[] = l(t("blog it"), "node/add/blog", array("title" => t("Comment on this news item in your personal blog.")), "iid=$item->iid");
- }
- $links[] = l(t("feed"), "import/feed/$item->fid", array("title" => t("Read more syndicated news from this feed.")));
-
- if ($item->link) {
- $output .= "<tr><td><a href=\"$item->link\">$item->title</a> &middot; ". l($item->ftitle, "import/feed/$item->fid", array("title" => t("View more information about this feed."))) ."</td><td style=\"text-align: right; vertical-align: top;\">". theme("links", $links) ."</td></tr>\n";
- }
-
- if ($item->description) {
- $output .= "<tr><td colspan=\"2\"><div style=\"margin-left: 20px;\">$item->description</div><br /></td></tr>";
- }
-
- unset($links);
- }
- $output .= "</table>\n";
-
- theme("header");
- theme("box", t("News feeds"), import_page_info());
- theme("box", t("Latest news"), $output);
- theme("footer");
-}
-
-function import_page_feed($fid) {
-
-
- $feed = db_fetch_object(db_query("SELECT * FROM feed WHERE fid = %d", $fid));
-
- $header .= "<p><b>". t("Website") .":</b><div style=\"margin-left: 20px;\"><a href=\"$feed->link\">$feed->link</a></div></p>";
- $header .= "<p><b>". t("Description") .":</b><div style=\"margin-left: 20px;\">$feed->description</div></p>";
- $header .= "<p><b>". t("Last update") .":</b><div style=\"margin-left: 20px; text-align: right;\">". format_interval(time() - $feed->timestamp) ." ". t("ago") ." <a href=\"$feed->url\"><img src=\"". theme("image", "xml.gif") ."\" width=\"36\" height=\"14\" style=\"border: 0px;\" alt=\"\" title=\"\" /></a><br /><br /></div></p>\n";
-
- $result = db_query_range("SELECT * FROM item WHERE fid = %d ORDER BY iid DESC", $fid, 0, variable_get("import_page_limit", 75));
-
- $output .= "<table border=\"0\" cellpadding=\"4\" cellspacing=\"2\">";
- while ($item = db_fetch_object($result)) {
- if (module_exist("blog") && user_access("maintain personal blog")) {
- $links[] = l(t("blog it"), "node/add/blog", array("title" => t("Comment on this news item in your personal blog.")), "iid=$item->iid");
- }
- $links[] = "<a href=\"$item->link\">". t("visit") ."</a>";
-
- if ($item->link) {
- $output .= "<tr><td><a href=\"$item->link\">$item->title</a></td><td style=\"text-align: right; vertical-align: top;\">". theme("links", $links) ."</td></tr>\n";
- }
- if ($item->description) {
- $output .= "<tr><td colspan=\"2\"><div style=\"margin-left: 20px;\">$item->description</div><br /></td></tr>";
- }
-
- unset($links);
- }
- $output .= "</table>\n";
-
- theme("header");
- theme("box", t("News feeds"), import_page_info());
- theme("box", $feed->title, $header);
- theme("box", t("Latest news"), $output);
- theme("footer");
-}
-
-function import_page_bundle($bid) {
-
-
- $bundle = db_fetch_object(db_query("SELECT * FROM bundle WHERE bid = %d", $bid));
-
- $header .= "<p><b>". t("Website") .":</b><div style=\"margin-left: 20px;\">". l($bundle->title, "import/bundle/$bundle->bid") ."</div></p>";
- $header .= "<p><b>". t("Description") .":</b><div style=\"margin-left: 20px;\">". t("A composite news feed about") ." $bundle->attributes.</div></p>";
-
- $keys = explode(",", $bundle->attributes);
- foreach ($keys as $key) $where[] = "i.attributes LIKE '%". trim($key) ."%'";
- $result = db_query_range("SELECT i.*, f.title AS ftitle, f.link AS flink FROM item i, feed f WHERE (". implode(" OR ", $where) .") AND i.fid = f.fid ORDER BY iid DESC", 0, variable_get("import_page_limit", 75));
-
- $output .= "<table border=\"0\" cellpadding=\"4\" cellspacing=\"2\">";
- while ($item = db_fetch_object($result)) {
- if (module_exist("blog") && user_access("maintain personal blog")) {
- $links[] = l(t("blog it"), "node/add/blog", array("title" => t("Comment on this news item in your personal blog.")), "iid=$item->iid");
- }
- $links[] = l(t("feed"), "import/feed/$item->fid", array("title" => t("Read more syndicated news from this feed.")));
- $links[] = "<a href=\"$item->link\">". t("visit") ."</a>";
-
- if ($item->link) {
- $output .= "<tr><td><a href=\"$item->link\">$item->title</a> &middot; ". l($item->ftitle, "import/feed/$item->fid", array("title" => t("View more information about this feed."))) ."</td><td style=\"text-align: right; vertical-align: top;\">". theme("links", $links) ."</td></tr>\n";
- }
-
- if ($item->description) {
- $output .= "<tr><td colspan=\"2\"><div style=\"margin-left: 20px;\">$item->description</div><br /></td></tr>";
- }
-
- unset($links);
- }
- $output .= "</table>\n";
-
- theme("header");
- theme("box", t("News feeds"), import_page_info());
- theme("box", $bundle->title, $header);
- theme("box", t("Latest news"), $output);
- theme("footer");
-
-}
-
-function import_page_sources() {
-
-
- $result = db_query("SELECT * FROM feed ORDER BY title");
-
- while ($feed = db_fetch_object($result)) {
- $output .= l($feed->title, "import/feed/$feed->fid");
- $output .= "<div style=\"margin-left: 20px;\">$feed->description</div><br />";
- }
-
- $output .= "<div style=\"text-align: right\">" . l("<img src=\"". theme("image", "xml.gif") ."\" width=\"36\" height=\"14\" style=\"border: 0px;\" />", "import/fd", array("title" => t("View the list of syndicated web sites in XML format."))) . "</div><br />";
-
- theme("header");
- theme("box", t("News feeds"), import_page_info());
- theme("box", t("News sources"), $output);
- theme("footer");
-}
-
-function import_page_fd() {
-
- $result = db_query("SELECT * FROM feed ORDER BY title");
-
- $output .= "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n";
- $output .= "<rssfeeds version=\"0.1\">\n\n";
-
- while ($feed = db_fetch_object($result)) {
- $output .= "<channel>\n";
- $output .= " <title>". drupal_specialchars($feed->title) ."</title>\n";
- $output .= " <link>". drupal_specialchars($feed->url) ."</link>\n";
- $output .= "</channel>\n\n";
- }
-
- $output .= "</rssfeeds>\n";
-
- header("Content-Type: text/xml");
-
- print $output;
-}
-
-function import_page_bundles() {
- import_page_blocks(import_get_bundles());
-}
-
-function import_page_feeds() {
- import_page_blocks(import_get_feeds());
-}
-
-function import_page_blocks($blocks) {
-
-
- theme("header");
- theme("box", t("News feeds"), import_page_info());
- print "<table cellpadding=\"0\" cellspacing=\"5\" border=\"0\" style=\"width: 100%;\">\n";
- print " <tr>\n";
-
- for ($t = 0; $t < 3; $t++) {
- $i = 1;
- print " <td style=\"vertical-align: top; width: 33%;\">\n";
- while ($block = each($blocks)) {
- theme("box", $block["value"]["subject"], $block["value"]["content"]);
- if ($i == ceil(count($blocks) / 3)) {
- break;
- }
- $i++;
- }
- print " </td>\n";
- }
-
- print " </tr>\n";
- print "</table>\n";
- theme("footer");
-}
-
-function import_page() {
- if (user_access("access news feeds")) {
- switch (arg(1)) {
- case "feed":
- import_page_feed(arg(2));
- break;
- case "bundle":
- import_page_bundle(arg(2));
- break;
- case "feeds":
- import_page_feeds();
- break;
- case "bundles":
- import_page_bundles();
- break;
- case "sources":
- import_page_sources();
- break;
- case "fd":
- import_page_fd();
- break;
- default:
- import_page_last();
- }
- }
-}
-
-?>
diff --git a/modules/aggregator/aggregator.module b/modules/aggregator/aggregator.module
deleted file mode 100644
index 1926605..0000000
--- a/modules/aggregator/aggregator.module
+++ /dev/null
@@ -1,825 +0,0 @@
-<?php
-// $Id$
-
-
-function import_help() {
- $output .= "<p>Thousands of web sites, especially news sites and weblogs, syndicate their most recent site content for others to display. The syndicated content always includes titles, also known as headlines, for the newest published stories. Each headline acts as a direct link to the stories on the remote site. Along with the headline, most sites typically provide either the first few paragraphs of the story or a short summary. Many individuals use client-based news aggregators on their personal computer to aggregate content, such as <a href=\"http://www.disobey.com/amphetadesk/\">AmphetaDesk</a>.</p>";
-
- $output .= "<p>Drupal also has a news aggregator built in as a standard feature. With it, you can subscribe to feeds from other sites and display their content for your site users. Simply enable the import module in site administration and enter the feeds that you choose.</p>";
- $output .= "<h3>What do I need to subscribe to a feed?</h3>";
- $output .= "<p>The standard method of syndication is using the XML-based <a href=\"http://groups.yahoo.com/group/rss-dev/files/specification.html\">Rich Site Summary</a> (RSS). To syndicate a site's content, obtain the full URL of the RSS page providing syndication. Common file tags for RSS pages are .rss, .xml and .rdf. Example: <a href=\"http://slashdot.org/slashdot.rdf\">http://slashdot.org/slashdot.rdf</a>.</p>";
- $output .= "<p>Most weblog sites that offer syndication will have an obvious link on the main page. Often you need only look for an xml syndication button, such as the one Drupal uses for site syndication.</p>";
- $output .= "<p>But some sites do not make their RSS feeds as easy to find. Or maybe you want to find a number of feeds on a given topic, without extensively searching the web. In that case, try an RSS syndication directory such as <a href=\"http://www.syndic8.com/\">Syndic8</a>.</p>";
- $output .= "<p>To learn much more about RSS, read Mark Pilgrim's <a href=\"http://www.xml.com/pub/a/2002/12/18/dive-into-xml.html\">What is RSS</a> and WebReference.com's <a href=\"http://www.webreference.com/authoring/languages/xml/rss/1/\">The Evolution of RSS</a>.</p>";
- $output .= "<p>NOTE: Enable your site's xml syndication button by turning on the Syndicate block in block management.</p>";
- $output .= "<h3>Configuring news feeds</h3>";
- $output .= "<p>To subscribe to an RSS feed on another site, use the <i>administer news feeds</i> shortcut at the top of the news aggregation page. The link leads directly to the news aggregation configuration section of Drupal site administration.</p>";
- $output .= "<p>Once there, select <i>add new feed</i> from the left hand menu. Drupal will then ask for the following:</p>";
- $output .= "<ul>";
- $output .= " <li><b>Title</b> -- The text entered here will be used in your news aggregator, within the administration configuration section, and as title for the news feed block. As a general rule, use the web site name from which the feed originates.</li>";
- $output .= " <li><b>URL</b> -- Here you'll enter the fully-qualified URL for the feed for the site you want to subscribe to.</li>";
- $output .= " <li><b>Attributes</b> -- Attributes are keywords which can be used to collect feeds into <i>bundles</i> (see below). Think of these as the means of classifying your feeds. Separate multiple attributes with commas. If you do not plan on using the specific feed in a bundle, this input field can be left blank.</li>";
- $output .= " <li><b>Update interval</b> -- The update interval is how often Drupal will automatically access the RSS URL for the site for fresh content. The 1 hour default is typically the minimum you will want to use. Accessing another site's RSS page more frequently can be considered impolite. After all, it does require the other site's server to handle your automatic requests. To take advantage of this feature, note that cron.php must be configured to have your feeds updated regularly. Otherwise, you'll have to manually update feeds one at a time within the news aggregation administration section by using <i>update items</i>.</li>";
- $output .= "</ul>";
- $output .= "<p>Once you submit your new feed, check to see if it is working properly. Select <i>update items </i> on the main news aggregation page. If you do not see any items listed for that feed, edit the feed and make sure that the URL was entered correctly.</p>";
- $output .= "<h3>Adding bundles</h3>";
- $output .= "<p>You may want to follow some feeds more closely than others. Or perhaps you'd like to display a select list of the titles for some feeds as a block for users. Bundles are a way of grouping your feeds into categories. Bundles look for feeds that contain at least one of the keywords, or attributes, associated with the bundle and display those feeds together.</p>";
- $output .= "<p>When adding a bundle, Drupal will ask for:</p>";
- $output .= "<ul>";
- $output .= " <li><b>Title</b> -- The title will be used in the <i>news by topics</i> listing in your news aggregator and with the customized block created for the bundle.</li>";
- $output .= " <li><b>Attributes</b> -- Enter one or more of the attributes used to categorize the news feeds already created. Separate multiple attributes with commas. Be careful to use the same spelling. Don't have any feeds with attributes for the bundle? After creating the bundle, edit existing feeds or create new ones and tag them with the attribute.</li>";
- $output .= "</ul>";
- $output .= "<h3>Using the news aggregator</h3>";
- $output .= "<p>The news aggregator has a number of ways that it displays your subscribed content:</p>";
- $output .= "<ul>";
- $output .= " <li><b>Latest news</b> -- Displays all incoming content in the order received with:";
- $output .= " <ul>";
- $output .= " <li>The title of the original post.</li>";
- $output .= " <li>The name of the source, which acts as a link to an individual feed page, listing information about that feed and incoming content for that feed only.</li>";
- $output .= " <li>A description, the first few paragraphs or summary of the originating post (if any).</li>";
- $output .= " <li>A <i>blog it</i> link. Users can select this link to have Drupal automatically prepare a blog post for the specific item.</li>";
- $output .= " <li>A <i>feed</i> link, which acts as a link to an individual feed page, listing information about that feed and incoming content for that feed only.</li>";
- $output .= " </ul>";
- $output .= " </li>";
- $output .= " <li><b>News by source -- </b>Organizes incoming content by feed, displaying titles which link to the originating post. Also has an icon which acts as blog it link.</li>";
- $output .= " <li><b>News by topic</b> -- Organizes incoming content by bundles, displaying titles which link to the originating post. Also has an icon which acts as
- blog it link.</li>";
- $output .= " <li><b>News sources</b> -- Displays an alphabetical listing of all subscribed feeds and a description. The title acts as a link to an individual feed page, listing information about that feed and incoming content for that feed only.</li>";
- $output .= "</ul>";
- $output .= "<h3>RSS feed blocks</h3>";
- $output .= "<p>In addition to providing subscribed content through the news aggregator, Drupal automatically creates a block for each subscribed feed and every bundle created. Beside each headline in each block, Drupal includes an icon which acts a blog it link. Enable any or all of the blocks using block management.</p>";
- return $output;
-}
-
-function import_system($field){
- $system["description"] = t("Used to aggregate syndicated content (RSS and RDF).");
- $system["admin_help"] = t("Drupal's news aggregator controls how many RSS/RDF items from a single source are displayed in a \"Block\", and on the page that goes with that block.");
- return $system[$field];
-}
-
-function import_settings() {
- $number = array(5 => 5, 10 => 10, 15 => 15, 20 => 20, 25 => 25, 30 => 30, 35 => 35, 40 => 40, 45 => 45, 50 => 50, 55 => 55, 60 => 60, 65 => 65, 70 => 70, 75 => 75, 80 => 80, 85 => 85, 90 => 90, 95 => 95, 100 => 100);
- $output .= form_select("Items per block", "import_block_limit", variable_get("import_block_limit", 15), $number, "The maximum number of news items displayed in one block.");
- $output .= form_select("Items per page", "import_page_limit", variable_get("import_page_limit", 75), $number, "The maximum number of news items displayed on one page.");
-
- return $output;
-}
-
-function import_perm() {
- return array("administer news feeds", "access news feeds");
-}
-
-function import_link($type) {
-
- $links = array();
-
- if ($type == "page" && user_access("access news feeds")) {
- $links[] = l(t("news feeds"), "import", array("title" => t("Read the latest news from syndicated web sites.")));
- }
-
- if ($type == "admin" && user_access("administer news feeds")) {
- $help["general"] = t("Several web sites, especially news related sites, syndicate parts of their site's content for other web sites to display. Usually, the syndicated content includes the latest headlines with a direct link to that story on the remote site. Some syndicated content also includes a description of the headline. The standard method of syndication is using the XML based Rich Site Summary (RSS). To get a feed to work you <b>must</b> run \"cron.php\". To display the feed in a block you must turn on the <a href=\"%block\">feed's block</a>. <br /><ul><li>To delete a feed choose \"edit feed\"</li><li>To clear all of the entries from a feed choose \"Remove items\"</li><li>To check whether a feed is working, and to get new items <b>now</b> click on \"update items\"</li></ul><ul><li>To delete a bundle choose \"edit bundle\".</li></ul>", array("%block" => url("admin/block")));
- $help["addfeed"] = t("Add a site to that has an RSS/RDF feed. The URL is the full path to the RSS feed file. For the feed to update you must run \"cron.php\". The \"Attributes\" are used to bundle this feed with other feeds (See <a href=\"%bundle\">add new bundle</a>, and to tag articles from this feed.<br />Note: If you already have another feed with the URL you are planning to use, the system will not accept your entry.", array("%bundle" => url("admin/syndication/news/add/bundle")));
- $help["bundles"] = t("Bundles provide a generalized way of creating composite feeds. They allow you, for example, to combine various sport-related feeds into one bundle called <i>Sport</i>. If an article from a feed has been \"tag\"-ged (See <a href=\"%tag\">tag news item</a> too look at and change tags.) with a matching \"Attribute\" then it will be added to the bundle.", array("%tag" => url("admin/syndication/news/tag")));
- $help["tag"] = t("This allows you to see and change an news item's \"tag\". All articles are originally tagged with the \"Attributes\" of their feed.");
-
- menu("admin/syndication", "content syndication", NULL, NULL, 5);
- menu("admin/syndication/news", "news aggregation", "import_admin", $help["general"]);
- menu("admin/syndication/news/add/feed", "add new feed", "import_admin", $help["addfeed"], 2);
- menu("admin/syndication/news/add/bundle", "add new bundle", "import_admin", $help["bundles"], 3);
- menu("admin/syndication/news/tag", "tag news items", "import_admin", $help["tag"], 4);
- menu("admin/syndication/news/help", "help", "import_help", NULL, 9);
- }
-
- return $links;
-}
-
-function import_cron() {
- $result = db_query("SELECT * FROM feed WHERE timestamp + refresh < ". time());
- while ($feed = db_fetch_array($result)) {
- import_refresh($feed);
- }
-}
-
-function import_update() {
- $result = db_query("SELECT * FROM feed");
- while ($feed = db_fetch_array($result)) {
- import_refresh($feed);
- }
-}
-
-function import_format_item($item, $feed = 0) {
- global $user;
-
- if ($user->uid && user_access("maintain personal blog")) {
- $output .= "<div class=\"icon\">". l("<img src=\"". theme("image", "blog.gif") ."\" alt=\"". t("blog it") ."\" title=\"". t("blog it") ."\" />", "node/add/blog&amp;iid=$item->iid", array("title" => t("Comment on this news item in your personal blog."), "class" => "blog-it")) ."</div>";
- }
-
- // external link
- $output .= "<a href=\"$item->link\">$item->title</a>";
-
- return $output;
-}
-
-function import_bundle_block($attributes) {
-
- if ($attributes) {
- $keys = explode(",", $attributes);
- foreach ($keys as $key) $where[] = "attributes LIKE '%". trim($key) ."%'";
-
- $result = db_query_range("SELECT * FROM item WHERE ". implode(" OR ", $where) ." ORDER BY iid DESC", 0, variable_get("import_block_limit", 15));
- }
-
- $items = array();
- while ($item = db_fetch_object($result)) {
- $items[] = import_format_item($item);
- }
-
- $output = "<div class=\"import-block\"><div class=\"bundle\">";
- $output .= theme("theme_item_list", $items);
- $output .= "</div></div>";
-
- return $output;
-}
-
-function import_feed_block($feed) {
- $result = db_query_range("SELECT * FROM item WHERE fid = %d ORDER BY iid DESC ", $feed->fid, 0, variable_get("import_block_limit", 15));
-
- $items = array();
- while ($item = db_fetch_object($result)) {
- $items[] = import_format_item($item);
- }
-
- $output = "<div class=\"import-block\"><div class=\"feed\">";
- $output .= theme("theme_item_list", $items);
- $output .= "</div></div>";
-
- return $output;
-}
-
-function import_block($op, $delta) {
- if ($op == "list") {
- $result = db_query("SELECT * FROM bundle ORDER BY title");
- while ($bundle = db_fetch_object($result)) {
- $block["bundle:$bundle->bid"]["info"] = "$bundle->title bundle";
- }
-
- $result = db_query("SELECT * FROM feed ORDER BY fid");
- while ($feed = db_fetch_object($result)) {
- $block["feed:$feed->fid"]["info"] = "$feed->title feed";
- }
-
- return $block;
- }
- else {
- list($type, $id) = split(":", $delta);
- switch ($type) {
- case "feed":
- $feed = db_fetch_object(db_query("SELECT * FROM feed WHERE fid = %d", $id));
- $block["subject"] = $feed->title;
- $block["content"] .= import_feed_block($feed) ."<div style=\"text-align: right;\">". l(t("more"), "import/feed/$feed->fid", array("title" => t("View this feed's recent news."))) ."</div>";
- break;
-
- case "bundle":
- $bundle = db_fetch_object(db_query("SELECT * FROM bundle WHERE bid = %d", $id));
- $block["subject"] = $bundle->title;
- $block["content"] .= import_bundle_block($bundle->attributes) ."<div style=\"text-align: right;\">". l(t("more"), "import/bundle/$bundle->bid", array("title" => t("View this bundle's recent news."))) ."</div>";
- break;
- }
-
- return $block;
- }
-}
-
-function import_get_bundles($attributes = 0) {
-
- $block = array();
-
- $result = db_query("SELECT * FROM bundle ORDER BY title");
- while ($bundle = db_fetch_object($result)) {
- $block["bundle:$bundle->bid"]["subject"] = $bundle->title;
- $block["bundle:$bundle->bid"]["content"] = import_bundle_block($bundle->attributes) ."<div style=\"text-align: right;\">".
- l(t("more"), "import/bundle/$bundle->bid", array("title" => t("View this bundle's recent news.")))
- ."</div>";
- $block["bundle:$bundle->bid"]["info"] = "$bundle->title bundle";
- }
-
- return $block;
-}
-
-function import_get_feeds($attributes = 0) {
-
- $block = array();
-
- $result = db_query("SELECT * FROM feed ORDER BY fid");
- while ($feed = db_fetch_object($result)) {
- $block["feed:$feed->fid"]["subject"] = $feed->title;
- $block["feed:$feed->fid"]["content"] = import_feed_block($feed) ."<div style=\"text-align: right;\">".
- l(t("more"), "import/feed/$feed->fid", array("title" => t("View this feed's recent news.")))
- ."</div>";
- $block["feed:$feed->fid"]["info"] = "$feed->title feed";
- }
-
- return $block;
-}
-
-function import_remove($feed) {
- db_query("DELETE FROM item WHERE fid = %d", $feed["fid"]);
- return t("removed news items from '%site'.", array("%site" => $feed["title"]));
-}
-
-// Call-back function used by XML parser:
-function import_element_start($parser, $name, $attributes) {
- global $item, $element, $tag;
-
- switch ($name) {
- case "IMAGE":
- case "TEXTINPUT":
- $element = $name;
- break;
- case "ITEM":
- $element = $name;
- $item += 1;
- }
-
- $tag = $name;
-}
-
-// Call-back function used by XML parser:
-function import_element_end($parser, $name) {
- global $element;
-
- switch ($name) {
- case "IMAGE":
- case "TEXTINPUT":
- case "ITEM":
- $element = "";
- }
-}
-
-// Call-back function used by XML parser:
-function import_element_data($parser, $data) {
- global $channel, $element, $items, $item, $tag;
-
- switch ($element) {
- case "ITEM":
- $items[$item][$tag] .= $data;
- break;
- case "IMAGE":
- case "TEXTINPUT":
- /*
- ** The sub-elements "image" and "textinput" are not supported
- ** but we have recognize them or their content will end up in
- ** the items-array.
- */
- break;
- default:
- $channel[$tag] .= $data;
- }
-}
-
-function import_refresh($feed) {
-
- // unset the global variables before we use them:
- unset($GLOBALS["channel"], $GLOBALS["element"], $GLOBALS["item"], $GLOBALS["items"], $GLOBALS["tag"]);
-
- // after we unset the variables, we can global them again:
- global $items, $channel;
-
- /*
- ** Check whether the feed is properly configured:
- */
-
- if (!ereg("^http://|ftp://", $feed["url"])) {
- return t("failed to parse RSS feed '%site': incorrect or missing URL.", array("%side" => $feed["title"]));
- }
-
- /*
- ** Grab the news items:
- */
-
- if ($fp = @fopen($feed["url"], "r")) {
- // fetch data:
- while (!feof($fp)) {
- $data .= fgets($fp, 128);
- }
- fclose($fp);
-
- // filter the input data:
- xss_check_input_data($data);
-
- // parse the data:
- $xml_parser = xml_parser_create();
- xml_set_element_handler($xml_parser, "import_element_start", "import_element_end");
- xml_set_character_data_handler($xml_parser, "import_element_data");
- xml_parser_set_option($xml_parser, XML_OPTION_TARGET_ENCODING, "utf-8");
-
- if (!xml_parse($xml_parser, $data, 1)) {
- return t("failed to parse RSS feed '%site': %error at line %line.", array("%site" => $feed["title"], "%error" => xml_error_string(xml_get_error_code($xml_parser)), "%line" => xml_get_current_line_number($xml_parser)));
- }
- xml_parser_free($xml_parser);
-
- // initialize the translation table:
- $tt = array_flip(get_html_translation_table(HTML_ENTITIES));
- $tt["&apos;"] = "'";
-
- db_query("UPDATE feed SET timestamp = %d, link = '%s', description = '%s' WHERE fid = %d", time(), $channel["LINK"], $channel["DESCRIPTION"], $feed["fid"]);
-
- /*
- ** We reverse the array such that we store the first item last,
- ** and the last item first. In the database, the newest item
- ** should be at the top.
- */
-
- $items = array_reverse($items);
-
- foreach ($items as $item) {
- unset($title, $link, $author, $description);
-
- // Prepare the item:
- foreach ($item as $key => $value) {
- $item[$key] = node_filter(strtr(trim($value), $tt));
- }
-
- if ($item["TITLE"]) {
- $title = $item["TITLE"];
- }
- else {
- /*
- ** Use up to 40 characters of the description, ending at
- ** word boundary, but don't split potential entities.
- */
- $title = preg_replace('/^(.*)[^\w;&].*?$/', "\\1", substr($item["DESCRIPTION"], 0, 40));
- }
-
- if ($item["LINK"]) {
- $link = $item["LINK"];
- }
- elseif ($item["GUID"] && (strncmp($item["GUID"], "http://", 7) == 0)) {
- $link = $item["GUID"];
- }
- else {
- $link = $feed["link"];
- }
-
- /*
- ** Save this item. Try to avoid duplicate entries as much as
- ** possible. If we find a duplicate entry, we resolve it and
- ** pass along it's ID such that we can update it if needed.
- */
-
- if ($link && $link != $feed["link"] && $link != $feed["url"]) {
- $entry = db_fetch_object(db_query("SELECT iid FROM item WHERE fid = %d AND link = '%s'", $feed["fid"], $link));
- }
- else {
- $entry = db_fetch_object(db_query("SELECT iid FROM item WHERE fid = %d AND title = '%s'", $feed["fid"], $title));
- }
-
- import_save_item(array(iid => $entry->iid, fid => $feed["fid"], title => $title, link => $link, author => $item["AUTHOR"], description => $item["DESCRIPTION"], attributes => $feed["attributes"]));
- }
-
- /*
- ** Remove all the old, expired items:
- */
-
- unset($items);
-
- $result = db_query("SELECT iid FROM item WHERE fid = %d ORDER BY timestamp", $feed["fid"]);
-
- while ($item = db_fetch_object($result)) {
- $items[] = "iid = '$item->iid'";
- }
-
- if (sizeof($items) > 50) {
- db_query("DELETE FROM item WHERE ". implode(" OR ", array_slice($items, 0, - 50)));
- }
-
- cache_clear_all();
- }
- else {
- return t("failed to parse RSS feed '%site': no data.", array("%site" => $feed["tite"]));
- }
-
- return t("syndicated content from '%site'.", array("%site" => $feed["title"]));
-}
-
-function import_save_item($edit) {
- if ($edit["iid"] && $edit["title"]) {
- db_query("UPDATE item SET title = '%s', link = '%s', author = '%s', description = '%s', attributes = '%s' WHERE iid = %d", $edit["title"], $edit["link"], $edit["author"], $edit["description"], $edit["attributes"], $edit["iid"]);
- }
- else if ($edit["iid"]) {
- db_query("DELETE FROM item WHERE iid = %d", $edit["iid"]);
- }
- else if ($edit["title"] && $edit["link"]) {
- db_query("INSERT INTO item (fid, title, link, author, description, attributes, timestamp) VALUES (%d, '%s', '%s', '%s', '%s', '%s', %d)", $edit["fid"], $edit["title"], $edit["link"], $edit["author"], $edit["description"], $edit["attributes"], time());
- }
-}
-
-function import_form_bundle($edit = array()) {
-
- $form .= form_textfield("Title", "title", $edit["title"], 50, 64, "The name of the bundle.");
- $form .= form_textfield("Attributes", "attributes", $edit["attributes"], 50, 128, "A comma-separated list of keywords describing the bundle.");
-
- $form .= form_submit("Submit");
-
- if ($edit["bid"]) {
- $form .= form_submit("Delete");
- $form .= form_hidden("bid", $edit["bid"]);
- }
-
- return form($form);
-}
-
-function import_save_bundle($edit) {
- if ($edit["bid"] && $edit["title"]) {
- db_query("UPDATE bundle SET title = '%s', attributes = '%s' WHERE bid = %d", $edit["title"], $edit["attributes"], $edit["bid"]);
- }
- else if ($edit["bid"]) {
- db_query("DELETE FROM bundle WHERE bid = %d", $edit["bid"]);
- }
- else if ($edit["title"]) {
- // a single unique id for bundles and feeds, to use in blocks
- $next_id = db_next_id("bundle_bid");
- db_query("INSERT INTO bundle (bid, title, attributes) VALUES (%d, '%s', '%s')", $next_id, $edit["title"], $edit["attributes"]);
- }
-}
-
-function import_form_feed($edit = array()) {
-
- $period = array(900 => format_interval(900), 1800 => format_interval(1800), 3600 => format_interval(3600), 7200 => format_interval(7200), 10800 => format_interval(10800), 21600 => format_interval(21600), 32400 => format_interval(32400), 43200 => format_interval(43200), 64800 => format_interval(64800), 86400 => format_interval(86400), 172800 => format_interval(172800), 259200 => format_interval(259200), 604800 => format_interval(604800), 1209600 => format_interval(1209600), 2419200 => format_interval(2419200));
-
- if ($edit["refresh"] == "") {
- $edit["refresh"] = 3600;
- }
-
- $form .= form_textfield("Title", "title", $edit["title"], 50, 64, "The name of the feed; typically the name of the web site you syndicate content from.");
- $form .= form_textfield("Url", "url", $edit["url"], 50, 128, "The fully-qualified URL of the feed.");
- $form .= form_textfield("Attributes", "attributes", $edit["attributes"], 50, 128, "A comma-separated list of keywords describing the feed.");
- $form .= form_select("Update interval", "refresh", $edit["refresh"], $period, "The refresh interval indicating how often you want to update this feed. Requires crontab.");
-
- $form .= form_submit("Submit");
-
- if ($edit["fid"]) {
- $form .= form_submit("Delete");
- $form .= form_hidden("fid", $edit["fid"]);
- }
-
- return form($form);
-}
-
-function import_save_feed($edit) {
- if ($edit["fid"] && $edit["title"]) {
- db_query("UPDATE feed SET title = '%s', url = '%s', attributes = '%s', refresh = %d WHERE fid = %d", $edit["title"], $edit["url"], $edit["attributes"], $edit["refresh"], $edit["fid"]);
- db_query("DELETE FROM item WHERE fid = %d", $edit["fid"]);
- }
- else if ($edit["fid"]) {
- db_query("DELETE FROM feed WHERE fid = %d", $edit["fid"]);
- db_query("DELETE FROM item WHERE fid = %d", $edit["fid"]);
- }
- else if ($edit["title"]) {
- // a single unique id for bundles and feeds, to use in blocks
- $next_id = db_next_id("feed_fid");
- db_query("INSERT INTO feed (fid, title, url, attributes, refresh) VALUES (%d, '%s', '%s', '%s', %d)", $next_id, $edit["title"], $edit["url"], $edit["attributes"], $edit["refresh"]);
- }
-}
-
-function import_save_attributes($edit) {
- foreach ($edit as $iid => $value) {
- db_query("UPDATE item SET attributes = '%s' WHERE iid = %d", $value, $iid);
- }
- return "attributes has been saved";
-}
-
-function import_get_feed($fid) {
- return db_fetch_array(db_query("SELECT * FROM feed WHERE fid = %d", $fid));
-}
-
-function import_get_bundle($bid) {
- return db_fetch_array(db_query("SELECT * FROM bundle WHERE bid = %d", $bid));
-}
-
-function import_view() {
- $result = db_query("SELECT f.*, COUNT(i.iid) AS items FROM feed f LEFT JOIN item i ON f.fid = i.fid GROUP BY f.fid, f.title, f.url, f.refresh, f.timestamp, f.attributes, f.link, f.description ORDER BY f.title");
-
- $output .= "<h3>Feed overview</h3>";
-
- $header = array(t("title"), t("attributes"), t("items"), t("last update"), t("next update"), array("data" => t("operations"), "colspan" => 3));
- unset($rows);
- while ($feed = db_fetch_object($result)) {
- $rows[] = array($feed->title, $feed->attributes, format_plural($feed->items, "1 item", "%count items"), ($feed->timestamp ? format_interval(time() - $feed->timestamp) ." ago" : "never"), ($feed->timestamp ? format_interval($feed->timestamp + $feed->refresh - time()) ." left" : "never"), l(t("edit feed"), "admin/syndication/news/edit/feed/$feed->fid"), l(t("remove items"), "admin/syndication/news/remove/$feed->fid"), l(t("update items"), "admin/syndication/news/update/$feed->fid"));
- }
- $output .= table($header, $rows);
-
- $result = db_query("SELECT * FROM bundle ORDER BY title");
-
- $output .= "<h3>Bundle overview</h3>";
-
- $header = array(t("title"), t("attributes"), t("operations"));
- unset($rows);
- while ($bundle = db_fetch_object($result)) {
- $rows[] = array($bundle->title, $bundle->attributes, l(t("edit bundle"), "admin/syndication/news/edit/bundle/$bundle->bid"));
- }
- $output .= table($header, $rows);
-
- return $output;
-}
-
-function import_tag() {
-
- $result = db_query_range("SELECT i.*, f.title AS feed FROM item i LEFT JOIN feed f ON i.fid = f.fid ORDER BY i.iid DESC", 0, 50);
-
- $header = array(t("date"), t("feed"), t("news item"));
- while ($item = db_fetch_object($result)) {
- $rows[] = array(array("data" => format_date($item->timestamp, "small"), "nowrap" => "nowrap", "valign" => "top"), array("data" => l($item->feed, "admin/syndication/news/edit/feed/$item->fid"), "valign" => "top"), "<a href=\"$item->link\">$item->title</a>". ($item->description ? "<br /><small><i>$item->description</i></small>" : "") ."<br /><input type=\"text\" name=\"edit[$item->iid]\" value=\"". check_form($item->attributes) ."\" size=\"50\" />");
- }
-
- $output .= table($header, $rows);
- $output .= "<input type=\"submit\" name=\"op\" value=\"Save attributes\" />\n";
-
- return form($output);
-}
-
-function import_admin() {
- $op = $_POST["op"];
- $edit = $_POST["edit"];
-
- if (user_access("administer news feeds")) {
-
- if (empty($op)) {
- $op = arg(3);
- }
-
- switch ($op) {
- case "add":
- if (arg(4) == "bundle") {
- print import_form_bundle();
- }
- else {
- print import_form_feed();
- }
- break;
- case "edit":
- if (arg(4) == "bundle") {
- print import_form_bundle(import_get_bundle(arg(5)));
- }
- else {
- print import_form_feed(import_get_feed(arg(5)));
- }
- break;
- case "remove":
- print status(import_remove(import_get_feed(arg(4))));
- print import_view();
- break;
- case "update":
- print status(import_refresh(import_get_feed(arg(4))));
- print import_view();
- break;
- case "tag":
- print import_tag();
- break;
- case "Save attributes":
- print status(import_save_attributes($edit));
- print import_tag();
- break;
- case "Delete":
- $edit["title"] = 0;
- // fall through:
- case "Submit":
- if (arg(4) == "bundle") {
- print status(import_save_bundle($edit));
- }
- else {
- print status(import_save_feed($edit));
- }
- // fall through:
- default:
- print import_view();
- }
- }
- else {
- print message_access();
- }
-}
-
-function import_page_info() {
-
-
- $links[] = l(t("latest news"), "import", array("title" => t("Read the latest news from syndicated web sites.")));
- $links[] = l(t("news by source"), "import/feeds", array("title" => t("View the latest headlines sorted by source.")));
- $links[] = l(t("news by topic"), "import/bundles", array("title" => t("View the latest headlines sorted by topic.")));
- $links[] = l(t("news sources"), "import/sources", array("title" => t("View a list of all the web sites we syndicate from.")));
-
- if (user_access("administer news feeds")) {
- $links[] = l(t("administer news feeds"), "admin/syndication/news", array("title" => t("View the news feed administrative pages.")));
- }
-
- return "<div style=\"text-align: center;\">". theme("links", $links) ."</div>";
-}
-
-function import_page_last() {
-
-
- $result = db_query_range("SELECT i.*, f.title AS ftitle, f.link AS flink FROM item i LEFT JOIN feed f ON i.fid = f.fid ORDER BY i.iid DESC", 0, variable_get("import_page_limit", 75));
-
- $output .= "<table border=\"0\" cellpadding=\"4\" cellspacing=\"2\">";
- while ($item = db_fetch_object($result)) {
- if (module_exist("blog") && user_access("maintain personal blog")) {
- $links[] = l(t("blog it"), "node/add/blog", array("title" => t("Comment on this news item in your personal blog.")), "iid=$item->iid");
- }
- $links[] = l(t("feed"), "import/feed/$item->fid", array("title" => t("Read more syndicated news from this feed.")));
-
- if ($item->link) {
- $output .= "<tr><td><a href=\"$item->link\">$item->title</a> &middot; ". l($item->ftitle, "import/feed/$item->fid", array("title" => t("View more information about this feed."))) ."</td><td style=\"text-align: right; vertical-align: top;\">". theme("links", $links) ."</td></tr>\n";
- }
-
- if ($item->description) {
- $output .= "<tr><td colspan=\"2\"><div style=\"margin-left: 20px;\">$item->description</div><br /></td></tr>";
- }
-
- unset($links);
- }
- $output .= "</table>\n";
-
- theme("header");
- theme("box", t("News feeds"), import_page_info());
- theme("box", t("Latest news"), $output);
- theme("footer");
-}
-
-function import_page_feed($fid) {
-
-
- $feed = db_fetch_object(db_query("SELECT * FROM feed WHERE fid = %d", $fid));
-
- $header .= "<p><b>". t("Website") .":</b><div style=\"margin-left: 20px;\"><a href=\"$feed->link\">$feed->link</a></div></p>";
- $header .= "<p><b>". t("Description") .":</b><div style=\"margin-left: 20px;\">$feed->description</div></p>";
- $header .= "<p><b>". t("Last update") .":</b><div style=\"margin-left: 20px; text-align: right;\">". format_interval(time() - $feed->timestamp) ." ". t("ago") ." <a href=\"$feed->url\"><img src=\"". theme("image", "xml.gif") ."\" width=\"36\" height=\"14\" style=\"border: 0px;\" alt=\"\" title=\"\" /></a><br /><br /></div></p>\n";
-
- $result = db_query_range("SELECT * FROM item WHERE fid = %d ORDER BY iid DESC", $fid, 0, variable_get("import_page_limit", 75));
-
- $output .= "<table border=\"0\" cellpadding=\"4\" cellspacing=\"2\">";
- while ($item = db_fetch_object($result)) {
- if (module_exist("blog") && user_access("maintain personal blog")) {
- $links[] = l(t("blog it"), "node/add/blog", array("title" => t("Comment on this news item in your personal blog.")), "iid=$item->iid");
- }
- $links[] = "<a href=\"$item->link\">". t("visit") ."</a>";
-
- if ($item->link) {
- $output .= "<tr><td><a href=\"$item->link\">$item->title</a></td><td style=\"text-align: right; vertical-align: top;\">". theme("links", $links) ."</td></tr>\n";
- }
- if ($item->description) {
- $output .= "<tr><td colspan=\"2\"><div style=\"margin-left: 20px;\">$item->description</div><br /></td></tr>";
- }
-
- unset($links);
- }
- $output .= "</table>\n";
-
- theme("header");
- theme("box", t("News feeds"), import_page_info());
- theme("box", $feed->title, $header);
- theme("box", t("Latest news"), $output);
- theme("footer");
-}
-
-function import_page_bundle($bid) {
-
-
- $bundle = db_fetch_object(db_query("SELECT * FROM bundle WHERE bid = %d", $bid));
-
- $header .= "<p><b>". t("Website") .":</b><div style=\"margin-left: 20px;\">". l($bundle->title, "import/bundle/$bundle->bid") ."</div></p>";
- $header .= "<p><b>". t("Description") .":</b><div style=\"margin-left: 20px;\">". t("A composite news feed about") ." $bundle->attributes.</div></p>";
-
- $keys = explode(",", $bundle->attributes);
- foreach ($keys as $key) $where[] = "i.attributes LIKE '%". trim($key) ."%'";
- $result = db_query_range("SELECT i.*, f.title AS ftitle, f.link AS flink FROM item i, feed f WHERE (". implode(" OR ", $where) .") AND i.fid = f.fid ORDER BY iid DESC", 0, variable_get("import_page_limit", 75));
-
- $output .= "<table border=\"0\" cellpadding=\"4\" cellspacing=\"2\">";
- while ($item = db_fetch_object($result)) {
- if (module_exist("blog") && user_access("maintain personal blog")) {
- $links[] = l(t("blog it"), "node/add/blog", array("title" => t("Comment on this news item in your personal blog.")), "iid=$item->iid");
- }
- $links[] = l(t("feed"), "import/feed/$item->fid", array("title" => t("Read more syndicated news from this feed.")));
- $links[] = "<a href=\"$item->link\">". t("visit") ."</a>";
-
- if ($item->link) {
- $output .= "<tr><td><a href=\"$item->link\">$item->title</a> &middot; ". l($item->ftitle, "import/feed/$item->fid", array("title" => t("View more information about this feed."))) ."</td><td style=\"text-align: right; vertical-align: top;\">". theme("links", $links) ."</td></tr>\n";
- }
-
- if ($item->description) {
- $output .= "<tr><td colspan=\"2\"><div style=\"margin-left: 20px;\">$item->description</div><br /></td></tr>";
- }
-
- unset($links);
- }
- $output .= "</table>\n";
-
- theme("header");
- theme("box", t("News feeds"), import_page_info());
- theme("box", $bundle->title, $header);
- theme("box", t("Latest news"), $output);
- theme("footer");
-
-}
-
-function import_page_sources() {
-
-
- $result = db_query("SELECT * FROM feed ORDER BY title");
-
- while ($feed = db_fetch_object($result)) {
- $output .= l($feed->title, "import/feed/$feed->fid");
- $output .= "<div style=\"margin-left: 20px;\">$feed->description</div><br />";
- }
-
- $output .= "<div style=\"text-align: right\">" . l("<img src=\"". theme("image", "xml.gif") ."\" width=\"36\" height=\"14\" style=\"border: 0px;\" />", "import/fd", array("title" => t("View the list of syndicated web sites in XML format."))) . "</div><br />";
-
- theme("header");
- theme("box", t("News feeds"), import_page_info());
- theme("box", t("News sources"), $output);
- theme("footer");
-}
-
-function import_page_fd() {
-
- $result = db_query("SELECT * FROM feed ORDER BY title");
-
- $output .= "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n";
- $output .= "<rssfeeds version=\"0.1\">\n\n";
-
- while ($feed = db_fetch_object($result)) {
- $output .= "<channel>\n";
- $output .= " <title>". drupal_specialchars($feed->title) ."</title>\n";
- $output .= " <link>". drupal_specialchars($feed->url) ."</link>\n";
- $output .= "</channel>\n\n";
- }
-
- $output .= "</rssfeeds>\n";
-
- header("Content-Type: text/xml");
-
- print $output;
-}
-
-function import_page_bundles() {
- import_page_blocks(import_get_bundles());
-}
-
-function import_page_feeds() {
- import_page_blocks(import_get_feeds());
-}
-
-function import_page_blocks($blocks) {
-
-
- theme("header");
- theme("box", t("News feeds"), import_page_info());
- print "<table cellpadding=\"0\" cellspacing=\"5\" border=\"0\" style=\"width: 100%;\">\n";
- print " <tr>\n";
-
- for ($t = 0; $t < 3; $t++) {
- $i = 1;
- print " <td style=\"vertical-align: top; width: 33%;\">\n";
- while ($block = each($blocks)) {
- theme("box", $block["value"]["subject"], $block["value"]["content"]);
- if ($i == ceil(count($blocks) / 3)) {
- break;
- }
- $i++;
- }
- print " </td>\n";
- }
-
- print " </tr>\n";
- print "</table>\n";
- theme("footer");
-}
-
-function import_page() {
- if (user_access("access news feeds")) {
- switch (arg(1)) {
- case "feed":
- import_page_feed(arg(2));
- break;
- case "bundle":
- import_page_bundle(arg(2));
- break;
- case "feeds":
- import_page_feeds();
- break;
- case "bundles":
- import_page_bundles();
- break;
- case "sources":
- import_page_sources();
- break;
- case "fd":
- import_page_fd();
- break;
- default:
- import_page_last();
- }
- }
-}
-
-?>
diff --git a/modules/archive/archive.module b/modules/archive/archive.module
deleted file mode 100644
index 1afd48c..0000000
--- a/modules/archive/archive.module
+++ /dev/null
@@ -1,247 +0,0 @@
-<?php
-// $Id$
-
-function archive_system($field){
- $system["description"] = t("Displays a calendar to navigate old content.");
- $system["admin_help"] = t("Choose the starting \"day of the week\" for the displayed calendar block.");
- return $system[$field];
-}
-
-function archive_calendar($original = 0) {
- global $user;
- $edit = $_POST["edit"];
-
- // Extract today's date:
- $offset = time() + $user->timezone;
- $start_of_today = mktime(0, 0, 0, date("n", $offset), date("d", $offset), date("Y", $offset)) + $user->timezone;
- $end_of_today = mktime(23, 59, 59, date("n", $offset), date("d", $offset), date("Y", $offset)) + $user->timezone;
-
- // Extract the requested date:
- if ($edit["year"] && $edit["month"] && $edit["day"]) {
- $year = $edit["year"];
- $month = $edit["month"];
- $day = $edit["day"];
-
- $requested = mktime(0, 0, 0, $month, $day, $year) + $user->timezone;
- }
- else if (arg(0) == "archive" && arg(3)) {
- $year = arg(1);
- $month = arg(2);
- $day = arg(3);
-
- $requested = mktime(0, 0, 0, $month, $day, $year) + $user->timezone;
- }
- else {
- $year = date("Y", time());
- $month = date("n", time());
- $day = date("d", time());
-
- $requested = $end_of_today + $user->timezone;
- }
-
- $start_of_month = mktime(0, 0, 0, $month, 1, $year);
-
- // Extract first day of the month:
- $first = date("w", $start_of_month);
-
- // Extract last day of the month:
- $last = date("t", $start_of_month);
-
- $end_of_month = mktime(23,59,59, $month, $last, $year);
-
- $cache = cache_get("archive:calendar:$start_of_month");
-
- if (!empty($cache)) {
- return $cache->data;
- }
-
- // Calculate previous and next months dates and check for shorter months (28/30 days)
- $prevmonth = mktime(23, 59, 59, $month - 1, 1, $year);
- $prev = mktime(23, 59, 59, $month - 1, min(date("t", $prevmonth), $day), $year);
- $nextmonth = mktime(23, 59, 59, $month + 1, 1, $year);
- $next = mktime(23, 59, 59, $month + 1, min(date("t", $nextmonth), $day), $year);
-
-
- $result = db_query("SELECT created FROM node WHERE status = 1 AND created > $start_of_month AND created < $end_of_month");
-
- $days_with_posts = array();
- while ($day_with_post = db_fetch_object($result)) {
- $days_with_posts[] = date("j", $day_with_post->created + $user->timezone);
- }
- $days_with_posts = array_unique($days_with_posts);
-
- // Generate calendar header:
- $output .= "\n<!-- calendar -->\n";
- $output .= "<div class=\"calendar\">";
- $output .= "<table>\n";
- $output .= " <tr><td colspan=\"7\" class=\"header-month\">". l("&laquo;", "archive/". date("Y/m/d", $prev)) ." ". date("F Y", $requested) ." ". ($nextmonth <= time() ? l("&raquo;", "archive/". date("Y/m/d", $next)) : "&nbsp;") ."</td></tr>\n";
-
- // First day of week (0 => Sunday, 1 => Monday, ...)
- $weekstart = variable_get("default_firstday", 0);
-
- // Last day of week
- ($weekstart - 1 == -1 ) ? $lastday = 6 : $lastday = $weekstart - 1;
-
- // Generate the days of the week:
- $firstcolumn = mktime(0, 0, 0, 3, 20 + $weekstart, 1994);
-
- $output .= " <tr class=\"header-week\">";
- for ($i = 0; $i < 7; $i++) {
- $output .= "<td>". t(substr(ucfirst(date("l", $firstcolumn + $i * 86400)), 0, 2)) ."</td>";
- }
- $output .= "</tr>\n";
-
- // Initialize temporary variables:
- $nday = 1;
- $sday = $first;
-
- // Loop through all the days of the month:
- while ($nday <= $last) {
- // Set up blank days for first week of the month:
- if ($first != $weekstart) {
- $blankdays = ($first - $weekstart + 7) % 7;
- $output .= " <tr class=\"row-week\"><td class=\"day-blank\" colspan=\"$blankdays\">&nbsp;</td>\n";
- $first = $weekstart;
- }
- // Start every week on a new line:
- if ($sday == $weekstart) {
- $output .= " <tr class=\"row-week\">\n";
- }
-
- // Print one cell:
- $date = mktime(0, 0, 0, $month, $nday, $year) + $user->timezone;
- if (in_array($nday, $days_with_posts)) {
- $daytext = l($nday, "archive/$year/$month/$nday");
- $dayclass = "day-link";
- }
- else {
- $daytext = "<div>$nday</div>";
- $dayclass = "day-normal";
- }
- if ($date == $requested) {
- $output .= " <td class=\"day-selected\">$daytext</td>\n";
- }
- else if ($date == $start_of_today) {
- $output .= " <td class=\"day-today\">$daytext</td>\n";
- }
- else if ($date > $end_of_today) {
- $output .= " <td class=\"day-future\">$daytext</td>\n";
- }
- else {
- $output .= " <td class=\"$dayclass\">$daytext</td>\n";
- }
-
- // Start every week on a new line:
- if ($sday == $lastday) {
- $output .= " </tr>\n";
- }
-
- // Update temporary variables:
- $sday++;
- $sday = $sday % 7;
- $nday++;
- }
-
- // Complete the calendar:
- if ($sday != $weekstart) {
- $end = (7 - $sday + $weekstart) % 7;
- $output .= " <td class=\"day-blank\" colspan=\"$end\">&nbsp;</td>\n </tr>\n";
- }
-
- $output .= "</table></div>\n\n";
-
- cache_set("archive:calendar:$start_of_month", $output, time() + variable_get("cache_clear", 120));
-
- return $output;
-}
-
-function archive_block($op = "list", $delta = 0) {
- global $date;
- if ($op == "list") {
- $blocks[0]["info"] = t("Calendar to browse archives");
- return $blocks;
- }
- else if (user_access("access content")) {
- switch ($delta) {
- case 0:
- $block["subject"] = t("Browse archives");
- $block["content"] = archive_calendar();
- return $block;
- }
- }
-}
-
-function archive_link($type) {
-
- $links = array();
-
- if ($type == "page" && user_access("access content")) {
- $links[] = l(t("archives"), "archive", array("title" => t("Read the older content in our archive.")));
- }
-
- return $links;
-}
-
-function archive_page() {
- global $date, $month, $year, $meta, $user;
-
- $op = $_POST["op"];
- $edit = $_POST["edit"];
-
- theme("header");
-
- if (user_access("access content")) {
- if ($op == t("Show")) {
- $year = $edit["year"];
- $month = $edit["month"];
- $day = $edit["day"];
- }
- else {
- $year = arg(1);
- $month = arg(2);
- $day = arg(3);
- }
-
- $date = mktime(0, 0, 0, $month, $day, $year) - $user->timezone;
-
- /*
- ** Prepare the values of the form fields:
- */
-
- $years = array(2000 => "2000", 2001 => "2001", 2002 => "2002", 2003 => "2003", 2004 => "2004", 2005 => "2005");
- $months = array(1 => t("January"), 2 => t("February"), 3 => t("March"), 4 => t("April"), 5 => t("May"), 6 => t("June"), 7 => t("July"), 8 => t("August"), 9 => t("September"), 10 => t("October"), 11 => t("November"), 12 => t("December"));
- for ($i = 1; $i <= 31; $i++) $days[$i] = $i;
-
- $start = "<div class=\"container-inline\">";
- $start .= form_select("", "year", ($year ? $year : date("Y")), $years). form_select("", "month", ($month ? $month : date("m")), $months) . form_select("", "day", ($day ? $day : date("d")), $days) . form_submit(t("Show"));
- $start .= "</div>";
- theme("box", t("Archives"), form($start));
-
- /*
- ** Fetch nodes for the selected date, or current date if none
- ** selected.
- */
-
- if ($year && $month && $day) {
- $result = db_query_range("SELECT nid FROM node WHERE status = '1' AND created > %d ORDER BY created", $date, 0, 20);
-
- while ($nid = db_fetch_object($result)) {
- node_view(node_load(array("nid" => $nid->nid)), 1);
- }
- }
- }
- else {
- message_access();
- }
-
- theme("footer");
-}
-
-function archive_settings() {
-
- $output .= form_select( t("First day of week"), "default_firstday", variable_get("default_firstday", 0), array(0 => t("Sunday"), 1 => t("Monday"), 2 => t("Tuesday"), 3 => t("Wednesday"), 4 => t("Thursday"), 5 => t("Friday"), 6 => t("Saturday")), t("The first day of the week. By changing this value you choose how the calendar block is rendered."));
-
- return $output;
-}
-
-?>
diff --git a/modules/block/block.module b/modules/block/block.module
deleted file mode 100644
index 5ac9d9f..0000000
--- a/modules/block/block.module
+++ /dev/null
@@ -1,336 +0,0 @@
-<?php
-// $Id$
-
-function block_help() {
- $output .= "<p>Blocks are the boxes visible in the sidebar(s) of your web site. These are usually generated automatically by modules (e.g. recent forum topics), but you can also create your own blocks using either static HTML or dynamic PHP content.</p>";
- $output .= "<p>Which sidebar each block appears in depends on which theme you're using (some are left-only, some right, some both), and also on the settings in block management.</p><p>Whether a block is visible in the first place depends on three things:</p><ul><li>It must have its \"enabled\" box checked in block management.</li><li>If it has its \"custom\" box checked in block management, the user must have chosen to display it in their user preferences.</li><li>If the \"path\" field in block management is set, the visitor must be on a page that matches the path specification (more on this later).</li></ul>";
- $output .= "<p>The block management screen also lets you specify the vertical sort-order of the blocks within a sidebar. You do this by assigning a <b>weight</b> to each block. Lighter blocks (smaller weight) \"float up\" towards the top of the sidebar. Heavier ones \"sink down\" towards the bottom of it. Once you've positioned things just so, you can preview what the layout will look like in different types of themes by clicking the preview placement link in the menu to the left.</p>";
- $output .= "<p>The path setting lets you define on which pages you want a specific block to be shown. If you leave the path blank it will show on all pages. The path uses a regular expression syntax so remember to escape special characters!</p>";
- $output .= "<p>In case you should not know what a regular expression is, you should read about them in the PHP manual. The chapter to look at is the one on <a href=\"http://php.net/pcre\">Perl-Compatible Regular Expressions (PCRE)</a>.</p>";
- $output .= "<p>However, for basic tasks it is sufficient to look at the following examples:</p>";
- $output .= "<p>If the block should only show up on blog pages, use &lt;/blog&gt;. To display on all node views use &lt;/node/view&gt;. The angular brackets are used as delimiters of the regular expression. To show up on either forum or book pages use &lt;(/forum|/book)&gt;. The round brackets form a group of expressions, divided by the | character. It matches if any of the expressions in it match. A more complicated example is &lt;/node/add/(story|blog|image)&gt;. Blocks which have their paths set to this expression will show up on story, block, or image composition pages.</p>";
- $output .= "<h3>Custom Blocks</h3>";
- $output .= "<p>A custom block is a block that contains admin-supplied HTML, text or PHP content (as opposed to being generated automatically by a module). Each custom block consists of a title, a description, and a body of text, HTML, or PHP code which can be as long as you wish. The Drupal engine will 'render' the content of the custom block.</p>";
- $output .= "<h4>PHP in custom blocks</h4>";
- $output .= "<p>If you know how to script in PHP, Drupal gives you the power to embed any script you like inside a block. It will be executed at page view and dynamically embedded into the page. This gives you amazing flexibility and power, but of course with that comes danger and insecurity if you don't write good code. If you are not familiar with PHP, SQL or with the site engine, avoid experimenting with PHP custom blocks because you can corrupt your database or render your site insecure or even unusable! If you don't plan to do fancy stuff with custom blocks then you're probably better off with straight HTML.</p>";
- $output .= "<p>Remember that the code within each PHP custom block must be valid PHP code - including things like correctly terminating statements with a semicolon so that the parser won't die. It is highly recommended that you develop your cusom blocks separately using a simple test script on top of a test database before migrating to your production environment.</p>";
- $output .= "<p>Notes:</p><ul><li>You can use global variables, such as configuration parameters, within the scope of a PHP box but remember that variables which have been given values in a PHP box will retain these values in the engine or module afterwards.</li><li>register_globals is now set to <b>off</b> by default. If you need form information you need to get it from the \"superglobals\" \$_POST, \$_GET, etc.</li><li>You can use the <code>return</code> statement to return the actual content for your block as well.</li></ul>";
- $output .= "<p>A basic example:</p>";
- $output .= "<blockquote><p>You want to have a box with the title \"Welcome\" that you use to greet your visitors. The content for this box could be created by going:</p>";
- $output .= "<pre>
- return t(\"Welcome visitor, ... welcome message goes here ...\");
-</pre>";
- $output .= "<p>If we are however dealing with a registered user, we can customize the message by using:</p>";
- $output .= "<pre>
- if (\$user->uid) {
- return t(\"Welcome \$user->name, ... welcome message goes here ...\");
- }
- else {
- return t(\"Welcome visitor, ... welcome message goes here ...\");
- }";
- $output .= "</pre></blockquote>";
- $output .= "<p>For more in-depth examples, we recommend that you check the existing boxes and use them as a starting point.</p>";
- return t($output);
-
-}
-
-function block_system($field){
- $system["description"] = t("Controls the boxes that are displayed around the main content.");
- return $system[$field];
-}
-
-function block_perm() {
- return array("administer blocks");
-}
-
-function block_link($type) {
- if ($type == "admin" && user_access("administer blocks")) {
- $help["block"] = t("Blocks are the boxes visible in the side bars on the left- and right-hand side of the web site, depending on the choosen theme. They are created by <b>active</b> Drupal modules. In order to view a block it must be enabled. You can assign the block's placement by giving it a region and a weight. The region specifies which side of the page the block is on, and the weight sorts blocks within a region. Lighter (smaller weight value) blocks \"float up\" towards the top of the page. The path setting is a mask which lets you define on which pages you want the specific block to be shown. The custom checkbox lets your users hide the block from their account setting page. You can also create your own blocks, where you specify the content of the block rather than it being generated by a module (you can even use PHP in these). You can create one of these by clicking the %createblock link in the menu to the left. Edit and delete links will become active below for these customized blocks.", array("%createblock" => l(t("create new block"), "admin/block/add")));
- $help["create"] = t("Here you can create a custom content block. Once you have created this block you must make it active, and give it a place on the page using <a href=\"%overview\">block management</a>. The title is used when displaying the block. The description is used in the \"block\" column on the <a href=\"%overview\">block management</a> page. If you are going to place PHP code in the block, and you have <b>create php content</b> permission (see <a href=\"%permission\">user management >> user permissions</a>) you <B>must</b> change the type to PHP to make your code active.", array("%overview" => url("admin/block"), "%permission" => url("admin/user/permission")));
- $help["preview"] = t("This page helps show you the placement of your blocks in different themes. The numbers are the weight of each block, which is used to sort them within the sidebars.");
-
- menu("admin/block", "block management", "block_admin", $help["block"], 3);
- menu("admin/block/add", "create new block", "block_admin", $help["create"], 2);
- menu("admin/block/preview", "preview placement", "block_admin", $help["preview"], 3);
- menu("admin/block/help", "help", "block_help", NULL, 9);
- }
-}
-
-function block_block($op = "list", $delta = 0) {
- if ($op == "list") {
- $result = db_query("SELECT bid, title, info FROM boxes ORDER BY title");
- while ($block = db_fetch_object($result)) {
- $blocks[$block->bid]["info"] = $block->info;
- }
- return $blocks;
- }
- else {
- $block = db_fetch_object(db_query("SELECT * FROM boxes WHERE bid = %d", $delta));
- $data["subject"] = $block->title;
- $data["content"] = ($block->type == 1) ? eval($block->body) : $block->body;
- return $data;
- }
-}
-
-function block_admin_save($edit) {
- foreach ($edit as $module => $blocks) {
- foreach ($blocks as $delta => $block) {
- db_query("UPDATE blocks SET region = %d, status = %d, custom = %d, path = '%s', weight = %d WHERE module = '%s' AND delta = '%s'",
- $block["region"], $block["status"], $block["custom"], $block["path"], $block["weight"], $module, $delta);
- }
- }
-
- return t("the block settings have been updated.");
-}
-
-/**
- * update blocks db table with blocks currently exported by modules
- *
- * @param array $order_by php array_multisort() style sort ordering, eg. "weight", SORT_ASC, SORT_STRING. see {@link http://www.php.net/manual/en/function.array-multisort.php}
- * @return array blocks currently exported by modules, sorted by $order_by
- * @access private
- */
-function _block_rehash($order_by = array("weight")) {
- $result = db_query("SELECT * FROM blocks");
- while ($old_block = db_fetch_object($result)) {
- $old_blocks[$old_block->module][$old_block->delta] = $old_block;
- }
-
- db_query("DELETE FROM blocks");
-
- foreach (module_list() as $module) {
- $module_blocks = module_invoke($module, "block", "list");
- if ($module_blocks) {
- foreach ($module_blocks as $delta => $block) {
- $block["module"] = $module;
- $block["delta"] = $delta;
- if ($old_blocks[$module][$delta]) {
- $block["status"] = $old_blocks[$module][$delta]->status;
- $block["weight"] = $old_blocks[$module][$delta]->weight;
- $block["region"] = $old_blocks[$module][$delta]->region;
- $block["path"] = $old_blocks[$module][$delta]->path;
- $block["custom"] = $old_blocks[$module][$delta]->custom;
- }
- else {
- $block["status"] = $block["weight"] = $block["region"] = $block["custom"] = 0;
- $block["path"] = "";
- }
-
- // reinsert blocks into table
- db_query("INSERT INTO blocks (module, delta, status, weight, region, path, custom) VALUES ('%s', '%s', %d, %d, %d, '%s', %d)",
- $block["module"], $block["delta"], $block["status"], $block["weight"], $block["region"], $block["path"], $block["custom"]);
-
- $blocks[] = $block;
-
- // build array to sort on
- $order[$order_by[0]][] = $block[$order_by[0]];
- }
- }
- }
-
- // sort
- array_multisort($order[$order_by[0]], $order_by[1] ? $order_by[1] : SORT_ASC, $order_by[2] ? $order_by[2] : SORT_REGULAR, $blocks);
-
- return $blocks;
-}
-
-function block_admin_display() {
-
- $blocks = _block_rehash();
-
- $header = array(t("block"), t("enabled"), t("custom"), t("weight"), t("region"), t("path"), array("data" => t("operations"), "colspan" => 2));
-
- foreach ($blocks as $block) {
- if ($block["module"] == "block") {
- $edit = l(t("edit"), "admin/block/edit/". $block["delta"]);
- $delete = l(t("delete"), "admin/block/delete/". $block["delta"]);
- }
- else {
- $edit = "";
- $delete = "";
- }
-
- $rows[] = array($block["info"], array("data" => form_checkbox(NULL, $block["module"]."][".$block["delta"]."][status", 1, $block["status"]), "align" => "center"), array("data" => form_checkbox(NULL, $block["module"]."][".$block["delta"]."][custom", 1, $block["custom"]), "align" => "center"), form_weight(NULL, $block["module"]."][".$block["delta"]."][weight", $block["weight"]), form_select(NULL, $block["module"]."][".$block["delta"]."][region", $block["region"], array(t("left"), t("right"))), form_textfield(NULL, $block["module"]."][".$block["delta"]."][path", $block["path"], 10, 255), $edit, $delete);
- }
-
- $output = table($header, $rows);
- $output .= form_submit(t("Save blocks"));
-
- print form($output);
-}
-
-function block_admin_preview() {
-
- $result = db_query("SELECT * FROM blocks WHERE status > 0 AND region = 0 ORDER BY weight");
- $lblocks .= "<table border=\"0\" cellpadding=\"2\" cellspacing=\"2\">\n";
- while ($block = db_fetch_object($result)) {
- $block_data = module_invoke($block->module, "block", "list");
- $name = $block_data[$block->delta]["info"];
- $lblocks .= " <tr><td>". ($block->status == 2 ? "<b>$name</b>" : $name) ."</td><td>$block->weight</td></tr>\n";
- }
- $lblocks .= "</table>\n";
-
- $result = db_query("SELECT * FROM blocks WHERE status > 0 AND region = 1 ORDER BY weight");
- $rblocks .= "<table border=\"0\" cellpadding=\"2\" cellspacing=\"2\">\n";
- while ($block = db_fetch_object($result)) {
- $block_data = module_invoke($block->module, "block", "list");
- $name = $block_data[$block->delta]["info"];
- $rblocks .= " <tr><td>". ($block->status == 2 ? "<b>$name</b>" : $name) ."</td><td>$block->weight</td></tr>\n";
- }
- $rblocks .= "</table>\n";
-
- $output .= "<h3>". t("Themes with both left and right sidebars") .":</h3>\n";
- $output .= "<table border=\"1\" cellpadding=\"2\" cellspacing=\"2\">\n";
- $output .= " <tr><td colspan=\"3\" style=\"text-align: center;\">". t("header") ."</td></tr>\n";
- $output .= " <tr><td>\n". ($lblocks ? $lblocks : "&nbsp;") ."</td><td style=\"width: 300px;\">&nbsp;</td><td>\n". ($rblocks ? $rblocks : "&nbsp;") ."</td></tr>\n";
- $output .= " <tr><td colspan=\"3\" style=\"text-align: center;\">". t("footer") ."</td></tr>\n";
- $output .= "</table>\n";
-
- $result = db_query("SELECT * FROM blocks WHERE status > 0 ORDER BY weight");
- $blocks .= "<table border=\"0\" cellpadding=\"2\" cellspacing=\"2\">\n";
- while ($block = db_fetch_object($result)) {
- $block_data = module_invoke($block->module, "block", "list");
- $name = $block_data[$block->delta]["info"];
- $blocks .= " <tr><td>". ($block->status == 2 ? "<b>$name</b>" : $name) ."</td><td>$block->weight</td></tr>\n";
- }
- $blocks .= "</table>\n";
-
- $output .= "<h3>". t("Themes with right-sidebar only") .":</h3>\n";
- $output .= "<table border=\"1\" cellpadding=\"2\" cellspacing=\"2\">\n";
- $output .= " <tr><td colspan=\"2\" style=\"text-align: center;\">". t("header") ."</td></tr>\n";
- $output .= " <tr><td style=\"width: 400px;\">&nbsp;</td><td>\n". ($blocks ? $blocks : "&nbsp;") ."</td></tr>\n";
- $output .= " <tr><td colspan=\"2\" style=\"text-align: center;\">". t("footer") ."</td></tr>\n";
- $output .= "</table>\n";
-
- $output .= "<h3>". t("Themes with left-sidebar only") .":</h3>\n";
- $output .= "<table border=\"1\" cellpadding=\"2\" cellspacing=\"2\">\n";
- $output .= " <tr><td colspan=\"2\" style=\"text-align: center;\">". t("header") ."</td></tr>\n";
- $output .= " <tr><td>\n". ($blocks ? $blocks : "&nbsp;") ."</td><td style=\"width: 400px;\">&nbsp;</td></tr>\n";
- $output .= " <tr><td colspan=\"2\" style=\"text-align: center;\">". t("footer") ."</td></tr>\n";
- $output .= "</table>\n";
-
- print $output;
-}
-
-function block_box_get($bid) {
- return db_fetch_array(db_query("SELECT * FROM boxes WHERE bid = %d", $bid));
-}
-
-function block_box_form($edit = array()) {
- $type = array(0 => "HTML", 1 => "PHP");
-
- $form = form_textfield(t("Title"), "title", $edit["title"], 50, 64);
- $form .= form_textfield(t("Description"), "info", $edit["info"], 50, 64);
- $form .= form_textarea(t("Body"), "body", $edit["body"], 70, 10);
- if (user_access("create php content")) {
- $form .= form_select(t("Type"), "type", $edit["type"], $type);
- }
-
- if ($edit["bid"]) {
- $form .= form_hidden("bid", $edit["bid"]);
- }
-
- $form .= form_submit(t("Save block"));
-
- print form($form);
-}
-
-function block_box_save($edit) {
- if (!user_access("create php content")) {
- $edit["type"] = 0;
- }
-
- if ($edit["bid"]) {
- db_query("UPDATE boxes SET title = '%s', body = '%s', info = '%s', type = %d WHERE bid = %d", $edit["title"], $edit["body"], $edit["info"], $edit["type"], $edit["bid"]);
- return t("the block has been updated.");
- }
- else {
- db_query("INSERT INTO boxes (title, body, info, type) VALUES ('%s', '%s', '%s', %d)", $edit["title"], $edit["body"], $edit["info"], $edit["type"]);
- return t("the new block has been added.");
- }
-}
-
-function block_box_delete($bid) {
- if ($bid) {
- db_query("DELETE FROM boxes WHERE bid = %d", $bid);
- return t("the block has been deleted.");
- }
-}
-
-function block_admin() {
- $op = $_POST["op"];
- $edit = $_POST["edit"];
-
- if (user_access("administer blocks")) {
-
- if (empty($op)) {
- $op = arg(2);
- }
-
- switch ($op) {
- case "preview":
- block_admin_preview();
- break;
- case "add":
- block_box_form();
- break;
- case "edit":
- block_box_form(block_box_get(arg(3)));
- break;
- case "delete":
- print status(block_box_delete(arg(3)));
- cache_clear_all();
- block_admin_display();
- break;
- case t("Save block"):
- print status(block_box_save($edit));
- cache_clear_all();
- block_admin_display();
- break;
- case t("Save blocks"):
- print status(block_admin_save($edit));
- cache_clear_all();
- // fall through
- default:
- block_admin_display();
- }
- }
- else {
- print message_access();
- }
-}
-
-function block_user($type, &$edit, &$user) {
- switch ($type) {
- case "register_form":
- $result = db_query("SELECT * FROM blocks WHERE custom = %d ORDER BY module, delta", 1);
-
- while ($block = db_fetch_object($result)) {
- $form .= form_hidden("block][$block->module][$block->delta", $block->status);
- }
-
- return $form;
- case "edit_form":
- $result = db_query("SELECT * FROM blocks WHERE custom = %d ORDER BY module, delta", 1);
-
- while ($block = db_fetch_object($result)) {
- $data = module_invoke($block->module, "block", "list");
- if ($data[$block->delta]["info"]) {
- $form .= "<tr><td>".$data[$block->delta]["info"]."</td><td>". form_checkbox(NULL, "block][$block->module][$block->delta", 1, $user->block[$block->module][$block->delta]) ."</td></tr>\n";
- }
- }
-
- if (isset($form)) {
- return form_item(t("Block configuration"), "<table border=\"0\" cellpadding=\"2\" cellspacing=\"2\">". $form ."</table>", t("Enable the blocks you would like to see displayed in the side bars."));
- }
-
- break;
- case "edit_validate":
- if (!$edit["block"]) {
- $edit["block"] = array();
- }
- return $edit;
- }
-}
-
-?>
diff --git a/modules/blog/blog.module b/modules/blog/blog.module
deleted file mode 100644
index 939ba82..0000000
--- a/modules/blog/blog.module
+++ /dev/null
@@ -1,261 +0,0 @@
-<?php
-// $Id$
-
-function blog_system($field){
- $system["description"] = t("Enables keeping a blog or easily and regularly updated web page.");
- $system["admin_help"] = t("A weBLOG is a running journal of a users ideas. Enter the minimum word count for a single entry, and the text displayed on the entry submission form");
- return $system[$field];
-}
-
-function blog_settings() {
- $output = form_textarea(t("Explanation or submission guidelines"), "blog_help", variable_get("blog_help", ""), 70, 4, t("This text is displayed at the top of the blog submission form. It's useful for helping or instructing your users."));
- $words = t("words");
- $output .= form_select(t("Minimum number of words in a blog entry"), "minimum_blog_size", variable_get("minimum_blog_size", 0), array(0 => "0 $words", 10 => "10 $words", 25 => "25 $words", 50 => "50 $words", 75 => "75 $words", 100 => "100 $words", 125 => "125 $words", 150 => "150 $words", 175 => "175 $words", 200 => "200 $words"), t("The minimum number of words a personal blog entry should contain. This is useful to rule out submissions that do not meet the site's standards, such as short test posts."));
- return $output;
-}
-
-function blog_node($field) {
- global $user;
-
- $info["name"] = t("personal blog entry");
- $info["description"] = t("A blog is a regularly updated journal made up of individual entries, often called posts, that are time stamped and typically arranged by the day, with the newest on top (a diary is the reverse). They tend to be quite personal, often containing links to things you've seen, or to editorials that you find interesting. Some blogs also contain original material written solely for the blog. Since a Blog is personal, you and only you have full control over what you publish. The most interesting blog entries or those blog entries that fit the site's topic well might get promoted to the front page by the community or by users with the access do this.");
-
- return $info[$field];
-}
-
-function blog_perm() {
- return array("maintain personal blog");
-}
-
-function blog_access($op, $node) {
- global $user;
-
- if ($op == "view") {
- return $node->status;
- }
-
- if ($op == "create") {
- return user_access("maintain personal blog") && $user->uid;
- }
-
- if ($op == "update") {
- return user_access("maintain personal blog") && ($user->uid == $node->uid);
- }
-
- if ($op == "delete") {
- return user_access("maintain personal blog") && ($user->uid == $node->uid);
- }
-
-}
-
-function blog_head($main = 0) {
- $mod = arg(0);
- $id = arg(1);
-
- $output = array();
-
- if ($mod == "blog") {
- $output[] = "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"RSS feed\" href=\"". url("blog/feed/$id") ."\" />";
- }
-
- return $output;
-}
-
-function blog_user($type, &$edit, &$user) {
- switch ($type) {
- case "view_public":
- case "view_private":
- if (user_access("maintain personal blog", $user)) {
- return form_item(t("Blog"), l(t("view recent blog entries"), "blog/$user->uid", array("title" => t("Read %username's latest blog entries.", array("%username" => $user->name)))));
- }
- }
-}
-
-function blog_help() {
- $output .= "<p>Drupal's blog module allows registered users to maintain an online weblog (commonly known as a blog), often referred to as an online journal or diary. These can be filled with daily thoughts, poetry, boneless blabber, spiritual theories, intimate details, valuable experiences, cynical rants, semi-coherent comments, writing experiments, artistic babblings, critics on current facts, fresh insights, diverse dreams, chronicles and mumbling madness available for public consumption.</p>";
- $output .= "<p>Blogs are made up of individual entries (nodes) that are timestamped and are typically viewed by day as you would a diary. Blogs often contain links to things you've seen, or agree/disagree with. A typical example of a long term blog can be seen at <a href=\"http://www.scripting.com/\">http://www.scripting.com/</a>.</p>";
- $output .= "<p>The blog module adds a \"user blogs\" navigation link to the site, which takes any visitor to a page that displays the most recent blog entries from all the users on the site. Personal user menus gain a \"create a blog entry\" link (which takes you to a submission form) and a \"view personal blog\" link (which displays your blog entries as other people will see them). On the bottom of each of your own blog entries, there is an \"edit this blog entry\" link that lets you edit or delete that entry.</p>";
- $output .= "<p>If a user has the ability to post blogs, then the import module (news aggregator) will display a blog-it link <b>(b)</b> next to each news item in its lists. Click on this and you will be taken to the blog submission form, with the title, a link to the item, and a link to the source into the body text already in the text box, ready for you to add your explanation. This actively encourages people to add blog entries about things they see and hear elsewhere in the Drupal site and from your syndicated partner sites.</p>";
-
- return t($output);
-
-}
-
-function blog_feed_user($uid = 0) {
- global $user;
-
- if ($uid) {
- $account = user_load(array("uid" => $uid, "status" => 1));
- }
- else {
- $account = $user;
- }
-
- $result = db_query_range("SELECT n.nid, n.title, n.teaser, n.created, u.name, u.uid FROM node n LEFT JOIN users u ON n.uid = u.uid WHERE n.type = 'blog' AND u.uid = %d AND n.status = 1 ORDER BY n.nid DESC", $uid, 0, 15);
- $channel["title"] = $account->name. "'s blog";
- $channel["link"] = url("blog/view/$uid");
- $channel["description"] = $term->description;
- node_feed($result, $channel);
-}
-
-function blog_feed_last() {
- $result = db_query_range("SELECT n.nid, n.title, n.teaser, n.created, u.name, u.uid FROM node n LEFT JOIN users u ON n.uid = u.uid WHERE n.type = 'blog' AND n.status = 1 ORDER BY n.nid DESC", 0, 15);
- $channel["title"] = variable_get("site_name", "drupal") ." blogs";
- $channel["link"] = url("blog");
- $channel["description"] = $term->description;
- node_feed($result, $channel);
-}
-
-function blog_page_user($uid = 0) {
- global $user;
-
- if ($uid) {
- $account = user_load(array((is_numeric($uid) ? "uid" : "name") => $uid, "status" => 1));
- }
- else {
- $account = $user;
- }
-
- $result = pager_query("SELECT nid FROM node WHERE type = 'blog' AND uid = '$account->uid' AND status = 1 ORDER BY nid DESC", variable_get("default_nodes_main", 10));
- while ($node = db_fetch_object($result)) {
- node_view(node_load(array("nid" => $node->nid)), 1);
- }
- print pager_display(NULL, variable_get("default_nodes_main", 10));
- print "<div style=\"text-align: right\">" . l("<img src=\"". theme("image", "xml.gif") ."\" width=\"36\" height=\"14\" style=\"border: 0px;\" alt=\"\" title=\"\" />", "blog/feed/$account->uid", array("title" => t("View the XML version of %username's blog", array ("%username" => $account->name)))) . "</div>";
-}
-
-function blog_page_last() {
- global $user;
-
- $result = pager_query("SELECT nid FROM node WHERE type = 'blog' AND status = 1 ORDER BY nid DESC", variable_get("default_nodes_main", 10));
-
- while ($node = db_fetch_object($result)) {
- $output = node_view(node_load(array("nid" => $node->nid)), 1);
- }
- $output .= pager_display(NULL, variable_get("default_nodes_main", 10));
- $output .= "<div style=\"text-align: right;\">". l("<img src=\"". theme("image", "xml.gif") ."\" width=\"36\" height=\"14\" style=\"border: 0px;\" alt=\"\" title=\"\" />", "blog/feed", array("title" => t("Read the XML version of all blogs."))) ."</div>";
- return $output;
-}
-
-function blog_form(&$node, &$help, &$error) {
- global $nid;
- $iid = $_GET["iid"];
- if (empty($node->body)) {
-
- /*
- ** Carry out some explanation or submission guidelines:
- */
-
- $help = variable_get("blog_help", "");
-
- /*
- ** If the user clicked a "blog it" link, we load the data from the
- ** database and quote it in the blog:
- */
-
- if ($nid && $blog = node_load(array("nid" => $nid))) {
- $node->body = "<i>". $blog->body ."</i> [". l($blog->name, "node/view/$nid") ."]";
- }
-
- if ($iid && $item = db_fetch_object(db_query("SELECT i.*, f.title as ftitle, f.link as flink FROM item i, feed f WHERE i.iid = %d AND i.fid = f.fid", $iid))) {
- $node->title = $item->title;
- $node->body = "<a href=\"$item->link\">$item->title</a> - <i>". check_output($item->description) ."</i> [<a href=\"$item->flink\">$item->ftitle</a>]\n";
- }
- }
- else {
- /*
- ** Validate the size of the blog:
- */
-
- if (count(explode(" ", $node->body)) < variable_get("minimum_blog_size", 0)) {
- $error["body"] = theme("theme_error", t("The body of your blog is too short."));
- }
- }
-
- if (function_exists("taxonomy_node_form")) {
- $output .= implode("", taxonomy_node_form("blog", $node));
- }
- $output .= form_textarea(t("Body"), "body", $node->body, 60, 15, $error["body"] ? $error["body"] : form_allowed_tags_text());
-
- return $output;
-}
-
-function blog_page() {
-
- if (user_access("access content")) {
- switch (arg(1)) {
- case "feed":
- if (arg(2)) {
- blog_feed_user(arg(2));
- }
- else {
- blog_feed_last();
- }
- break;
- default:
- theme("header");
- if (arg(1)) {
- blog_page_user(arg(1));
- }
- else {
- print blog_page_last();
- }
- theme("footer");
- }
- }
- else {
- theme("header");
- theme("box", t("Access denied"), message_access());
- theme("footer");
- }
-
-}
-
-function blog_link($type, $node = 0, $main) {
- global $user;
-
- $links = array();
-
- if ($type == "page" && user_access("access content")) {
- $links[] = l(t("blogs"), "blog", array("title" => t("Read the latest blog entries.")));
- }
-
- if ($type == "menu.create" && user_access("maintain personal blog")) {
- $links[] = l(t("create blog entry"), "node/add/blog", array("title" => t("Add a new personal blog entry.")));
- }
-
- if ($type == "menu.view" && user_access("maintain personal blog")) {
- $links[] = l(t("view personal blog"), "blog/$user->uid", array("title" => t("Read your latest blog entries.")));
- }
-
- if ($type == "node" && $node->type == "blog") {
- global $mod, $op, $id;
-
- if (blog_access("update", $node)) {
- $links[] = l(t("edit this blog entry"), "node/edit/$node->nid", array("title" => t("Edit this blog entry.")));
- }
- elseif (empty($id)) {
- $links[] = l(t("%username's blog", array("%username" => $node->name)), "blog/$node->uid", array("title" => t("Read %username's latest blog entries.", array("%username" => $node->name))));
- }
- }
-
- return $links;
-}
-
-function blog_block($op = "list", $delta = 0) {
- global $user;
- if ($op == "list") {
- $block[0]["info"] = t("Blogs");
- return $block;
- }
- else {
- if (user_access("access content")) {
- $block["content"] = node_title_list(db_query_range("SELECT n.title, n.nid FROM node n WHERE n.type = 'blog' AND n.status = 1 ORDER BY n.nid DESC", 0, 10));
- $block["content"] .= "<div align=\"right\" id=\"blog_more\">". l(t("more"), "blog", array("title" => t("Read the latest blog entries."))) ."</div>";
- $block["subject"] = t("Blogs");
- }
- return $block;
- }
-}
-
-?>
diff --git a/modules/book/book.module b/modules/book/book.module
deleted file mode 100644
index 74737b2..0000000
--- a/modules/book/book.module
+++ /dev/null
@@ -1,787 +0,0 @@
-<?php
-// $Id$
-
-function book_system($field){
- $system["description"] = t("Allows users to collaboratively author a book.");
- return $system[$field];
-}
-
-function book_node($field) {
- global $user;
-
- $info["name"] = t("book page");
- $info["description"] = t("A book is a collaborative writing effort: users can collaborate writing the pages of the book, positioning the pages in the right order, and reviewing or modifying pages previously written. So when you have some information to share or when you read a page of the book and you didn't like it, or if you think a certain page could have been written better, you can do something about it.");
-
- return $info[$field];
-}
-
-function book_perm() {
- return array("maintain books");
-}
-
-function book_access($op, $node) {
- global $user;
-
- if ($op == "view") {
- /*
- ** Everyone can access all published book pages whether these pages
- ** are still waiting for approval or not. We might not always want
- ** to display pages that are waiting for approval, but we take care
- ** of that problem in the book_view() function.
- */
-
- return $node->status;
- }
-
- if ($op == "create") {
- /*
- ** Only registered users can create book pages. Given the nature
- ** of the book module this is considered to be a good/safe idea.
- */
-
- return user_access("maintain books");
- }
-
- if ($op == "update") {
- /*
- ** Only registered users can update book pages. Given the nature
- ** of the book module this is considered to be a good/safe idea.
- ** One can only upate a book page if there are no suggested updates
- ** of that page waiting for approval, when it is not a PHP-page and
- ** as long as the "create new revision"-bit is set. That is, only
- ** updates that don't overwrite the current or pending information
- ** are allowed.
- */
-
- return user_access("maintain books") && !$node->moderate && !$node->format && $node->revision;
- }
-}
-
-function book_link($type, $node = 0, $main = 0) {
-
- $links = array();
-
- if ($type == "page" && user_access("access content")) {
- $links[] = l(t("collaborative book"), "book", array("title" => t("Read and contribute to the collaborative books.")));
- }
-
- if ($type == "menu.create" && user_access("maintain books")) {
- $links[] = l(t("create book page"), "node/add/book", array("title" => t("Add a new book page.")));
- }
-
- if ($type == "node" && $node->type == "book") {
- if (book_access("update", $node)) {
- $links[] = l(t("edit this page"), "node/edit/$node->nid", array("title" => t("Suggest an update for this book page.")));
- }
- if (!$main) {
- $links[] = l(t("printer-friendly version"), "book/print/$node->nid", array("title" => t("Show a printer-friendly version of this book page and its sub-pages.")));
- }
- }
-
- if ($type == "admin" && user_access("maintain books")) {
- $help["book"] = "The collaborative book offers a mean to organize content, authored by many users, in an online manual, outline or FAQ.";
- $help["orphan"] = "Pages in a book are like a tree. As pages are edited, reorganized and removed, child pages might be left with no link to the rest of the book. Such pages are refered to as 'orphan pages'. On this page, administrators can review their books for orphans and reattach those pages as desired.";
-
- menu("admin/node/book", "collaborative books", "book_admin", $help["book"], 4);
- menu("admin/node/book/orphan", "orphan pages", "book_admin", $help["orphan"], 8);
- menu("admin/node/book/help", "help", "book_help", NULL, 9);
-
- $result = db_query("SELECT n.nid, n.title FROM node n INNER JOIN book b ON n.nid = b.nid WHERE b.parent = 0 ORDER BY b.weight, n.title");
- while ($book = db_fetch_object($result)) {
- menu("admin/node/book/$book->nid", "'$book->title' book", "book_admin");
- }
- }
-
- return $links;
-}
-
-function book_load($node) {
- global $user;
-
- $book = db_fetch_object(db_query("SELECT format, parent, weight, log FROM book WHERE nid = %d", $node->nid));
-
- if (strstr(request_uri(), "node/edit")) {
-
- /*
- ** If a user is about to update a book page, we overload some
- ** fields to reflect the changes. We use the request URI to
- ** dectect this as we don't want to interfer with updating a
- ** book page through the admin pages. See also: book_save().
- */
-
- if ($user->uid) {
- $book->uid = $user->uid;
- $book->name = $user->name;
- }
- else {
- $book->uid = 0;
- $book->name = "";
- }
- }
-
- /*
- ** We set the revision field to indicate that we have to create
- ** a new revision when updating this book page. We enable this
- ** always such that the "edit this page"-links appear.
- */
-
- $book->revision = 1;
-
- return $book;
-}
-
-function book_insert($node) {
- db_query("INSERT INTO book (nid, format, parent, weight, log) VALUES (%d, %d, %d, %d, '%s')", $node->nid, $node->format, $node->parent, $node->weight, $node->log);
-}
-
-function book_update($node) {
- db_query("UPDATE book SET format = %d, parent = %d, weight = %d, log = '%s' WHERE nid = %d", $node->format, $node->parent, $node->weight, $node->log, $node->nid);
-}
-
-function book_delete(&$node) {
- db_query("DELETE FROM book WHERE nid = %d", $node->nid);
-}
-
-function book_validate(&$node) {
- if ($node->format && user_access("create php content")) {
- // Do not filter PHP code, do not auto-extract a teaser
- $node->teaser = $node->body;
- }
- else {
- $node->format = 0;
- }
-
- // Set default values for non administrators:
- if (!user_access("administer nodes")) {
- $node->format = 0;
- $node->weight = 0;
- $node->revision = 1;
- }
-}
-
-function book_form(&$node, &$help, &$error) {
- global $user;
-
- $op = $_POST["op"];
- $output = form_select(t("Parent"), "parent", $node->parent, book_toc(), t("The parent subject or category the page belongs in."));
-
- if (function_exists("taxonomy_node_form")) {
- $output .= implode("", taxonomy_node_form("book", $node));
- }
-
- $output .= form_textarea(t("Body"), "body", $node->body, 60, 20, form_allowed_tags_text());
- $output .= form_textarea(t("Log message"), "log", $node->log, 60, 5, t("An explanation of the additions or updates being made to help the group understand your motivations."));
-
- if (user_access("administer nodes")) {
- $output .= form_weight(t("Weight"), "weight", $node->weight, 15, t("The heavier pages will sink and the lighter pages will be positioned nearer the top."));
- if (user_access("create php content")) {
- $output .= form_select("Type", "format", $node->format, array(0 => "HTML / text", 1 => "PHP"));
- }
- }
- else {
-
- /*
- ** Carry out some explanation or submission guidelines:
- */
-
- $help = book_node("description");
-
- /*
- ** If a regular user updates a book page, we create a new revision
- ** authored by that user:
- */
-
- $output .= form_hidden("revision", 1);
- }
-
- return $output;
-}
-
-function book_node_link($node = 0) {
- global $user;
-
- $op = $_POST["op"];
- $edit = $_POST["edit"];
-
- if ($node->type != "book") {
-
- if ($edit["nid"]) {
- $node = node_load(array("nid" => $edit["nid"]));
- }
-
- if ($op == t("Add to book outline")) {
- db_query("INSERT INTO book (nid, parent, weight) VALUES (%d, %d, %d)", $node->nid, $edit["parent"], $edit["weight"]);
- $output .= status(t("added the node to the book."));
- }
-
- if ($op == t("Update book outline")) {
- db_query("UPDATE book SET parent = %d, weight = %d WHERE nid = %d", $edit["parent"], $edit["weight"], $node->nid);
- $output .= status(t("updated the book outline."));
- }
-
- if ($op == t("Remove from book outline")) {
- db_query("DELETE FROM book WHERE nid = %d", $node->nid);
- $output .= status(t("removed the node form the book."));
- }
-
- $output .= "<h3>". t("Edit book outline for node <i>") . "$node->title</i></h3>";
-
- if ($edit["nid"]) {
- $page = db_fetch_object(db_query("SELECT * FROM book WHERE nid = %d", $node->nid));
-
- $output .= form_select(t("Parent"), "parent", $page->parent, book_toc(), t("The parent subject or category the page belongs in."));
- $output .= form_weight(t("Weight"), "weight", $node->weight, 15, t("The heavier pages will sink and the lighter pages will be positioned nearer the top."));
-
- if ($page->nid) {
- $output .= form_submit(t("Update book outline"));
- $output .= form_submit(t("Remove from book outline"));
- }
- else {
- $output .= form_submit(t("Add to book outline"));
- }
-
- }
- else {
- $output .= form_submit(t("Edit book outline"));
- }
-
- $output .= form_hidden("nid", $node->nid);
-
- return form($output, "post", url("admin/node/book"));
- }
-}
-
-/*
-** Return the the most recent revision that matches the specified
-** conditions.
-*/
-
-function book_revision_load($page, $conditions = array()) {
-
- $revisions = array_reverse(node_revision_list($page));
-
- foreach ($revisions as $revision) {
-
- /*
- ** Extract the specified revision:
- */
-
- $node = node_revision_load($page, $revision);
-
- /*
- ** Check to see if the conditions are met:
- */
-
- $status = 1;
-
- foreach ($conditions as $key => $value) {
- if ($node->$key != $value) {
- $status = 0;
- }
- }
-
- if ($status) {
- return $node;
- }
- }
-}
-
-/*
-** Return the path (call stack) to a certain book page.
-*/
-function book_location($node, $nodes = array()) {
- $parent = db_fetch_object(db_query("SELECT n.nid, n.title, b.parent FROM node n INNER JOIN book b ON n.nid = b.nid WHERE n.nid = %d", $node->parent));
- if ($parent->title) {
- $nodes = book_location($parent, $nodes);
- array_push($nodes, $parent);
- }
- return $nodes;
-}
-
-function book_location_down($node, $nodes = array()) {
- $last_direct_child = db_fetch_object(db_query("SELECT n.nid, n.title, b.parent FROM node n INNER JOIN book b ON n.nid = b.nid WHERE b.parent = %d ORDER BY b.weight DESC, n.title DESC", $node->nid));
- if ($last_direct_child) {
- array_push($nodes, $last_direct_child);
- $nodes = book_location_down($last_direct_child, $nodes);
- }
- return $nodes;
-}
-
-function book_prev($node) {
- // if the parent is zero, we are at the start of a book so there is no previous
- if ($node->parent == 0) {
- return NULL;
- }
-
- // previous on the same level
- $direct_above = db_fetch_object(db_query("SELECT n.nid, n.title FROM node n INNER JOIN book b ON n.nid = b.nid WHERE b.parent = %d AND n.status = 1 AND (n.moderate = 0 OR n.revisions != '') AND (b.weight < %d OR (b.weight = %d AND n.title < '%s')) ORDER BY b.weight DESC, n.title DESC", $node->parent, $node->weight, $node->weight, $node->title));
- if ($direct_above) {
- // get last leaf of $above
- $path = book_location_down($direct_above);
-
- return $path ? (count($path) > 0 ? array_pop($path) : NULL) : $direct_above;
- }
- else {
- // direct parent
- $prev = db_fetch_object(db_query("SELECT n.nid, n.title FROM node n INNER JOIN book b ON n.nid = b.nid WHERE n.nid = %d AND n.status = 1 AND (n.moderate = 0 OR n.revisions != '')", $node->parent));
- return $prev;
- }
-}
-
-function book_next($node) {
- // get first direct child
- $child = db_fetch_object(db_query("SELECT n.nid, n.title FROM node n INNER JOIN book b ON n.nid = b.nid WHERE b.parent = %d AND n.status = 1 AND (n.moderate = 0 OR n.revisions != '') ORDER BY b.weight ASC, n.title ASC", $node->nid));
- if ($child) {
- return $child;
- }
-
- // no direct child: get next for this level or any parent in this book
- array_push($path = book_location($node), $node); // path to root node including this one
- // loop through nodes to book root, starting with this node
- while (($leaf = array_pop($path)) && count($path)) {
- $next = db_fetch_object(db_query("SELECT n.nid, n.title FROM node n INNER JOIN book b ON n.nid = b.nid WHERE b.parent = %d AND n.status = 1 AND (n.moderate = 0 OR n.revisions != '') AND (b.weight > %d OR (b.weight = %d AND n.title > '%s')) ORDER BY b.weight ASC, n.title ASC", $leaf->parent, $leaf->weight, $leaf->weight, $leaf->title));
- if ($next) {
- return $next;
- }
- }
-}
-
-function book_body($node) {
- $op = $_POST["op"];
-
- if ($node->format == 1) {
- // Make sure only authorized users can preview PHP pages.
- if ($op == t("Preview") && !user_access("create php content")) {
- return;
- }
-
- ob_start();
- eval($node->body);
- $output = ob_get_contents();
- ob_end_clean();
- }
- else {
- $output = check_output($node->body);
- }
-
- return $output;
-}
-
-function book_view($node, $main = 0) {
-
- /*
- ** Always display the most recently approved revision of a node
- ** (if any) unless we have to display this page in the context of
- ** the moderation queue.
- */
-
- if ($node->moderate && arg(0) != "queue") {
- $revision = book_revision_load($node, array("moderate" => 0, "status" => 1));
-
- if ($revision) {
- $node = $revision;
- }
- }
-
- /*
- ** Extract the page body. If body is dynamic (using PHP code), the body
- ** will be generated.
- */
-
- $node->body = book_body($node);
-
- /*
- ** Display the node. If not displayed on the main page, we render
- ** the node as a page in the book with extra links to the previous
- ** and the next page.
- */
-
- if ($main) {
- theme("node", $node, $main);
- }
- else {
- /*
- ** Construct the "next" and "previous" links:
- */
-
- if ($node->nid) {
- $prev = book_prev($node);
- $next = book_next($node);
- }
-
- // build the tree from bottom to top to have the book index in $level for navigation later
- $path = book_location($node);
- foreach ($path as $level) {
- $trail[] = l($level->title, "node/view/$level->nid");
- }
-
- $output .= "<div class=\"book\">";
- if ($trail) {
- $output .= "<div class=\"location\">". implode($trail, " &raquo; ") ."</div><hr />";
- }
- $output .= "<div class=\"title\">$node->title</div>";
- $output .= "<div class=\"last-updated\">". t("Last updated by %u on %d", array("%u" => format_name($node), "%d" => format_date($node->changed))) ."</div>";
-
- $output .= "<div class=\"body\">$node->body</div>";
-
- if ($node->moderate) {
- $output .= "<div class=\"log\"><div class=\"title\">". t("Log") .":</div>$node->log</div>";
- }
-
- if ($node->nid) {
- $output .= "<div class=\"tree\">". book_tree($node->nid) ."</div>";
- if ($prev) {
- $links .= "<div class=\"prev\">";
- $links .= l(t("previous"), "node/view/$prev->nid", array("title" => t("View the previous page in this book.")));
- $links .= "</div>";
- $titles .= "<div class=\"prev\">$prev->title</div>";
- }
- if ($next) {
- $links .= "<div class=\"next\">";
- $links .= l(t("next"), "node/view/$next->nid", array("title" => t("View the next page in this book.")));
- $links .= "</div>";
- $titles .= "<div class=\"next\">$next->title</div>";
- }
- if ($node->parent) {
- $links .= "<div class=\"up\">";
- $links .= l(t("up"), "node/view/$node->parent", array("title" => t("View this page's parent section.")));
- if ($node->parent != $level->nid) {
- $links .= " | ";
- $links .= l(t("index"), "node/view/$level->nid", array("title" => t("View this book's table of contents.")));
- }
- $links .= "</div>";
- }
- $output .= "<div class=\"nav\">";
- $output .= "<div class=\"links\">$links</div>";
- $output .= "<div class=\"titles\">$titles</div>";
- $output .= "</div>";
- }
- $output .= "<div class=\"links\">". theme("links", link_node($node, $main)) ."</div>";
- $output .= "</div>";
-
- theme("box", t("Handbook"), $output);
- }
-}
-
-function book_toc_recurse($nid, $indent, $toc, $children) {
-
- if ($children[$nid]) {
- foreach ($children[$nid] as $foo => $node) {
- $toc[$node->nid] = "$indent $node->title";
- $toc = book_toc_recurse($node->nid, "$indent--", $toc, $children);
- }
- }
-
- return $toc;
-}
-
-function book_toc($parent = 0, $indent = "", $toc = array()) {
-
- $result = db_query("SELECT n.nid, n.title, b.parent FROM node n INNER JOIN book b ON n.nid = b.nid WHERE n.status = '1' ORDER BY b.weight, n.title");
-
- while ($node = db_fetch_object($result)) {
- $list = $children[$node->parent] ? $children[$node->parent] : array();
- array_push($list, $node);
- $children[$node->parent] = $list;
- }
-
- /*
- ** If the user is an administrator, add the root node; only
- ** administrators can start new books.
- */
-
- if (user_access("administer nodes")) {
- $toc[0] = "<". t("root") .">";
- }
-
- /*
- ** Iterate root book nodes:
- */
-
- $toc = book_toc_recurse($parent, $indent, $toc, $children);
-
- return $toc;
-}
-
-
-function book_tree_recurse($nid, $depth, $children) {
-
- if ($depth > 0) {
- if ($children[$nid]) {
- foreach ($children[$nid] as $foo => $node) {
- $output .= "<li>";
- $output .= l($node->title, "node/view/$node->nid");
- if ($tree = book_tree_recurse($node->nid, $depth - 1, $children)) {
- $output .= "<ul>$tree</ul>";
- }
- $output .= "</li>";
- }
- }
- }
-
- return $output;
-}
-
-
-function book_tree($parent = 0, $depth = 3) {
-
- $result = db_query("SELECT n.nid, n.title, b.parent FROM node n INNER JOIN book b ON n.nid = b.nid WHERE n.status = '1' AND n.moderate = '0' ORDER BY b.weight, n.title");
-
- while ($node = db_fetch_object($result)) {
- $list = $children[$node->parent] ? $children[$node->parent] : array();
- array_push($list, $node);
- $children[$node->parent] = $list;
- }
-
- $output = book_tree_recurse($parent, $depth, $children);
- $output = "<ul>$output</ul>";
-
- return $output;
-}
-
-
-function book_render() {
-
- $result = db_query("SELECT n.nid FROM node n INNER JOIN book b ON n.nid = b.nid WHERE b.parent = 0 AND n.status = 1 AND (n.moderate = 0 OR n.revisions IS NOT NULL) ORDER BY b.weight, n.title");
-
- while ($page = db_fetch_object($result)) {
- // load the node:
- $node = node_load(array("nid" => $page->nid));
-
- // take the most recent approved revision:
- if ($node->moderate) {
- $node = book_revision_load($node, array("moderate" => 0, "status" => 1));
- }
-
- if ($node) {
- // output the content:
- $output .= "<div class=\"book\">";
- $output .= "<div class=\"title\">". l($node->title, "node/view/$node->nid") ."</div>";
- $output .= "<div class=\"body\">". book_body($node) ."</div>";
- $output .= "</div>";
- }
- }
-
- theme("header");
- theme("box", t("Handbook"), "$output");
- theme("footer");
-}
-
-function book_page() {
-
-
- if (user_access("access content")) {
- switch (arg(1)) {
- case "print":
- print book_print(arg(2), $depth = 1);
- break;
- default:
- book_render();
- }
- }
- else {
- theme("header");
- theme("box", t("Access denied"), message_access());
- theme("footer");
- }
-}
-
-function book_print($id = "", $depth = 1) {
- global $base_url;
- $result = db_query("SELECT n.nid FROM node n INNER JOIN book b ON n.nid = b.nid WHERE n.status = 1 AND n.nid = %d AND (n.moderate = 0 OR n.revisions IS NOT NULL) ORDER BY b.weight, n.title", $id);
-
- while ($page = db_fetch_object($result)) {
- // load the node:
- $node = node_load(array("nid" => $page->nid));
-
- // take the most recent approved revision:
- if ($node->moderate) {
- $node = book_revision_load($node, array("moderate" => 0, "status" => 1));
- }
-
- if ($node) {
- // output the content:
- $output .= "<h1 id=\"$node->nid\" name=\"$node->nid\" class=\"book-h$depth\">$node->title</h1>";
-
- if ($node->body) {
- $output .= book_body($node);
- }
- }
- }
-
- $output .= book_print_recurse($id, $depth);
-
- $html = "<html><head><title>$node->title</title>";
- $html .= "<base href=\"$base_url/\" />";
- $html .= "<style type=\"text/css\">\n@import url(misc/print.css);\n</style>";
- $html .= "</head><body>". $output ."</body></html>";
-
- return $html;
-}
-
-function book_print_recurse($parent = "", $depth = 1) {
- $result = db_query("SELECT n.nid FROM node n INNER JOIN book b ON n.nid = b.nid WHERE n.status = 1 AND b.parent = '$parent' AND (n.moderate = 0 OR n.revisions IS NOT NULL) ORDER BY b.weight, n.title");
-
- while ($page = db_fetch_object($result)) {
- // load the node:
- $node = node_load(array("nid" => $page->nid));
-
- // take the most recent approved revision:
- if ($node->moderate) {
- $node = book_revision_load($node, array("moderate" => 0, "status" => 1));
- }
-
- if ($node) {
- // output the content:
- $output .= "<h1 id=\"$node->nid\" name=\"$node->nid\" class=\"book-h$depth\">$node->title</h1>";
-
- if ($node->body) {
- $output .= "<ul>". book_body($node) ."</ul>";
- }
-
- $output .= book_print_recurse($node->nid, $depth + 1);
- }
- }
-
- return $output;
-}
-
-function book_admin_view_line($node, $depth = 0) {
-
- $row = array("<div style=\"padding-left: ". (25 * $depth) ."px;\">". form_textfield(NULL, "$node->nid][title", $node->title, 64, 255) ."</div>", form_weight(NULL, "$node->nid][weight", $node->weight), l(t("view node"), "node/view/$node->nid"), l(t("edit node"), "admin/node/edit/$node->nid"), l(t("delete node"), "admin/node/delete/$node->nid"));
-
- return $row;
-}
-
-function book_admin_view_book($nid, $depth = 1) {
- $result = db_query("SELECT n.nid FROM node n INNER JOIN book b ON n.nid = b.nid WHERE b.parent = %d ORDER BY b.weight, n.title", $nid);
-
- while ($node = db_fetch_object($result)) {
- $node = node_load(array("nid" => $node->nid));
- $rows[] = book_admin_view_line($node, $depth);
- $rows = array_merge($rows, book_admin_view_book($node->nid, $depth + 1));
- }
-
- return $rows;
-}
-
-function book_admin_view($nid, $depth = 0) {
-
- if ($nid) {
- $node = node_load(array("nid" => $nid));
-
- $output .= "<h3>$node->title</h3>";
-
- $header = array(t("title"), t("weight"), array("data" => t("operations"), "colspan" => 3));
- $rows[] = book_admin_view_line($node);
- $rows = array_merge($rows, book_admin_view_book($nid));
-
- $output .= table($header, $rows);
- $output .= form_submit(t("Save book pages"));
-
- return form($output);
- }
-}
-
-function book_admin_save($nid, $edit = array()) {
-
- if ($nid) {
- $book = node_load(array("nid" => $nid));
-
- foreach ($edit as $nid => $value) {
- /*
- ** Check to see whether the title needs updating:
- */
-
- $title = db_result(db_query("SELECT title FROM node WHERE nid = %d", $nid));
- if ($title != $value["title"]) {
- db_query("UPDATE node SET title = '%s' WHERE nid = %d", $value["title"], $nid);
- }
-
- /*
- ** Check to see whether the weight needs updating:
- */
-
- $weight = db_result(db_query("SELECT weight FROM book WHERE nid = %d", $nid));
- if ($weight != $value["weight"]) {
- db_query("UPDATE book SET weight = %d WHERE nid = %d", $value["weight"], $nid);
- }
- }
-
- $message = t("updated book '%title'", array("%title" => $book->title));
- watchdog("special", $message);
-
- return $message;
- }
-}
-
-function book_admin_orphan() {
-
- $result = db_query("SELECT n.nid, n.title, n.status, b.parent FROM node n INNER JOIN book b ON n.nid = b.nid WHERE n.type = 'book'");
-
- while ($page = db_fetch_object($result)) {
- $pages[$page->nid] = $page;
- }
-
- if ($pages) {
- $output .= "<h3>Orphan pages</h3>";
- $header = array(t("title"), t("weight"), array("data" => t("operations"), "colspan" => 3));
- foreach ($pages as $nid => $node) {
- if ($node->parent && empty($pages[$node->parent])) {
- $rows[] = book_admin_view_line($node, $depth);
- $rows = array_merge($rows, book_admin_view_book($node->nid, $depth + 1));
- }
- }
- $output .= table($header, $rows);
- }
-
- return $output;
-}
-
-function book_admin_links() {
-}
-
-function book_admin() {
- $op = $_POST["op"];
- $edit = $_POST["edit"];
-
- if (user_access("administer nodes")) {
- if (empty($op)) {
- $op = arg(3);
- }
-
- switch ($op) {
- case t("Edit book outline"):
- case t("Add to book outline"):
- case t("Remove from book outline"):
- case t("Update book outline"):
- print book_node_link();
- break;
- case "orphan":
- print book_admin_orphan();
- break;
- case t("Save book pages"):
- print status(book_admin_save(arg(3), $edit));
- // fall through:
- default:
- print book_admin_view(arg(3));
- break;
- }
- }
-}
-
-function book_help() {
- $output .= "<p>The <i>collaborative book</i> organises content into a nested hierarchical structure. It is particularly good for manuals,FAQs and the like, allowing you to have chapters, sections, etc.</p>";
- $output .= "<p>A book is simply a collection of nodes that have been linked together. These nodes are usually of type <i>book page</i>, but you can insert nodes of any type into a book outline. Every node in the book has a <i>parent</i> node which \"contains\" it. This is how book.module establishes its hierarchy. At any given level in the hierarchy, a book can contain many nodes. All these sibling nodes are sorted according to the <i>weight</i> that you give them.</p>";
- $output .= "<p>A book page is a special node type that allows you to embed PHP within the body of the page. This capability is only offerred to administrators, since malicious users could abuse this power. In addiiton, book pages contain a <i>log message</i> field which helps your users understand the motivation behind an edit of a book page. Each edited version of a book page is stored as a new revision of a node. This capability makes it easy to revert to an old version of a page, should that be desirable.</p>";
- $output .= "<p>Like other node types, book submissions and edits may be subject to moderation, depending on your configuration. Similarly, books use ". l("permissions", "admin/user/permission") ." to determine who may read and write to them. Only administrators are allowed to create new books, which are really just nodes whose parent is <i>&lt;root&gt;</i>. To include an existing node in your book, click on the \"administer\"-link in that node. At the bottom of this administration page, click on the <i>edit book outline</i> button. This enables you to place the node wherever you'd like within the book hierarchy. To add a new node into your book, use the <i>create book page</i> link.</p>";
- $output .= "<p>Administrators may review the hierarchy of their books by clicking on the ". l("collaborative book", "admin/node/book")." link in the adminstration pages. There, nodes may be edited, reorganized, removed from book, and deleted. This behavior may change in the future. When a parent node is deleted, it may leave behind child nodes. These nodes are now <i>orphans</i>. Administrators should periodically ". l("review their books for orphans", "admin/node/book/orphan") ." and reaffiliate those pages as desired. Finally, administrators may also ". l("export their books", "book/print") ." to a single, flat HTML page which is suitable for printing.</p>";
- $output .= "<h3>Maintaining a FAQ using a collaborative book</h3>";
- $output .= "<p>Collaborative books let you easily set up a Frequently Asked Questions section on your web site. The main benefit is that you don't have to write all the questions/answers by yourself - let the community do it for you!</p>";
- $output .= "<p>In order to set up the FAQ, you have to create a new book which will hold all your content. To do so, click on <i>create book page</i> in your user box. Give it a thoughtful title, and body. A title like \"Estonia Travel - FAQ\" is nice. You may always edit these fields later. You will probably want to designate <i>&lt;root&gt;</i> as the parent of this page. Leave the <i>log message</i> and <i>type</i> fields blank for now. After you have submitted this book page, you are ready to begin filling up your book with questions that are frequently asked.</p>";
- $output .= "<p>Whenever you come across a post which you want to include in your FAQ, click on the <i>administer</i> link. Then click on the <i>edit book outline</i> button at the bottom of the page. Then place the relevant post wherever is most appropriate in your book by selecting a <i>parent</i>. Books are quite flexible. They can have sections like <i>Flying to Estonia</i>, <i>Eating in Estonia</i> and so on. As you get more experienced with the <i>collaborative book</i>, you can reorganize posts in your book so that it stays organized.</p>";
- $output .= "<p>Notes:</p><ul><li>Any comments attached to those relevant posts which you designate as book pages will also be transported into your book. This is a great feature, since much wisdom is shared via comments. Remember that all future comments and edits will automatically be reflected in your book.</li><li>You may wish to edit the title of posts when adding them to your FAQ. This is done on the same page as the <i>Edit book outline</i> button. Clear titles improve navigability enormously.</li><li>Book pages may come from any content type (blog, story, page, etc.). If you are creating a post solely for inclusion in your book, then use the <i>Create book page</i> link.</li><li>If you don't see the <i>administer</i> link, then you probably have insufficient ". l("permissions", "admin/user/permission") .".</li><li>If you want to get really fancy, note that books are one of the few content types which allow raw PHP in their <i>body</i>. So you've got lots of geeky possibilities there.</li></ul>";
- return t($output);
-
-}
-?>
diff --git a/modules/comment/comment.module b/modules/comment/comment.module
deleted file mode 100644
index f6d6518..0000000
--- a/modules/comment/comment.module
+++ /dev/null
@@ -1,1549 +0,0 @@
-<?php
-// $Id$
-
-$GLOBALS["cmodes"] = array(1 => t("Flat list - collapsed"), 2 => t("Flat list - expanded"), 3 => t("Threaded list - collapsed"), 4 => t("Threaded list - expanded"));
-$GLOBALS["corder"] = array(1 => t("Date - newest first"), 2 => t("Date - oldest first"));
-
-function comment_help() {
- $output .= t("<p>When enabled, the Drupal comment module creates a discussion board for each Drupal node. Users can post comments to discuss a forum topic, weblog post, collaborative book page, etc.</p>
-
-<h3>User control of comment display</h3>
-<p>Attached to each comment board is a control panel for customizing the way that comments are displayed. Users can control the chronological ordering of posts (newest or oldest first) and the number of posts to display on each page. Additional settings include:</p>
-<ul>
- <li><b>Threaded </b>-- Comment posts are displayed much like the subject view of an email client: the posts are grouped according to the conversations and subconversations.</li>
- <li><b>Flat </b>-- Displays the posts in chronological order, in the order in which they are posted.</li>
- <li><b>Expanded </b>-- Displays the title and text for each post.</li>
- <li><b>Collapsed</b> -- Displays only the title for each post.</li>
-</ul>
-<p>When users choose <i>save settings</i>, the comments are then redisplayed with the user's choices. Know that administrators can set the default settings for the control panel, along with other comment configuration defaults, in <i>site configuration &raquo; modules &raquo; comment</i>.</p>
-<p>NOTE: When comment moderation is enabled, users will have another control panel option to control thresholds (see below).</p>
-
-<h3>Additional comment configurations</h3>
-<p>Comments behave like other user submissions in Drupal. Filters, smileys and HTML that work in nodes will also work with content. To prevent a single user from spamming the web site with too many comments, administrators can set a comment throttle in <i>site configuration</i> under <i>Submission settings</i>.</p>
-<p>Administrators can control access to various comment module functions through <i>user management &raquo; user permissions</i>. Know that in a new Drupal installation, all comment permissions are disabled by default. The choice of which permissions to grant to which roles (groups of users) is left up to the site administrator.</p>
-<p>The following permissions can be enabled for anonymous users, authenticated users, or any other roles that the administrator chooses to define:</p>
-<ul>
- <li><b>Access comments</b> -- Necessary for users to view comments.</li>
- <li><b>Administrate comments</b> -- Gives the user complete control over configuring, editing and deleting all comments on the site. Best reserved for very trusted users.</li>
- <li><b>Moderate comments</b> -- Users with this permission can rate comment postings (see more on moderation below).</li>
- <li><b>Post comments</b> -- Allows users to post comments into an administrator moderation queue. Administrators then post the comment to the site. </li>
- <li><b>Post comments without approval</b> -- Bypasses the administrator moderation queue and comments are posted directly.</li>
-</ul>
-
-<h3>Notification of new comments</h3>
-<p>Drupal provides specific features to inform site members when new comments have been posted:</p>
-<ul>
- <li>On the home page, Drupal displays the total number of comments along with each node. Drupal also tracks comments read by individual site members. Logged in members will see a notice accompanying nodes containing comments which they have not read.</li>
- <li>The <i>tracker</i> module displays all recent posts on the site (note that the tracker module is disabled by default). When logged in, members will find a <i>view recent posts </i>in their user information block with a link to the <i>Recent activity</i> page. This page is a useful way to browse new or updated nodes and comments. Content which the user has not yet read is tagged with a red star (this graphic may depend on the current theme). Visit the comment board for any node, and Drupal will display a red <i>new</i> label beside the text of unread comments.</li>
- <li>Some administrators may want to <a href=\"http://drupal.org/node/view/68\">download</a>, install and configure the notify module. Users can then request that Drupal send them an email when new comments are posted (the notify module requires that cron.php be configured properly).</li>
-</ul>
-
-<h3>Comment moderation</h3>
-<p>On sites with active commenting from users, the administrator can turn over comment moderation to the community. </p>
-<p>With comment moderation, each comment is automatically assigned an initial rating. As users read comments, they can apply a vote which affects the comment rating. At the same time, users have an additional option in the control panel which allows them to set a threshold for comment display. Those comments with ratings lower than the set threshold will not appear.</p>
-<p>To enable moderation, the administrator must grant <i>moderate comments</i> permissions. Then, a number of options in <i>comment management &raquo; comment moderation</i> must be configured.</p>
-
-<h4>Moderation votes</h4>
-<p>The first step is to create moderation labels which allow users to rate a comment. Go to <i>comment management &raquo; comment moderation &raquo; votes</i>. In the <i>vote</i> field, enter the textual labels which users will see when casting their votes. Some examples might be</p>
-<ul>
- <li>Excellent +3</li>
- <li>Insightful +2</li>
- <li>Caught My Attention +1</li>
- <li>Useful +1</li>
- <li>Redundant -1</li>
- <li>Flame -3</li>
-</ul>
-<p>So that users know how there votes affect the comment, these examples include the vote value as part of the label, although that is optional.</p>
-<p>Using the weight option, you can control the order in which the votes appear to users. Setting the weight heavier (positive numbers) will make the vote label appear at the bottom of the list. Lighter (a negative number) will push it to the top. To encourage positive voting, a useful order might be higher values, positive votes, at the top, with negative votes at the bottom.</p>
-
-<h4>Moderators/vote values matrix</h4>
-
-<p> Next go to <i>comment management &raquo; comment moderation &raquo; matrix</i>. Enter vote values for each of the labels in the matrix with each permission role. The values entered here will be used to create the rating for each comment.</p>
-<p>NOTE: Comment ratings are calculated by averaging user votes with the initial rating.</p>
-<h4>Creating comment thresholds</h4>
-<p>In <i>comment management &raquo; comment moderation &raquo; thresholds</i>, you'll have to create some comment thresholds to make the comment rating system useful. When comment moderation is enabled and the thresholds are created, users will find another comment control panel option for selecting thresholds. They'll use the thresholds you enter here to filter out comments with low ratings. Consequently, you'll probably want to create more than one threshold to give users some flexibility in filtering comments.</p>
-<p>When creating the thresholds, note that the <i>Minimum score</i> is asking you for the lowest rating that a comment can have in order to be displayed.</p>
-<p>To see a common example of how thresholds work, you might visit <a href=\"http://slashdot.org/\">Slashdot</a> and view one of their comment boards associated with a story. You can reset the thresholds in their comment control panel.</p>
-
-<h4>Initial comment scores</h4>
-<p>Finally, you may want to enter some <i>initial comment scores</i>. In <i>comment management &raquo; initial comment scores </i>you can assign a beginning rating for all comments posted by a particular permission role. If you do not assign any initial scores, Drupal will assign a rating of <b>0</b> as the default.</p>");
-
- return $output;
-}
-
-function comment_system($field) {
- $system["description"] = t("Enables user to comment on content (nodes).");
- $system["admin_help"] = t("Comments can be attached to any node. Below are the settings for comments. The display comes in two types, a \"flat list\" where everything is flush to the left side, and comments come in cronological order, and a \"threaded list\" where comments to other comments are placed immediately below the orignal, and slightly indented forming an outline of comments. They also come in two styles: \"expanded\", where you get to see both the title and the contents, and \"collapsed\" where you only see the titles. To set the default threshold you first have to set up thresholds in the <a href=\"%threshold\">comment management &gt;&gt; comment moderation &gt;&gt; thresholds</a> area. Preview comment forces a user to click on a \"Preview\" button so they can see what their comment will look like before they can actually add the comment to the system. If \"New comment form\" is enabled then at the bottom of every comment page there will be a form too add a new comment.", array("%threshold" => url("admin/comment/moderation/filters")));
- return $system[$field];
-}
-
-function comment_settings() {
- global $cmodes, $corder;
-
- $output .= form_select(t("Default display mode"), "comment_default_mode", variable_get("comment_default_mode", 4), $cmodes, t("The default view for comments. Expanded views display the body of the comment. Threaded views keep replies together."));
- $output .= form_select(t("Default display order"), "comment_default_order", variable_get("comment_default_order", 1), $corder, t("The default sorting for new users and anonymous users while viewing comments. These users may change their view using the comment control panel. For registered users, this change is remembered as a persistent user preference."));
- $output .= form_textfield(t("Default comments per page"), "comment_default_per_page", variable_get("comment_default_per_page", "50"), 5, 5, t("Default number of comments for each page; more comments are distributed in several pages."));
-
- $result = db_query("SELECT fid, filter FROM moderation_filters");
- while ($filter = db_fetch_object($result)) {
- $thresholds[$filter->fid] = ($filter->filter);
- }
-
- $output .= form_select(t("Default threshold"), "comment_default_threshold", variable_get("comment_default_threshold", 0), $thresholds, t("Thresholds are values below which comments are hidden. These thresholds are useful for busy sites which want to hide poor comments from most users."));
-
- $output .= form_select(t("Preview comment"), "comment_preview", variable_get("comment_preview", 1), array(t("Optional"), t("Required")), t("Must users preview comments before submitting?"));
- $output .= form_select(t("New comment form"), "comment_new_form", variable_get("comment_new_form", 0), array(t("Disabled"), t("Enabled")), t("New comment form in the node page?"));
- $output .= form_select(t("Comment controls"), "comment_controls", variable_get("comment_controls", 0), array(t("Above comments"), t("Below comments"), t("Above and below")), t("Position of the comment controls box."));
-
- return $output;
-}
-
-function comment_user($type, $edit, &$user) {
- switch ($type) {
- case "view_public":
- if ($user->signature) {
- return form_item(t("Signature"), check_output($user->signature));
- }
- break;
- case "view_private":
- if ($user->signature) {
- return form_item(t("Signature"), check_output($user->signature));
- }
- break;
- case "edit_form":
- // when user tries to edit his own data
- return form_textarea(t("Signature"), "signature", $edit["signature"], 70, 3, t("Your signature will be publicly displayed at the end of your comments.") ."<br />". form_allowed_tags_text());
- case "edit_validate":
- // validate user data editing
- return array("signature" => $edit["signature"]);
- }
-}
-
-function comment_access($op, $comment) {
- global $user;
-
- if ($op == "edit") {
-
- /*
- ** Authenticated users can edit their comments as long they have
- ** not been replied to. This, in order to avoid people changing
- ** or revising their statements based on the replies their posts
- ** got. Furthermore, users can't reply to their own comments and
- ** are encouraged to extend their original comment.
- */
-
- return $user->uid && $user->uid == $comment->uid && comment_num_replies($comment->cid) == 0;
- }
-
-}
-
-function comment_form($edit) {
- global $user;
-
- $form .= "<a id=\"comment\"></a>\n";
-
- // name field:
- $form .= form_item(t("Your name"), format_name($user));
-
- // subject field:
- $form .= form_textfield(t("Subject"), "subject", $edit["subject"], 50, 64);
-
- // comment field:
- $form .= form_textarea(t("Comment"), "comment", $edit["comment"] ? $edit["comment"] : $user->signature, 70, 10, form_allowed_tags_text());
-
- // preview button:
- $form .= form_hidden("cid", $edit["cid"]);
- $form .= form_hidden("pid", $edit["pid"]);
- $form .= form_hidden("nid", $edit["nid"]);
-
- if (!$edit["comment"] && variable_get("comment_preview", 1)) {
- $form .= form_submit(t("Preview comment"));
- }
- else {
- $form .= form_submit(t("Preview comment"));
- $form .= form_submit(t("Post comment"));
- }
-
- return form($form, "post", url("comment/reply/". $edit["nid"]));
-}
-
-function comment_edit($cid) {
- global $user;
-
- $comment = db_fetch_object(db_query("SELECT c.*, u.uid, u.name, u.data FROM comments c LEFT JOIN users u ON c.uid = u.uid WHERE c.cid = %d AND c.status != 2", $cid));
-
- if (comment_access("edit", $comment)) {
- comment_preview(object2array($comment));
- }
-}
-
-function comment_reply($pid, $nid) {
-
-
- if (user_access("access comments")) {
-
- /*
- ** Show comment
- */
-
- if ($pid) {
- $comment = db_fetch_object(db_query("SELECT c.*, u.uid, u.name, u.data FROM comments c LEFT JOIN users u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0", $pid));
- comment_view($comment);
- }
- else {
- node_view(node_load(array("nid" => $nid)));
- $pid = 0;
- }
-
- /*
- ** If possible, show reply form
- */
-
- if (node_comment_mode($nid) == 1) {
- theme("box", t("Reply"), t("This discussion is closed: you can't post new comments."));
- }
- else if (user_access("post comments", $context)) {
- theme("box", t("Reply"), comment_form(array("pid" => $pid, "nid" => $nid)));
- }
- else {
- theme("box", t("Reply"), t("You are not authorized to post comments."));
- }
- }
- else {
- theme("box", t("Reply"), t("You are not authorized to view comments."));
- }
-}
-
-function comment_preview($edit) {
- global $user;
-
- foreach ($edit as $key => $value) {
- $comment->$key = $value;
- }
-
- /*
- ** Attach the user and time information:
- */
-
- $comment->uid = $user->uid;
- $comment->name = $user->name;
- $comment->timestamp = time();
-
- /*
- ** Preview the comment:
- */
-
- comment_view($comment, t("reply to this comment"));
-
- theme("box", t("Reply"), comment_form($edit));
-
- if ($edit["pid"]) {
- $comment = db_fetch_object(db_query("SELECT c.*, u.uid, u.name, u.data FROM comments c LEFT JOIN users u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0", $edit["pid"]));
- comment_view($comment);
- }
- else {
- node_view(node_load(array("nid" => $edit["nid"])));
- $edit["pid"] = 0;
- }
-}
-
-function comment_post($edit) {
- global $user;
-
- if (user_access("post comments") && node_comment_mode($edit["nid"]) == 2) {
-
- /*
- ** Validate the comment's subject. If not specified, extract
- ** one from the comment's body.
- */
-
- $edit["subject"] = strip_tags($edit["subject"]);
-
- if ($edit["subject"] == "") {
- $edit["subject"] = substr(strip_tags($edit["comment"]), 0, 29);
- }
-
- /*
- ** Validate the comment's body.
- */
-
- if ($edit["comment"] == "") {
- return array(t("Empty comment"), t("The comment you submitted is empty."));
- }
-
- /*
- ** Check for duplicate comments. Note that we have to use the
- ** validated/filtered data to perform such check.
- */
-
- $duplicate = db_result(db_query("SELECT COUNT(cid) FROM comments WHERE pid = %d AND nid = %d AND subject = '%s' AND comment = '%s'", $edit["pid"], $edit["nid"], $edit["subject"], $edit["comment"]), 0);
-
- if ($duplicate != 0) {
- watchdog("warning", "comment: duplicate '". $edit["subject"] ."'");
- return array(t("Duplicate comment"), t("The comment you submitted has already been inserted."));
- }
- else {
-
- if ($edit["cid"]) {
-
- /*
- ** Update the comment in the database. Note that the update
- ** query will fail if the comment isn't owned by the current
- ** user.
- */
-
- db_query("UPDATE comments SET subject = '%s', comment = '%s' WHERE cid = %d AND uid = '$user->uid'", $edit["subject"], $edit["comment"], $edit["cid"]);
-
- /*
- ** Fire a hook
- */
-
- module_invoke_all("comment", "update", $edit);
-
- /*
- ** Add entry to the watchdog log:
- */
-
- watchdog("special", "comment: updated '". $edit["subject"] ."'", l(t("view comment"), "node/view/". $edit["nid"] ."#". $edit["cid"]));
- }
- else {
- /*
- ** Check the user's comment submission rate. If exceeded,
- ** throttle() will bail out.
- */
-
- throttle("post comment", variable_get("max_comment_rate", 60));
-
- /*
- ** Add the comment to database:
- */
-
- $status = user_access("post comments without approval") ? 0 : 1;
- $roles = variable_get("comment_roles", array());
- $score = $roles[$user->rid] ? $roles[$user->rid] : 0;
- $users = serialize(array(0 => $score));
-
- $edit["cid"] = db_next_id("comments_cid");
-
- db_query("INSERT INTO comments (cid, nid, pid, uid, subject, comment, hostname, timestamp, status, score, users) VALUES (%d, %d, %d, %d, '%s', '%s', '%s', %d, %d, %d, '%s')", $edit["cid"], $edit["nid"], $edit["pid"], $user->uid, $edit["subject"], $edit["comment"], getenv("REMOTE_ADDR"), time(), $status, $score, $users);
-
- /*
- ** Tell the other modules a new comment has been submitted:
- */
-
- module_invoke_all("comment", "insert", $edit);
-
- /*
- ** Add entry to the watchdog log:
- */
-
- watchdog("special", "comment: added '". $edit["subject"] ."'", l(t("view comment"), "node/view/". $edit["nid"] ."#". $edit["cid"]));
- }
-
- /*
- ** Clear the cache so an anonymous user can see his comment being
- ** added.
- */
-
- cache_clear_all();
- }
- }
- else {
- watchdog("error", "comment: unauthorized comment submitted or comment submitted to a closed node '". $edit["subject"] ."'");
- return array(t("Error"), t("You are not authorized to post comments, or this node doesn't accept new comments."));
- }
-
- /*
- ** Redirect the user the node he commented on, or explain queue
- */
-
- if ($status == 1) {
- return array(t("Comment queued"), t("Your comment has been queued for moderation by site administrators and will be published after approval."));
- }
-}
-
-function comment_links($comment, $return = 1) {
- global $user;
-
- $links = array();
-
- /*
- ** If we are viewing just this comment, we link back to the node
- */
-
- if ($return) {
- $links[] = l(t("parent"), "node/view/$comment->nid#$comment->cid");
- }
-
- /*
- ** Admin link
- */
-
- if (user_access("administer comments") && user_access("access administration pages")) {
- $links[] = l(t("administer"), "admin/comment/edit/$comment->cid");
- }
-
- /*
- ** Possibly show edit and reply links
- */
-
- if (node_comment_mode($comment->nid) == 2) {
- if (user_access("post comments")) {
- if (comment_access("edit", $comment)) {
- $links[] = l(t("edit your comment"), "comment/edit/$comment->cid", array("title" => t("Make changes to your comment.")));
- }
- $links[] = l(t("reply to this comment"), "comment/reply/$comment->nid/$comment->cid");
- }
- else {
- $links[] = theme("comment_post_forbidden");
- }
- }
-
- if ($moderation = comment_moderation_form($comment)) {
- $links[] = $moderation;
- }
-
- return theme("links", $links);
-}
-
-function comment_view($comment, $links = "", $visible = 1) {
-
- /*
- ** Switch to folded/unfolded view of the comment
- */
-
- if (node_is_new($comment->nid, $comment->timestamp)) {
- $comment->new = 1;
- print "<a id=\"new\"></a>\n";
- }
-
- print "<a id=\"$comment->cid\"></a>\n";
-
- if ($visible) {
- $comment->comment = check_output($comment->comment);
- theme("comment", $comment, $links);
- }
- else {
- theme("comment_folded", $comment);
- }
-}
-
-function comment_render($node, $cid = 0) {
- global $user;
-
- $mode = $_GET["mode"];
- $order = $_GET["order"];
- $threshold = $_GET["threshold"];
- $comments_per_page = $_GET["comments_per_page"];
- $comment_page = $_GET["comment_page"];
-
- if (user_access("access comments")) {
-
- /*
- ** Pre-process variables:
- */
-
- $nid = $node->nid;
- if (empty($nid)) {
- $nid = 0;
- }
-
- if (empty($mode)) {
- $mode = $user->mode ? $user->mode : variable_get("comment_default_mode", 4);
- }
-
- if (empty($order)) {
- $order = $user->sort ? $user->sort : variable_get("comment_default_order", 1);
- }
-
- if (empty($threshold)) {
- $threshold = $user->uid ? $user->threshold : variable_get("comment_default_threshold", 0);
- }
- $threshold_min = db_result(db_query("SELECT minimum FROM moderation_filters WHERE fid = %d", $threshold));
-
- if (empty($comment_page)) {
- $comment_page = 1;
- }
-
- if (empty($comments_per_page)) {
- $comments_per_page = $user->comments_per_page ? $user->comments_per_page : variable_get("comment_default_per_page", "50");
- }
-
- print "<a id=\"comment\"></a>\n";
-
-
- if ($cid) {
-
- /*
- ** Single comment view
- */
-
- print "<form method=\"post\" action=\"". url("comment") ."\"><div>\n";
- print form_hidden("nid", $nid);
-
- $result = db_query("SELECT c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.data, c.score, c.users FROM comments c LEFT JOIN users u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0 GROUP BY c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.data, c.score, c.users", $cid);
-
- if ($comment = db_fetch_object($result)) {
- comment_view($comment, comment_links($comment));
- }
-
- if ((comment_user_can_moderate($node)) && $user->uid != $comment->uid && !(comment_already_moderated($user->uid, $comment->users))) {
- print "<div style=\"text-align: center;\">". form_submit(t("Moderate comment")) ."</div><br />";
- }
- print "</div></form>";
- }
- else {
-
- /*
- ** Multiple comments view
- */
-
- $query .= "SELECT c.cid as cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.data, c.score, c.users FROM comments c LEFT JOIN users u ON c.uid = u.uid WHERE c.nid = '". check_query($nid) ."' AND c.status = 0";
-
- $query .= " GROUP BY c.cid, c.pid, c.nid, c.subject, c.comment, c.timestamp, u.uid, u.name, u.data, c.score, c.users";
-
- if ($order == 1) {
- $query .= " ORDER BY c.timestamp DESC";
- }
- else if ($order == 2) {
- $query .= " ORDER BY c.timestamp";
- }
-
- /*
- ** Start a form, to use with comment control and moderation
- */
-
- $result = db_query($query);
- $comment_num = db_num_rows($result);
-
- if ($comment_num && ((variable_get("comment_controls", 0) == 0) || (variable_get("comment_controls", 0) == 2))) {
- print "<form method=\"post\" action=\"". url("comment") ."\"><div>\n";
- theme("box", "", theme("comment_controls", $threshold, $mode, $order, $nid, $comment_page, $comment_num, $comments_per_page));
- print form_hidden("nid", $nid);
- print "</div></form>";
- }
-
- print "<form method=\"post\" action=\"". url("comment") ."\"><div>\n";
- print form_hidden("nid", $nid);
-
- if ($comment_num) {
- if ($mode == 1) {
- /*
- ** Flat collapsed
- */
-
- while ($comment = db_fetch_object($result)) {
- $comments[$comment->cid] = $comment;
- }
- theme("comment_flat_collapsed", $comments, $threshold_min);
- }
- else if ($mode == 2) {
- /*
- ** Flat expanded
- **
- ** We page using PHP, not using SQL because otherwise we'd
- ** have to use two queries; one for each comment and one for
- ** the paged comments. In method 1-3 we take all results
- ** anyway, wheras in method 4 we need every result to create
- ** proper pages. It is here where we lose more, in fact for
- ** higher pages we transfer unneeded data from the db and
- ** the web server.
- **
- ** TODO: the comment above is a bit cryptic. Mind to make it
- ** a bit more verbose/explanatory?
- */
-
- $comment_num = 0;
- $page = 1;
- while ($comment = db_fetch_object($result)) {
- if ($page == $comment_page) {
- $comments[$comment->cid] = $comment;
- }
- $comment_num++;
- if ($comment_num == $comments_per_page) {
- if ($page == $comment_page) {
- break;
- }
- else {
- $comment_num = 0;
- $page++;
- }
- }
-
- if ($user->uid != $comment->uid && !(comment_already_moderated($user->uid, $comment->users))) {
- $show_moderate_button = 1;
- }
- }
-
- theme("comment_flat_expanded", $comments, $threshold_min);
-
- if (comment_user_can_moderate($node) && $show_moderate_button) {
- print "<div style=\"text-align: center;\">". form_submit(t("Moderate comments")) ."</div><br />";
- }
- }
- else if ($mode == 3) {
- /*
- ** Threaded collapsed
- */
-
- while ($comment = db_fetch_object($result)) {
- $comments[$comment->cid] = $comment;
- }
- if ($comments) {
- theme("comment_thread_min", $comments, $threshold_min);
- }
- }
- else {
- /*
- ** Threaded expanded
- */
-
- while ($comment = db_fetch_object($result)) {
- $comments[$comment->cid] = $comment;
-
- if ($user->uid != $comment->uid && !(comment_already_moderated($user->uid, $comment->users))) {
- $show_moderate_button = 1;
- }
- }
-
- /*
- ** Build the comment structure
- */
-
- $structure = comment_thread_structure($comments, 0, 0, array());
-
- $comment_num = 0;
- $page = 1;
- foreach ($structure as $cid => $depth) {
- if ($page == $comment_page) {
- theme("comment_thread_max", $comments[$cid], $threshold_min, $depth - 1);
- }
- $comment_num++;
- if ($comment_num == $comments_per_page) {
- if ($page == $comment_page) {
- break;
- }
- else {
- $comment_num = 0;
- $page++;
- }
- }
- }
-
- if (comment_user_can_moderate($node) && $show_moderate_button) {
- print "<div style=\"text-align: center;\">". form_submit(t("Moderate comments")) ."</div><br />";
- }
- }
- }
-
- print "</div></form>";
-
- if ($comment_num && ((variable_get("comment_controls", 0) == 1) || (variable_get("comment_controls", 0) == 2))) {
- print "<form method=\"post\" action=\"". url("comment") ."\"><div>\n";
- theme("box", t("Control panel"), theme("comment_controls", $threshold, $mode, $order, $nid, $comment_page, $comment_num, $comments_per_page));
- print form_hidden("nid", $nid);
- print "</div></form>";
- }
- }
-
- /*
- ** If enabled, show new comment form
- */
-
- if (user_access("post comments") && node_comment_mode($nid) == 2 && variable_get("comment_new_form", 0)) {
- theme("box", t("Post new comment"), comment_form(array("nid" => $nid)));
- }
-
- }
-}
-
-function comment_perm() {
- return array("access comments", "post comments", "administer comments", "moderate comments", "post comments without approval", "administer moderation");
-}
-
-function comment_link($type, $node = 0, $main = 0) {
-
- if ($type == "node" && $node->comment) {
-
- if ($main) {
-
- /*
- ** Main page: display the number of comments that have been posted.
- */
-
- if (user_access("access comments")) {
- $all = comment_num_all($node->nid);
- $new = comment_num_new($node->nid);
-
- if ($all) {
- $links[] = l(format_plural($all, "1 comment", "%count comments"), "node/view/$node->nid#comment", array("title" => t("Jump to the first comment of this posting.")));
-
- if ($new) {
- $links[] = l(format_plural($new, "1 new comment", "%count new comments"), "node/view/$node->nid#new", array("title" => t("Jump to the first new comment of this posting.")));
- }
- }
- else {
- if (user_access("post comments")) {
- $links[] = l(t("add new comment"), "comment/reply/$node->nid", array("title" => t("Add a new comment to this page.")));
- }
- else {
- $links[] = theme("comment_post_forbidden");
- }
- }
- }
- }
- else {
- /*
- ** Node page: add a "post comment" link if the user is allowed to
- ** post comments and if this node is not read-only
- */
-
- if ($node->comment == 2) {
- if (user_access("post comments")) {
- $links[] = l(t("add new comment"), "comment/reply/$node->nid#comment", array("title" => t("Share your thoughts and opinions related to this posting.")));
- }
- else {
- $links[] = theme("comment_post_forbidden");
- }
- }
- else {
- $links[] = t("Closed discussion: you can't post new comments.");
- }
- }
- }
-
- if ($type == "admin" && user_access("administer comments")) {
- $help["general"] = t("Comments let users give feedback to content authors. Here you may review/approve/deny recent comments, and configure moderation if desired.");
- $help["post-overview"] = t("Click on <a href=\"%nup\">new or updated comments</a> to see your latest comments, or <a href=\"%queue\">comment approval queue</a> to approve new comments.", array("%nup" => url("admin/comment/0"), "%queue" => url("admin/comment/1")));
- $help["new-update"] = t("Below is a list of the latest comments posted your site. Click on a subject to see the comment, the author's name to edit the author's user information , \"edit comment\" to edit the comment, and \"delete comment\" to remove the comment.");
- $help["queue"] = t("Below is a list of the comments posted to your site that need <b>approval</b>. To approve a comment click on <b>\"edit comment\"</b> and then change it's <b>moderation status</b> to Approved.<br />Click on a subject to see the comment, the author's name to edit the author's user information, \"edit comment\" to edit the comment, and \"delete comment\" to remove the comment.");
- $help["moderation-overview"] = t("If you have a get a lot of comments, you can enable comment moderation. Once moderation is enabled users can vote on a comment based on dropdown menus. <a href=\"%votes\">votes</a> sets up the names of each item, and the order of the menu, using weights. <a href=\"%matrix\">matrix</a> sets up the value of each user's vote, and <a href=\"%threshold\">threshold</a> sets up the levels at which a comment will be displayed.", array("%votes" => url("admin/comment/moderation/votes"), "%matrix" => url("admin/comment/moderation/matrix"), "%threshold" => url("admin/comment/moderation/threshold")));
- $help["moderation-vote"] = t("Here is where you setup the names of each type of vote. Weight lets you set the order of the drop down menu. Click <b>edit</b> to edit a current vote weight.<br />Notes: <ul><li>you can have more than one type with the same name. The system does not protect you from this.</li><li>To <b>delete</b> a name/weight combiniation go to the <b>edit</b> area.</li></ul>");
- $help["moderation-matrix"] = t("Here is where you assign a value to each item in the dropdown. This value is added to the vote total, which is then divided by the number of users who have voted and rounded off to the nearest integer.<br />Notes:<ul><li>In order to use comment moderation, every text box on this page should be populated.</li><li>You must assign the <b>moderate comments</b> permission to at least one role in order to use this page.</li><li>Every box not filled in will have a value of zero, which will have the effect of <b>lowering</b> a comments over all score.</li></ul> ");
- $help["moderation-threshold"] = t("<i>Optional</i> Here you can setup the name and minimum \"cut off\" score to help your users hide comments that they don't want too see. These thresholds appear in the Comment Control Panel. Click \"edit\" to edit the values of an already exsisting threashold. To <b>delete</b> a threshold click on \"edit\". ");
- $help["initial"] = t("Here you can setup the <b>initial</b> vote value of a comment posted by each user role. This value is used before any other users vote on the comment.<br />Note: Blank entries are valued at zero");
- $help["search"] = t("Enter a simple pattern ( '*' maybe used as a wildcard match) to search for a comment. For example, one may search for 'br' and Drupal might return 'bread brakers', 'our daily bread' and 'brenda'.");
-
- menu("admin/comment", "comment management", "comment_admin", $help["general"], 2);
- menu("admin/comment/comments", "comment overview",NULL, $help["post-overview"], 2);
- menu("admin/comment/comments/0", "new or updated comments", "comment_admin", $help["new-update"], 1);
- menu("admin/comment/comments/1", "comment approval queue", "comment_admin", $help["queue"], 2);
- menu("admin/comment/search", "search comments", "comment_admin", $help["search"], 8);
- menu("admin/comment/help", "help", "comment_help", NULL, 9);
- menu("admin/comment/edit", "edit comment", "comment_admin", NULL, 0, 1);
-
- // comment settings:
- if (user_access("administer moderation")) {
- menu("admin/comment/moderation", "comment moderation", NULL, $help["moderation-overview"], 3);
- menu("admin/comment/moderation/votes", "votes", "comment_admin", $help["moderation-vote"]);
- menu("admin/comment/moderation/matrix", "matrix", "comment_admin", $help["moderation-matrix"]);
- menu("admin/comment/moderation/filters", "thresholds", "comment_admin", $help["moderation-threshold"]);
- menu("admin/comment/roles", "initial comment scores", "comment_admin", $help["initial"], 6);
- }
- }
-
- return $links ? $links : array();
-}
-
-function comment_page() {
- $op = $_POST["op"];
- $edit = $_POST["edit"];
-
- if (empty($op)) {
- $op = arg(1);
- }
-
- switch ($op) {
- case "edit":
- theme("header");
- comment_edit(check_query(arg(2)));
- theme("footer");
- break;
- case t("Moderate comments"):
- case t("Moderate comment"):
- comment_moderate($edit);
- drupal_goto(url("node/view/". $edit["nid"]));
- break;
- case "reply":
- theme("header");
- comment_reply(check_query(arg(3)), check_query(arg(2)));
- theme("footer");
- break;
- case t("Preview comment"):
- theme("header");
- comment_preview($edit);
- theme("footer");
- break;
- case t("Post comment"):
- list($error_title, $error_body) = comment_post($edit);
- if ($error_body) {
- theme("header");
- theme("box", $error_title, $error_body);
- theme("footer");
- }
- else {
- drupal_goto(url("node/view/". $edit["nid"]));
- }
- break;
- case t("Save settings"):
- $mode = $_POST["mode"];
- $order = $_POST["order"];
- $threshold = $_POST["threshold"];
- $comments_per_page = $_POST["comments_per_page"];
-
- comment_save_settings(check_query($mode), check_query($order), check_query($threshold), check_query($comments_per_page));
- drupal_goto(url("node/view/". $edit["nid"], "mode=$mode&order=$order&threshold=$threshold&comments_per_page=$comments_per_page"));
- break;
- }
-}
-
-/**
-*** admin functions
-**/
-
-function comment_node_link($node) {
-
- if (user_access("administer comments")) {
-
- /*
- ** Edit comments:
- */
-
- $result = db_query("SELECT c.cid, c.subject, u.uid, u.name FROM comments c LEFT JOIN users u ON u.uid = c.uid WHERE nid = %d AND c.status = 0 ORDER BY c.timestamp", $node->nid);
-
-
- $header = array(t("title"), t("author"), array("data" => t("operations"), "colspan" => 3));
-
- while ($comment = db_fetch_object($result)) {
- $rows[] = array(l($comment->subject, "node/view/$node->nid#$comment->cid"), format_name($comment), l(t("view comment"), "node/view/$node->nid#$comment->cid"), l(t("edit comment"), "admin/comment/edit/$comment->cid"), l(t("delete comment"), "admin/comment/delete/$comment->cid"));
- }
-
- if ($rows) {
- $output = "<h3>". t("Edit comments") ."</h3>";
- $output .= table($header, $rows);
- }
-
- return $output;
- }
-}
-
-function comment_admin_edit($id) {
-
- $result = db_query("SELECT c.*, u.name, u.uid FROM comments c LEFT JOIN users u ON c.uid = u.uid WHERE c.cid = %d AND c.status != 2", $id);
- $comment = db_fetch_object($result);
-
- // if a comment is "deleted", it's deleted
- if ($comment) {
- $form .= form_item(t("Author"), format_name($comment));
- $form .= form_textfield(t("Subject"), "subject", $comment->subject, 70, 128);
- $form .= form_textarea(t("Comment"), "comment", $comment->comment, 70, 15);
- $form .= form_select(t("Status"), "status", $comment->status, array("published", "not published"));
- $form .= form_hidden("cid", $id);
- $form .= form_submit(t("Submit"));
- $form .= form_submit(t("Delete"));
-
- return form($form);
- }
-}
-
-function comment_delete($edit) {
-
- if ($edit["confirm"]) {
- db_query("UPDATE comments SET status = 2 WHERE cid = %d", $edit["cid"]);
- watchdog("special", "comment: deleted comment #". $edit["cid"]);
- $output = "deleted comment.";
- }
- else {
- $output .= form_item(t("Confirm deletion"), "");
- $output .= form_hidden("cid", $edit["cid"]);
- $output .= form_hidden("confirm", 1);
- $output .= form_submit(t("Delete"));
- $output = form($output);
- }
-
- return $output;
-}
-
-function comment_save($id, $edit) {
- db_query("UPDATE comments SET subject = '%s', comment = '%s', status = %d WHERE cid = %d", $edit["subject"], $edit["comment"], $edit["status"], $id);
- watchdog("special", "comment: modified '". $edit["subject"] ."'");
- return "updated comment.";
-}
-
-function comment_admin_overview($status = 0) {
-
- $result = pager_query("SELECT c.*, u.name, u.uid FROM comments c LEFT JOIN users u ON u.uid = c.uid WHERE c.status = '". check_query($status). "' ORDER BY c.timestamp DESC", 50);
-
- $header = array(t("subject"), t("author"), t("status"), array("data" => t("operations"), "colspan" => 2));
- while ($comment = db_fetch_object($result)) {
- $rows[] = array(l($comment->subject, "node/view/$comment->nid/$comment->cid#$comment->cid", array("title" => htmlspecialchars(substr($comment->comment, 0, 128)))) ." ". (node_is_new($comment->nid, $comment->timestamp) ? theme_mark() : ""), format_name($comment), ($comment->status == 0 ? t("published") : t("not published")) ."</td><td>". l(t("edit comment"), "admin/comment/edit/$comment->cid"), l(t("delete comment"), "admin/comment/delete/$comment->cid"));
- }
-
- if ($pager = pager_display(NULL, 50, 0, "admin")) {
- $rows[] = array(array("data" => $pager, "colspan" => 5));
- }
-
- return table($header, $rows);
-}
-
-function comment_mod_matrix($edit) {
-
- $output .= "<h3>Moderators/vote values matrix</h3>";
-
- if ($edit) {
- db_query("DELETE FROM moderation_roles");
- foreach ($edit as $role_id => $votes) {
- foreach ($votes as $mid => $value) {
- $sql[] = "('$mid', '$role_id', '". ($value ? $value : 0 ) ."')";
- }
- }
- db_query("INSERT INTO moderation_roles (mid, rid, value) VALUES ". implode(", ", $sql));
- }
-
- $result = db_query("SELECT r.rid, r.name FROM role r, permission p WHERE r.rid = p.rid AND p.perm LIKE '%moderate comments%'");
- $role_names = array();
- while ($role = db_fetch_object($result)) {
- $role_names[$role->rid] = $role->name;
- }
-
- $result = db_query("SELECT rid, mid, value FROM moderation_roles");
- while ($role = db_fetch_object($result)) {
- $mod_roles[$role->rid][$role->mid] = $role->value;
- }
-
- $header = array_merge(array(t("votes")), array_values($role_names));
-
- $result = db_query("SELECT mid, vote FROM moderation_votes ORDER BY weight");
- while ($vote = db_fetch_object($result)) {
- $row = array($vote->vote);
- foreach (array_keys($role_names) as $rid) {
- $row[] = array("data" => form_textfield(NULL, "$rid][$vote->mid", $mod_roles[$rid][$vote->mid], 4, 3), "align" => "center");
- }
- $rows[] = $row;
- }
- $output .= table($header, $rows);
- $output .= "<br />". form_submit(t("Submit votes"));
-
- return form($output);
-}
-
-function comment_mod_roles($edit) {
-
- $output .= "<h3>Initial comment scores</h3>";
-
- if ($edit) {
- variable_set("comment_roles", $edit);
- }
-
- $start_values = variable_get("comment_roles", array());
-
- $result = db_query("SELECT r.rid, r.name FROM role r, permission p WHERE r.rid = p.rid AND p.perm LIKE '%post comments%'");
-
- $header = array(t("user role"), t("initial score"));
-
- while ($role = db_fetch_object($result)) {
- $rows[] = array($role->name, array("data" => form_textfield(NULL, $role->rid, $start_values[$role->rid], 4, 3), "align" => "center"));
- }
-
- $output .= table($header, $rows);
- $output .= "<br />". form_submit(t("Save scores"));
-
- return form($output);
-}
-
-function comment_mod_votes($edit) {
- $op = $_POST["op"];
-
- $mid = arg(4);
-
- if ($op == t("Save vote")) {
- db_query("UPDATE moderation_votes SET vote = '%s', weight = %d WHERE mid = %d", $edit["vote"], $edit["weight"], $mid);
- $mid = 0;
- }
- else if ($op == t("Delete vote")) {
- db_query("DELETE FROM moderation_votes WHERE mid = %d", $mid);
- db_query("DELETE FROM moderation_roles WHERE mid = %d", $mid);
- $mid = 0;
- }
- else if ($op == t("Add new vote")) {
- db_query("INSERT INTO moderation_votes (vote, weight) VALUES ('%s', %d)", $edit["vote"], $edit["weight"]);
- $mid = 0;
- }
-
- $output .= "<h3>" . t("Moderation votes overview") . "</h3>";
- $header = array(t("votes"), t("weight"), t("operations"));
-
- $result = db_query("SELECT mid, vote, weight FROM moderation_votes ORDER BY weight");
- while ($vote = db_fetch_object($result)) {
- $rows[] = array($vote->vote, array("data" => $vote->weight, "align" => "center"), array("data" => l(t("edit"), "admin/comment/moderation/votes/$vote->mid"), "align" => "center"));
- }
- $output .= table($header, $rows);
-
- if ($mid) {
- $vote = db_fetch_object(db_query("SELECT vote, weight FROM moderation_votes WHERE mid = %d", $mid));
- }
-
- $output .= "<br /><h3>". (isset($mid) ? "Edit" : "Add new") ."moderation option</h3>";
- $form .= form_textfield(t("Vote"), "vote", $vote->vote, 32, 64, t("The name of this vote. Example: 'off topic', 'excellent', 'sucky'."));
- $form .= form_textfield(t("Weight"), "weight", $vote->weight, 32, 64, t("Used to order votes in the comment control box; heavier sink."));
- if ($mid) {
- $form .= form_submit(t("Save vote"));
- $form .= form_submit(t("Delete vote"));
- }
- else {
- $form .= form_submit(t("Add new vote"));
- }
-
- $output .= form($form);
-
- return $output;
-}
-
-function comment_mod_filters($edit) {
- $op = $_POST["op"];
-
- $fid = arg(4);
-
- if ($op == t("Save threshold")) {
- db_query("UPDATE moderation_filters SET filter = '%s', minimum = %d WHERE fid = %d", $edit["filter"], $edit["minimum"], $fid);
- $fid = 0;
- }
- else if ($op == t("Delete threshold")) {
- db_query("DELETE FROM moderation_filters WHERE fid = %d", $fid);
- $fid = 0;
- }
- else if ($op == t("Add new threshold")) {
- db_query("INSERT INTO moderation_filters (filter, minimum) VALUES ('%s', %d)", $edit["filter"], $edit["minimum"]);
- $fid = 0;
- }
-
- $output .= "<h3>Comment threshold overview</h3>";
-
- $header = array(t("name"), t("minimum score"), t("operations"));
-
- $result = db_query("SELECT fid, filter, minimum FROM moderation_filters ORDER BY minimum");
- while ($filter = db_fetch_object($result)) {
- $rows[] = array($filter->filter, array("data" => $filter->minimum, "align" => "center"), array("data" => l(t("edit"), "admin/comment/moderation/filters/$filter->fid"), "align" => "center"));
- }
- $output .= table($header, $rows);
-
- if ($fid) {
- $filter = db_fetch_object(db_query("SELECT filter, fid, minimum FROM moderation_filters WHERE fid = %d", $fid));
- }
-
- $output .= "<br /><h3>". (isset($fid) ? "Edit" : "Add new") ." threshold</h3>";
- $form .= form_textfield(t("Threshhold name"), "filter", $filter->filter, 32, 64, t("The name of this threshold. Example: 'good comments', '+1 comments', 'everything'."));
- $form .= form_textfield(t("Minimum score"), "minimum", $filter->minimum, 32, 64, t("Show all comments whose score is larger or equal to the provided minimal score. Range: -127 +128"));
- if ($fid) {
- $form .= form_submit(t("Save threshold"));
- $form .= form_submit(t("Delete threshold"));
- }
- else {
- $form .= form_submit(t("Add new threshold"));
- }
-
- $output .= form($form);
-
- return $output;
-}
-
-
-function comment_admin() {
- $op = $_POST["op"];
- $edit = $_POST["edit"];
-
- if (empty($op)) {
- $op = arg(2);
- }
-
- if ($op == t("moderation")) {
- $op = arg(3);
- }
-
- if (user_access("administer comments")) {
- switch ($op) {
- case "edit":
- print comment_admin_edit(arg(3));
- break;
- case "search":
- print search_type("comment", url("admin/comment/search"), $_POST["keys"]);
- break;
- case "votes":
- case t("Add new vote"):
- case t("Delete vote"):
- case t("Save vote"):
- if (user_access("administer moderation")) {
- print comment_mod_votes($edit);
- }
- break;
- case "roles":
- case t("Save scores"):
- if (user_access("administer moderation")) {
- print comment_mod_roles($edit);
- }
- break;
- case "matrix":
- case t("Submit votes"):
- if (user_access("administer moderation")) {
- print comment_mod_matrix($edit);
- }
- break;
- case "filters":
- case t("Add new threshold"):
- case t("Delete threshold"):
- case t("Save threshold"):
- if (user_access("administer moderation")) {
- print comment_mod_filters($edit);
- }
- break;
- case "delete":
- print comment_delete(array("cid" => arg(3)));
- break;
- case t("Delete"):
- print status(comment_delete($edit));
- print comment_admin_overview(0);
- break;
- case t("Submit"):
- print status(comment_save(check_query(arg(3)), $edit));
- print comment_admin_overview(0);
- break;
- default:
- if (arg(3) == 1) {
- print comment_admin_overview(1);
- }
- else {
- print comment_admin_overview(0);
- }
- }
- }
- else {
- print message_access();
- }
-}
-
-/*
-** Renderer or visualization functions this can be optionally
-** overridden by themes.
-*/
-
-function comment_mode_form($mode) {
- global $cmodes;
-
- foreach ($cmodes as $key => $value) {
- $options .= " <option value=\"$key\"". ($mode == $key ? " selected=\"selected\"" : "") .">". t($value) ."</option>\n";
- }
-
- return "<select name=\"mode\">$options</select>\n";
-}
-
-function comment_order_form($order) {
- global $corder;
-
- foreach ($corder as $key=>$value) {
- $options .= " <option value=\"$key\"". ($order == $key ? " selected=\"selected\"" : "") .">". t($value) ."</option>\n";
- }
-
- return "<select name=\"order\">$options</select>\n";
-}
-
-function comment_per_page_form($comments_per_page) {
- for ($i = 10; $i < 100; $i = $i + 20) {
- $options .= " <option value=\"$i\"". ($comments_per_page == $i ? " selected=\"selected\"" : "") .">". t("%a comments per page", array("%a" => $i)) ."</option>";
- }
- return "<select name=\"comments_per_page\">$options</select>\n";
-}
-
-function comment_threshold($threshold) {
- $result = db_query("SELECT fid, filter FROM moderation_filters");
- $options .= " <option value=\"0\">". t("-- threshold --") ."</option>";
- while ($filter = db_fetch_object($result)) {
- $filters .= " <option value=\"$filter->fid\"". ($threshold == $filter->fid ? " selected=\"selected\"" : "") .">". t($filter->filter) ."</option>";
- }
- if ($filters) {
- return "<select name=\"threshold\">$filters</select>\n";
- }
-}
-
-function comment_controls($threshold = 1, $mode = 3, $order = 1, $nid, $page = 0, $comment_num = 0, $comments_per_page = 50) {
- static $output;
-
- if (!$output) {
- $output .= comment_mode_form($mode);
- $output .= comment_order_form($order);
- $output .= comment_per_page_form($comments_per_page);
- $output .= comment_threshold($threshold);
-
- $output .= " ". form_submit(t("Save settings"));
-
- $output = form_item(t("Comment viewing options"), $output, t("Select your preferred way to display the comments and click 'Save settings' to submit your changes."));
-
- if (($mode == 2 || $mode == 4) && $comment_num > $comments_per_page) {
- $query = "mode=$mode&order=$order&threshold=$threshold&comments_per_page=$comments_per_page";
-
- if ($page > 1) {
- $p[] = l(t("previous"), "node/view/$nid&amp;comment_page=". ($page - 1), array(), $query);
- }
- for ($n = 1; $n <= ceil($comment_num / $comments_per_page); $n++) {
- $p[] = ($n == $page) ? "<b>&raquo;$n&laquo;</b>" : l($n, "node/view/$nid&amp;comment_page=$n", array(), $query);
- }
- if ($page < ceil($comment_num / $comments_per_page)) {
- $p[] = l(t("next"), "node/view/$nid&amp;comment_page=". ($page + 1), array(), $query);
- }
- $output .= form_item(t("Browse %a comments", array("%a" => $comment_num)), implode("&nbsp;&#149;&nbsp;", $p), t("There are more than %a comments in this node. Use these links to navigate through them.", array("%a" => $comments_per_page)));
- }
- }
-
- return $output;
-}
-
-function comment_moderation_form($comment) {
- global $comment_votes, $user, $node;
- static $votes;
-
- $op = $_POST["op"];
-
- if ($op == "reply") {
- // preview comment:
- $output .= "&nbsp;";
- }
- else if ((comment_user_can_moderate($node)) && $user->uid != $comment->uid && !(comment_already_moderated($user->uid, $comment->users))) {
- // comment hasn't been moderated yet:
-
- if (!isset($votes)) {
- $result = db_query("SELECT v.mid, v.vote, r.value FROM moderation_votes v, moderation_roles r WHERE v.mid = r.mid AND r.rid = %d ORDER BY weight", $user->rid);
- $votes = array();
- while ($vote = db_fetch_object($result)) {
- if ($vote->value != 0) {
- $votes[] = $vote;
- }
- }
- }
-
- $options .= " <option value=\"\">". t("moderate comments") ."</option>\n";
- if ($votes) {
- foreach ($votes as $vote) {
- $options .= " <option value=\"$vote->mid\">$vote->vote</option>\n";
- }
- }
-
- $output .= "<select name=\"moderation[$comment->cid]\">$options</select>\n";
- }
-
- return $output;
-}
-
-function comment($comment, $links = 0) {
- $output .= "<div class=\"comment\">";
- $output .= "<div class=\"subject\">$comment->subject". ($comment->new ? " ". theme("theme_mark") : "") ."</div>";
- $output .= "<div class=\"moderation\">". $comment->moderation ."</div>";
- $output .= "<div class=\"credit\">". t("by %a on %b", array("%a" => format_name($comment), "%b" => format_date($comment->timestamp))) ."</div>";
- $output .= "<div class=\"body\">". check_output($comment->comment) ."</div";
- $output .= "<div class=\"links\">$links</div>";
- $output .= "</div>";
- print $output;
-}
-
-function comment_folded($comment) {
- print "<div class=\"comment-folded\"><span class=\"subject\">". l($comment->subject, "node/view/$comment->nid/$comment->cid#$comment->cid") ."</span> <span class=\"credit\">". t("by") . " " . format_name($comment) ."</span></div>";
-}
-
-function comment_flat_collapsed($comments, $threshold) {
- foreach ($comments as $comment) {
- if (comment_visible($comment, $threshold)) {
- comment_view($comment, "", 0);
- }
- }
-}
-
-function comment_flat_expanded($comments, $threshold) {
- foreach ($comments as $comment) {
- comment_view($comment, comment_links($comment, 0), comment_visible($comment, $threshold));
- }
-}
-
-function comment_thread_min($comments, $threshold, $pid = 0) {
- // this is an inner loop, so it's worth some optimization
- // from slower to faster
-
- foreach ($comments as $comment) {
- #for ($n=0; $n<count($comments); $n++) {
- #for ($n=0, $max = count($comments); $n<$max; $n++) {
- #$comment = $comments[$n];
- if (($comment->pid == $pid) && (comment_visible($comment, $threshold))) {
- print "<ul>";
- comment_view($comment, "", 0);
- comment_thread_min($comments, $threshold, $comment->cid);
- print "</ul>";
- }
- }
-}
-
-function comment_thread_max($comment, $threshold, $level = 0) {
- /*
- ** We had quite a few browser specific issues: expanded comments below
- ** the top level got truncated on the right hand side. A range of
- ** solutions have been proposed and tried but either the right margins of
- ** the comments didn't line up well, or the heavily nested tables made
- ** for slow rendering and cluttered HTML. This is the best work-around
- ** in terms of speed and size.
- */
-
- if ($level) {
- print "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" style=\"width: 100%;\"><tr><td style=\"width: ". ($level * 25) ."px;\">&nbsp;</td><td>\n";
- }
-
- comment_view($comment, comment_links($comment, 0), comment_visible($comment, $threshold));
-
- if ($level) {
- print "</td></tr></table>\n";
- }
-
-}
-
-function comment_post_forbidden() {
- global $user;
- if ($user->uid) {
- return t("You can't post comments.");
- }
- else {
- return t("%login or %register to post comments", array("%login" => l(t("login"), "user/login"), "%register" => l(t("register"), "user/register")));
- }
-}
-
-/**
-*** misc functions: helpers, privates, history, search
-**/
-
-
-function comment_visible($comment, $threshold = 0) {
- if ($comment->score >= $threshold) {
- return 1;
- }
- else {
- return 0;
- }
-}
-
-function comment_moderate() {
- global $moderation, $user;
-
- if ($moderation) {
- $result = db_query("SELECT mid, value FROM moderation_roles WHERE rid = %d", $user->rid);
- while ($mod = db_fetch_object($result)) {
- $votes[$mod->mid] = $mod->value;
- }
-
- $node = node_load(array("nid" => db_result(db_query("SELECT nid FROM comments WHERE cid = %d", key($moderation)))));
-
- if (user_access("administer comments") || comment_user_can_moderate($node)) {
- foreach ($moderation as $cid => $vote) {
- if ($vote) {
- if (($vote == 'offline') && (user_access("administer comments"))) {
- db_query("UPDATE comments SET status = 1 WHERE cid = %d", $cid);
- watchdog("special", "comment: unpublished comment #". $cid);
-
- /*
- ** Fire a hook
- */
-
- module_invoke_all("comment", "unpublish", $cid);
- }
- else {
- $comment = db_fetch_object(db_query("SELECT * FROM comments WHERE cid = %d", $cid));
- $users = unserialize($comment->users);
- if ($user->uid != $comment->uid && !(comment_already_moderated($user->uid, $comment->users))) {
- $users[$user->uid] = $vote;
- $tot_score = 0;
- foreach ($users as $uid => $vote) {
- if ($uid) {
- $tot_score = $tot_score + $votes[$vote];
- }
- else {
- // vote 0 is the start value
- $tot_score = $tot_score + $vote;
- }
- }
- $new_score = round($tot_score / count($users));
- db_query("UPDATE comments SET score = '$new_score', users = '%s' WHERE cid = %d", serialize($users), $cid);
-
- /*
- ** Fire a hook
- */
-
- module_invoke_all("comment", "moderate", $cid, $vote);
- }
- }
- }
- }
- }
- }
-}
-
-function comment_save_settings($mode, $order, $threshold, $comments_per_page) {
- global $user;
-
- if ($user->uid) {
- $user = user_save($user, array("mode" => $mode, "sort" => $order, "threshold" => $threshold, "comments_per_page" => $comments_per_page));
- }
-}
-
-function comment_num_all($nid) {
- static $cache;
-
- if (!isset($cache[$nid])) {
- $comment = db_fetch_object(db_query("SELECT COUNT(c.nid) AS number FROM node n LEFT JOIN comments c ON n.nid = c.nid WHERE n.nid = %d AND c.status = 0 GROUP BY n.nid", $nid));
- $cache[$nid] = $comment->number ? $comment->number : 0;
- }
- return $cache[$nid];
-}
-
-function comment_num_replies($id) {
- static $cache;
-
- if (!isset($cache[$nid])) {
- $result = db_query("SELECT COUNT(cid) FROM comments WHERE pid = %d AND status = 0", $id);
- $cache[$nid] = $result ? db_result($result, 0) : 0;
- }
-
- return $cache[$nid];
-}
-
-/**
- * get number of new comments for current user and specified node
- *
- * @param $nid node-id to count comments for
- * @param $timestamp time to count from (defaults to time of last user access to node)
- */
-function comment_num_new($nid, $timestamp = 0) {
- global $user;
-
- if ($user->uid) {
- /*
- ** Retrieve the timestamp at which the current user last viewed the
- ** specified node.
- */
-
- if (!$timestamp) {
- $timestamp = node_last_viewed($nid);
- }
-
- /*
- ** Use the timestamp to retrieve the number of new comments
- */
-
- $result = db_result(db_query("SELECT COUNT(c.cid) FROM node n LEFT JOIN comments c ON n.nid = c.nid WHERE n.nid = %d AND timestamp > %d AND c.status = 0", $nid, $timestamp));
-
- return $result;
- }
- else {
- return 0;
- }
-
-}
-
-function comment_thread_structure($comments, $pid, $depth, $structure) {
- $depth++;
-
- foreach ($comments as $key => $comment) {
- if ($comment->pid == $pid) {
- $structure[$comment->cid] = $depth;
- $structure = comment_thread_structure($comments, $comment->cid, $depth, $structure);
- }
- }
-
- return $structure;
-}
-
-function comment_user_can_moderate($node) {
- global $user;
- return (user_access("moderate comments"));
- // TODO: || (($user->uid == $node->uid) && user_access("moderate comments in owned node")));
-}
-
-function comment_already_moderated($uid, $users) {
- $comment_users = unserialize($users);
- if (!$comment_users) {
- $comment_users = array();
- }
- return in_array($uid, array_keys($comment_users));
-}
-
-function comment_search($keys) {
-
- /*
- ** Return the results of performing a search using the indexed search
- ** for this particular type of node.
- **
- ** Pass an array to the "do_search" function which dictates what it
- ** will search through, and what it will search for
- **
- ** "keys"'s value is the keywords entered by the user
- **
- ** "type"'s value is used to identify the node type in the search
- ** index.
- **
- ** "select"'s value is used to relate the data from the specific nodes
- ** table to the data that the search_index table has in it, and the the
- ** do_search functino will rank it.
- **
- ** The select must always provide the following fields - lno, title,
- ** created, uid, name, count
- **
- ** The select statement may optionally provide "nid", which is a secondary
- ** identifier which is currently used byt the comment module.
- */
-
- $find = do_search(array("keys" => $keys, "type" => "comment", "select" => "select s.lno as lno, c.nid as nid, c.subject as title, c.timestamp as created, u.uid as uid, u.name as name, s.count as count FROM search_index s, comments c LEFT JOIN users u ON c.uid = u.uid WHERE s.lno = c.cid AND s.type = 'comment' AND c.status = 0 AND s.word like '%'"));
-
- return $find;
-}
-
-function comment_update_index() {
-
- /*
- ** Return an array of values to dictate how to update the search index
- ** for this particular type of node.
- **
- ** "last_update"'s value is used with variable_set to set the
- ** last time this node type (comment) had an index update run.
- **
- ** "node_type"'s value is used to identify the node type in the search
- ** index (commentt in this case).
- **
- ** "select"'s value is used to select the node id and text fields from
- ** the table we are indexing. In this case, we also check against the
- ** last run date for the comments update.
- */
-
- return array("last_update" => "comment_cron_last", "node_type" => "comment", "select" => "SELECT c.cid as lno, c.subject as text1, c.comment as text2 FROM comments c WHERE c.status = 0 AND timestamp > ". variable_get("comment_cron_last", 1));
-}
-
-function comment_nodeapi(&$node, $op, $arg = 0) {
- switch ($op) {
- case "settings":
- $output[t("comment")] = form_select("", "comment_$node->type", variable_get("comment_$node->type", 2), array("Disabled", "Read only", "Read/Write"));
- return $output;
- case "fields":
- return array("comment");
- case "form admin":
- if (user_access("administer comments")) {
- $selected = isset($node->comment) ? $node->comment : variable_get("comment_$node->type", 2);
- $output = form_radio(t("Disabled"), "comment", 0, ($selected == 0));
- $output .= form_radio(t("Read only"), "comment", 1, ($selected == 1));
- $output .= form_radio(t("Read/write"), "comment", 2, ($selected == 2));
- return form_item(t("Allow user comments"), $output);
- }
- break;
- case "validate":
- if (!user_access("administer nodes")) {
- // Force default for normal users:
- $node->comment = variable_get("comment_$node->type", 2);
- }
- break;
- case "delete":
- db_query("DELETE FROM comments WHERE nid = '$node->nid'");
- break;
- }
-}
-
-?>
diff --git a/modules/drupal/drupal.module b/modules/drupal/drupal.module
deleted file mode 100644
index dfd8473..0000000
--- a/modules/drupal/drupal.module
+++ /dev/null
@@ -1,196 +0,0 @@
-<?php
-// $Id$
-
-function drupal_help_directory() {
-
- $output .= "<p>The \"Drupal\" module features a capability whereby other drupal sites may <i>call home</i> to report their existence. In turn, this enables a pod of Drupal sites to find, cooperate and advertise each other.</p>";
- $output .= "<p>Currently, the main application of this feature is the <a href=\"http://www.drupal.org/node/view/3\">Drupal sites page</a>. By default, fresh Drupal installations can use <a href=\"http://www.drupal.org/\">drupal.org</a> as their <i>directory server</i> and report their existence. This reporting occurs via scheduled <a href=\"http://www.xmlrpc.com/\">XML-RPC</a> pings.</p>";
- $output .= "<p>Drupal administrators should simply enable this feature to get listed on the <a href=\"http://www.drupal.org/node/view/3\">Drupal sites page</a>; just set your site's name, e-mail address, slogan and mission statement. Then make sure that the field called <i>Drupal XML-RPC server</i> on the <i>site settings</i> tab of the <i>site configuration</i> page is set to http://www.drupal.org/xmlrpc.php. Also, make sure you enable this feature using the checkbox directly below.</p>";
- $output .= "<p>The listing of your site will occur shortly after your site's next ". l("cron run", "admin/system/help") .". Note that cron.php should be called using the domain name which you want to have listed at <a href=\"http://www.drupal.org/\">drupal.org</a>. For example, don't kick off cron by requesting http://127.0.0.1/cron.php. Instead, use a publicly accessible domain name such as http://www.mydomain.org/cron.php.</p>";
- $output .= "<p>Also note that your installation need not use drupal.org as its directory server. For example, this feature is perfectly capable of aggregating pings from all of your departmental drupal installations sites within an enterprise.</p>";
- return t($output);
-}
-
-function drupal_help() {
- return drupal_help_directory();
-}
-
-function drupal_system($field) {
- $system["description"] = t("Lets users log in using a Drupal ID and can notify drupal.org about your site.");
- $system["admin_help"] = t("Using this your Drupal site can \"call home\" and add itself to the Drupal directory. If you want it to add itself to a different directory server you can change the \"Drupal XML-RPC server\" setting -- but the directory server has to be able to handle Drupal XML. To get a full listing go to <a href=\"%general\">site configuration</a> and set:<ul><li>The site name,</li><li>Site E-Mail address,</li><li>Site slogan, and</li><li>The sire mission statement.</li></ul>",array("%general" => url("admin/system")));
- return $system[$field];
-}
-
-function drupal_settings() {
- $output .= form_textfield("Drupal XML-RPC server", "drupal_server", variable_get("drupal_server", "http://www.drupal.org/xmlrpc.php"), 55, 128, "The URL of your root Drupal XML-RPC server.");
- $output .= form_select("Drupal directory", "drupal_directory", variable_get("drupal_directory", 0), array("Disabled", "Enabled"), "If enabled, your Drupal site will make itself known to the Drupal directory at the specified Drupal XML-RPC server. For this to work properly, you have to set your site's name, e-mail address, slogan and mission statement. When the \"Drupal XML-RPC server\" field is set to \"http://www.drupal.org/xmlrpc.php\", your web site will get listed on <a href=\"http://www.drupal.org/\">http://www.drupal.org/</a>. Requires crontab.");
-
- return $output;
-}
-
-function drupal_cron() {
- if (time() - variable_get("drupal_cron_last", 0) > 21600) {
- variable_set("drupal_cron_last", time());
-
- /*
- ** If this site acts as a Drupal XML-RPC server, delete the sites that
- ** stopped sending "ping" messages.
- */
-
- db_query("DELETE FROM directory WHERE timestamp < '". (time() - 259200) ."'");
-
- /*
- ** If this site acts as a Drupal XML-RPC client, send a message to the
- ** Drupal XML-RPC server.
- */
-
- if (variable_get("drupal_directory", 0) && variable_get("drupal_server", 0)) {
- drupal_notify(variable_get("drupal_server", ""));
- }
- }
-}
-
-function drupal_directory_ping($arguments) {
-
- /*
- ** Parse our parameters:
- */
-
- $argument = $arguments->getparam(0);
- $link = strip_tags($argument->scalarval());
- $argument = $arguments->getparam(1);
- $name = strip_tags($argument->scalarval());
- $argument = $arguments->getparam(2);
- $mail = strip_tags($argument->scalarval());
- $argument = $arguments->getparam(3);
- $slogan = strip_tags($argument->scalarval());
- $argument = $arguments->getparam(4);
- $mission = strip_tags($argument->scalarval());
-
- /*
- ** Update the data in our database and send back a reply:
- */
-
- if ($link && $name && $mail && $slogan && $mission) {
- db_query("DELETE FROM directory WHERE link = '%s' OR mail = '%s'", $link, $mail);
- db_query("INSERT INTO directory (link, name, mail, slogan, mission, timestamp) VALUES ('%s', '%s', '%s', '%s', '%s', %d)", $link, $name, $mail, $slogan, $mission, time());
-
- watchdog("message", "directory: ping from '$name' ($link)");
-
- return new xmlrpcresp(new xmlrpcval(1, "int"));
- }
- else {
- return new xmlrpcresp(new xmlrpcval(0, "int"));
- }
-
-}
-
-function drupal_directory_page() {
- $result = db_query("SELECT * FROM directory ORDER BY name");
-
- while ($site = db_fetch_object($result)) {
- $output .= "<a href=\"$site->link\">$site->name</a> - $site->slogan<div style=\"padding-left: 20px;\">$site->mission</div><br />";
- }
-
- return $output;
-}
-
-function drupal_xmlrpc() {
- return array("drupal.site.ping" => array("function" => "drupal_directory_ping"), "drupal.login" => array("function" => "drupal_login"));
-}
-
-function drupal_notify($server) {
- global $base_url;
-
- $url = parse_url($server);
-
- $client = new xmlrpc_client($url["path"], $url["host"], 80);
-
- $message = new xmlrpcmsg("drupal.site.ping", array(new xmlrpcval($base_url, "string"), new xmlrpcval(variable_get("site_name", ""), "string"), new xmlrpcval(variable_get("site_mail", ""), "string"), new xmlrpcval(variable_get("site_slogan", ""), "string"), new xmlrpcval(variable_get("site_mission", ""), "string")));
-
- $result = $client->send($message, 5);
-
- if (!$result || $result->faultCode()) {
- watchdog("error", "failed to notify '". $url["host"] ."' at '". $url["path"] ."': ". $result->faultString());
- }
-
-}
-
-function drupal_info($field = 0) {
- $info["name"] = "Drupal";
- $info["protocol"] = "XML-RPC";
-
- if ($field) {
- return $info[$field];
- }
- else {
- return $info;
- }
-}
-
-function drupal_auth($username, $password, $server) {
-
- $message = new xmlrpcmsg("drupal.login", array(new xmlrpcval($username, "string"), new xmlrpcval($password, "string")));
-
- // TODO remove hard coded Port 80
- // TODO manage server/path such that HTTP_HOST/xml.rpc.php is not assumed
- $client = new xmlrpc_client("/xmlrpc.php", $server, 80);
- $result = $client->send($message, 5);
- if ($result && !$result->faultCode()) {
- $value = $result->value();
- $login = $value->scalarval();
- }
-
- return $login;
-}
-
-function drupal_page() {
-
- theme("header");
- theme("box", "Drupal", drupal_auth_help());
- theme("footer");
-}
-
-function drupal_login($arguments) {
- // an XML-RPC method called by external clients (usually other Drupal instances)
- $argument = $arguments->getparam(0);
- $username = $argument->scalarval();
- $argument = $arguments->getparam(1);
- $password = $argument->scalarval();
-
- if ($user = user_load(array(name => "$username", "pass" => $password, "status" => 1))) {
- return new xmlrpcresp(new xmlrpcval($user->uid, "int"));
- }
- else {
- return new xmlrpcresp(new xmlrpcval(0, "int"));
- }
-}
-
-function drupal_auth_help() {
- $site = variable_get("site_name", "this web site");
-
- $output = "<p><a href=\"http://www.drupal.org\">Drupal</a> is the name of the software which powers %s. There are Drupal web sites all over the world, and many of them share their registration databases so that users may freely login to any Drupal site using a single <b>Drupal ID</b>.</p>\n";
- $output .= "<p>So please feel free to login to your account here at %s with a username from another Drupal site. The format of a Drupal ID is similar to an email address: <b>username</b>@<i>server</i>. An example of valid Drupal ID is <b>mwlily</b>@<i>www.drupal.org</i>.</p>";
-
- return t($output, array("%s" => "<i>$site</i>"));
-}
-
-function drupal_user($type, $edit, $user) {
-
- $module = "drupal";
- $name = module_invoke($module, "info", "name");
- switch ($type) {
- case "view_private":
- $result = user_get_authname($user, $module);
- if ($result) {
- $output .= form_item(t("$name ID"), $result);
- }
- else {
- // TODO: use a variation of $base_url instead of $HTTP_HOST below
- $output .= form_item(t("$name ID"), "$user->name@". $_SERVER["HTTP_HOST"]);
- }
- return $output;
- }
-}
-
-?>
diff --git a/modules/forum/forum.module b/modules/forum/forum.module
deleted file mode 100644
index 24c5fb6..0000000
--- a/modules/forum/forum.module
+++ /dev/null
@@ -1,728 +0,0 @@
-<?php
-// $Id$
-
-function forum_system($field){
- $system["description"] = t("Enable threaded discussions about general topics.");
- $system["admin_help"] = t("Forums are threaded discussions based on the taxonomy system so you must first define a <a href=\"%taxonomy-create\">taxonomy</a> of type \"forum\" to place the forum tree in. Then <a href=\"%taxonomy\">add terms</a> to this taxonomy. Each term becomes the name of a forum. If you define a term as a \"Container\" (See below) the term is not a forum itself, but rather holds forms. This lets you group your forums.", array("%taxonomy-create" => url("admin/taxonomy/add/vocabulary"), "%taxonomy" => url("admin/taxonomy")));
- return $system[$field];
-}
-
-function forum_node($field) {
- $info["name"] = t("forum topic");
- $info["description"] = t("A forum is a threaded discussion, enabling users to communicate about a particular topic.");
-
- return $info[$field];
-}
-
-function forum_access($op, $node) {
- if ($op == "view") {
- return $node->status;
- }
- if ($op == "create") {
- return user_access("create forum topics");
- }
-}
-
-function forum_perm() {
- return array("create forum topics");
-}
-
-function forum_settings() {
-
- if (module_exist("taxonomy")) {
- $vocs[0] = "<". t("none") .">";
- foreach (taxonomy_get_vocabularies("forum") as $vid => $voc) {
- $vocs[$vid] = $voc->name;
- }
-
- if ($voc) {
- $output .= form_textarea(t("Explanation or submission guidelines"), "forum_help", variable_get("forum_help", ""), 70, 5, t("This text will be displayed at the top of the forum submission form. Useful for helping or instructing your users."));
- $output .= form_select(t("Forum vocabulary"), "forum_nav_vocabulary", variable_get("forum_nav_vocabulary", ""), $vocs, t("The taxonomy vocabulary that will be used as the navigation tree."));
- $output .= _taxonomy_term_select(t("Containers"), "forum_containers", variable_get("forum_containers", array()), variable_get("forum_nav_vocabulary", ""), t("You can choose forums which will not have topics, but will be just containers for other forums."), 1, t("<none>"));
-
- $output .= form_textfield(t("Topic icons path"), "forum_topic_icon_path", variable_get("forum_topic_icon_path", ""), 30, 255, t("The path to the topic icons. Leave blank to disable icons."));
- $output .= form_textfield(t("Folder icons path"), "forum_folder_icon_path", variable_get("forum_folder_icon_path", ""), 30, 255,t( "The path to the <b>default</b>, <b>hot</b>, <b>new</b>, <b>hot & new</b>, and <b>closed</b> folder icons. Leave blank to disable icons."));
- $number = array(5 => 5, 10 => 10, 15 => 15, 20 => 20, 25 => 25, 30 => 30, 35 => 35, 40 => 40, 50 => 50, 60 => 60, 80 => 80, 100 => 100, 10000=>10000);
- $output .= form_select(t("Hot topic threshold"), "forum_hot_topic", variable_get("forum_hot_topic", 15), $number, t("The number of posts a topic must have to be considered <b>hot</b>."));
- $number = array(10 => 10, 25 => 25, 50 => 50, 75 => 75, 100 => 100);
- $output .= form_select(t("Topics per page"), "forum_per_page", variable_get("forum_per_page", 25), $number, t("The default number of topics displayed per page; links to browse older messages are automatically being displayed."));
- $forder = array(1 => t("Date - newest first"), 2 => t("Date - oldest first"), 3 => t("Posts - most active first"), 4=> t("Posts - least active first"));
- $output .= form_select(t("Default order"), "forum_order", variable_get("forum_order", 1), $forder, t("The default display order for topics."));
- $output .= form_textfield(t("Number of topics in block"), "forum_block_num", variable_get("forum_block_num", "5"), 5, 5, t("The number of topics in the <b>Forum topics</b>-block. To enable the block, click ". l("here", "admin/block") ."."));
- }
- else {
- $output .= _forum_message_taxonomy();
- }
- }
- else {
- $output .= _forum_message_taxonomy();
- }
-
- return $output;
-}
-
-function forum_taxonomy($op, $type, $object) {
- if ($type == "vocabulary" && ($op == "insert" || $op == "update")) {
- if (variable_get("forum_nav_vocabulary", "") == "" && in_array("forum", $object["nodes"])) {
- // since none is already set, silently set this vocabulary as the navigation vocabulary
- variable_set("forum_nav_vocabulary", $object["vid"]);
- }
- }
-}
-
-function forum_load($node) {
- $forum = db_fetch_object(db_query("SELECT * FROM forum WHERE nid = %d", $node->nid));
-
- return $forum;
-}
-
-function forum_block($op = "list", $delta = 0) {
- if ($op == "list") {
- $blocks[0]["info"] = t("Forum topics");
- }
- else {
- if (user_access("access content")) {
- $cache = cache_get("forum:block");
-
- if (empty($cache)) {
- unset($items);
- $content = node_title_list(db_query_range("SELECT n.nid, n.title, u.uid, u.name, GREATEST(n.created, MAX(c.timestamp)) AS sort FROM node n LEFT JOIN forum f ON n.nid = f.nid LEFT JOIN comments c ON n.nid = c.nid LEFT JOIN users u ON n.uid = u.uid WHERE n.type = 'forum' AND n.nid = f.nid AND n.status = 1 GROUP BY n.nid, n.title, n.created, u.uid, u.name ORDER BY sort DESC", 0, variable_get("forum_block_num", "5")), t("Active forum topics:"));
-
- unset ($items);
- $content .= node_title_list(db_query_range("SELECT n.nid, n.title, u.uid, u.name FROM node n LEFT JOIN forum f ON n.nid = f.nid LEFT JOIN users u ON n.uid = u.uid WHERE n.type = 'forum' ORDER BY n.nid DESC", 0, variable_get("forum_block_num", "5")), t("New forum topics:"));
-
- if ($content) {
- $content .= "<div id=\"forum_more\" style=\"text-align: right;\">". l(t("more"), "forum", array("title" => t("Read the latest forum topics."))) ."</div>";
- }
-
- cache_set("forum:block", $content, time() + variable_get("cache_clear", 120));
- }
- else {
- $content = $cache->data;
- }
-
- $blocks["subject"] = t("Forum topics");
- $blocks["content"] = $content;
- }
- }
-
- return $blocks;
-}
-
-function forum_link($type, $node = 0, $main = 0) {
- global $user;
-
- $links = array();
-
- if ($type == "page" && user_access("access content")) {
- $links[] = l(t("forum"), "forum");
- }
-
- if (!$main && $type == "node" && $node->type == "forum") {
- // get previous and next topic
-
- $result = db_query("SELECT n.nid, n.title, n.body, GREATEST(n.created, MAX(c.timestamp)) AS date_sort, COUNT(c.nid) AS num_comments FROM node n LEFT JOIN forum f ON n.nid = f.nid LEFT JOIN comments c ON n.nid = c.nid WHERE n.nid = f.nid AND f.tid = %d AND n.status = 1 GROUP BY n.nid, n.title, n.body, n.created ORDER BY ". _forum_get_topic_order(isset($user->sortby) ? $user->sortby : variable_get("forum_order",1)), $node->tid);
-
- while ($topic = db_fetch_object($result)) {
- if ($stop == 1) {
- $next->nid = $topic->nid;
- $next->title = $topic->title;
- $next->body = $topic->body;
- break;
- }
- if ($topic->nid == $node->nid) {
- $stop = 1;
- }
- else {
- $prev->nid = $topic->nid;
- $prev->title = $topic->title;
- $prev->body = $topic->body;
- }
- }
-
- if ($prev) {
- $links[] = l(t("previous forum topic"), "node/view/$prev->nid", array("title" => $prev->title .": ". substr(strip_tags($prev->body), 0, 100)."..."));
- }
-
- if ($next) {
- $links[] = l(t("next forum topic"), "node/view/$next->nid", array("title" => $next->title .": ". substr(strip_tags($next->body), 0, 100)."..."));
- }
- }
-
- return $links;
-}
-
-function forum_view($node, $main = 0) {
-
-
- $term_data = array_shift(taxonomy_node_get_terms($node->nid));
- if (!$term_data) {
- // we are previewing
- $term_data = taxonomy_get_term($node->taxonomy[0]);
- }
- $voc = taxonomy_get_vocabulary($term_data->vid);
-
- if (!$main) {
- $node->title = _forum_get_icon($node) ." ". l($voc->name, "forum") ." : ". l($term_data->name, "forum/$term_data->tid") ." / <b>$node->title</b>";
- }
-
- $node->teaser = check_output($node->teaser);
- $node->body = check_output($node->body);
-
- theme("node", $node, $main);
-}
-
-function forum_validate(&$node) {
- // Make sure all fields are set properly:
- $node->icon = $node->icon ? $node->icon : "";
- $node->shadow = $node->shadow ? $node->shadow : 0;
- $node->tid = $node->tid ? $node->tid : 0;
- // We use the validate hook to remember the old taxonomy terms:
- if ($node->tid) {
- $node->taxonomy = array_keys(taxonomy_node_get_terms($node->nid));
- if (!in_array($node->tid[0], $node->taxonomy)) {
- $node->taxonomy[] = $node->tid[0];
- }
- }
-}
-
-function forum_form(&$node, &$help, &$error) {
- if ($node->tid) {
- // editing
- $tid = $node->tid;
- }
- else {
- // new topic
- $tid = arg(3);
- }
-
- // outputs the compose guidelines
- $help = variable_get("forum_help", "");
-
- $output .= _taxonomy_term_select(t("Forum"), "tid", $tid, variable_get("forum_nav_vocabulary", ""), "", 0, "", variable_get("forum_containers", array()));
-
- if ($node->nid) {
- // if editing, give option to leave shadows
- $output .= form_checkbox(t("Leave shadow copy"), "shadow", 1, $node->shadow, t("If you move this topic, you can leave a link in the old forum to the new forum."));
- }
-
- if ($icon_path = variable_get("forum_topic_icon_path", "")) {
- if ($node->icon) {
- // we are editing post
- if ($dir = @opendir($icon_path)) {
- $icon_num = 0;
- while($icon = readdir($dir)) {
- if ($icon == '.' || $icon == '..') {continue;}
- if ($node->icon == $icon) {$checked = "checked";} else {$checked = "";}
- $radio .= "<input type=\"radio\" name=\"edit[icon_num]\" value=\"$icon_num\" $checked /><img src=\"$icon_path$icon\" alt=\"\" title=\"\" /> \n";
- $icon_num++;
- }
- closedir($dir);
- }
- }
- else {
- if ($dir = @opendir($icon_path)) {
- $icon_num = 0;
- while($icon = readdir($dir)) {
- if ($icon == '.' || $icon == '..') {continue;}
- if ($node->icon_num == $icon_num) {$checked = "checked";} else {$checked = "";}
- $radio .= "<input type=\"radio\" name=\"edit[icon_num]\" value=\"$icon_num\" $checked /><img src=\"$icon_path$icon\" alt=\"\" title=\"\" /> \n";
- $icon_num++;
- }
- closedir($dir);
- }
- }
- $output .= form_item(t("Topic icon"), $radio);
- }
- $output .= form_textarea(t("Body"), "body", $node->body, 60, 10);
-
- return $output;
-}
-
-function forum_insert($node) {
- $node->icon = _forum_decode_icon($node);
- db_query("INSERT INTO forum (nid, icon, shadow, tid) VALUES (%d, '%s', %d, %d)", $node->nid, $node->icon, $node->shadow, $node->tid[0]);
-}
-
-function forum_update($node) {
- $node->icon = _forum_decode_icon($node);
- db_query("UPDATE forum SET icon = '%s', shadow = %d, tid = %d WHERE nid = %d", $node->icon, $node->shadow, $node->tid[0], $node->nid);
-}
-
-function _forum_decode_icon($node) {
- // to prevent malicious users
- if ($icon_path = variable_get("forum_topic_icon_path", "")) {
- if ($dir = @opendir($icon_path)) {
- $icon_num = 0;
- while($icon = readdir($dir)) {
- if ($icon == '.' || $icon == '..') {continue;}
- if ($icon_num == $node->icon_num) {$myicon = $icon;}
- $icon_num++;
- }
- closedir($dir);
- }
- }
- return $myicon;
-}
-
-function forum_delete(&$node) {
- db_query("DELETE FROM forum WHERE nid = %d", $node->nid);
-}
-
-function _forum_num_comments($nid) {
- $value = db_fetch_object(db_query("SELECT COUNT(cid) AS count FROM comments WHERE nid = %d AND status = 0", $nid));
- return ($value) ? $value->count : 0;
-}
-
-function _forum_last_comment($nid) {
- $value = db_fetch_object(db_query_range("SELECT timestamp FROM comments WHERE nid = %d AND status = 0 ORDER BY timestamp DESC", $nid, 0, 1));
- return ($value) ? format_date($value->timestamp, "small") : "&nbsp;";
-}
-
-function _forum_last_reply($nid) {
- $value = db_fetch_object(db_query_range("SELECT c.timestamp, u.name, u.uid FROM comments c LEFT JOIN users u ON c.uid = u.uid WHERE c.nid = %d AND c.status = 0 ORDER BY c.timestamp DESC", $nid, 0, 1));
- return $value;
-}
-
-function _forum_format($topic) {
- if ($topic) {
- return "<small>". t("%date<br />by %author", array("%date" => format_date($topic->timestamp, "small"), "%author" => format_name($topic))) ."</small>";
- }
- else {
- return message_na();
- }
-}
-
-function forum_get_forums($tid = 0) {
- global $user;
-
- if (!$tid) {
- $tid = 0;
- }
-
- $cache = cache_get("forum:$tid");
-
- if (empty($cache)) {
- $forums = array();
- $_forums = taxonomy_get_tree(variable_get("forum_nav_vocabulary", ""), $tid);
- $n = 0;
- foreach ($_forums as $forum) {
- if (in_array($forum->tid, variable_get("forum_containers", array()))) {
- $forum->container = 1;
- }
- else {
- $forum->num_topics = _forum_num_topics($forum->tid);
- $forum->num_posts = _forum_num_replies($forum->tid) + $forum->num_topics;
- $forum->last_post = _forum_last_post($forum->tid);
- }
- $forums[$forum->tid] = $forum;
- $n++;
- }
-
- cache_set("forum:$tid", serialize($forums), time() + variable_get("cache_clear", 120));
- }
- else {
- $forums = unserialize($cache->data);
- }
-
- if ($user->uid && $forums) {
- foreach (_forum_topics_read($user->uid) as $tid => $old) {
- if ($forums[$tid]) {
- $forums[$tid]->old_topics = $old;
- }
- }
- }
- return $forums;
-}
-
-function forum_get_parents($tid) {
- if ($tid) {
- $parents[] = taxonomy_get_term($tid);
- }
- $n = 0;
- while ($parent = taxonomy_get_parents($parents[$n]->tid)) {
- $parents = array_merge($parents, $parent);
- $n++;
- }
-
- return $parents;
-}
-
-function _forum_num_topics($term) {
- $value = db_fetch_object(db_query("SELECT COUNT(n.nid) AS count FROM node n LEFT JOIN forum f ON n.nid = f.nid WHERE f.tid = %d AND n.nid = f.nid AND n.status = 1 AND n.type = 'forum'", $term));
- return ($value) ? $value->count : 0;
-}
-
-function _forum_num_replies($term) {
- $value = db_fetch_object(db_query("SELECT COUNT(*) AS count FROM comments c LEFT JOIN node n ON n.nid = c.nid LEFT JOIN forum f ON n.nid = f.nid WHERE f.tid = %d AND n.nid = f.nid AND n.nid = c.nid AND n.status = 1 AND c.status = 0 AND n.type = 'forum'", $term));
- return ($value) ? $value->count : 0;
-}
-
-function _forum_topics_read($uid) {
- $result = db_query("SELECT tid, count(*) AS c FROM history h LEFT JOIN node n ON n.nid = h.nid LEFT JOIN forum f ON n.nid = f.nid WHERE f.nid = n.nid AND n.nid = h.nid AND n.type = 'forum' AND n.status = 1 AND h.uid = %d GROUP BY tid", $uid);
-
- while ($obj = db_fetch_object($result)) {
- $topics_read[$obj->tid] = $obj->c;
- }
-
- return $topics_read ? $topics_read : array();
-}
-
-function _forum_last_post($term) {
- $topic = db_fetch_object(db_query_range("SELECT n.nid, n.created AS timestamp, u.name AS name, u.uid AS uid FROM forum f LEFT JOIN node n ON n.nid = f.nid LEFT JOIN users u ON n.uid = u.uid WHERE f.tid = %d AND n.nid = f.nid AND n.type = 'forum' AND n.status = 1 ORDER BY timestamp DESC", $term, 0, 1));
-
- $reply = db_fetch_object(db_query_range("SELECT n.nid, c.timestamp, u.name AS name, u.uid AS uid FROM forum f LEFT JOIN node n ON n.nid = f.nid LEFT JOIN comments c ON n.nid = c.nid LEFT JOIN users u ON c.uid = u.uid WHERE f.tid = %d AND n.nid = f.nid AND n.type = 'forum' AND n.status = 1 AND c.status = 0 ORDER BY c.timestamp DESC", $term, 0, 1));
-
- $value = ($topic->timestamp > $reply->timestamp) ? $topic : $reply;
-
- return $value;
-}
-
-function forum_get_topics($tid, $sortby, $forum_per_page) {
- global $user;
-
- $term = taxonomy_get_term($tid);
- $voc = taxonomy_get_vocabulary($term->vid);
-
- $sql_sortby = _forum_get_topic_order($sortby);
-
- // show topics with the correct tid, or in the forum but with shadow = 1
- $sql = "SELECT n.nid, n.title, u.name AS name, u.uid AS uid, n.created AS timestamp, GREATEST(n.created, MAX(c.timestamp)) AS date_sort, COUNT(c.nid) AS num_comments, f.icon, n.comment AS comment_mode, f.tid FROM node n LEFT JOIN term_node r ON n.nid = r.nid LEFT JOIN users u ON n.uid = u.uid LEFT JOIN comments c ON n.nid = c.nid LEFT JOIN forum f ON n.nid = f.nid WHERE n.nid = r.nid AND ((r.tid = '".check_query($tid)."' AND f.shadow = 1) OR f.tid = '".check_query($tid)."') AND n.status = 1 AND n.type = 'forum' GROUP BY n.nid, n.title, u.name, u.uid, n.created, n.comment, f.tid, f.icon ORDER BY $sql_sortby";
-
- $sql_count = "SELECT COUNT(DISTINCT(n.nid)) FROM node n LEFT JOIN forum f ON n.nid = f.nid LEFT JOIN term_node r ON n.nid = r.nid WHERE n.nid = r.nid AND ( (r.tid = '".check_query($tid)."' AND f.shadow = 1) OR f.tid = '".check_query($tid)."') AND n.status = 1 AND n.type = 'forum'";
-
- $result = pager_query($sql, $forum_per_page, 0, $sql_count);
- $topic_num = db_num_rows($result);
-
- $n = 0;
- while ($topic = db_fetch_object($result)) {
- if ($user->uid) {
- $history = _forum_user_last_visit($topic->nid);
- // folder is new if topic is new or there are new comments since last visit
- if ($topic->shadow > 0) {
- $topic->new = 0;
- }
- else {
- if (!$history && $user->uid) {
- $topic->new_replies = 0;
- $topic->new = 1;
- }
- else {
- $comments = db_result(db_query("SELECT COUNT(c.nid) FROM node n LEFT JOIN comments c ON n.nid = c.nid WHERE n.nid = '$topic->nid' AND n.status = 1 AND c.status = 0 AND timestamp > '$history' GROUP BY n.nid"));
-
- $topic->new_replies = $comments ? $comments : 0;
- if ($topic->new_replies) {
- $topic->new = 1;
- }
- else {
- $topic->new = 0;
- }
- }
- }
- }
- else {
- // you're not logged in eh?
- $topic->new_replies = 0;
- $topic->new = 0;
- }
-
- $topic->last_reply = _forum_last_reply($topic->nid);
- $topics[] = $topic;
- }
-
- return $topics;
-}
-
-function _forum_new($tid) {
- global $user;
- $result = db_query("SELECT n.nid FROM node n, history h, forum f WHERE n.type = 'forum' AND n.status = 1 AND h.nid = n.nid AND f.nid = h.nid AND f.tid = %d AND h.uid = %d", $tid, $user->uid);
- while ($r = db_fetch_object($result)) {
- $read[] = $r->nid;
- }
-
- $nid = db_result(db_query_range("SELECT n.nid FROM node n LEFT JOIN forum f ON n.nid = f.nid WHERE n.type = 'forum' AND f.nid = n.nid AND n.status = 1 AND f.tid = %d ".($read ? "AND NOT (n.nid IN (".implode(",", $read).")) " : "") ."ORDER BY created", $tid, 0, 1));
-
- return $nid ? $nid : 0;
-}
-
-function _forum_message_taxonomy() {
- return t("For the forums to work, the taxonomy module has to be installed and enabled. When activated, a taxonomy vocubulary needs to be created, bound to the forum module. The vocabulary's terms define the forums.");
-}
-
-function forum_page() {
- global $sortby, $forum_per_page, $from, $user;
-
- $op = $_POST["op"];
-
- if (user_access("access content")) {
- if (module_exist("taxonomy")) {
- $tid = arg(1);
- if ($op == t("Update settings") && $user->uid) {
- $user = user_save($user, array("sortby" => $sortby, "forum_per_page" => $forum_per_page));
- }
-
- if (arg(2) == "new") {
- if ($nid = _forum_new($tid)) {
- drupal_goto(url("node/view/$nid"));
- }
- }
-
- if (empty($sortby)) {
- $sortby = isset($user->sortby) ? $user->sortby : variable_get("forum_order",1);
- }
-
- if (empty($forum_per_page)) {
- $forum_per_page = isset($user->forum_per_page) ? $user->forum_per_page : variable_get("forum_per_page", 25);
- }
-
- $offset = ($from / $forum_per_page) + 1;
-
- $forums = forum_get_forums($tid);
-
- $parents = forum_get_parents($tid);
- if ($tid && !in_array($tid, variable_get("forum_containers", array()))) {
- $topics = forum_get_topics($tid, $sortby, $forum_per_page);
- }
-
- theme("forum_theme_display", $forums, $topics, $parents, $tid, $sortby, $forum_per_page, $offset);
- }
- else {
- theme("header");
- theme("box", t("Warning"), _forum_message_taxonomy());
- theme("footer");
- }
- }
- else {
- theme("header");
- theme("box", t("Access denied"), message_access());
- theme("footer");
- }
-}
-
-/*
-** Theme functions
-*/
-
-function forum_theme_display($forums, $topics, $parents, $tid, $sortby, $forum_per_page, $offset) {
- // forum list, topics list, topic browser and "add new topic" link
-
-
- $output .= theme("forum_theme_list", $forums, $parents, $tid);
- if ($tid && !in_array($tid, variable_get("forum_containers", array()))) {
- $output .= theme("forum_theme_topic_list", $tid, $topics, $sortby, $forum_per_page, $offset);
- }
-
- theme("header");
- theme("box", t("Discussion forum"), $output);
- if ($tid && !in_array($tid, variable_get("forum_containers", array()))) {
- theme("box", t("Control panel"), theme("forum_theme_topic_browser", $sortby, $forum_per_page, $offset));
- }
- theme("footer");
-}
-
-function forum_theme_list($forums, $parents, $tid) {
- global $user;
- if ($parents) {
- foreach($parents as $p) {
- if ($tid != $p->tid) {
- $t[] = l($p->name, "forum/$p->tid");
- }
- else {
- $t[] = $p->name;
- }
- }
- }
- $t[] = l(t("Discussion forum"), "forum");
-
- $output .= "<table border=\"0\" cellpadding=\"5\">\n";
- $output .= " <tr><th colspan=\"3\" style=\"text-align: left;\">".implode(" : ", array_reverse($t)) ."</th>";
- if ($forums) {
- $output .= "<th>". t("topics") ."</th><th>". t("posts") ."</th><th>". t("last post") ."</th></tr>";
-
-
- foreach ($forums as $forum) {
- if ($forum->container) {
- $output .= " <tr><td colspan=\"5\">". l($forum->name, "forum/$forum->tid") ."<br /><small>". ($forum->description ? check_output($forum->description) : "") ."</small></td></tr>";
- }
- else {
- if ($user->uid) $new_topics = $forum->num_topics - $forum->old_topics;
- $icon = _forum_get_folder_icon($new_topics);
- $output .= " <tr><td>&nbsp;</td><td>$icon</td>";
- $output .= "<td><table border=\"0\"><tr><td style=\"width: ". ($forum->depth * 20) ."px;\">&nbsp;</td><td>". l($forum->name, "forum/$forum->tid") ."<div style=\"padding-top: 5px;\">". check_output($forum->description);
-
- $links = array();
- if ($forum->last_post) {
- $links[] = l(t("the most recent topic"), "node/view/". $forum->last_post->nid);
- }
- if ($new_topics) {
- $links[] = l(t("the first new topic"), "forum/$forum->tid/new");
- }
-
- if ($links) {
- $output .= "<br />". t("Jump to") .": ". implode(", ", $links);
- }
-
- $output .= "</div></td></tr></table></td>";
- $output .= "<td style=\"text-align: center;\">".$forum->num_topics.($new_topics ? "<br />(".t("%a new", array("%a" => $new_topics)).")" : "")."</td><td style=\"text-align: center;\">".$forum->num_posts."</td><td style=\"text-align: center;\">"._forum_format($forum->last_post)."</td></tr>";
- }
- }
- }
- $output .= "</table>\n";
-
- return $output;
-}
-
-function forum_theme_topic_browser() {
- global $tid, $sortby, $forum_per_page, $offset;
-
- if (empty($sortby)) {
- $sortby = variable_get("forum_order",1);
- }
- if (empty($forum_per_page)) {
- $forum_per_page = variable_get("forum_per_page", 25);
- }
-
- $forum_per_page_options = array(10, 25, 50, 75, 100);
- foreach ($forum_per_page_options as $value) {
- $options .= " <option value=\"$value\"". ($forum_per_page == $value ? " selected=\"selected\"" : "") .">".t("%a topics per page", array("%a" => $value))."</option>\n";
- }
-
- $output .= "<select name=\"forum_per_page\">$options</select>\n";
-
- $options = "";
- $sortby_options = array(1 => t("Date - newest first"), 2 => t("Date - oldest first"), 3 => t("Posts - most active first"), 4=> t("Posts - least active first"));
- foreach ($sortby_options as $key => $value) {
- $options .= " <option value=\"$key\"". ($sortby == $key ? " selected=\"selected\"" : "") .">$value</option>\n";
- }
-
- $output .= "\n<select name=\"sortby\">$options</select>\n";
- $output .= form_hidden("tid", $tid);
- $output .= form_submit(t("Update settings"));
- return form(form_item(t("Topic viewing options"), $output, t("Select your preferred way to display the topics and click 'Update settings'.")));
-}
-
-function forum_theme_topic_list($tid, $topics, $sortby, $forum_per_page, $offset) {
- global $id, $status, $user, $pager_total;
-
- if ($topics) {
- $output .= "<table border=\"0\" cellpadding=\"5\" cellspacing=\"5\">\n";
- $output .= " <tr><th>&nbsp;</th><th>&nbsp;</th><th>". t("topic") ."</th><th>". t("replies") ."</th><th>". t("posted") ."</th><th>". t("last reply") ."</th></tr>";
-
- foreach ($topics as $topic) {
- // folder is new if topic is new or there are new comments since last visit
- if ($topic->tid != $tid) {
- $output .= "
- <tr>
- <td>"._forum_get_folder_icon($topic->new, $topic->num_comments, $topic->comment_mode)."</td>
- <td>"._forum_get_icon($topic)."</td>
- <td style=\"vertical-align: top;\">$topic->title</td>
- <td style=\"text-align: center; vertical-align: top;\" colspan=\"3\">". l(t("This topic has been moved"), "forum/$topic->tid")."</td>
- </tr>";
- }
- else {
- $output .= "
- <tr>
- <td>"._forum_get_folder_icon($topic->new, $topic->num_comments, $topic->comment_mode)."</td>
- <td>"._forum_get_icon($topic)."</td>
- <td style=\"vertical-align: top;\">". l($topic->title, "node/view/$topic->nid") ."</td>
- <td style=\"text-align: center; vertical-align: top;\">".$topic->num_comments.($topic->new_replies ? " (".t("%a new", array("%a" => $topic->new_replies)).")" : "")."</td>
- <td style=\"text-align: center;\">"._forum_format($topic)."</td>
- <td style=\"text-align: center;\">"._forum_format($topic->last_reply)."</td>
- </tr>";
- }
- }
-
- $output .= "</table></blockquote>\n";
- }
- $output .= "<hr />";
-
- $output .= "<div style=\"text-align: center;\">" .t("%a topics, %b topics per page, page %c of %d", array("%a" => $pager_total[0], "%b" => $forum_per_page, "%c" => $offset, "%d" => ceil($pager_total[0]/$forum_per_page))) ."</div>";
-
- $output .= (($pager = pager_display(NULL, $forum_per_page, 0, "default")) ? "$pager" : "");
-
- if (user_access("create forum topics")) {
- $output .= "<div style=\"text-align: center; font-style: bold;\">". l(t("create new forum topic"), "node/add/forum/$tid") ."</div>";
- }
-
- return $output;
-}
-
-
-function _forum_get_icon($node) {
- if (variable_get("forum_topic_icon_path", "") && $node->icon) {
- return "<img src=\"". variable_get("forum_topic_icon_path", "") ."$node->icon\" />";
- }
- else {
- return "&nbsp;";
- }
-}
-
-function _forum_get_folder_icon($new_posts, $num_posts = 0, $comment_mode = 0) {
- // "folder" icon because it's generally rendered as a folder
-
-
- $base_path = variable_get("forum_folder_icon_path", "");
- if ($base_path) {
- if ($num_posts > variable_get("forum_hot_topic", 15)) {
- $icon = $new_posts ? "hot_new" : "hot";
- }
- else {
- $icon = $new_posts ? "new" : "default";
- }
-
- if ($comment_mode == 1) {
- $icon = "closed";
- }
-
- // default
- $file = $base_path."/".$icon.".gif";
-
- return "<img src=\"$file\" alt=\"\" title=\"\" />";
- }
- else {
- return "&nbsp;";
- }
-}
-
-function _forum_user_last_visit($nid) {
- global $user;
- static $history;
- if (!$history) {
- $result = db_query("SELECT nid, timestamp FROM history WHERE uid = %d", $user->uid);
- while ($t = db_fetch_object($result)) {
- $history[$t->nid] = $t->timestamp;
- }
- }
- return $history[$nid] ? $history[$nid] : 0;
-}
-
-function _forum_get_topic_order($sortby) {
- switch ($sortby) {
- case 1:
- return "date_sort DESC";
- break;
- case 2:
- return "date_sort ASC";
- break;
- case 3:
- return "num_comments DESC";
- break;
- case 4:
- return "num_comments ASC";
- break;
- }
-}
-
-function forum_help() {
- $output .= "<h3>Creating a forum</h3><p>The forum module uses taxonomy to organize itself. To create a forum you first have to create a ". l("taxonomy vocuabulary", "admin/taxonomy/add/vocabulary") ." When doing this, choose a sensible name for it (such as \"fora\") and make sure under \"Types\" that \"forum\" is selected. Once you have done this, ". l("add some terms", "admin/taxonomy") ." to it. Each term will become a forum. If you fill in the description field, users will be given additonal information about the forum on the main forum page. For example: \"troubleshooting\" - \"Please ask your questions here.\"</p>";
- $output .= "<p>When you are happy with your vocabulary, go to ". l("site configuration &raquo; modules &raquo; forum","admin/system/modules/forum") ." and set <b>Forum vocabulary</b> to the one you have just created. There will now be fora active on the site. For users to access them they must have the \"access content\" permission and to create a topic they must have ithe \"create forum topics\" permission. These permissions can be set in the ". l("user management", "admin/user/permission") ." pages.</p>";
- $output .= "<h3>Containers</h3><p>If you designate a forum as a <i>container</i>, users will not be able to post to it. The forum will be visible on the forum listing page, so it acts as a section delimiter if you will. This is useful if you have a lots of forums which are nested. For example,</p>";
- $output .= "<p>Marketing<br />-- Market research<br />-- Brand management<br /><br />Sales<br />-- Closing the deal<br />-- Avoiding ear and throat pain</p>";
- $output .= "<p>If you don't want people posting into the Marketing or Sales folders, you designate them as Containers.</p>";
- $output .= "<h4>Icons</h4><p>To disable icons, set the icon path as blank in ". l("site configuration &raquo; modules &raquo; forums","admin/system/module/forum") ."</p>";
- $output .= "<p>All files in the icon directory are assumed to be images. You may use images of whatever size you wish, but it is customary to use 15x15 or 16x16.</p>";
- return t($output);
-
-}
-
-?>
diff --git a/modules/help/help.module b/modules/help/help.module
deleted file mode 100644
index d07e77f..0000000
--- a/modules/help/help.module
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-// $Id$
-
-function help_system($field){
- $system["description"] = t("Manages displaying online help.");
- return $system[$field];
-}
-
-function help_link($type) {
- if ($type == "admin") {
- menu("admin/help/glossary", "glossary", "help_glossary", NULL, 8);
- menu("admin/help", "help", "help_admin", NULL, 9);
- }
-}
-
-function help_glossary() {
-
- $output .= "<h3>Glossary</h3><dl>";
- $output .= "<dt>Block</dt><dd>A small box containing information or content placed in the left-hand or right-hand sidebar of a web page.</dd>";
- $output .= "<dt>Comment</dt><dd>A note attached to a node. Usually intended to clarify, explain, criticize, or express an opinion on the original material.</dd>";
- $output .= "<dt>Moderation</dt><dd>The activity of making sure a post to a Drupal site fits in with what is expected for that Drupal site.<dl>";
- $output .= "<dt>Approved</dt><dd>A moderated post which has been accepted by the moderators for publication. (See published).</dd>";
- $output .= "<dt>Waiting</dt><dd>A moderated post which is still being voted on to be accepted for publication. (See published.)</dd>";
- $output .= "<dt>Moderators</dt><dd>The group of Drupal users that reviews posts before they are published. These users have the \"access submission queue\" permission. (See Published).</dd></dl></dd>";
- $output .= "<dt>Node</dt><dd>The basic data unit in Drupal. Everything is a node or an extention of a node.</dd>";
- $output .= "<dt>Public</dt><dd>See published.</dd>";
- $output .= "<dt>Published</dt><dd>A node that is viewable by everyone. (See unpublished.)</dd>";
- $output .= "<dt>Role</dt><dd>You can classify users into roles, for the purpose of setting lots of users' permissions at once.</dd>";
- $output .= "<dt>Taxonomy</dt><dd>A division of a collection of things into ordered, classified groups. (See ". l("taxonomy help","admin/taxonomy/help") .")</dd>";
- $output .= "<dt>Unpublished</dt><dd>A node that is only viewable by administrators and moderators.</dd>";
- $output .= "<dt>User</dt><dd>A person who has an account at your Drupal site, and is logged in with that account.</dd>";
- $output .= "<dt>Visitor</dt><dd>A person who does not have an account at your Drupal site or a person who has an account at your Drupal bite but is <u>not</u> logged in with that account. Also termed \"anonymous user\".</dd>";
- $output .= "</dl>";
- return t($output);
-
-}
-
-function help_admin() {
-
- foreach (module_list() as $name) {
- if (module_hook($name, "help")) {
- $links[] = l($name, "admin/help#$name");
- }
- }
-
- print "<small>". implode(" &middot; ", $links) ."</small><hr />";
-
- foreach (module_list() as $name) {
- if (module_hook($name, "help")) {
- print "<h2><a id=\"$name\">". ucfirst($name) ." module</a></h2>";
- print module_invoke($name, "help");
- }
- }
-}
-
-?>
diff --git a/modules/locale/locale.module b/modules/locale/locale.module
deleted file mode 100644
index 4e8c4d5..0000000
--- a/modules/locale/locale.module
+++ /dev/null
@@ -1,301 +0,0 @@
-<?php
-// $Id$
-
-function locale_help() {
- $output .= "<p>Normally programs are written and documented in English, and use English to interact with users. This is true for a great deal of web sites. However, most people are less comfortable with English than with their own native language, and would prefer to use their mother tongue as much as possible. Many people love see their web site showing a lot less of English, and far more of their own language.</p>";
- $output .= "<p>Therefore Drupal provides a framework to setup a multi-lingual web site, or to overwrite the default texts in English. We explored the various alternatives to support internationalization and decided to design the framework in such a way that the impact of internationalization on drupal's sources is minimized, modular and that it doesn't require a HTML or PHP wizard to maintain translations. Maintaining translations had to be simple so it became as easy as filling out forms on the administration page.</p>";
- $output .= "<h3>How to translate texts</h3><p>The actual translation starts at the ". l("overview","admin/locale") ." of the locale section of the administration pages. In the \"localization\" section you will see a list of the languages you have configured. Click on the name of the language to start translating. Looking at a page full of all the strings in the site can be a bit overwhelming, so Drupal allows you to limit the strings you are working on. If you want to limit based on translated strings click \"translated strings\", if you want to limit the string based on the untranslated strings click \"untranslated strings\". Both will take you to the same page. Once there enter the string pattern to limit on, choose the language to search for, and the status, weather translated, untranslated or both, finally where you want to look, modules, specific modules, or pages.</p>";
- $output .= "<p>At the locale page, users with the proper access rights will see the various texts that need translation on the left column of the table.</p>";
- $output .= "<p>Below the text you can see an URI where this text shows up one your site. Changes are most of these texts will be used and displayed on more than one page, though only one example URI is presented.</p>";
- $output .= "<p>The second column displays the supported languages as defined in the configuration file. See below for more information on how to support new languages. If the symbol for a language is seen like <strike>this</strike>, it means that this entry still needs to be translated into that language. If not, it has been translated already.</p>";
- $output .= "<p>To add or change a translation click the \"edit locale\" link in the third column, the \"operations\" column. You'll be presented the original text and fields for translation in the supported languages. Enter the translations and confirm by clicking the \"Save translations\" button. The translations need not be accurate; they are for your site so you can choose what to show to your users.</p>";
- $output .= "<p>To delete a translation, click the \"delete locale\" link at the overview page and the translation will be immediately deleted without confirmation. Deleting translations is convenient for removing texts that belonged to an obsolete module.</p>";
- $output .= "<p>In some texts special strings such as \"%a\" and \"%b\" show up. Those get replaced by some string at run-time when Drupal dynamically generate pages. You can find out which string this is by looking at the page where the text appears. This is where the above mentioned URI can come in handy.</p>";
- $output .= "<h3>How to add new languages</h3><p>Adding a new language requires you to edit your configuration file and to edit your SQL database. Assuming you want to support Dutch (ISO 639 code: \"nl\") and French (ISO 639 code: \"fr\"), you add the following line to your configuration file's <code>\$languages</code>-variable:</p>";
- $output .= "<pre>
- \$languages = array(\"nl\" => \"Dutch / Nederlands\", \"fr\" => \"French / Francais\");
- </pre>";
-
- $output .= "<p>Note that the default language must come first and that if you want to overwrite the default text you can add an entry for English (ISO 639 code: \"en\"):</p>";
- $output .= "<pre>
- \$languages = array(\"en\" => \"English\", \"nl\" => \"Dutch / Nederlands\", \"fr\" => \"French / Francais\");
- </pre>";
- $output .= "<p>After having edited your configuration file, make sure your SQL table \"locales\" has the required database fields setup to host your new translations. You can add the required rows to your \"locales\" table from the MySQL prompt:</p>";
- $output .= "<pre>
- mysql> ALTER TABLE locales ADD en TEXT DEFAULT '' NOT NULL;
- mysql> ALTER TABLE locales ADD nl TEXT DEFAULT '' NOT NULL;
- mysql> ALTER TABLE locales ADD fr TEXT DEFAULT '' NOT NULL;
- </pre>";
- return t($output);
-}
-
-function locale_system($field){
- $system["description"] = t("Enables the translation of the user interface to languages other than English.");
- return $system[$field];
-}
-
-function locale_perm() {
- return array("administer locales");
-}
-
-function locale_link($type) {
- global $languages;
-
- if ($type == "admin" && user_access("administer locales")) {
- $help["general"] = t("The locale module handles translations into new languages. It also enables you to add jargon, slang or other special language as fits the web site. For each language you want to support, a line needs to be added to your configuration file.");
- $help["search"] = t("Search the localization database. ('*' can be used as a wildcard)");
- $help["translated"] = t("Start by searching the translated strings.");
- $help["untranslated"] = t("Start by searching the untranslated strings.");
-
- menu("admin/locale", "localization", NULL, $help["general"], 5);
- menu("admin/locale/search", "search string", "locale_admin", $help["search"], 8);
- menu("admin/locale/help", "help", "locale_help", NULL, 9);
- menu("admin/locale/edit", "edit string", "locale_admin", NULL, 0, 1); // hidden menu
- menu("admin/locale/delete", "delete string", "locale_admin", NULL, 0, 1); // hidden menu
-
- foreach ($languages as $key => $value) {
- menu("admin/locale/$key", "$value", NULL, $help["general"]);
- menu("admin/locale/$key/translated", "translated strings", "locale_admin", $help["translated"]);
- menu("admin/locale/$key/untranslated", "untranslated strings", "locale_admin", $help["untranslated"]);
- }
- }
-}
-
-function locale_delete($lid) {
- db_query("DELETE FROM locales WHERE lid = %d", $lid);
- locale_refresh_cache();
-
- return t("deleted string");
-}
-
-function locale_save($lid) {
- $edit =& $_POST["edit"];
- foreach ($edit as $key=>$value) {
- db_query("UPDATE locales SET $key = '%s' WHERE lid = %d", $value, $lid);
- }
- locale_refresh_cache();
- // delete form data so it will remember where it came from
- $edit = '';
-
- return t("saved string");
-}
-
-function locale_refresh_cache() {
- global $languages;
-
- foreach (array_keys($languages) as $locale) {
- $result = db_query("SELECT string, %s FROM locales", $locale);
- while ($data = db_fetch_object($result)) {
- if (empty($data->$locale)) {
- $t[$data->string] = $data->string;
- }
- else {
- $t[$data->string] = $data->$locale;
- }
- }
- cache_set("locale:$locale", serialize($t));
- }
-}
-
-function locale_edit($lid) {
- global $languages;
-
- $result = db_query("SELECT * FROM locales WHERE lid = '$lid'");
- if ($translation = db_fetch_object($result)) {
-
- $form .= form_item(t("Original text"), wordwrap(drupal_specialchars($translation->string, 0)));
-
- foreach ($languages as $code=>$language) {
- $form .= (strlen($translation->string) > 30) ? form_textarea($language, $code, $translation->$code, 50, 10) : form_textfield($language, $code, $translation->$code, 50, 128);
- }
-
- $form .= form_submit(t("Save translations"));
-
- return form($form);
- }
-}
-
-function locale_languages($translation) {
- global $languages;
-
- foreach ($languages as $key => $value) {
- $output .= ($translation->$key) ? "<a href=\"#\" title=\"". $translation->$key ."\">$key</a> " : "<strike>$key</strike> ";
- }
-
- return $output;
-}
-
-function locale_seek() {
- global $id, $languages;
- $op = $_POST["op"];
- $edit =& $_POST["edit"];
-
- if ($op != 'overview' && !$edit && isset($_SESSION["locale_settings"])) {
- $edit = $_SESSION["locale_settings"];
- }
- else {
- $_SESSION["locale_settings"] = $edit;
- }
-
- if (is_array($edit)) {
-
- if ($edit["status"]) {
- switch ($edit["language"]) {
- case "all":
- foreach ($languages as $key=>$value) {
- $tmp[] = $key . (check_query($edit["status"]) == 1 ? " !=" : " =") ." ''";
- }
- $query[] = implode(" AND ", $tmp);
- break;
- case "any":
- foreach ($languages as $key=>$value) {
- $tmp[] = $key . (check_query($edit["status"]) == 1 ? " !=" : " =") ." ''";
- }
- $query[] = "(". implode(" || ", $tmp) .")";
- break;
- default:
- $query[] = check_query($edit["language"]) . (check_query($edit["status"]) == 1 ? " !=" : " =") ." ''";
- }
- }
-
- if ($edit["string"]) {
- $string_query[] = "string LIKE '%". check_query($edit["string"]) ."%'";
- if ($edit["status"] != 2) {
- if (strlen($edit["language"]) == 2) {
- $string_query[] = check_query($edit["language"]) ." LIKE '%". check_query($edit["string"]) ."%'";
- }
- else {
- foreach ($languages as $key=>$value) {
- $string_query[] = check_query($key) ." LIKE '%". check_query($edit["string"]) ."%'";
- }
- }
- }
- $query[] = "(". implode(" || ", $string_query) .")";
- }
-
- $result = db_query("SELECT * FROM locales". (count($query) ? " WHERE ". implode(" && ", $query) : "") ." ORDER BY string");
-
- $header = array(t("string"), (($edit["status"] != 2 && strlen($edit["language"]) == 2) ? t("translated string") : t("languages")), array("data" => t("operations"), "colspan" => "2"));
- while ($locale = db_fetch_object($result)) {
- $rows[] = array("$locale->string<br /><small><i>$locale->location</i></small>", array("data" => (($edit["status"] != 2 && strlen($edit["language"]) == 2) ? $locale->$edit["language"] : locale_languages($locale)), "align" => "center"), array("data" => l(t("edit locale"), "admin/locale/edit/$locale->lid"), "nowrap" => "nowrap"), array("data" => l(t("delete locale"), "admin/locale/delete/$locale->lid"), "nowrap" => "nowrap"));
- }
- $output .= table($header, $rows);
- }
-
- return $output;
-}
-
-function locale_seek_form() {
- global $languages;
- $edit =& $_POST["edit"];
- $form .= form_textfield(t("Strings to search for"), "string", $edit["string"], 30, 30, t("Leave blank to show all strings."));
- $form .= form_select(t("Language"), "language", ($edit["language"] ? $edit["language"] : key($languages)), array_merge(array("any" => t("Any language"), "all" => t("All languages")), $languages), t("In which language must the string be translated/untranslated (see status)?"));
- $form .= form_select(t("Status"), "status", $edit["status"], array(2 => t("Untranslated"), 1 => t("Translated"), 0 => t("All")));
- $form .= form_submit(t("Search"));
-
- $output .= form($form);
-
- return $output;
-}
-
-function locale_admin() {
- $op = $_POST["op"];
- $edit =& $_POST["edit"];
-
- if (user_access("administer locales")) {
- locale_admin_initialize();
-
- if (empty($op)) {
- $op = arg(2);
- }
-
- switch ($op) {
- case "delete":
- print status(locale_delete(check_query(arg(3))));
- print locale_seek();
- break;
- case "edit":
- print locale_edit(check_query(arg(3)));
- break;
- case "search":
- print locale_seek_form();
- break;
- case t("Search"):
- print locale_seek();
- print locale_seek_form();
- break;
- case t("Save translations"):
- print status(locale_save(check_query(arg(3))));
- print locale_seek();
- break;
- default:
- if (arg(3) == "translated") {
- $edit["status"] = 1;
- $edit["language"] = arg(2);
- }
- else {
- $edit["status"] = 2;
- $edit["language"] = arg(2);
- }
- print locale_seek();
- print locale_seek_form();
- }
- }
- else {
- print message_access();
- }
-}
-
-function locale_admin_initialize() {
- /*
- ** This function inserts common strings into the locale table (eg.
- ** names of months and days). We use $revision and a stored variable
- ** to track if the locale table is up-to-date.
- */
-
- $revision = 1;
-
- if (variable_get("locale_initialize_revision", 0) < $revision) {
- variable_set("locale_initialize_revision", $revision);
- for ($i = 1; $i <= 12; $i++) {
- $stamp = mktime(0, 0, 0, $i, 1, 1971);
- t(date("F", $stamp));
- t(date("M", $stamp));
- }
-
- for ($i = 0; $i <= 7; $i++) {
- $stamp = $i * 86400;
- t(date("D", $stamp));
- t(date("l", $stamp));
- }
- }
-}
-
-function locale($string) {
- global $locale;
- static $locale_t;
-
- if (!isset($locale_t)) {
- $cache = cache_get("locale:$locale");
- if ($cache == 0) {
- locale_refresh_cache();
- $cache = cache_get("locale:$locale");
- }
- $locale_t = unserialize($cache->data);
- }
-
- if ($locale_t[$string] != "") {
- $string = $locale_t[$string];
- }
- else {
- $result = db_query("SELECT lid, $locale FROM locales WHERE string = '%s'", $string);
- if (!db_fetch_object($result)) {
- db_query("INSERT INTO locales (string, location) VALUES ('%s', '%s')", $string, request_uri());
- cache_clear_all("locale:$locale");
- }
- }
-
- return $string;
-}
-
-?>
diff --git a/modules/node/node.module b/modules/node/node.module
deleted file mode 100644
index a8e59ce..0000000
--- a/modules/node/node.module
+++ /dev/null
@@ -1,1481 +0,0 @@
-<?php
-// $Id$
-
-function node_help() {
- global $mod;
-
- $output .= "<h3>Nodes</h3>The core of the Drupal system is the node. All of the contents of the system are placed in nodes, or extensions of nodes. ";
- $output .= "A base node contains:<dl>";
- $output .= "<dt>A Title</dt><dd>Up to 128 characters of text that titles the node.</dd>";
- $output .= "<dt>A Teaser</dt><dd>A small block of text that is meant to get you interested in the rest of node. Drupal automatically pulls a small amount of the body of the node to make the teaser (To configure how long the teaser will be ". l("click here","admin/system/modules/node") ."). The teaser can be changed if you don't like what Drupal grabs.</dd>";
- $output .= "<dt>The Body</dt><dd>The main text that comprises your content.</dd>";
- $output .= "<dt>A Type</dt><dd>What kind of node is this? Blog, book, forum, comment, unextended, etc.</dd>";
- $output .= "<dt>An Author</dt><dd>The author's name. It will either be \"anonymous\" or a valid user. You <i>cannot</i> set it to an arbitrary value.</dd>";
- $output .= "<dt>Authored on</dt><dd>The date it was written on.</dd>";
- $output .= "<dt>Changed</dt><dd>The last time this node was changed.</dd>";
- $output .= "<dt>Static on front page</dt><dd>The front page is configured to show the teasers from only a few of the total nodes you have on your site (To configure how many teasers ". l("click here","admin/system/modules/node") ."), but if you think a node is important enough that you want it to stay on the front page enable this.</dd>";
- $output .= "<dt>Allow user comments</dt><dd>A node can have comments, which are other nodes. These comments can be written by other users (Read-write), or only by admins (Read-only).</dd>";
- $output .= "<dt>Attributes</dt><dd>A way to sort nodes.</dd><dt>Revisions</dt><dd>Drupal has a revision system so that you can \"roll back\" to an older version of a node if the new version is not what you want.</dd>";
- $output .= "<dt>Promote to front page</dt><dd>To get people to look at the new stuff on your site you can choose to move it to the front page.</dd>";
- $output .= "<dt>In moderation queue</dt><dd>Drupal has a moderation system. If it is active, a node is in one of three states: approved and published, approved and unpublished, and awaiting approval. If you are moderating a node it should be in the moderation queue.</dd>";
- $output .= "<dt>Votes</dt><dd>If you are moderating a node this counts how many votes the node has gotten. Once a node gets a certain number of vote if will either be Approved, or Dropped (To setup the number of votes needed and the promote and dump scores ". l("click here","admin/system/modules/queue") .".)</a>.</dd>";
- $output .= "<dt>Score</dt><dd>The score of the node is gotten by the votes it is given.</dd>";
- $output .= "<dt>Users</dt><dd>The list of users who have voted on a moderated node.</dd>";
- $output .= "<dt>Published</dt><dd>When using Drupal's moderation system a node remains unpublished -- unavaliable to non-moderators -- until it is marked Published.</dd></dl>";
- $output .= "<p>Now that you know what is in a node, here are some of the types of nodes available.</p>";
-
- if ($mod == "admin") {
- foreach (module_list() as $name) {
- if (module_hook($name, "node") && $name != "node") {
- $output .= "<h3>". t("Node type: %module", array("%module" => module_invoke($name, "node", "name"))). "</h3>";
- $output .= module_invoke($name, "help");
-
- }
- }
- }
- return t($output);
-}
-
-function node_system($field){
- $system["description"] = t("The core that allows content to be submitted to the site.");
- $system["admin_help"] = t("Settings for the core of Drupal. Almost everything is a node so these settings will affect most of the site.");
- return $system[$field];
-}
-
-/*
-** Accepts a DB result object which can be used to fetch node objects.
-** Returns an HTML list suitable as content for a block.
-*/
-function node_title_list($result, $title = NULL) {
- while ($node = db_fetch_object($result)) {
- $number = module_invoke("comment", "num_all", $node->nid);
- $items[] = l($node->title, "node/view/$node->nid", array("title" => format_plural($number, "%count comment", "%count comments")));
- }
-
- return theme("theme_node_list", $items, $title);
-}
-
-function theme_node_list($items, $title = NULL) {
- return theme("theme_item_list", $items, $title);
-}
-
-// Update the 'last viewed' timestamp of the specified node for current user.
-function node_tag_new($nid) {
- global $user;
-
- if ($user->uid) {
- $result = db_query("SELECT timestamp FROM history WHERE uid = %d AND nid = %d", $user->uid, $nid);
- if (db_fetch_object($result)) {
- db_query("UPDATE history SET timestamp = %d WHERE uid = %d AND nid = %d", time(), $user->uid, $nid);
- }
- else {
- db_query("INSERT INTO history (uid, nid, timestamp) VALUES (%d, %d, %d)", $user->uid, $nid, time());
- }
- }
-}
-
-/*
-** Retrieves the timestamp at which the current user last viewed the
-** specified node.
-*/
-function node_last_viewed($nid) {
- global $user;
-
- $history = db_fetch_object(db_query("SELECT timestamp FROM history WHERE uid = '$user->uid' AND nid = %d", $nid));
- return ($history->timestamp ? $history->timestamp : 0);
-}
-
-/**
- * Determines whether the supplied timestamp is newer than the user's last view of a given node
- *
- * @param $nid node-id twhose history supplies the 'last viewed' timestamp
- * @param $timestamp time which is compared against node's 'last veiwed' timestamp
-*/
-function node_is_new($nid, $timestamp) {
- global $user;
- static $cache;
-
- if (!isset($cache[$nid])) {
- if ($user->uid) {
- $history = db_fetch_object(db_query("SELECT timestamp FROM history WHERE uid = %d AND nid = %d", $user->uid, $nid));
- $cache[$nid] = $history->timestamp ? $history->timestamp : 0;
- }
- else {
- $cache[$nid] = time();
- }
- }
-
- if ($timestamp > $cache[$nid]) {
- return 1;
- }
- else {
- return 0;
- }
-}
-
-function node_teaser($body) {
-
- $size = variable_get("teaser_length", 600);
-
- /*
- ** If the size is zero, teasers are disabled so we
- ** return the entire body.
- */
-
- if ($size == 0) {
- return $body;
- }
-
- /*
- ** If we have a short body, return the entire body:
- */
-
- if (strlen($body) < $size) {
- return $body;
- }
-
- /*
- ** If a valid delimiter has been specified, use it to
- ** chop of the teaser. The delimiter can be outside
- ** the allowed range but no more than a factor two.
- */
-
- $delimiter = strpos($body, "<!--break-->");
- if ($delimiter > 0) {
- return substr($body, 0, $delimiter);
- }
-
- /*
- ** In some cases no delimiter has been specified (eg.
- ** when posting using the Blogger API) in which case
- ** we try to split at paragraph boundaries.
- */
-
- if ($length = strpos($body, "<br />", $size)) {
- return substr($body, 0, $length);
- }
-
- if ($length = strpos($body, "<br>", $size)) {
- return substr($body, 0, $length);
- }
-
- if ($length = strpos($body, "</p>", $size)) {
- return substr($body, 0, $length);
- }
-
- if ($length = strpos($body, "\n", $size)) {
- return substr($body, 0, $length);
- }
-
- /*
- ** When even the first paragraph is too long, try to
- ** split at the end of the next sentence.
- */
-
- if ($length = strpos($body, ". ", $size)) {
- return substr($body, 0, $length + 1);
- }
-
- if ($length = strpos($body, "! ", $size)) {
- return substr($body, 0, $length + 1);
- }
-
- if ($length = strpos($body, "? ", $size)) {
- return substr($body, 0, $length + 1);
- }
-
- /*
- ** Nevermind, we split it the hard way ...
- */
-
- return substr($body, 0, $size);
-}
-
-function node_invoke(&$node, $hook, $arg = 0) {
- if (is_array($node)) {
- $function = $node["type"] ."_$hook";
- }
- else if (is_object($node)) {
- $function = $node->type ."_$hook";
- }
- else if (is_string($node)) {
- $function = $node ."_$hook";
- }
-
- if (function_exists($function)) {
- return ($arg ? $function($node, $arg) : $function($node));
- }
-}
-
-function node_invoke_all(&$node, $hook, $op, $arg = 0) {
- $return = array();
- foreach (module_list() as $name) {
- if ((module_hook($name, "node") || module_hook($name, "nodeapi")) && module_hook($name, $hook)) {
- $function = $name ."_". $hook;
- $result = $function($node, $op, $arg);
- if (isset($result)) {
- $return = array_merge($return, $result);
- }
- }
- }
- return $return;
-}
-
-function node_load($conditions, $revision = -1) {
-
- /*
- ** Turn the conditions into a query:
- */
-
- foreach ($conditions as $key => $value) {
- $cond[] = "n.". check_query($key) ." = '". check_query($value) ."'";
- }
-
- /*
- ** Retrieve the node:
- */
-
- $node = db_fetch_object(db_query("SELECT n.*, u.uid, u.name FROM node n LEFT JOIN users u ON u.uid = n.uid WHERE ". implode(" AND ", $cond)));
-
- /*
- ** Unserialize the revisions field:
- */
-
- if ($node->revisions) {
- $node->revisions = unserialize($node->revisions);
- }
-
- /*
- ** Call the node specific callback (if any) and piggy-back the
- ** results to the node or overwrite some values:
- */
-
- if ($extra = module_invoke($node->type, "load", $node)) {
- foreach ($extra as $key => $value) {
- $node->$key = $value;
- }
- }
-
- /*
- ** Return the desired revision
- */
- if ($revision != -1 && isset($node->revisions[$revision])) {
- $node = $node->revisions[$revision]["node"];
- }
-
- return $node;
-}
-
-function node_save($node) {
-
- /*
- ** Fetch fields to save to node table:
- */
- $fields = node_invoke_all($node, "nodeapi", "fields");
-
- /*
- ** Serialize the revisions field:
- */
-
- if ($node->revisions) {
- $node->revisions = serialize($node->revisions);
- }
-
- /*
- ** Apply filters to some default node fields:
- */
-
- if (empty($node->nid)) {
-
- /*
- ** Insert a new node:
- */
-
- // Set some required fields:
- if (!$node->created) {
- $node->created = time();
- }
- $node->changed = time();
- $node->nid = db_next_id("node_nid");
-
- // Prepare the query:
- foreach ($node as $key => $value) {
- if (in_array($key, $fields)) {
- $k[] = check_query($key);
- $v[] = "'". check_query($value) ."'";
- }
- }
-
- // Insert the node into the database:
- db_query("INSERT INTO node (". implode(", ", $k) .") VALUES (". implode(", ", $v) .")");
-
- // Call the node specific callback (if any):
- node_invoke($node, "insert");
- node_invoke_all($node, "nodeapi", "insert");
- }
- else {
-
- /*
- ** Update an existing node:
- */
-
- // Set some required fields:
- $node->changed = time();
-
- // Prepare the query:
- foreach ($node as $key => $value) {
- if (in_array($key, $fields)) {
- $q[] = check_query($key) ." = '". check_query($value) ."'";
- }
- }
-
- // Update the node in the database:
- db_query("UPDATE node SET ". implode(", ", $q) ." WHERE nid = '$node->nid'");
-
- // Call the node specific callback (if any):
- node_invoke($node, "update");
- node_invoke_all($node, "nodeapi", "update");
- }
-
- /*
- ** Clear the cache so an anonymous poster can see the node being
- ** added or updated.
- */
-
- cache_clear_all();
-
- /*
- ** Return the node ID:
- */
-
- return $node->nid;
-
-}
-
-function node_view($node, $main = 0) {
-
-
- $node = array2object($node);
-
- /*
- ** Remove the delimiter (if any) that seperates the teaser from the
- ** body. TODO: this strips legitimate uses of '<!--break-->' also.
- */
-
- $node->body = str_replace("<!--break-->", "", $node->body);
-
- /*
- ** The "view" hook can be implemented to overwrite the default function
- ** to display nodes.
- */
-
- if (module_hook($node->type, "view")) {
- node_invoke($node, "view", $main);
- }
- else {
-
- /*
- ** Default behavior:
- */
-
- $node->teaser = check_output($node->teaser);
- $node->body = check_output($node->body);
-
- theme("node", $node, $main);
- }
-}
-
-function node_show($node, $cid) {
-
- if (node_access("view", $node)) {
-
- node_view($node);
-
- if (function_exists("comment_render") && $node->comment) {
- comment_render($node, $cid);
- }
-
- /*
- ** Update the history table, stating that this user viewed this node.
- */
-
- node_tag_new($node->nid);
- }
-}
-
-function node_access($op, $node = 0) {
-
- if (user_access("administer nodes")) {
- return 1;
- }
-
- /*
- ** Convert the node to an object if necessary:
- */
-
- $node = array2object($node);
-
- /*
- ** Construct a function:
- */
-
- if ($node->type) {
- $type = $node->type;
- }
- else {
- $type = $node;
- }
-
- $function = $type ."_access";
-
- if (function_exists($function)) {
- return $function($op, $node);
- }
- else {
- return 0;
- }
-}
-
-function node_perm() {
- return array("administer nodes", "access content");
-}
-
-function node_search($keys) {
-
- // Return the results of performing a search using the indexed search
- // for this particular type of node.
- //
- // Pass an array to the "do_search" function which dictates what it
- // will search through, and what it will search for
- //
- // "keys"'s value is the keywords entered by the user
- //
- // "type"'s value is used to identify the node type in the search
- // index.
- //
- // "select"'s value is used to relate the data from the specific nodes
- // table to the data that the search_index table has in it, and the the
- // do_search functino will rank it.
- //
- // The select must always provide the following fields - lno, title,
- // created, uid, name, count
- //
- $find = do_search(array("keys" => $keys, "type" => "node", "select" => "select s.lno as lno, n.title as title, n.created as created, u.uid as uid, u.name as name, s.count as count FROM search_index s, node n LEFT JOIN users u ON n.uid = u.uid WHERE s.lno = n.nid AND s.type = 'node' AND s.word like '%' AND n.status = 1"));
-
- return $find;
-}
-
-function node_settings() {
- $output .= form_select(t("Number of posts on main page"), "default_nodes_main", variable_get("default_nodes_main", 10), array(1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10, 15 => 15, 20 => 20, 25 => 25, 30 => 30), t("The default maximum number of posts to display per page on overview pages such as the main page."));
- $output .= form_select(t("Length of trimmed posts"), "teaser_length", variable_get("teaser_length", 600), array(0 => t("Unlimited"), 200 => t("200 characters"), 400 => t("400 characters"), 600 => t("600 characters"), 800 => t("800 characters"), 1000 => t("1000 characters"), 1200 => t("1200 characters"), 1400 => t("1400 characters"), 1600 => t("1600 characters"), 1800 => t("1800 characters"), 2000 => t("2000 characters")), t("The maximum number of characters used in the trimmed version of a post. Drupal will use this setting to determine at which offset long posts should be trimmed. The trimmed version of a post is typically used as a teaser when displaying the post on the main page, in XML feeds, etc. To disable teasers, set to 'Unlimited'."));
- $output .= form_select(t("Preview post"), "node_preview", variable_get("node_preview", 0), array(t("Optional"), t("Required")), t("Must users preview posts before submitting?"));
- return $output;
-}
-
-function node_conf_filters() {
- $output .= form_select(t("Filter HTML tags"), "filter_html", variable_get("filter_html", 0), array(t("Disabled"), t("Enabled")), t("Filter HTML and PHP tags in user-contributed content."));
- $output .= form_textfield(t("Allowed HTML tags"), "allowed_html", variable_get("allowed_html", "<a> <b> <dd> <dl> <dt> <i> <li> <ol> <u> <ul>"), 64, 255, t("If enabled, optionally specify tags which should not be stripped. 'STYLE' attributes, 'ON*' attributes and unclosed tags are always stripped."));
- $output .= form_select(t("Rewrite old URLs"), "rewrite_old_urls", variable_get("rewrite_old_urls", 0), array(t("Disabled"), t("Enabled")), t("The introduction of 'clean URLs' in Drupal 4.2.0 breaks internal URLs that date back from Drupal 4.1.0 and before. If enabled, this filter will attempt to rewrite the old style URLs to avoid broken links. If <code>mod_rewrite</code> is available on your system, use the rewrite rules in Drupal's <code>.htaccess</code> file instead as these will also correct external referrers."));
- $output .= "<hr />";
- return $output;
-}
-
-function node_filter_html($text) {
- $text = strip_tags($text, variable_get("allowed_html", ""));
- return $text;
-}
-
-function node_filter_link($text) {
- $pat = '\[{2}([^\|]+)(\|([^\|]+)?)?\]{2}'; // [link|description]
- return ereg_replace($pat, $dst, $text);
-}
-
-function node_comment_mode($nid) {
- static $comment_mode;
- if (!isset($comment_mode[$nid])) {
- $comment_mode[$nid] = db_result(db_query("SELECT comment FROM node WHERE nid = %d", $nid));
- }
- return $comment_mode[$nid];
-}
-
-function node_filter($text) {
- if (variable_get("filter_html", 0)) {
- $text = node_filter_html($text);
- }
-
- if (variable_get("rewrite_old_urls", 0)) {
- $text = rewrite_old_urls($text);
- }
-
- return trim($text);
-}
-
-function node_link($type, $node = 0, $main = 0) {
-
- $links = array();
-
- if ($type == "page") {
- $links[] = l(t("submit"), "node/add", array("title" => t("Submit or suggest new content.")));
- }
-
- if ($type == "node") {
- if ($node->links) {
- $links = $node->links;
- }
-
- if ($main == 1 && $node->teaser && $node->teaser != $node->body) {
- $links[] = l(t("read more"), "node/view/$node->nid", array("title" => t("Read the rest of this posting.")));
- }
-
- if (user_access("administer nodes")) {
- $links[] = l(t("administer"), "admin/node/edit/$node->nid", array("title" => t("Administer this node.")));
- }
- }
-
- if ($type == "admin" && user_access("administer nodes")) {
- $help["overview"] = t("Below is a list of all of the nodes in your site. Other forms of content are listed elsewhere (e.g. ". l("comments", "admin/comment") .").<br />Clicking a title views that node, while clicking an author's name edits their user information.<br />Other node-related tasks are available from the menu on the left.");
- $help["post-overview"] = t("Click on <a href=\"%nup\">new or updated posts</a> to see your latest nodes, or <a href=\"%queue\">approval queue</a> to approve new messages.", array("%nup" => url("admin/node/nodes/0"), "%queue" => url("admin/node/nodes/1")));
- $help["new-update"] = t("Below is a list of the latest nodes in your site. Clicking a title views that node, while clicking an author's name edits their user information.");
- $help["queue"] = t("Below is a list of the node in your site that await approval. To approve a node click on <b>edit node</b> and then change its moderation status to <b>approved</b>.<br />Clicking a title views that node, while clicking an author's name edits their user information.");
- $help["search"] = t("Enter a simple pattern to search for a post. This can include the wildcard character *.<br />For example, a search for \"br*\" might return \"bread bakers\", \"our daily bread\" and \"brenda\".");
- $help["setting"] = t("This pages lets you set the defaults used during creation of nodes for all the different node types.<br /><b>comment:</b> Read/write setting for comments.<br /><b>publish:</b> Is this node publicly viewable, has it been published?<br /><b>promote:</b> Is this node to be promoted to the front page?<br /><b>moderate:</b> Does this node need approval before it can be viewed?<br /><b>static:</b> Is this node always visible on the front page?<br /><b>revision:</b> Will this node go into the revision system allowing multiple versions to be saved?");
-
- menu("admin/node", "content management", "node_admin", $help["overview"]);
- menu("admin/node/nodes", "post overview", NULL, $help["post-overview"]);
- menu("admin/node/nodes/0", "new or updated posts", "node_admin", $help["new-update"], 0);
- menu("admin/node/nodes/1", "approval queue", "node_admin", $help["queue"], 1);
- menu("admin/node/search", "search posts", "node_admin", $help["search"], 8);
- menu("admin/node/help", "help", "node_help", NULL, 9);
- menu("admin/node/edit", "edit node", "node_admin", NULL, 0, 1);
- menu("admin/node/settings", "content settings", "node_admin", $help["setting"], 8);
- }
-
- return $links;
-}
-
-function node_admin_edit($node) {
-
- if (is_numeric($node)) {
- $node = node_load(array("nid" => $node));
- }
-
- /*
- ** Edit node:
- */
-
- $output .= "<h3>". t("Edit %module", array("%module" => module_invoke($node->type, "node", "name"))) ."</h3>";
-
- $output .= node_form($node);
-
- /*
- ** Edit revisions:
- */
-
- if ($node->revisions) {
- $output .= "<h3>". t("Edit revisions") ."</h3>";
- $output .= "<table border=\"1\" cellpadding=\"2\" cellspacing=\"2\">";
- $output .= " <tr><th>". t("older revisions") ."</th><th colspan=\"3\">". t("operations") ."</th></tr>";
- foreach ($node->revisions as $key => $revision) {
- $output .= " <tr><td>". t("revision #%r revised by %u on %d", array("%r" => $key, "%u" => format_name(user_load(array("uid" => $revision["uid"]))), "%d" => format_date($revision["timestamp"], "small"))) . ($revision["history"] ? "<br /><small>". $revision["history"] ."</small>" : "") ."</td><td>". l(t("view revision"), "node/view/$node->nid", array(), "revision=$key") ."</td><td>". l(t("rollback revision"), "admin/node/rollback+revision/$node->nid/$key") ."</td><td>". l(t("delete revision"), "admin/node/delete+revision/$node->nid/$key") ."</td></tr>";
- }
- $output .= "</table>";
- }
-
- /*
- ** Display the node form extensions:
- */
-
- foreach (module_list() as $name) {
- $output .= module_invoke($name, "node_link", $node);
- }
-
- return $output;
-
-}
-
-function node_admin_nodes() {
-
- $query = arg(3);
- $queries = array("ORDER BY n.changed DESC", "WHERE n.status = 0 OR n.moderate = 1 ORDER BY n.changed DESC");
-
- $result = pager_query("SELECT n.*, u.name, u.uid FROM node n LEFT JOIN users u ON n.uid = u.uid ". $queries[$query ? $query : 0], 50);
-
- $header = array(t("title"), t("type"), t("author"), t("status"), array("data" => t("operations"), "colspan" => 2));
-
- while ($node = db_fetch_object($result)) {
- $rows[] = array(l($node->title, "node/view/$node->nid") ." ". (node_is_new($node->nid, $node->changed) ? theme_mark() : ""), module_invoke($node->type, "node", "name"), format_name($node), ($node->status ? t("published") : t("not published")), l(t("edit node"), "admin/node/edit/$node->nid"), l(t("delete node"), "admin/node/delete/$node->nid"));
- }
-
- if ($pager = pager_display(NULL, 50, 0, "admin")) {
- $rows[] = array(array("data" => $pager, "colspan" => 6));
- }
-
- return table($header, $rows);
-}
-
-/*
-**
-*/
-
-function node_admin_settings($edit) {
- $op = $_POST["op"];
-
- if ($op == t("Save configuration")) {
- /*
- ** Save the configuration options:
- */
-
- foreach ($edit as $name => $value) {
- variable_set($name, $value);
- }
- $output = status(t("the content settings have been saved."));
- }
-
- if ($op == t("Reset to defaults")) {
- /*
- ** Reset the configuration options to their default value:
- */
-
- foreach ($edit as $name => $value) {
- variable_del($name);
- }
- $output = status(t("the content settings have been reset to their default values."));
- }
-
- $header = array_merge(array(t("type")), array_keys(node_invoke_all($node, "nodeapi", "settings")));
- foreach (module_list() as $name) {
- if (module_hook($name, "node")) {
- $node->type = $name;
- $cols = array();
- foreach (node_invoke_all($node, "nodeapi", "settings") as $setting) {
- $cols[] = array("data" => $setting, "align" => "center", "width" => 55);
- }
- $rows[] = array_merge(array(module_invoke($name, "node", "name")), $cols);
- }
- }
-
- $output .= table($header, $rows);
-
- /* This is an idea for the future.
- foreach (module_list() as $name) {
- if (module_hook($name, "node")) {
- $node->type = $name;
-
- // Create table() data:
- $header = array_keys(node_invoke_all($node, "nodeapi", "settings"));
- $cols = array();
- foreach (node_invoke_all($node, "nodeapi", "settings") as $setting) {
- $cols[] = array("data" => $setting, "align" => "center", "width" => 75);
- }
-
- $output .= "<h2>". module_invoke($name, "node", "name") ."</h2>";
- $output .= table($header, array($cols));
- $output .= "<br /><br />";
- }
- }
- */
-
- $output .= form_submit(t("Save configuration"));
- $output .= form_submit(t("Reset to defaults"));
-
- print form($output);
-
-}
-
-/*
-** Return the revision with the specified revision number.
-*/
-
-function node_revision_load($node, $revision) {
- return $node->revisions[$revision]["node"];
-}
-
-/*
-** Create and return a new revision of the given node.
-*/
-
-function node_revision_create($node) {
- global $user;
-
- /*
- ** 'revision' is the name of the field used to indicicate that we
- ** have to create a new revision of a node.
- */
-
- if ($node->nid && $node->revision) {
- $prev = node_load(array("nid" => $node->nid));
- $node->revisions = $prev->revisions;
- unset($prev->revisions);
- $node->revisions[] = array("uid" => $user->uid, "timestamp" => time(), "node" => $prev, "history" => $node->history);
- }
-
- return $node;
-}
-
-/*
-** Roll-back to the revision with the specified revision number.
-*/
-
-function node_revision_rollback($node, $revision) {
- global $user;
-
- /*
- ** Extract the specified revision:
- */
-
- $rev = $node->revisions[$revision]["node"];
-
- /*
- ** Inherit all the past revisions:
- */
-
- $rev->revisions = $node->revisions;
-
- /*
- ** Save the original/current node:
- */
-
- $rev->revisions[] = array("uid" => $user->uid, "timestamp" => time(), "node" => $node);
-
- /*
- ** Remove the specified revision:
- */
-
- unset($rev->revisions[$revision]);
-
- /*
- ** Save the node:
- */
-
- foreach ($node as $key => $value) {
- $filter[] = $key;
- }
-
- node_save($rev, $filter);
-
- watchdog("special", "$node->type: rollbacked to revision #$revision of '$node->title'");
-}
-
-/*
-** Delete the revision with specified revision number.
-*/
-
-function node_revision_delete($node, $revision) {
-
- unset($node->revisions[$revision]);
-
- node_save($node, array("nid", "revisions"));
-
- watchdog("special", "$node->type: removed revision #$revision of '$node->title'");
-}
-
-/*
-** Return a list of all the existing revision numbers.
-*/
-
-function node_revision_list($node) {
- if (is_array($node->revisions)) {
- return array_keys($node->revisions);
- }
- else {
- return array();
- }
-}
-
-function node_admin() {
- $op = $_POST["op"];
- $edit = $_POST["edit"];
-
- if (user_access("administer nodes")) {
-
- if (empty($op)) {
- $op = arg(2);
- }
-
- /*
- ** Compile a list of the administrative links:
- */
- switch ($op) {
- case "search":
- print search_type("node", url("admin/node/search"), $_POST["keys"]);
- break;
- case "edit":
- print node_admin_edit(arg(3));
- break;
- case "delete":
- print node_delete(array("nid" => arg(3)));
- break;
- case "rollback revision":
- print node_revision_rollback(node_load(array("nid" => arg(3))), arg(4));
- print node_admin_edit(arg(3));
- break;
- case "delete revision":
- print node_revision_delete(node_load(array("nid" => arg(3))), arg(4));
- print node_admin_edit(arg(3));
- break;
- case t("Preview"):
- $edit = node_validate($edit, $error);
- print node_preview($edit, $error);
- break;
- case t("Submit"):
- print node_submit($edit);
- break;
- case t("Delete"):
- print node_delete($edit);
- break;
- case t("Save configuration"):
- case t("Reset to defaults"):
- case "settings":
- print node_admin_settings($edit);
- break;
- default:
- print node_admin_nodes();
- }
- }
- else {
- print message_access();
- }
-}
-
-function node_block($op = "list", $delta = 0) {
-
- if ($op == "list") {
- $blocks[0]["info"] = t("Syndicate");
- return $blocks;
- }
- else {
- $block["subject"] = t("Syndicate");
- $block["content"] = "<div style=\"text-align: center;\">". l("<img src=\"". theme("image", "xml.gif") ."\" width=\"36\" height=\"14\" style=\"border: 0px;\" alt=\"XML\" title=\"XML\" />", "node/feed", array("title" => t("Read the XML version of this page."))) ."</div>";
-
- return $block;
- }
-}
-
-function node_feed($nodes = 0, $channel = array()) {
- global $base_url, $languages;
-
- /*
- ** A generic function for generating RSS feeds from a set of nodes.
- ** - $nodes should be an object as returned by db_query() which contains
- ** the nid field.
- ** - $channel is an associative array containing title, link, and
- ** description keys.
- */
-
- if (!$nodes) {
- $nodes = db_query_range("SELECT nid FROM node WHERE promote = '1' AND status = '1' ORDER BY created DESC", 0, 15);
- }
-
- while ($node = db_fetch_object($nodes)) {
- $item = node_load(array("nid" => $node->nid));
- $link = url("node/view/$item->nid");
- $items .= format_rss_item($item->title, $link, ($item->teaser ? $item->teaser : $item->body));
- }
-
- $output .= "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
- $output .= "<!DOCTYPE rss [<!ENTITY % HTMLlat1 PUBLIC \"-//W3C//ENTITIES Latin 1 for XHTML//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent\">]>\n";
- if (!$channel["version"]) $channel["version"] = "0.91";
- if (!$channel["title"]) $channel["title"] = variable_get("site_name", "drupal") ." - ". variable_get("site_slogan", "");
- if (!$channel["link"]) $channel["link"] = $base_url;
- if (!$channel["description"]) $channel["description"] = variable_get("site_mission", "");
- foreach ($languages as $key => $value) break;
- if (!$channel["language"]) $channel["language"] = $key ? $key : "en";
- $output .= "<rss version=\"". $channel["version"] . "\">\n";
- $output .= format_rss_channel($channel["title"], $channel["link"], $channel["description"], $items, $channel["language"]);
- $output .= "</rss>\n";
-
- header("Content-Type: text/xml");
- print $output;
-}
-
-function node_validate($node, &$error) {
- global $user;
- $error = array();
-
- /*
- ** Convert the node to an object if necessary:
- */
-
- $node = array2object($node);
-
- /*
- ** Validate the title field:
- */
-
- if (isset($node->title)) {
- $node->title = strip_tags($node->title);
- if (!$node->title) {
- $error["title"] = theme("theme_error", t("You have to specify a valid title."));
- }
- }
-
- /*
- ** Common default values:
- */
-
- $node->teaser = node_teaser($node->body);
-
- /*
- ** Create a new revision when required:
- */
-
- $node = node_revision_create($node);
-
- if (user_access("administer nodes")) {
-
- /*
- ** Setup default values if required:
- */
-
- if (!$node->created) {
- $node->created = time();
- }
-
- if (!$node->date) {
- $node->date = date("M j, Y g:i a", $node->created);
- }
-
- if (!is_numeric($node->status)) {
- $node->status = 1;
- }
-
- /*
- ** Validate the "authored by"-field:
- */
-
- if (empty($node->name)) {
- /*
- ** The use of empty() is mandatory in the context of usernames
- ** as the empty string denotes the anonymous user. In case we
- ** are dealing with an anomymous user we set the user ID to 0.
- */
- $node->uid = 0;
- }
- else if ($account = user_load(array("name" => $node->name))) {
- $node->uid = $account->uid;
- }
- else {
- $error["name"] = theme("theme_error", t("The name '%u' does not exist.", array ("%u" => $node->name)));
- }
-
- /*
- ** Validate the "authored on"-field:
- */
-
- if (strtotime($node->date) > 1000) {
- $node->created = strtotime($node->date);
- }
- else {
- $error["date"] = theme("theme_error", t("You have to specifiy a valid date."));
- }
- }
- else {
- // Validate for normal users:
- $node->uid = $user->uid ? $user->uid : 0;
- // Force defaults in case people modify the form:
- $node->status = variable_get("node_status_$node->type", 1);
- $node->promote = variable_get("node_promote_$node->type", 1);
- $node->moderate = variable_get("node_moderate_$node->type", 0);
- $node->static = variable_get("node_static_$node->type", 0);
- $node->revision = variable_get("node_revision_$node->type", 0);
- unset($node->created);
- }
-
- /*
- ** Do node type specific validation checks.
- */
-
- $result = node_invoke($node, "validate");
- $error = $error + (is_array($result) ? $result : array()) + node_invoke_all($node, "nodeapi", "validate");
-
- return $node;
-}
-
-
-function node_form($edit, $error = NULL) {
-
- /*
- ** Save the referer. We record where the user came from such that we
- ** can redirect him after having completed the node forms.
- */
-
- referer_save();
-
- /*
- ** Validate the node:
- */
-
- if (!$error) {
- /* Only validate if we don't already know the errors. */
- $edit = node_validate($edit, $error);
- }
-
- // Prepend extra node form:
- $form = implode("", node_invoke_all($edit, "nodeapi", "form pre", $error));
-
- /*
- ** Get the node specific bits:
- */
-
- $function = $edit->type ."_form";
- if (function_exists($function)) {
- $form .= $function($edit, $help, $error, $param);
- }
-
- // Append extra node form:
- $form .= implode("", node_invoke_all($edit, "nodeapi", "form post", $error));
-
- /*
- ** Add the help text:
- */
-
- if ($help) {
- $output .= "<p>$help</p>";
- }
-
- $output .= "<div class=\"node-form\">";
-
- /*
- ** Add the admin specific parts:
- */
-
- if (user_access("administer nodes")) {
- $output .= "<div class=\"admin\">";
- $output .= "<div class=\"authored\">";
- $output .= form_textfield(t("Authored by"), "name", $edit->name, 20, 60, $error["name"]);
- $output .= form_textfield(t("Authored on"), "date", $edit->date, 20, 25, $error["date"]);
- $output .= "</div>";
-
- $options .= form_checkbox(t("Published"), "status", 1, isset($edit->status) ? $edit->status : variable_get("node_status_$edit->type", 1));
- $options .= form_checkbox(t("In moderation queue"), "moderate", 1, isset($edit->moderate) ? $edit->moderate : variable_get("node_moderate_$edit->type", 0));
- $options .= form_checkbox(t("Promoted to front page"), "promote", 1, isset($edit->promote) ? $edit->promote : variable_get("node_promote_$edit->type", 1));
- $options .= form_checkbox(t("Static on front page"), "static", 1, isset($edit->static) ? $edit->static : variable_get("node_static_$edit->type", 0));
- $options .= form_checkbox(t("Create new revision"), "revision", 1, isset($edit->revision) ? $edit->revision : variable_get("node_revision_$edit->type", 0));
-
- $output .= "<div class=\"options\">";
- $output .= form_item(t("Options"), $options);
- $output .= "</div>";
-
- $extras .= implode("</div><div class=\"extra\">", node_invoke_all($edit, "nodeapi", "form admin"));
- $output .= $extras ? "<div class=\"extra\">$extras</div></div>" : "</div>";
- }
-
- /*
- ** Add the default fields:
- */
- $output .= "<div class=\"standard\">";
- $output .= form_textfield(t("Title"), "title", $edit->title, 60, 128, $error["title"]);
-
- /*
- ** Add the node specific fields:
- */
-
- $output .= $form;
-
- /*
- ** Add the hidden fields:
- */
-
- if ($edit->nid) {
- $output .= form_hidden("nid", $edit->nid);
- }
-
- if (isset($edit->uid)) {
- /*
- ** The use of isset() is mandatory in the context of user IDs as uid
- ** 0 denotes the anonymous user.
- */
- $output .= form_hidden("uid", $edit->uid);
- }
-
- if ($edit->created) {
- $output .= form_hidden("created", $edit->created);
- }
-
- $output .= form_hidden("type", $edit->type);
-
- /*
- ** Add the buttons:
- */
-
- $output .= form_submit(t("Preview"));
-
- if ($edit->title && $edit->type && !$error) {
- $output .= form_submit(t("Submit"));
- }
- elseif (!variable_get("node_preview", 0)) {
- $output .= form_submit(t("Submit"));
- }
-
- if ($edit->nid && node_access("delete", $edit)) {
- $output .= form_submit(t("Delete"));
- }
-
- $output .= "</div></div>";
-
- return form($output, ($param["method"] ? $param["method"] : "post"), $param["action"], $param["options"]);
-}
-
-function node_add($type) {
- global $user;
-
- $edit = $_POST["edit"];
-
- /*
- ** If a node type has been specified, validate it existence. If no
- ** (valid) node type has been provied, display a node type overview.
- */
-
- if ($type && node_access("create", $type)) {
- // Initialize settings:
- $node = array("uid" => $user->uid, "name" => $user->name, "type" => $type);
-
- /*
- ** Allow the following fields to be initialized via $_GET (eg. for use
- ** with a "blog it" bookmarklet):
- */
- foreach (array("title", "teaser", "body") as $field) {
- if ($_GET["edit"][$field]) {
- $node[$field] = $_GET["edit"][$field];
- }
- }
- $output = node_form($node);
- }
- else {
-
- /*
- ** Compile a list with the different node types and their explanation:
- */
-
- foreach (module_list() as $name) {
- if (module_hook($name, "node") && node_access("create", $name)) {
- $output .= "<li>";
- $output .= " ". l(module_invoke($name, "node", "name"), "node/add/$name", array("title" => t("Add a new %s.", array("%s" => module_invoke($name, "node", "name")))));
- $output .= " <div style=\"margin-left: 20px;\">". module_invoke($name, "node", "description") ."</div>";
- $output .= "</li>";
- }
- }
-
- $output = t("Choose the appropriate item from the list:") ."<ul>$output</ul>";
-
- }
-
- return $output;
-}
-
-function node_edit($id) {
- global $user;
-
- $node = node_load(array("nid" => $id));
-
- if (node_access("update", $node)) {
- $output = node_form($node);
- }
- else {
- $output = message_access();
- }
-
- return $output;
-}
-
-function node_preview($node, $error = NULL) {
-
- /*
- ** Convert the array to an object:
- */
-
- $node = array2object($node);
-
- if (node_access("create", $node) || node_access("update", $node)) {
-
- /*
- ** Load the user's name when needed:
- */
-
- if (isset($node->name)) {
- /*
- ** The use of isset() is mandatory in the context of user IDs as uid
- ** 0 denotes the anonymous user.
- */
-
- if ($user = user_load(array("name" => $node->name))) {
- $node->uid = $user->uid;
- }
- else {
- $node->uid = 0; // anonymous user
- }
- }
- else if ($node->uid) {
- $user = user_load(array("uid" => $node->uid));
- $node->name = $user->name;
- }
-
- /*
- ** Set the created time when needed:
- */
-
- if (empty($node->created)) {
- $node->created = time();
- }
- $node->changed = time();
-
- /*
- ** Extract a teaser:
- */
-
- $node->teaser = node_teaser($node->body);
-
- /*
- ** Apply the required filters:
- */
-
- if ($node->nid) {
- $view = array2object(array_merge(object2array($node), module_invoke($node->type, "save", "update", $node)));
- }
- else {
- $view = array2object(array_merge(object2array($node), module_invoke($node->type, "save", "create", $node)));
- }
-
- /*
- ** Display a preview of the node:
- */
-
- if ($view->teaser && $view->teaser != $view->body) {
- print "<h3>". t("Preview trimmed version") ."</h3>";
- node_view($view, 1);
- print "<p><i>". t("The trimmed version of your post shows how your post looks like when promoted to the main page or when exported for syndication. You can insert a delimiter '&lt;!--break--&gt' (without the quotes) to fine-tune where your post gets split.") ."</i></p>";
- print "<h3>". t("Preview full version") ."</h3>";
- node_view($view, 0);
- }
- else {
- node_view($view, 0);
- }
-
- return node_form($node, $error);
- }
-}
-
-function node_submit($node) {
- global $user;
-
- /*
- ** Fixup the node when required:
- */
-
- $node = node_validate($node, $error);
-
- /*
- ** If something went wrong, go back to the preview form:
- */
-
- if ($error) {
- return node_preview($node, $error);
- }
-
- /*
- ** Prepare the node's body:
- */
-
- if ($node->nid) {
-
- /*
- ** Check whether the current user has the proper access rights to
- ** perform this operation:
- */
-
- if (node_access("update", $node)) {
- $nid = node_save($node);
- watchdog("special", "$node->type: updated '$node->title'", l("view post", "node/view/$node->nid"));
- $output = t("The %name has been updated.", array ("%name" => module_invoke($node->type, "node", "name")));
- }
- }
- else {
-
- /*
- ** Check whether the current user has the proper access rights to
- ** perform this operation:
- */
-
- if (node_access("create", $node)) {
-
- /*
- ** Verify a user's submission rate and avoid duplicate nodes being
- ** inserted:
- */
-
- throttle("node", variable_get("max_node_rate", 900));
-
- $nid = node_save($node);
- watchdog("special", "$node->type: added '$node->title'", l("view post", "node/view/$nid"));
- $output = t("Thanks for your submission.");
- }
- }
-
- /*
- ** Reload the node from the database:
- */
-
- $node = node_load(array("nid" => $nid));
-
- /*
- ** For usability's sake, make sure to present the user with some
- ** useful links as where to go next.
- */
-
- if ($referer = referer_load()) {
- $links[] = "<a href=\"$referer\">". t("return") ."</a>";
- }
-
- if ($nid && node_access("view", $node)) {
- $links[] = l(t("view"), "node/view/$nid");
- }
-
- if ($nid && node_access("update", $node)) {
- $links[] = l(t("edit"), "node/edit/$nid");
- }
-
- $output .= "<p>". theme("links", $links) ."</p>";
-
- return $output;
-}
-
-function node_delete($edit) {
-
- $node = node_load(array("nid" => $edit["nid"]));
-
- if (node_access("delete", $node)) {
-
- if ($edit["confirm"]) {
-
- /*
- ** Delete the specified node:
- */
-
- db_query("DELETE FROM node WHERE nid = '$node->nid'");
-
- /*
- ** Call the node specific callback (if any):
- */
-
- node_invoke($node, "delete");
- node_invoke_all($node, "nodeapi", "delete");
-
- /*
- ** Clear the cache so an anonymous poster can see the node being
- ** deleted.
- */
-
- cache_clear_all();
-
- watchdog("special", "$node->type: deleted '$node->title'");
- $output = t("The node has been deleted.");
- }
- else {
- $output .= form_item(t("Confirm deletion"), $node->title);
- $output .= form_hidden("nid", $node->nid);
- $output .= form_hidden("confirm", 1);
- $output .= form_submit(t("Delete"));
- $output = form($output);
- }
- }
-
- return $output;
-}
-
-function node_page() {
- global $id, $user, $or, $and;
-
- $op = $_POST["op"];
- $edit = $_POST["edit"];
-
- if (user_access("access content")) {
- if (empty($op)) {
- $op = arg(1);
- }
-
- if ($op == "feed") {
- node_feed();
- return;
- }
-
- if ($op == "view") {
- $node = node_load(array("nid" => arg(2), "status" => 1), $_GET["revision"]);
- }
-
- theme("header", $node->title);
-
- $name = module_invoke(arg(2), "node", "name");
-
- switch ($op) {
- case "add":
- theme("box", t("Create new $name"), node_add(arg(2)));
- break;
- case "edit":
- theme("box", t("Edit $name"), node_edit(arg(2)));
- break;
- case "view":
- print node_show($node, arg(3));
- break;
- case t("Preview"):
- $edit = node_validate($edit, $error);
- theme("box", t("Preview $name"), node_preview($edit, $error));
- break;
- case t("Submit"):
- theme("box", t("Submit $name"), node_submit($edit));
- break;
- case t("Delete"):
- theme("box", t("Delete $name"), node_delete($edit));
- break;
- default:
- $result = pager_query("SELECT nid, type FROM node WHERE promote = '1' AND status = '1' ORDER BY static DESC, created DESC", variable_get("default_nodes_main", 10));
-
- while ($node = db_fetch_object($result)) {
- node_view(node_load(array("nid" => $node->nid, "type" => $node->type)), 1);
- }
- print pager_display(NULL, variable_get("default_nodes_main", 10));
- }
-
- theme("footer");
- }
- else {
- theme("header");
- theme("box", t("Access denied"), message_access());
- theme("footer");
- }
-
-}
-
-function node_update_index() {
-
- // Return an array of values to dictate how to update the search index
- // for this particular type of node.
- //
- // "last_update"'s value is used with variable_set to set the
- // last time this node type had an index update run.
- //
- // "node_type"'s value is used to identify the node type in the search
- // index.
- //
- // "select"'s value is used to select the node id and text fields from
- // the table we are indexing. In this case, we also check against the
- // last run date for the nodes update.
- return array("last_update" => "node_cron_last",
- "node_type" => "node",
- "select" => "SELECT n.nid as lno, n.title as text1, n.body as text2 FROM node n WHERE n.status = 1 AND moderate = 0 and (created > " . variable_get("node_cron_last", 1) . " or changed > " . variable_get("node_cron_last", 1) . ")");
-}
-
-function node_nodeapi(&$node, $op, $arg = 0) {
- switch ($op) {
- case "settings":
- $output[t("publish")] = form_checkbox("", "node_status_$node->type", 1, variable_get("node_status_$node->type", 1));
- $output[t("promote")] = form_checkbox("", "node_promote_$node->type", 1, variable_get("node_promote_$node->type", 1));
- $output[t("moderate")] = form_checkbox("", "node_moderate_$node->type", 1, variable_get("node_moderate_$node->type", 0));
- $output[t("static")] = form_checkbox("", "node_static_$node->type", 1, variable_get("node_static_$node->type", 0));
- $output[t("revision")] = form_checkbox("", "node_revision_$node->type", 1, variable_get("node_revision_$node->type", 0));
- return $output;
- case "fields":
- return array("nid", "uid", "type", "title", "teaser", "body", "revisions", "status", "promote", "moderate", "static", "created", "changed");
- }
-}
-
-?>
diff --git a/modules/page/page.module b/modules/page/page.module
deleted file mode 100644
index de77eb2..0000000
--- a/modules/page/page.module
+++ /dev/null
@@ -1,145 +0,0 @@
-<?php
-// $Id$
-
-function page_help() {
- $output .= "<p>The page module is used to create a <i>static page</i>. Unlike a story, a static page is a persistent web page on your site which usually shortcuts the typical lifecycle of user generated content (i.e. submit -&gt; moderate -&gt; post -&gt; comment). A static page is usually linked from the main navigation bar, using whatever text the author wishes. To create a static page without this navigation link, simply skip the form field which requests link text.</p>";
- $output .= "<p>Site pages, unlike many other forms of Drupal content, may be made of PHP code in addition to HTML and text. All Drupal objects and functions are available to a site administrator.</p>";
-
- return $output;
-}
-
-function page_system($field) {
- $system["description"] = t("Enables the creation of a static pages that can be added to the navigation system.");
- return $system[$field];
-}
-
-function page_perm() {
- return array("maintain static pages");
-}
-
-function page_node($field) {
- $info["name"] = t("static page");
- $info["description"] = t("If you just want to add a page with a link in the menu to your site, this would be the best choice. Unlike a story, a static page by-passes the submission queue.");
-
- return $info[$field];
-}
-
-function page_access($op, $node) {
- if ($op == "view") {
- return $node->status;
- }
-
- if ($op == "create") {
- return user_access("maintain static pages");
- }
-
- if ($op == "update") {
- return user_access("maintain static pages");
- }
-
- if ($op == "delete") {
- return user_access("maintain static pages");
- }
-}
-
-function page_save($op, $node) {
- if ($op == "approve") {
- return array("status" => 1);
- }
-
- if ($op == "decline") {
- return array("status" => 0);
- }
-}
-
-function page_insert($node) {
- db_query("INSERT INTO page (nid, format, link, description) VALUES (%d, %d, '%s', '%s')", $node->nid, $node->format, $node->link, $node->description);
-}
-
-function page_update($node) {
-db_query("UPDATE page SET format = %d, link = '%s', description = '%s' WHERE nid = %d", $node->format, $node->link, $node->description, $node->nid);
- }
-
-function page_delete(&$node) {
- db_query("DELETE FROM page WHERE nid = %d", $node->nid);
-}
-
-function page_load($node) {
- $page = db_fetch_object(db_query("SELECT format, link, description FROM page WHERE nid = %d", $node->nid));
-
- return $page;
-}
-
-function page_link($type) {
-
- $links = array();
-
- if ($type == "page" && user_access("access content")) {
- $result = db_query("SELECT n.nid, n.title, p.link, p.description FROM page p LEFT JOIN node n ON p.nid = n.nid WHERE n.status = '1' AND p.link != '' ORDER BY p.link");
- while ($page = db_fetch_object($result)) {
- $links[] = l($page->link, "node/view/$page->nid", array("title" => $page->description));
- }
- }
-
- if ($type == "menu.create" && user_access("maintain static pages")) {
- $links[] = l(t("create static page"), "node/add/page", array("title" => t("Add a new static page.")));
- }
-
- return $links;
-}
-
-function page_view($node, $main = 0) {
- /*
- ** Extract the page body. If body is dynamic (using PHP code), the body
- ** will be generated.
- */
-
- if ($node->format == 0) {
- // HTML type
- $node->teaser = check_output($node->teaser);
- $node->body = check_output($node->body);
- }
- else {
- // PHP type
- ob_start();
- eval($node->body);
- $node->teaser = $node->body = ob_get_contents();
- ob_end_clean();
- }
-
- if ($main) {
- theme("node", $node, $main);
- }
- else {
- /*
- ** Add the node specific links:
- */
-
- theme("box", $node->title, "$node->body<div style=\"text-align: right;\">". theme("links", link_node($node, $main)) ."</div>");
- }
-}
-
-function page_form(&$node, &$help, &$error) {
- if (function_exists("taxonomy_node_form")) {
- $output .= implode("", taxonomy_node_form("page", $node));
- }
-
- $output .= form_textarea(t("Body"), "body", $node->body, 60, 20);
- $output .= form_textfield(t("Link name"), "link", $node->link, 60, 64, t("To make the page show up in the navigation links, enter the name of the link, otherwise leave blank."));
- $output .= form_textfield(t("Link description"), "description", $node->description, 60, 64, t("The description displayed when hovering over the page's link. Leave blank when you don't want a description."));
- $output .= form_select(t("Type"), "format", $node->format, array(0 => "HTML", 1 => "PHP"));
-
- return $output;
-}
-
-function page_validate(&$node) {
- if ($node->format && user_access("create php content")) {
- // Do not filter PHP code, do not auto-extract a teaser
- $node->teaser = $node->body;
- }
- else {
- $node->format = 0;
- }
-}
-
-?>
diff --git a/modules/ping/ping.module b/modules/ping/ping.module
deleted file mode 100644
index 4216164..0000000
--- a/modules/ping/ping.module
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-// $Id$
-
-function ping_help() {
- $output = "<p>Drupal can pings sites automatically to notify them that your site has changed. It can ping the following sites :</p>";
- $output .= "<p><a href=\"http://www.weblogs.com/\">Weblogs.com</a>, a web site that tracks and displays links to changed weblogs and news-oriented web sites. To get your Drupal site listed, weblogs.com must be informed about your site's updates. This is the job of the ping module and when installed, the administrator doesn't have to do anything to participate in the <a href=\"http://www.weblogs.com/\">weblogs.com system</a>. The weblog module automatically notifies weblogs.com when your site is updated. To do so, Drupal implements the <a href=\"http://www.xmlrpc.com/weblogsCom/\">XML-RPC interface of weblogs.com</a>.</p>";
- $output .= "<p><a href=\"http://www.xmlrpc.com/weblogsComForRss\">Weblogs.Com for RSS</a>, a web site that tracks and displays links to recently changed RSS feeds in XML format. To get your Drupal site listed, weblogs.com for RSS must be informed about updates to your RSS feed. This is the job of the ping module and when installed, the administrator doesn't have to do anything to participate in the <a href=\"http://www.weblogs.com/rssUpdates/changes.xml\">weblogs.com for RSS system</a>. The ping module automatically notifies weblogs.com for RSS when your site is updated.</p>";
- $output .= "<p><a href=\"http://blo.gs/\">blo.gs</a>, a directory of recently updated weblogs and tools for tracking interesting weblogs, in the spirit of services like <a href=\"http://www.weblogs.com/\">weblogs.com</a>, <a href=\"http://www.dansanderson.com/blogtracker/\">blogtracker</a> and <a href=\"http://www.blogrolling.com/\">blogrolling.com</a>. To get your Drupal site listed, blo.gs must be informed about your site's updates. This is the job of the ping module and when installed, the administrator doesn't have to do anything to participate in the <a href=\"http://blo.gs/\">blo.gs system</a>. The ping module automatically notifies blo.gs when your site is updated. To do so, Drupal implements the <a href=\"http://blo.gs/ping.php\">XML-RPC interface of blo.gs</a>.</p>";
- // for optional modules that ping other sites
- // $output .= module_invoke_all("ping_help");
- $output .= "<p>The ping feature requires crontab.</p>";
- print $output;
-}
-
-function ping_system($field){
- $system["description"] = t("Alerts other site(s) that your site has been updated.");
- return $system[$field];
-}
-
-function ping_cron() {
- global $base_url;
-
- if (variable_get("site_name", 0) && variable_get("site_slogan", 0)) {
- if (db_num_rows(db_query("SELECT nid FROM node WHERE status = 1 AND moderate = 0 AND (created > '". variable_get("ping_cron_last", time()) ."' OR changed > '". variable_get("ping_cron_last", time()) ."')"), 1)) {
- _ping_notify(variable_get("site_name", "") ." - ". variable_get("site_slogan", ""), $base_url);
- }
-
- variable_set("ping_cron_last", time());
- }
-}
-
-function _ping_notify($name, $url) {
- module_invoke_all("ping", $name, $url);
-}
-
-function ping_ping($name = "", $url = "") {
- $feed = url("node/feed");
-
- $client = new xmlrpc_client("/RPC2", "rpc.weblogs.com", 80);
-
- $message = new xmlrpcmsg("weblogUpdates.ping", array(new xmlrpcval($name), new xmlrpcval($url)));
-
- $result = $client->send($message);
-
- if (!$result || $result->faultCode()) {
- watchdog("error", "failed to notify 'weblogs.com' (site)");
- }
-
- unset($client);
-
- $client = new xmlrpc_client("/RPC2", "rssrpc.weblogs.com", 80);
-
- $message = new xmlrpcmsg("rssUpdate", array(new xmlrpcval($name), new xmlrpcval($feed)));
-
- $result = $client->send($message);
-
- if (!$result || $result->faultCode()) {
- watchdog("error", "failed to notify 'weblogs.com' (RSS)");
- }
-
- unset($client);
-
- $client = new xmlrpc_client("/", "ping.blo.gs", 80);
-
- $message = new xmlrpcmsg("weblogUpdates.extendedPing", array(new xmlrpcval($name), new xmlrpcval($url), new xmlrpcval($url), new xmlrpcval($feed)));
-
- $result = $client->send($message);
-
- if (!$result || $result->faultCode()) {
- watchdog("error", "failed to notify 'blo.gs' ");
- }
-
-}
-?>
diff --git a/modules/poll/poll.module b/modules/poll/poll.module
deleted file mode 100644
index 0313b62..0000000
--- a/modules/poll/poll.module
+++ /dev/null
@@ -1,387 +0,0 @@
-<?php
-// $Id$
-
-function poll_allowvotes(&$node) {
- /*
- ** Only accept votes on specific cases to prevent double voting and abuse.
- ** We only need to determine this once for a poll, but we don't do this in
- ** poll_load() (i.e. for every poll that is loaded) for speed reasons.
- */
- global $user;
-
- if ($node->allowvotes != -1) {
- return $node;
- }
-
- $node->allowvotes = 0;
- if (user_access("vote on polls")) {
- if ($user->uid) {
- // Pad the UID with underscores to allow a simple strstr() search
- $id = "_". $user->uid ."_";
- }
- else {
- $id = $_SERVER["REMOTE_ADDR"];
- }
- if (!strstr($node->voters, $id)) {
- $node->allowvotes = $node->active;
- }
-
- // Save this for later
- $node->polluserid = $id;
- }
- return $node;
-}
-
-function poll_access($op, $node) {
- if ($op == "view") {
- return $node->status;
- }
-
- if ($op == "create") {
- return user_access("create polls");
- }
-}
-
-function poll_block($op = "list", $delta = 0) {
- if (user_access("access content")) {
- if ($op == "list") {
- $blocks[0]["info"] = t("Most recent poll");
- return $blocks;
- }
- else {
- $timestamp = db_result(db_query("SELECT MAX(created) FROM node WHERE type = 'poll' AND status = '1' AND moderate = '0'"));
- if ($timestamp) {
- $poll = node_load(array("type" => "poll", "created" => $timestamp, "moderate" => "0", "status" => "1"));
- if ($poll->nid) {
- // Poll_view dumps the output into $poll->body
- poll_view($poll, 1, 1);
- }
- }
- $block["subject"] = t("Poll: %t", array("%t" => $poll->title));
- $block["content"] = $poll->body;
- return $block;
- }
- }
-}
-
-function poll_cron() {
- // Close polls that have exceeded their allowed runtime
- $result = db_query("SELECT p.nid FROM poll p LEFT JOIN node n ON p.nid=n.nid WHERE (n.created + p.runtime) < '". time() ."' AND p.active = '1' AND p.runtime != '0'");
- while ($poll = db_fetch_object($result)) {
- db_query("UPDATE poll SET active='0' WHERE nid = %d", $poll->nid);
- }
-}
-
-function poll_delete($node) {
- db_query("DELETE FROM poll WHERE nid=%d", $node->nid);
- db_query("DELETE FROM poll_choices WHERE nid = %d", $node->nid);
-}
-
-function poll_form(&$node, &$help, &$error) {
- $admin = user_access("administer nodes");
-
- $_duration = array(0 => t("Unlimited"), 86400 => format_interval(86400), 172800 => format_interval(172800), 345600 => format_interval(345600), 604800 => format_interval(604800), 1209600 => format_interval(1209600), 2419200 => format_interval(2419200), 4838400 => format_interval(4838400), 9676800 => format_interval(9676800), 31536000 => format_interval(31536000));
- $_active = array(0 => t("Closed"), 1 => t("Active"));
-
- $node->choices = $node->choices ? $node->choices : max(2, count($node->choice) ? count($node->choice) : 5);
-
- if (isset($node->title)) {
- // Check for at least two options and validate amount of votes:
- for ($i = 0; $i < $node->choices; $i++) {
- if ($node->choice[$i] != "") {
- $actualchoices++;
- }
-
- if ($node->chvotes[$i] < 0) {
- $error["chvotes][$i"] = theme("theme_error", t("Negative values are not allowed."));
- }
- }
-
- if ($actualchoices < 2) {
- $error["choice][0"] = theme("theme_error", t("You must fill in at least two choices."));
- }
- }
- else {
- $help = variable_get("poll_help", "");
- }
-
- if (function_exists("taxonomy_node_form")) {
- $output = implode("", taxonomy_node_form("poll", $node));
- }
-
- for ($c = 2; $c <= 30; $c++) {
- $opts[$c] = $c;
- }
- $output .= form_select(t("Number of choices"), "choices", $node->choices, $opts, t("This item sets the number of multiple choice options in the poll, but it doesn't have to equal the actual amount of options; you can leave the extra boxes empty."));
- $output .= form_submit(t("Preview")) ."<br /><br /><br />";
-
- for ($a = 0; $a < $node->choices; $a++) {
- $output .= form_textfield(t("Choice") ." ". ($a + 1), "choice][$a", $node->choice[$a], 50, 127, $error["choice][$a"]);
- if ($admin) {
- $output .= form_textfield(t("Votes for choice %n", array("%n" => ($a + 1))), "chvotes][$a", $node->chvotes[$a] ? $node->chvotes[$a] : 0, 7, 7, $error["chvotes][$a"]);
- }
- }
-
- if ($admin) {
- $output .= form_select(t("Poll status"), "active", isset($node->active) ? $node->active : 1, $_active);
- }
-
- $output .= form_select(t("Poll duration"), "runtime", $node->runtime ? $node->runtime : 0, $_duration, t("After this period, the poll will be closed automatically."));
-
- return $output;
-}
-
-function poll_help() {
- $output .= "<p>Users with the correct ". l("permissions","admin/user/permission") ." can create and/or vote on polls.</p><ul><li> To create a poll a user needs the \"create polls\" permission.</li><li>To vote on a poll question a user must have the \"vote on polls\" permission.</li><li>To view the results one needs the \"access content\" permission.</li><li>To administer polls you need the \"administer nodes\" permission.</li></ul><p>Creating a poll is much like creating any other node. Click \"create poll\" in your user box. The title of the poll should be the question, then enter the answers and the \"base\" vote counts. You can also choose the time period over which the vote will run.</p><p>The ". l("Poll", "poll") ." item in the navigation links will take you to a page where you can see all the current polls, vote on them (if you haven't already) and view the results.</p>";
- return t($output);
-}
-
-function poll_insert($node) {
- if (!user_access("administer nodes")) {
- // Make sure all votes are 0 initially
- for ($i = 0; $i < count($node->chvotes); $i++) $node->chvotes[$i] = 0;
- $node->active = 1;
- }
-
- db_query("INSERT INTO poll (nid, runtime, voters, active) VALUES (%d, %d, '', %d)", $node->nid, $node->runtime, $node->active);
-
- for ($i = 0; $i < $node->choices; $i++) {
- if ($node->choice[$i] != "") {
- db_query("INSERT INTO poll_choices (nid, chtext, chvotes, chorder) VALUES (%d, '%s', %d, %d)", $node->nid, $node->choice[$i], $node->chvotes[$i], $i);
- }
- }
-}
-
-function poll_link($type, $node = 0, $main) {
- $links = array();
-
- if ($type == "menu.create" && user_access("create polls")) {
- $links[] = l(t("create poll"), "node/add/poll", array("title" => t("Add a new poll.")));
- }
- else if ($type == "page" && user_access("access content")) {
- $links[] = l(t("polls"), "poll", array("title" => t("View the list of polls on this site.")));
- }
- else if ($type == "node" && $node->type == "poll") {
- /*
- ** Add links to allow the user to switch between the results and the voting
- ** form, if he/she hasn't voted yet.
- */
-
- // Make sure we have determined the 'allowvotes' flag
- poll_allowvotes($node);
-
- if ($node->allowvotes == 1) {
- $pollresults = $_GET["pollresults"];
-
- // Change the current URL: add/edit the value of pollresults[nid]
- if ($pollresults[$node->nid]) {
- // Disable
- $url = eregi_replace("pollresults\[$node->nid\]=1", "pollresults[$node->nid]=0", request_uri());
-
- $links[] = "<a href=\"". htmlentities($url) ."\">". t("voting form") . "</a>";
- }
- else {
- // Enable
- if (strstr(request_uri(), "pollresults[$node->nid]=")) {
- $url = eregi_replace("pollresults\[$node->nid\]=0", "pollresults[$node->nid]=1", request_uri());
- }
- else {
- $url = request_uri() . (strstr(request_uri(), "?") ? "&amp;" : "?") ."pollresults[$node->nid]=1";
- }
-
- $links[] = "<a href=\"". htmlentities($url) ."\">". t("view results") . "</a>";
- }
- }
- }
-
- return $links;
-}
-
-function poll_load($node) {
- // Load the appropriate choices into the $node object
- $poll = db_fetch_object(db_query("SELECT runtime, voters, active FROM poll WHERE nid = %d", $node->nid));
-
- $result = db_query("SELECT chtext, chvotes, chorder FROM poll_choices WHERE nid=%d ORDER BY chorder", $node->nid);
- while ($choice = db_fetch_object($result)) {
- $poll->choice[$choice->chorder] = $choice->chtext;
- $poll->chvotes[$choice->chorder] = $choice->chvotes;
- }
-
- // Reset allowvotes flag, will be filled in later on when needed.
- $poll->allowvotes = -1;
- return $poll;
-}
-
-function poll_node($field) {
- $info["name"] = t("poll");
- $info["description"] = t("A poll is a multiple-choice question which visitors can vote on.");
- return $info[$field];
-}
-
-function poll_page() {
-
- theme("header");
- $result = db_query("SELECT n.nid, n.title, p.active, SUM(c.chvotes) AS votes FROM node n LEFT JOIN poll p ON n.nid=p.nid LEFT JOIN poll_choices c ON n.nid=c.nid WHERE type = 'poll' AND status = '1' AND moderate = '0' GROUP BY n.nid, n.title, p.active, n.created ORDER BY n.created DESC");
- $output = "<ul>";
- while ($node = db_fetch_object($result)) {
- $output .= "<li>".l($node->title, "node/view/$node->nid") ." - ". format_plural($node->votes, "1 vote", "%count votes") ." - ". ($node->active ? t("open") : t("closed")) ."</li>";
- }
- $output .= "</ul>";
- theme("box", t("Polls"), $output);
- theme("footer");
-}
-
-function poll_perm() {
- return array("create polls", "vote on polls");
-}
-
-function poll_system($field){
- $system["description"] = t("Enables your site to capture votes on different topics in the form of multiple choice questions.");
- return $system[$field];
-}
-
-function poll_teaser($node) {
- // Create a simple teaser that lists all the choices
- if (is_array($node->choice)) {
- foreach ($node->choice as $k => $v) {
- if ($v != "") {
- $teaser .= "* $v\n";
- }
- }
- }
- return $teaser;
-}
-
-function poll_view_voting(&$node, $main, $block, $links) {
- // Display the vote form
-
-
- $url = request_uri();
- $output .= "<div class=\"poll\"><form action=\"". htmlentities($url) ."\" method=\"post\">";
-
- $output .= "<div class=\"vote-form\">";
- $output .= "<div class=\"choices\">";
- if ($node->choice) {
- foreach ($node->choice as $key => $value) {
- if ($value != "") {
- $output .= "<div><input type=\"radio\" name=\"pollvote[$node->nid]\" value=\"$key\" />". filter($value) ."</div>";
- }
- }
- }
- $output .= "</div>". form_submit(t("Vote"), "vote") ."</div>";
- $output .= $block ? "<div class=\"links\">". theme("links", $links) ."</div>" : "";
- $output .= "</form></div>";
-
- return $output;
-}
-
-function poll_view_results(&$node, $main, $block, $links) {
- // Display the results
-
-
- // Count the votes and find the maximum
- if ($node->choice) {
- foreach ($node->choice as $key => $value) {
- $votestotal += $node->chvotes[$key];
- $votesmax = max($votesmax, $node->chvotes[$key]);
- }
- $votesmax = max($votesmax, 1);
- }
-
- // Output the divs for the text, bars and percentages
- $output .= "<div class=\"poll\">";
- if ($node->choice) {
- foreach ($node->choice as $key => $value) {
- if ($value != "") {
- $width = round($node->chvotes[$key] * 100 / $votesmax);
- $percentage = round($node->chvotes[$key] * 100 / max($votestotal, 1));
- $output .= "<div class=\"text\">". filter($value) ."</div>";
- $output .= "<div class=\"bar\">";
- $output .= "<div style=\"width: ". $width ."%;\" class=\"foreground\"></div>";
- $output .= "<div style=\"width: ". (100 - $width) ."%;\" class=\"background\"></div>";
- $output .= "</div>";
- $output .= "<div class=\"percent\"> $percentage%". (!$block ? " (". format_plural($node->chvotes[$key], "1 vote", "%count votes") .")" : "") ."</div>";
- }
- }
- }
- $output .= "<div class=\"total\">". t("Total votes") .": $votestotal</div>";
-
- $output .= ($block ? "<div class=\"links\" />". theme("links", $links) ."</div>" : "") ."</div>";
-
- return $output;
-}
-
-function poll_view_processvote(&$node) {
- $pollvote = $_POST["pollvote"];
-
- if (isset($pollvote[$node->nid]) && ($node->allowvotes == 1)) {
- if (!empty($node->choice[$pollvote[$node->nid]])) {
- $node->voters = $node->voters ? ($node->voters ." ". $node->polluserid) : $node->polluserid;
- db_query("UPDATE poll SET voters='%s' WHERE nid = %d", $node->voters, $node->nid);
- db_query("UPDATE poll_choices SET chvotes = chvotes + 1 WHERE nid = %d AND chorder = %d", $node->nid, $pollvote[$node->nid]);
- $node->allowvotes = 0;
- $node->chvotes[$pollvote[$node->nid]]++;
- }
- }
-}
-
-function poll_view(&$node, $main = 0, $block = 0) {
- global $user;
-
- /*
- ** When several polls are displayed on the same page (e.g. on the front page and in the side bar)
- ** we distinguish between them using the nid as index into associative arrays:
- ** $pollvote[nid] - A user's vote
- ** $pollresults[nid] - When a user hasn't voted, he can choose to see the voting form or the results
- */
- $pollresults = $_GET["pollresults"];
-
- // Make sure we have determined the 'allowvotes' flag
- poll_allowvotes($node);
-
- // Because the voting form is embedded in the node-display, we process the data here
- poll_view_processvote($node);
-
- // Add extra link pointing to the list of polls (side-block only)
- if ($block) {
- $node->body = $node->teaser = "";
-
- $links = link_node($node, $main);
- $links[] = l(t("older polls"), "poll", array("title" => t("View the list of polls on this site.")));
- }
-
- if (($node->allowvotes == 1) && !$pollresults[$node->nid]) {
- $output = poll_view_voting($node, $main, $block, $links);
- }
- else {
- $output = poll_view_results($node, $main, $block, $links);
- }
-
- $node->body = $node->teaser = $output;
-
- // We also use poll_view() for the side-block
- if (!$block) {
- theme("node", $node, $main);
- }
-}
-
-function poll_update($node) {
- db_query("UPDATE poll SET runtime = %d, active = %d WHERE nid = %d", $node->runtime, $node->active, $node->nid);
-
- db_query("DELETE FROM poll_choices WHERE nid = %d", $node->nid);
- for ($i = 0; $i < $node->choices; $i++) {
- $choice->chtext = $node->choice[$i];
- $choice->chvotes = (int)$node->chvotes[$i];
- $choice->chorder = $i;
-
- if ($choice->chtext != "") {
- db_query("INSERT INTO poll_choices (nid, chtext, chvotes, chorder) VALUES (%d, '%s', %d, %d)", $node->nid, $choice->chtext, $choice->chvotes, $choice->chorder);
- }
- }
-}
-
-function poll_validate(&$node) {
- $node->teaser = poll_teaser($node);
-}
-
-?>
diff --git a/modules/profile/profile.module b/modules/profile/profile.module
deleted file mode 100644
index 1a6da51..0000000
--- a/modules/profile/profile.module
+++ /dev/null
@@ -1,294 +0,0 @@
-<?php
-// $Id$
-
-function _profile_init() {
- /*
- ** Add here any field you might need. Leave array[0] blank if you
- ** need a special tool (like birthday or avatar).
- ** TODO: add a clear description/explanation.
- */
-
- $GLOBALS["profile_fields"] = array(
- "address" => array("textfield", t("Address"), "", 64, 64, ""),
- "city" => array("textfield", t("City"), "", 64, 64, ""),
- "state" => array("textfield", t("State, province or region"), "", 64, 64, ""),
- "zip" => array("textfield", t("Zip or postal code"), "", 7, 10, ""),
- "country" => array("textfield", t("Country"), "", 64, 64, ""),
- "birthday" => array("", t("Birthday"), ""),
- "gender" => array("select", t("Gender"), "", array(0 => "-", "m" => t("male"), "f" => t("female")), "", 0, 0),
- "job" => array("textfield", t("Job title"), "", 64, 64, ""),
- "icq" => array("textfield", t("ICQ messenger ID"), "", 12, 12, ""),
- "msn" => array("textfield", t("MSN messenger ID"), "", 64, 64, ""),
- "yahoo" => array("textfield", t("Yahoo messenger ID"), "", 64, 64, ""),
- "aim" => array("textfield", t("AIM messenger ID"), "", 64, 64, ""),
- "homepage" => array("textfield", t("URL of homepage"), "", 64, 64, t("Make sure you enter a fully qualified URL: remember to include \"http://\".")),
- "biography" => array("textarea", t("Biography"), "", 64, 4, ""),
- "interests" => array("textarea", t("Interests"), "", 64, 4, ""),
- "publickey" => array("textarea", t("Public key"), "", 64, 4, ""),
- "avatar" => array("", t("Avatar or picture"), t("Your virtual face or picture. Maximum dimensions are %dimensions and the maximum size is %size kB.", array("%dimensions" => variable_get("profile_avatar_dimensions", "85x85"), "%size" => variable_get("profile_avatar_file_size", "30"))))
- );
-
- $GLOBALS["profile_days"][0] = t("day");
- for ($n = 1; $n <= 31; $n++) {
- $GLOBALS["profile_days"][$n] = $n;
- }
-
- $GLOBALS["profile_months"] = array(0 => t("month"), 1 => t("January"), 2 => t("February"), 3 => t("March"), 4 => t("April"), 5 => t("May"), 6 => t("June"), 7 => t("July"), 8 => t("August"), 9 => t("September"), 10 => t("October"), 11 => t("November"), 12 => t("December"));
-}
-
-function profile_system($field) {
- $system["description"] = t("Support for configurable user profiles.");
- $system["admin_help"] = t("When a user creates an account you can ask them to give you some extra information about themselves, as well as letting them use a small picture, called an avatar.<br />Notes:<ul><li>In order for a user to <i>enter</i> information you <b>MUST</b> check \"enable\".</li><li>In order for other people too see the entered information you must make it \"public\"</li><li>If an item is \"public\" but not enabled then the user can never give it a value and it will never been seen. Public does <b>not</b> imply \"enable\"</li><li>If an item is enabled, but not shown in the registration form the a user will have to ". l("edit their account", "user/edit") ." to place information in the field.</ul>");
- return $system[$field];
-}
-
-function profile_settings() {
- global $profile_fields;
- if (!$profile_fields) {
- _profile_init();
- }
-
- $profile_public_fields = variable_get("profile_public_fields", array());
- $profile_private_fields = variable_get("profile_private_fields", array());
- $profile_required_fields = variable_get("profile_required_fields", array());
- $profile_register_fields = variable_get("profile_register_fields", array());
-
- $output = "<table border=\"1\" cellpadding=\"2\" cellspacing=\"2\">\n";
- $output .= "<tr><th>field</th><th>enable</th><th>public</th><th>required</th><th>show in registration form</th></tr>\n";
- foreach ($profile_fields as $key => $field) {
- $output .= "<tr><td>$field[1]</td>";
- $output .= "<td style=\"text-align: center;\">". form_checkbox("", "profile_private_fields][", $key, in_array($key, $profile_private_fields)) ."</td>";
- $output .= "<td style=\"text-align: center;\">". form_checkbox("", "profile_public_fields][", $key, in_array($key, $profile_public_fields)) ."</td>";
- $output .= "<td style=\"text-align: center;\">". form_checkbox("", "profile_required_fields][", $key, in_array($key, $profile_required_fields)) ."</td>";
- $output .= "<td style=\"text-align: center;\">". form_checkbox("", "profile_register_fields][", $key, in_array($key, $profile_register_fields)) ."</td>";
- $output .= "</tr>\n";
- }
- $output .= "</table>\n";
-
- $output .= form_textfield(t("Avatar image path"), "profile_avatar_path", variable_get("profile_avatar_path", "misc/avatars/"), 30, 255, t("Path for avatar directory; it must be writable and visible from the web."));
- $output .= form_textfield(t("Avatar maximum dimensions"), "profile_avatar_dimensions", variable_get("profile_avatar_dimensions", "85x85"), 10, 10, t("Maximum dimensions for avatars."));
- $output .= form_textfield(t("Avatar maximum file size"), "profile_avatar_file_size", variable_get("profile_avatar_file_size", "30"), 10, 10, t("Maximum file size for avatars, in kB."));
-
- return $output;
-}
-
-function profile_user($type, $edit, &$user) {
- global $profile_fields;
- if (!$profile_fields) {
- _profile_init();
- }
-
- switch ($type) {
- case "register_form":
- // first registration form (to add something to just email and nick)
- return _profile_form($edit, "register");
- case "register_validate":
- // validate first registration form
- return _profile_validate($edit, "required", $user);
- case "edit_form":
- // when user tries to edit his own data
- return _profile_form(object2array($user), "private");
- case "edit_validate":
- // validate user data editing
- return _profile_validate($edit, "private", $user);
- case "view_public":
- // when others look at user data
- return _profile_user_view($user, "public");
- case "view_private":
- // when user looks at his own data
- return _profile_user_view($user, "private");
- }
-}
-
-function profile_required($title) {
- // this pleads "theme, theme" ;)
- return $title ." ". theme("theme_mark");
-}
-
-function _profile_form($edit, $mode) {
- global $profile_fields, $user;
-
- $reg_fields = _profile_active_fields($mode);
- $required_fields = _profile_active_fields("required");
-
- foreach ($profile_fields as $name => $field) {
- if ($field[0] && in_array($name, $reg_fields)) {
- $f = "form_". $field[0];
- $t = "profile_". $name;
- $output .= $f((in_array($name, $required_fields) ? profile_required($field[1]) : $field[1]), $t, $edit[$t], $field[3], $field[4], $field[5], $field[6]);
- }
- }
-
- if (in_array("birthday", $reg_fields)) {
- $output .= form_item((in_array("birthday", $required_fields) ? profile_required($profile_fields["birthday"][1]) : $profile_fields["birthday"][1]), _profile_edit_birth(array2object($edit)), $profile_fields["birthday"][2]);
- }
-
- if (in_array("avatar", $reg_fields)) {
- if ($edit["profile_avatar"] && $edit["uid"]) {
- $file = profile_avatar_path($edit["uid"], $edit["profile_avatar"]);
- if ($file) {
- $output .= "<img src=\"$file\" alt=\"\" title=\"\" /><br />";
- }
- }
- $output .= form_file($profile_fields["avatar"][1], "profile_avatar", 64, $profile_fields["avatar"][2]);
- }
-
- return $output;
-}
-
-function _profile_validate($edit, $mode, $user) {
-
- global $profile_fields;
-
- $enabled_fields = _profile_active_fields($mode);
-
- if (in_array("birthday", $enabled_fields) && ($birth_error = _profile_validate_birth($edit))) {
- $error .= $birth_error ."<br />";
- }
-
- if (in_array("avatar", $enabled_fields) && ($avatar_error = _profile_validate_avatar($edit, $user))) {
- $error .= $avatar_error ."<br />";
- }
-
- foreach (array_keys($profile_fields) as $field) {
- // replicate any key which was saved during registration but is not in this form
- if (!$edit[$field] && $user->$field) {
- $edit[$field] = $user->$field;
- }
- }
-
- // now check for required fields
- foreach (_profile_active_fields("required") as $required) {
- if ($required != "0" && in_array($required, $enabled_fields)) {
- if (!$edit["profile_". $required]) {
- $error .= t("This required field is missing: %a", array("%a" => $profile_fields[$required][1])) ."<br />";
- }
- }
- }
-
- return $error ? $error : $edit;
-}
-
-function _profile_user_view(&$user, $mode) {
- global $profile_fields;
-
- foreach (_profile_active_fields($mode) as $name) {
- $field = $profile_fields[$name];
- $t = "profile_". $name;
-
- if (!empty($user->$t)) {
- switch ($field[0]) {
- case "textfield":
- case "textarea":
- case "checkbox":
- $value = ($t == "profile_homepage") ? "<a href=\"". check_output($user->$t) ."\">". check_output($user->$t) ."</a>" : check_output($user->$t);
- $output .= form_item($field[1], $value);
- break;
- case "select":
- $output .= form_item($field[1], check_output($profile_fields[$name][3][$user->$t]));
- break;
- case "":
- // special
- if ($t == "profile_avatar") {
- $file = profile_avatar_path($user->uid, $user->profile_avatar);
- if (file_exists($file)) {
- $output .= form_item(t("Avatar"), "<img src=\"$file\" alt=\"\" title=\"\" />");
- }
- }
-
- if ($t == "profile_birthday") {
- if (isset($user->profile_birthday) && isset($user->profile_birthmonth) && isset($user->profile_birthyear)) {
- // this is very european-centric, can we use format_date?
- $time = mktime(0, 0, 0, $user->profile_birthmonth, $user->profile_birthday, $user->profile_birthyear);
- $output .= form_item(t("Birthday"), format_date($time, "custom", "F j, Y"));
- }
- }
- }
- }
- }
- return $output;
-}
-
-function _profile_validate_avatar(&$edit, $user) {
- // check that uploaded file is an image, with a maximum file size and maximum height/width
-
- unset($edit["profile_avatar"]);
-
- if ($_FILES["edit"]["name"]["profile_avatar"] == "") {
- $edit["profile_avatar"] = $user->profile_avatar;
- return "";
- }
-
- $image_file = $_FILES["edit"]["tmp_name"]["profile_avatar"];
- if (is_uploaded_file($image_file)) {
- $extension = strtolower(strrchr($_FILES["edit"]["name"]["profile_avatar"], "."));
- $size = getimagesize($image_file);
- list($maxwidth, $maxheight) = explode("x", variable_get("profile_avatar_dimensions", "85x85"));
- if ((!in_array($size[2], array(1, 2, 3))) || (!in_array($extension, array(".gif", ".jpg", ".png", ".jpeg")))) {
- $error = t("The uploaded file was not an image.");
- }
- else if (filesize($image_file) > (variable_get("profile_avatar_file_size", "30") * 1000)) {
- $error = t("The uploaded image is too large; the maximum file size is %a kB.", array("%a" => variable_get("profile_avatar_file_size", "30")));
- }
- else if ($size[0] > $maxwidth || $size[1] > $maxheight) {
- $error = t("The uploaded image is too large; the maximum dimensions are %a pixels.", array("%a" => variable_get("profile_avatar_dimensions", "85x85")));
- }
- else if (!is_dir(variable_get("profile_avatar_path", "misc/avatars/"))) {
- $error = t("Failed to upload the avatar image; the '%directory' directory doesn't exist.", array("%directory" => variable_get("profile_avatar_path", "misc/avatars/")));
- }
- else if (!is_writeable(variable_get("profile_avatar_path", "misc/avatars/"))) {
- $error = t("Failed to upload the avatar image; the webserver has no write permission to the '%directory' directory.", array("%directory" => variable_get("profile_avatar_path", "misc/avatars/")));
- }
- else if (!copy($image_file, variable_get("profile_avatar_path", "misc/avatars/").md5($user->uid).$extension)) {
- $error = t("Failed to upload the avatar image; could not copy file '%filename' to directory '%directory'.", array("%filename" => $_FILES["edit"]["name"]["profile_avatar"], "%directory" => variable_get("profile_avatar_path", "misc/avatars/")));
- }
- else {
- $edit["profile_avatar"] = $extension;
- }
- }
-
- return $error ? "$error<br />" : "";
-}
-
-function profile_avatar_path($uid, $extension) {
- return $extension ? variable_get("profile_avatar_path", "misc/avatars/") . md5($uid) . $extension : "";
-}
-
-function _profile_active_fields($mode) {
- return variable_get("profile_". $mode ."_fields", array());
-}
-
-function _profile_edit_birth($edit = "") {
- global $profile_months, $profile_days;
- $output = _profile_select("profile_birthday", $edit->profile_birthday, $profile_days);
- $output .= "&nbsp;";
- $output .= _profile_select("profile_birthmonth", $edit->profile_birthmonth, $profile_months);
- $output .= "&nbsp;";
- $output .= "<input type=\"text\" maxlength=\"4\" name=\"edit[profile_birthyear]\" size=\"5\" value=\"$edit->profile_birthyear\" />";
- return $output;
-}
-
-function _profile_validate_birth(&$edit) {
- if (!$edit["profile_birthday"] && !$edit["profile_birthmonth"] && !$edit["profile_birthyear"]) {
- // change this if you want required birth
- return;
- }
-
- if ($edit["profile_birthyear"] > 1900 && checkdate($edit["profile_birthmonth"], $edit["profile_birthday"], $edit["profile_birthyear"])) {
- return;
- }
- else {
- return t("The specified birthday is not valid.") ."<br />";
- }
-}
-
-function _profile_select($name, $value, $options, $extra = 0, $multiple = 0) {
- if (count($options) > 0) {
- foreach ($options as $key=>$choice) {
- $select .= "<option value=\"$key\"". (is_array($value) ? (in_array($key, $value) ? " selected=\"selected\"" : "") : ($key == $value ? " selected=\"selected\"" : "")) .">". check_form($choice) ."</option>";
- }
- return "<select name=\"edit[$name]". ($multiple ? "[]" : "") ."\"". ($multiple ? " multiple " : "") . ($extra ? " $extra" : "") .">$select</select>";
- }
-}
-
-?>
diff --git a/modules/search/search.module b/modules/search/search.module
deleted file mode 100644
index 7eebf9f..0000000
--- a/modules/search/search.module
+++ /dev/null
@@ -1,395 +0,0 @@
-<?php
-// $Id$
-
-function search_help() {
- $output = "<b>". t("Search guidelines") ."</b>";
- $output .= "<p>". t("The search page allows you to search the web site's content. You can specify multiple words, and they will all be searched for. You can also use wildcards, so 'walk*' will match 'walk', 'walking', 'walker', 'walkable' and so on. Furthermore, searches are not case sensitive so searching for 'walk', 'Walk' or 'WALK' will yield exactly the same results.") ."</p>";
- $output .= "<b>". t("Words excluded from the search") ."</b>";
- $output .= "<p>". t("Words that frequently occur, typically called 'noise words', are ignored. Example words are 'a', 'at', 'and', 'are', 'as', 'how', 'where', etc. Words shorter than %number letters are also ignored.", array("%number" => variable_get("minimum_word_size", 2))) ."</p>";
- return $output;
-}
-
-function search_system($field){
- $system["description"] = t("Enables site wide keyword searching.");
- $system["admin_help"] = t("The search engine works by keeping an index of \"interesting\" words. To make sure we only get \"interesting\" words you need to set the following.");
- return $system[$field];
-}
-
-/**
- * Return an array of valid search access permissions
- */
-function search_perm() {
- return array("search content", "administer search");
-}
-
-/**
- * Return an array of links to be displayed
- *
- * @param $type The type of page requesting the link
- *
- */
-function search_link($type) {
- $links = array();
-
- if ($type == "page" && user_access("search content")) {
- $links[] = l(t("search"), "search", array("title" => t("Search for older content.")));
- }
-
- return $links;
-}
-
-function search_settings() {
- $output = form_textfield(t("Minimum word length to index"), "minimum_word_size", variable_get("minimum_word_size", 2), 10, 10, t("The number of characters a word has to be to be indexed. Words shorter than this will not be searchable."));
- $output .= form_textfield(t("Minimum word length to search for"), "remove_short", variable_get("remove_short", 0), 10, 10, t("The number of characters a word has to be to be searched for."));
- $output .= form_textarea(t("Noise words"), "noisewords", variable_get("noisewords", ""), 70, 10, t("These words will not be indexed, enter comma separated list, linebreaks and whitespace do not matter. Example: and, or, not, a, to, I, it, ..."));
- $output .= form_select(t("Help text position"), "help_pos", variable_get("help_pos", 1), array("1" => t("Above search output"), "2" => t("Below search output"), "3" => t("Link from above search output"), "4" => t("Link from below search output")), t("Where to show the help text for users on the search page."));
-
- return $output;
-}
-
-/**
- * search engine administration actions
- *
- */
-function search_admin() {
- $op = $_POST["op"];
-
- // Only allow people with sufficient access.
- if (user_access("administer search")) {
- if ($op == "reindex") {
- search_invalidate();
- print t("index invalidated") ."<br />\n";
- search_cron();
- print t("index recreated") ."<br /><hr />\n";
- }
- }
-}
-
-/**
- * perform a regularly run action across all modules that have the
- * <module>_update_index function in them.
- *
- */
-function search_cron() {
- foreach (module_list() as $module) {
- $module_array = module_invoke($module, "update_index");
- if ($module_array) {
- update_index($module_array);
- }
- $module_array = null;
- }
- return;
-}
-
-/**
- * Perform a search on a word(s)
- *
- * Search function called by each node that supports the indexed search
- *
- * @param $search_array an array as returned from <module>_search
- * of type array("keys" => ...,
- * "type" => ..., "select" => ...)
- * see node_search in node.module for an
- * explanation of array items
- */
-function do_search($search_array) {
-
- $keys = strtolower($search_array["keys"]);
- $type = $search_array["type"];
- $select = $search_array["select"];
-
- // Replace wildcards with mysql wildcards
- $keys = str_replace("*", "%", $keys);
-
- // Split the words entered into an array
- $words = explode(" ", $keys);
-
- foreach ($words as $word) {
-
- // If the word is too short, and we've got it set to skip them, loop
- if (strlen($word) < variable_get("remove_short", 0)) {
- continue;
- }
-
- // Put the next search word into the query and do the query
- $query = preg_replace("'\%'", check_query($word), $select);
- $result = db_query($query);
-
- // If we got any results
- if (db_num_rows($result) != 0) {
- $found = 1;
-
- // Create an in memory array of the results,
- while ($row = db_fetch_array($result)) {
- $lno = $row["lno"];
- $nid = $row["nid"];
- $title = $row["title"];
- $created = $row["created"];
- $uid = $row["uid"];
- $name = $row["name"];
- $count = $row["count"];
-
- // Build reduction variable
- $reduction[$lno][$word] = true;
-
- // If the just fetched row is not already in the table
- if ($results[$lno]["lno"] != $lno) {
- $results[$lno]["count"] = $count;
-
- $results[$lno]["lno"] = $lno;
- $results[$lno]["nid"] = $nid;
- $results[$lno]["title"] = $title;
- $results[$lno]["created"] = $created;
- $results[$lno]["uid"] = $uid;
- $results[$lno]["name"] = $name;
- }
- else {
- /*
- ** Different word, but existing "lno", increase the count of
- ** matches against this "lno" by the number of times this
- ** word appears in the text
- */
- $results[$lno]["count"] = $results[$lno]["count"] + $count;
- }
- }
- }
- }
-
- if ($found) {
- foreach ($results as $lno => $values) {
- $pass = true;
- foreach ($words as $word) {
- if (!$reduction[$lno][$word]) {
- $pass = false;
- }
- }
- if ($pass) {
- $fullresults[$lno] = $values;
- }
- }
- $results = $fullresults;
- if (!is_array($results)) {
- $found = 0;
- }
- }
- if ($found) {
- // Black magic here to sort the results
- array_multisort($results, SORT_DESC);
-
- // OK, time to output the results.
- foreach ($results as $key => $value) {
- $lno = $value["lno"];
- $nid = $value["nid"];
- $title = $value["title"];
- $created = $value["created"];
- $uid = $value["uid"];
- $name = $value["name"];
- $count = $value["count"];
- switch ($type) {
- case "node":
- $find[$i++] = array("count" => $count, "title" => $title, "link" => (strstr(request_uri(), "admin") ? url("admin/node/edit/$lno") : url("node/view/$lno")), "user" => $name, "date" => $created, "keywords" => implode("|", $words));
- break;
- case "comment":
- $find[$i++] = array("count" => $count, "title" => $title, "link" => (strstr(request_uri(), "admin") ? url("admin/comment/edit/$lno") : url("node/view/$nid#$lno")), "user" => $name, "date" => $created, "keywords" => implode("|", $words));
- break;
- }
- }
- }
-
- return $find;
-}
-
-/**
- * Update the search_index table
- *
- * @param $search_array an array as returned from <module>_update_index
- * of type array("last_update" => ...,
- * "node_type" => ..., "select" => ...)
- * see node_update_index in node.module for an
- * explanation of array items
- */
-function update_index($search_array) {
- $last_update = variable_get($search_array["last_update"], 1);
- $node_type = $search_array["node_type"];
- $select = $search_array["select"];
- $minimum_word_size = variable_get("minimum_word_size", 2);
-
- //watchdog("user", "$last_update<br />$node_type<br />$select");
-
- $result = db_query($select);
-
- if (db_num_rows($result)) {
- // Wohoo, found some, look through the nodes we just selected
- while ($node = db_fetch_array ($result)) {
-
- /*
- ** Trash any existing entries in the search index for this node,
- ** in case its a modified node.
- */
- db_query("DELETE from search_index where lno = '". $node["lno"] ."' and type = '". $node_type ."'");
-
- /*
- ** Build the wordlist, teaser not included, as it then gives a
- ** false count of the number of hits, and doesn't show up
- ** when clicking on a node from the search interface anyway.
- */
- $wordlist = $node["text1"] ." ". $node["text2"];
-
- // Strip heaps of stuff out of it
- $wordlist = preg_replace("'<[\/\!]*?[^<>]*?>'si", "", $wordlist);
-
- // Remove punctuation and stuff
- $wordlist = preg_replace("'(\xBB|\xAB|!|\xA1|%|,|:|;|\(|\)|\&|\"|\'|\.|-|\/|\?|\\\)'", "", $wordlist);
-
- // Strip out (now mangled) http and tags.
- $wordlist = preg_replace("'http\w+'", "", $wordlist);
- $wordlist = preg_replace("'www\w+'", "", $wordlist);
-
- // Remove all newlines of any type
- $wordlist = preg_replace("'([\r\n]|[\r]|[\n])'", " ", $wordlist);
-
- // Lower case the whole thing.
- $wordlist = strtolower($wordlist);
-
- // Remove "noisewords"
- $noise = explode(",", variable_get("noisewords", ""));
- foreach ($noise as $word) {
- $wordlist = preg_replace("' $word '", " ", $wordlist);
- }
-
- // Remove whitespace
- $wordlist = preg_replace("'[\s]+'", " ", $wordlist);
-
- // Make it an array
- $eachword = explode(" ", $wordlist);
-
- /*
- ** walk through the array, giving a "weight" to each word, based on
- ** the number of times it appears in a page.
- */
- foreach ($eachword as $word) {
- if (strlen($word) >= $minimum_word_size) {
- if ($newwords[$word]) {
- $newwords[$word]++;
- }
- else {
- $newwords[$word] = 1;
- }
- }
- }
-
- /*
- ** Walk through the weighted words array, inserting them into
- ** the search index
- */
- if ($newwords) {
- foreach ($newwords as $key => $value) {
- db_query("INSERT INTO search_index VALUES('%s', %d, '%s', %d)", $key, $node["lno"], $node_type, $value);
- }
- }
-
- // Zap the weighted words array, so we don't add multiples.
- $newwords = array ();
- }
- }
-
- // update the last time this process was run.
- variable_set($search_array["last_update"], time());
-
- return true;
-}
-
-
-function search_invalidate() {
- foreach (module_list() as $module) {
- $module_array = module_invoke($module, "update_index");
- if ($module_array) {
- variable_set($module_array["last_update"], 1);
- }
- $module_array = null;
- }
- return;
-}
-
-/**
- * Save the values entered by the administrator for the search module
- *
- * @param $edit An array of fields as setup via calling form_textfield,
- * form_textarea etc
- */
-function search_save($edit) {
- variable_set("minimum_word_size", $edit["minimum_word_size"]);
-
- $data = strtr($edit["noisewords"], "\n\r\t", " ");
- $data = str_replace(" ", "", $data);
- variable_set("noisewords", $data);
- variable_set("help_pos", $edit["help_pos"]);
- variable_set("remove_short", $edit["remove_short"]);
-}
-
-function search_view($keys) {
- global $type;
-
- if (user_access("search content")) {
- // Construct the search form:
- $form = search_form(NULL, $keys, TRUE);
-
- // Collect the search results:
- $output = search_data($keys);
-
- // Display form and search results:
- $help_link = l(t("search help"), "search/help");
- switch (variable_get("help_pos", 1)) {
- case "1":
- $form = search_help(). $form;
- break;
- case "2":
- $form .= search_help();
- break;
- case "3":
- $form = $help_link. "<br />". $form;
- break;
- case "4":
- $form .= "<br />". $help_link;
- }
-
- theme("header");
-
- if ($form) {
- theme("box", t("Search"), $form);
- }
-
- if ($keys) {
- if ($output) {
- theme("box", t("Search Results"), $output);
- }
- else {
- theme("box", t("Search Results"), t("Your search yielded no results."));
- }
- }
-
- theme("footer");
- }
- else {
- theme("header");
- theme("box", t("Access denied"), message_access());
- theme("footer");
- }
-
-}
-
-function search_page() {
- $keys = isset($_GET["keys"]) ? $_GET["keys"] : $_POST["keys"];
-
- switch (arg(1)) {
- case "help":
- theme("header");
- theme("box", t("Search Help"), search_help());
- theme("footer");
- break;
- default:
- search_view($keys);
- }
-}
-
-?>
diff --git a/modules/statistics/statistics.module b/modules/statistics/statistics.module
deleted file mode 100644
index 7804bb9..0000000
--- a/modules/statistics/statistics.module
+++ /dev/null
@@ -1,855 +0,0 @@
-<?php
-// $Id$
-
-function statistics_init() {
- global $recent_activity;
-
- /*
- ** The following logic determines what the current throttle level should
- ** be, and can be disabled by the admin. If enabled, the rand() function
- ** returns a number between 0 and N, N being specified by the admin. If
- ** 0 is returned, the throttle logic is run, adding on additional database
- ** query. Otherwise, the following logic is skipped. This mechanism is
- ** referred to in the admin page as the 'probability limiter', roughly
- ** limiting throttle related database calls to 1 in N.
- */
- if ((variable_get("statistics_enable_auto_throttle", 0)) && (!rand(0, variable_get("statistics_probability_limiter", 9)))) {
- /*
- ** Note: The rand() function is supported by PHP 3+. However, prior to
- ** PHP 4.2.0 it needs to be seeded with a call to srand(). It is important
- ** that this only happens once, so this should be managed by the Drupal
- ** engine, not this module. The Drupal engine should use phpversion() to
- ** detect and automatically seed pre-4.2.0 systems.
- */
-
- $throttle = throttle_status();
- // if we're at throttle level 5, we don't do anything
- if ($throttle < 5) {
- $multiplier = variable_get("statistics_throttle_multiplier", 60);
- // count all hits in past sixty seconds
- $result = db_query("SELECT COUNT(timestamp) AS hits FROM accesslog WHERE timestamp >= %d", (time() - 60));
- $recent_activity = db_fetch_array($result);
- throttle_update($recent_activity["hits"]);
- }
- }
-}
-
-// Footer hook, runs at the end of every page request
-function statistics_exit() {
- global $user;
-
- if (variable_get("statistics_enable_node_counter", 0)) {
- // node view counters are enabled
- if ((arg(0) == "node") && (arg(1) == "view") && arg(2)) {
- // a node has been viewed, so updated the node's counters
- db_query("UPDATE statistics SET daycount = daycount + 1, totalcount = totalcount + 1, timestamp = %d WHERE nid = %d", time(), arg(2));
- // if we affected 0 rows, this is the first time viewing the node
- if (!db_affected_rows()) {
- // must create a new row to store counter's for new node
- db_query("INSERT INTO statistics (nid, daycount, totalcount) VALUES(%d, 1, 1)", arg(2));
- }
- }
- }
-
- if ((variable_get("statistics_enable_access_log", 0)) && (throttle_status() < 5)) {
- // statistical logs are enabled
- $referrer = referer_uri();
- $hostname = getenv("REMOTE_ADDR");
- // log this page access
- if ((arg(0) == "node") && (arg(1) == "view") && arg(2)) {
- db_query("INSERT INTO accesslog (nid, url, hostname, uid, timestamp) values(%d, '%s', '%s', %d, %d)", arg(2), $referrer, $hostname, $user->uid, time());
- }
- else {
- db_query("INSERT INTO accesslog (url, hostname, uid, timestamp) values('%s', '%s', %d, %d)", $referrer, $hostname, $user->uid, time());
- }
- }
-}
-
-/* System hook, sets description of module in admin page */
-function statistics_system($field) {
- $system["description"] = t("Logs access statistics for your site.");
- $system["admin_help"] = t("Settings for the statistical information that Drupal will keep about the site. See <a href=\"%statistics\">site statistics</a> for the actual information.", array("%statistics" => url("admin/statistics")));
- return $system[$field];
-}
-
-
-/* Permissions hook, defines module's permissions */
-function statistics_perm() {
- /*
- ** statistics module defines the following permissions:
- ** administer statistics module - full administrative control of module
- ** administer statistics - view statistics / referrer log
- ** access statistics - see counts per node (if enabled)
- ** access userlist - see list of online users
- */
- return array("administer statistics module", "administer statistics", "access statistics", "access userlist");
-}
-
-
-/* Link hook, defines module's links */
-function statistics_link($type, $node = 0, $main = 0) {
- global $id;
-
- $links = array();
-
- if ($type == "node" && user_access("access statistics") && variable_get("statistics_display_counter", 0)) {
- $statistics = statistics_get($node->nid);
- if ($statistics) {
- if (user_access("administer statistics")) {
- $links[] = l(format_plural($statistics["totalcount"], "1 read", "%count reads"), "admin/statistics/log/node/$node->nid");
- }
- else {
- $links[] = format_plural($statistics["totalcount"], "1 read", "%count reads");
- }
- }
- }
-
- if ($type == "page" && user_access("access content")) {
- $userlink = variable_get("statistics_userpage_link", "");
- if ($userlink) {
- $links[] = l(t($userlink), "statistics", array("title" => t("View the top nodes for this site.")));
- }
- }
-
- if ($type == "admin" && (user_access("administer statistics module") || (user_access("administer statistics")))) {
- $help["statistics"] = t("This page gives you an at-a-glance look at your top nodes. It is useful for understanding what content on your site is the most popular.");
- $help["referrers"] = t("This page shows you site-wide referrer statistics. You can see 'all referrers', 'external referrers' or 'internal referrers'. Defaults to 'external'. Referrers are web sites, both your site, and other peoples, that point to your web site.");
- $help["referrers-internal"] = t("This page shows you only 'internal referrers'. Links pointing to your web site, from within your web site.");
- $help["referrers-external"] = t("This page shows you only 'external referrers'. Links pointing to your web site from outside your web site.");
- $help["access"] = t("This pages shows you who is accessing your web site. You can see the hostnames, referrers. In particular, it is easy to inspect a user's navigation history/trail by clicking the username.");
- $help["top nodes page"] = t("The statistics module creates a user page that can display summaries of the day's top viewed nodes, the all time top nodes and the last nodes viewed. Each of these summaries can be enabled or disabled individually, and the number of nodes displayed for each can be configured with a drop down menu.");
- $help["top nodes block"] = t("The statistics module exports a block that can display the top viewed nodes of the day, the all time top viewed nodes and the last nodes viewed. Each of these links can be enabled or disabled individually, and the number of nodes displayed for each can be configured with a drop down menu. If you disable all sections of this block, it will not appear.");
- $help["who is online block"] = t("The statistics module exports a block that can display how many user's and guests are currently online. You can configure the name of the block, the name of a sub-block for displaying names of user's currently online, how recently a user must have been active to be considered online, the maximum characters to display from a user's name and the maximum number of user names to display.");
-
- menu("admin/statistics", "site statistics", "statistics_admin", $help["statistics"], 6);
- menu("admin/statistics/statistics", "most popular posts", "statistics_admin", $help["statistics"]);
- menu("admin/statistics/referrers", "referrer log", "statistics_admin", $help["referrers"]);
- menu("admin/statistics/referrers/internal", "internal referrers only", "statistics_admin", $help["referrers-internal"]);
- menu("admin/statistics/referrers/external", "external referrers only", "statistics_admin", $help["referrers-external"]);
- menu("admin/statistics/log", "access log", "statistics_admin", $help["access"]);
- menu("admin/statistics/log/node", "track node", "statistics_admin", $help["access"], 0, 1);
- menu("admin/statistics/log/user", "track user", "statistics_admin", $help["access"], 0, 1);
- menu("admin/statistics/log/host", "track host", "statistics_admin", $help["access"], 0, 1);
- menu("admin/statistics/top nodes page", "configure 'top nodes' page", "statistics_admin", $help["top nodes page"], 5);
- menu("admin/statistics/help", "help", "statistics_help", NULL, 9);
-
- // block configuration:
- menu("admin/block/top nodes block", "configure 'top nodes' block", "statistics_admin", $help["top nodes block"], 5);
- menu("admin/block/whos online block", "configure 'who is online' block", "statistics_admin", $help["who is online block"], 5);
-}
-
- return $links;
-}
-
-
-/* Administrative help page */
-function statistics_help() {
- $output .= "<h3>Introduction</h3><p>The statistics.module keeps track of numerous statistics for your site but be warned, statistical collection does cause a little overhead, thus everything comes disabled by default.<p>";
- $output .= "<p>The module counts how many times, and from where -- using HTTP referrer --, each of your nodes is viewed. Once we have that count the module can do the following with it:<ul><li> The count can be displayed in the node's link section next to \"# comments\".</li><li>A configurable block can be added which can display the day's top stories, the all time top stories, and the last stories read. Each section in the block has a title, which you can change, as well as being able to change how many node titles will be displayed</li><li>A configurable user page can be added, which can display the day's top stories, the all time top stories, and the last stories read. Each section in the page has a title, which you can change, as well as being able to change the number of stories to be displayed.</li><li>A configurable block can be added that displays the count of how many users, as well as a list of their names, and guests are currently accessing your site.</li><li>An auto-throttle, congestion controling mechanism can be used on your site if you have enabled the ". l("throttle.module", "admin/system/modules") .".</ul>";
- $output .= "<p>Notes on using the statistics:</p><ul><li>If you enable the node view counters, this adds 1 database query for each node that is viewed (2 queries if it's the first time the node has ever been viewed).</li><li>If you enable the access log, this adds 1 database query for each page that Drupal displays. Logged information includes: HTTP referrer (if any), node being accessed (if any), user ID (if any), the IP address of the user, and the time the page was viewed.</li></ul>";
- $output .= "<p>As with any new module, the <i>statistics.module</i> needs to be ". l("enabled", "admin/system/modules") ." before you can use it. Also refer to the ". l("permissions section", "admin/user/permission") .", as this module supports four separate permissions.</p>";
- $output .= l("<h3>referrers log</h3>", "admin/statistics/referrers")."<p>This admin page shows you site-wide referrer statistics. You can see '<i>all</i>' statistics, '<i>external</i>' statistics or '<i>internal</i>' statistics. Default is 'external'.</p>";
- $output .= l("<h3>access log</h3>", "admin/statistics/log") ."<p>This admin page gives you an at-a-glance look at your top nodes. It is useful for understanding what content on your Drupal site is the most popular. Also on this page are links to the referrer statistics for each listed node.</p>";
- $output .= "<h3>Configuring the statistics module</h3><p>There are some configuration options added to the main ". l("site configuration", "admin/system/modules/statistics") ." section:</p>";
- $output .= "<ul><li><i>enable access log</i> -- allows you to turn the access log on and off. This log is used to store things like referrers and who's online. Enabling the log adds one database call per page displayed by Drupal.</li>";
- $output .= "<li><i>discard access logs older than</i> -- allows you to configure how long an access log entry is saved, after which time it is deleted from the database table. To use this you need to run \"cron.php\"</li>";
- $output .= "<li><i>enable node view counter</i> -- allows you to turn on and off the node-counting functionality of this module. If it is turned on, an extra database query is added for each node displayed, which increments a counter.</li>";
- $output .= "<li><i>display node view counters</i> -- allows you to globally disable the displaying of node view counters. Additionally, a user group must have 'access statistics' permissions to view the counters.</li></ul>";
- $output .= "<h3>Top nodes block</h3><p>This module creates a block that can display the day's top viewed nodes, the all time top viewed nodes and the last nodes viewed. Each of these links can be enabled or disabled individually, and the number of nodes displayed for each can be configured with a drop down menu. If you disable all sections of this block, it will not appear.</p>";
- $output .= "<p>The administrative \"top nodes block\" screen also allows you to assign a name to the block.</p>";
- $output .= "<p>Don't forget to enable the block ". l("here", "admin/block") .".</p>";
-
- $output .= "<h3>Top nodes page</h3><p>This module creates a user page that can display summaries of the day's top viewed nodes, the all time top nodes and the last nodes viewed. Each of these summaries can be enabled or disabled individually, and the number of nodes displayed for each can be configured with a drop down menu.</p>";
- $output .= "<p>The administrative \"top nodes page\" screen also allows you to assign a name for the automatically generated link to the user page. If no name is set, the link will not be displayed.</p>";
- $output .= "<h3>Who's online block</h3><p>This module creates a block that can display how many user's and guests are currently online. You are able to configure the name of the block, the name of a sub-block for displaying names of user's currently online, how recently a user must have been active to be considered online, the maximum characters to display from a user's name and the maximum number of user names to display.</p>";
- $output .= "<p>Don't forget to enable the block ". l("here", "admin/block") .".</p>";
- $output .= "<h3>Permissions</h3><p>This module has four permissions that need to be configured in ". l("user permissions", "admin/user/permission") .".</p>";
- $output .= "<ul><li><i>access statistics</i> - enable for user roles that get to see individual node counts. (This does not define access to the block)</li><li><i>access userlist</i> - enable for user roles that get to see the list of user's that are currently online within the \"Who's online\" block.</li><li><i>administer statistics module</i> - enable for user roles that get to configure the statistics module.</li><li><i>administer statistics</i> - enable for user roles that get to view the referrer statistics.</li></ul>";
- $output .= "<p>If '<i>administer statistics</i>' and '<i>access statistics</i>' are both enabled, the user will see a link from each node to that node's referrer statistics (if enabled).</p>";
- $output .= "<h2>Statistics module (for developers)</h2><h3>Accessing statistics</h3><p>To get a node's \"view statistics\" make a call to the function <i>statistics_get(\$nid)</i>. When you pass in a Node ID (\$nid), the function returns an array with three entires: [0]=totalcount, [1]=daycount, [2]=timestamp. For example, you could use this function call to add node view counts to your theme.</p>";
- $output .= "<ul><li>The <i>totalcount</i> is a count of the total number of times that node has been viewed.</li><li>The <i>daycount</i> is a count of the total number of times that node has been viewed \"today\". For the daycount to be reset, cron must be enabled.</li><li>The <i>timestamp</i> is a timestamp of when that node was last viewed.</li></ul>";
- $output .= "<p>The module automatically adds '# reads' to each node's link section (if enabled).</p>";
- $output .= "<h3>Top stories</h3><p>The statistics.module provides a function '<i>statistics_title_list(\$dbfield, \$dbrows)</i>' to return an array of links to any of the following: the top viewed nodes of all time, the top viewed nodes of today, the last viewed nodes. You can pass in:</p>";
- $output .= "<ul><li><i>totalcount</i> - This will return an array with links to the top viewed nodes of all time.<br />Example: <code>statistics_title_list(\"totalcount\", \"5\");</code><br /><br /></li><li><i>daycount</i> - This will return an array with links to the top viewed nodes for today.<br />Example: <code>statistics_title_list(\"daycount\",\"5\");</code><br /><br /></li><li><i>timestamp</i> - This will return a array with links to the last viewed node.<br />Example: <code>statistics_title_list(\"timestamp\",\"5\");</code></li></ul><p>\$dbrows is the number or rows you want returned in your array.</p>";
- $output .= "<h3>Throttle</h3><p>The function <code>throttle_status()</code> will return a number from 0 to 5. 0 means that there is no throttle enabled at this time. Each number above that is a progressively more throttled system... To disable a feature when a site first begins to get busy, disable it at a throttle of 2 or 3. To hold on to the bitter end, wait until 4 or 5.</p>";
- $output .= "<p>To implement the throttle, you should do something like this:<pre> \$throttle = 0;
- /* verify that the statitistics module is installed */
- if (function_exists(throttle_status) {
- \$throttle = throttle_status()
- }
- if (\$throttle >= \$my_throttle_value) {
- // throttle limit reached, disable stuff
- }
- else {
- // throttle limit not reached, execute normally
- }</pre></p>";
- $output .= "<p>Note: Even though the configuration for the throttle is handled by the 'throttle.module', the throttle logic itself is part of the 'statistics.module'. The configuration has been separated in order to make things easier for the average site that will not be utilizing the throttling mechanism. More information about how the throttle works can be found on the throttle.module help page. (Find the throttle help page ". l("here", "admin/help#throttle") ." if you have enabled the throttle.module).</p>";
- return t($output);
-
-}
-
-
-/* Administration hook, defines module's administrative page */
-function statistics_admin() {
- $op = $_POST["op"];
- $edit = $_POST["edit"];
-
- /* Only allow people with sufficient access. */
- if ((user_access("administer statistics module")) || (user_access("administer statistics"))) {
-
- if (empty($op)) {
- $op = arg(2);
- }
-
- /* non-configuration admin pages */
- switch ($op) {
- case "statistics":
- return statistics_admin_displaycounts();
- case "referrers":
- return statistics_recent_refer() . statistics_top_refer();
- case "log":
- return statistics_admin_displaylog();
- }
-
- /* configuration admin pages */
- if (user_access("administer statistics module")) {
- switch (stripslashes($op)) {
- case "Submit \"top nodes\" block changes":
- statistics_save_topnodes_block($edit);
- return status(t("saved 'top nodes' block changes."));
- case "top nodes block":
- return statistics_config_topnodes_block(array(
- "statistics_block_top_title" => variable_get("statistics_block_top_title", "Top nodes"),
- "statistics_block_top_day_head" => variable_get("statistics_block_top_day_head", "<b>Todays top:</b>"),
- "statistics_block_top_day_num" => variable_get("statistics_block_top_day_num", 0),
- "statistics_block_top_all_head" => variable_get("statistics_block_top_all_head", "<b>All time top:</b>"),
- "statistics_block_top_all_num" => variable_get("statistics_block_top_all_num", 0),
- "statistics_block_top_last_head" => variable_get("statistics_block_top_last_head" ,"<b>Last:</b>"),
- "statistics_block_top_last_num" => variable_get("statistics_block_top_last_num", 0)
- ));
- case "Submit \"who's online\" block changes":
- statistics_save_online_block($edit);
- return status(t("saved 'who's online' block changes."));
- case "whos online block":
- return statistics_config_online_block(array(
- "statistics_block_online_title" => variable_get("statistics_block_online_title", "Who's online"),
- "statistics_block_online_subtitle" => variable_get("statistics_block_online_subtitle", "Online users:"),
- "statistics_block_online_time" => variable_get("statistics_block_online_time", 2700),
- "statistics_block_online_max_len" => variable_get("statistics_block_online_max_len", 15),
- "statistics_block_online_max_cnt" => variable_get("statistics_block_online_max_cnt", 10)
- ));
- case "Submit \"top nodes\" page changes":
- statistics_save_userconfig($edit);
- return status(t("saved 'top nodes' page changes."));
- case "top nodes page":
- return statistics_admin_userpage_config(array(
- "statistics_userpage_link" => variable_get("statistics_userpage_link", ""),
- "statistics_userpage_day_head" => variable_get("statistics_userpage_day_head", "Todays top"),
- "statistics_userpage_day_cnt" => variable_get("statistics_userpage_day_cnt", 0),
- "statistics_userpage_all_head" => variable_get("statistics_userpage_all_head", "All time top"),
- "statistics_userpage_all_cnt" => variable_get("statistics_userpage_all_cnt", 0),
- "statistics_userpage_last_head" => variable_get("statistics_userpage_last_head", "Last read"),
- "statistics_userpage_last_cnt" => variable_get("statistics_userpage_last_cnt", 0)
- ));
- default:
- return statistics_admin_displaycounts();
- }
- }
- }
-}
-
-
-/* Displays the various admin tables */
-function statistics_admin_count_table($dbfield, $dbrows) {
- $result = db_query_range("SELECT s.nid, s.daycount, s.totalcount, s.timestamp, n.title FROM statistics s LEFT JOIN node n USING (nid) WHERE s.%s <> '0' ORDER BY s.%s DESC", $dbfield, $dbfield, 0, $dbrows);
-
- $header = array(t("title"), t("today"), t("all time"), t("last hit"), t("operations"));
-
- while ($nid = db_fetch_array($result)) {
- $rows[] = array(l($nid["title"], "node/view/". $nid["nid"], array("title" => t("View this posting."))), $nid["daycount"], $nid["totalcount"], format_date($nid["timestamp"], "small"), l("track node", "admin/statistics/log/node/$nid[nid]"));
- }
-
- return table($header, $rows);
-}
-
-
-function statistics_admin_accesslog_table($type, $id) {
-
- if ($type == 1) {
- /* retrieve user access logs */
- if ($id) {
- /* retrieve recent access logs for user $id */
- $result = pager_query("SELECT nid, url, hostname, uid, timestamp FROM accesslog WHERE uid = '". check_query($id) ."' ORDER BY timestamp DESC", 50);
- }
- else {
- /* retrieve recent access logs for all users */
- $result = pager_query("SELECT nid, url, hostname, uid, MAX(timestamp) AS timestamp FROM accesslog WHERE uid <> '0' GROUP BY uid, nid, url, hostname ORDER BY timestamp DESC", 50);
- }
- }
- else if ($type == 2) {
- /* retrieve recent access logs for node $id */
- $result = pager_query("SELECT nid, url, hostname, uid, timestamp FROM accesslog WHERE nid = '". check_query($id) ."' ORDER BY timestamp DESC", 50);
- }
- else if ($type == 3) {
- /* retrieve recent access logs for hostname $id */
- $result = pager_query("SELECT nid, url, hostname, uid, timestamp FROM accesslog WHERE hostname = '". check_query($id) ."' ORDER BY timestamp DESC", 50);
- }
- else {
- /* retrieve all recent access logs */
- $result = pager_query("SELECT nid, url, hostname, uid, timestamp FROM accesslog ORDER BY timestamp DESC", 50);
- }
-
- $header = array(t("timestamp"), t("post"), t("user"), t("hostname"), t("referrer"), array("data" => t("operations"), "colspan" => "3"));
-
- while ($log = db_fetch_object($result)) {
- if (!$node = node_load(array("nid" => $log->nid))) {
- $node->nid = 0;
- }
- $user = user_load(array("uid" => $log->uid));
-
- if ($log->url) {
- $url = "<a href=\"$log->url\" title=\"$log->url\">". (strlen($log->url) > 28 ? substr($log->url, 0, 28) . '...' : $log->url) ."</a>";
- }
- else {
- $url = message_na();
- }
-
- $rows[] = array(array("data" => format_date($log->timestamp, "small"), "nowrap" => "nowrap"), ($node->nid ? l($node->title, "node/view/$node->nid") : message_na()), format_name($user), $log->hostname ? $log->hostname : message_na(), $url, ($log->nid ? l("track node", "admin/statistics/log/node/$log->nid") : ""), ($user->uid ? l("track user", "admin/statistics/log/user/$user->uid") : ""), ($log->hostname ? l("track host", "admin/statistics/log/host/$log->hostname") : ""));
- }
-
- if ($pager = pager_display(NULL, 50, 0, "admin")) {
- $rows[] = array(array("data" => $pager, "colspan" => 8));
- }
-
- return table($header, $rows);
-}
-
-
-function statistics_recent_refer() {
-
- $view = arg(3);
-
- if ($view == "all") {
- $query = "SELECT url,timestamp FROM accesslog WHERE url <> '' ORDER BY timestamp DESC";
- }
- elseif ($view == "internal") {
- $query = "SELECT url,timestamp FROM accesslog WHERE url LIKE '%". check_query($_SERVER["HTTP_HOST"]) ."%' ORDER BY timestamp DESC";
- $describe = "internal ";
- }
- else {
- $query = "SELECT url,timestamp FROM accesslog WHERE url NOT LIKE '%". check_query($_SERVER["HTTP_HOST"]) ."%' AND url <> '' ORDER BY timestamp DESC";
- $describe = "external ";
- }
-
- $result = db_query_range($query, 0, 25);
- $output = "<h3>". t("Most recent $describe referrers") ."</h3>";
-
- $header = array(t("URL"), t("date"));
- while ($referrer = db_fetch_array($result)) {
- $rows[] = array("<a href=\"". $referrer["url"] ."\">". substr($referrer["url"], 0, 100) ."</a>", format_date($referrer["timestamp"], "small"));
- }
-
- $output .= table($header, $rows);
-
- return $output;
-}
-
-
-function statistics_top_refer() {
-
- $view = arg(3);
-
- if ($view == "all") {
- $query = "SELECT url, COUNT(url) AS count FROM accesslog WHERE url <> '' GROUP BY url ORDER BY count DESC";
- }
- elseif ($view == "internal") {
- $query = "SELECT url, COUNT(url) AS count FROM accesslog WHERE url LIKE '%". check_query($_SERVER["HTTP_HOST"]) ."%' GROUP BY url ORDER BY count DESC";
- $describe = "internal ";
- }
- else {
- /* default to external */
- $query = "SELECT url, COUNT(url) AS count FROM accesslog WHERE url NOT LIKE '%". check_query($_SERVER["HTTP_HOST"]) ."%' AND url <> '' GROUP BY url ORDER BY count DESC";
- $describe = "external ";
- }
-
- $output = "<h3>". t("Top $describe referrers of the past %interval", array("%interval" => format_interval(variable_get("statistics_flush_accesslog_timer", 259200)))) ."</h3>";
-
- $result = db_query($query);
-
- $header = array(t("URL"), t("count"));
- while ($referrer = db_fetch_array($result)) {
- $rows[] = array("<a href=\"". $referrer["url"] ."\">". substr($referrer["url"], 0, 100) ."</a>", $referrer["count"]);
- }
-
- $output .= table($header, $rows);
-
- return $output;
-
-}
-
-
-function statistics_admin_displaycounts() {
-
- $output = "<h3>". t("Today's top nodes") ."</h3>\n";
- $output .= statistics_admin_count_table("daycount", 15);
-
- $output .= "<br />";
-
- $output .= "<h3>". t("All time top nodes") ."</h3>\n";
- $output .= statistics_admin_count_table("totalcount", 15);
-
- $output .= "<br />";
-
- $output .= "<h3>". t("Last nodes viewed") ."</h3>\n";
- $output .= statistics_admin_count_table("timestamp", 15);
-
- return $output;
-}
-
-
-function statistics_admin_displaylog() {
-
- $type = arg(3);
- $value = arg(4);
-
- switch ($type) {
- case "user":
- $user = user_load(array("uid" => $value));
- $output = "<h3>". t("Recent access logs for '%name'", array("%name" => $user->name)) ."</h3>\n";
- $output .= statistics_admin_accesslog_table(1, $user->uid);
- break;
- case "node":
- $node = node_load(array("nid" => $value));
- $output = "<h3>". t("Recent access logs for '%title'", array("%title" => $node->title)) ."</h3>\n";
- $output .= statistics_admin_accesslog_table(2, $value);
- break;
- case "host":
- $output = "<h3>". t("Recent access logs for '%hostname'", array("%hostname" => $value)) ."</h3>\n";
- $output .= statistics_admin_accesslog_table(3, $value);
- break;
- default:
- $output = "<h3>". t("Recent access logs") ."</h3>\n";
- $output .= statistics_admin_accesslog_table(0, 0);
- }
-
- return $output;
-}
-
-
-/* Displays the block configuration administration form */
-function statistics_config_topnodes_block($edit) {
-
- $form = form_textfield(t("Block name"), "statistics_block_top_title", $edit["statistics_block_top_title"], 20, 40, t("This module generates a block with top nodes. You may assign a name for this block."));
-
- $form .= "<hr />";
-
- $form .= form_textfield(t("Today's top nodes title"), "statistics_block_top_day_head", $edit["statistics_block_top_day_head"], 20, 40, t("Specify a name for the \"day's top\" section of the block generated by this module. HTML tags permitted."));
- $form .= form_select(t("Number of day's top views to display"), "statistics_block_top_day_num", $edit["statistics_block_top_day_num"], array("0" => t("Disabled"), "1" => "1", "2" => "2", "3" => "3", "4" => "4", "5" => "5", "6" => "6", "7" => "7", "8" => "8", "9" => "9", "10" => "10", "15" => "15", "20" => "20", "25" => "25", "30" => "30", "40" => "40"), t("Set how many \"today's top\" nodes to display on the block generated by this module."));
-
- $form .= "<hr />";
-
- $form .= form_textfield(t("All time top nodes title"), "statistics_block_top_all_head", $edit["statistics_block_top_all_head"], 20, 40, t("Specify a name for the \"all time top\" section of the block generated by this module. HTML tags permitted."));
- $form .= form_select(t("Number of all time views to display"), "statistics_block_top_all_num", $edit["statistics_block_top_all_num"], array("0" => t("Disabled"), "1" => "1", "2" => "2", "3" => "3", "4" => "4", "5" => "5", "6" => "6", "7" => "7", "8" => "8", "9" => "9", "10" => "10", "15" => "15", "20" => "20", "25" => "25", "30" => "30", "40" => "40"), t("Set how many \"all time top\" nodes to display on the block generated by this module."));
-
- $form .= "<hr />";
-
- $form .= form_textfield(t("Most recent views heading"), "statistics_block_top_last_head", $edit["statistics_block_top_last_head"], 20, 40, t("Specify a name for the \"last views\" section of the block generated by this module. HTML tags permitted."));
- $form .= form_select(t("Number of most recent views to display"), "statistics_block_top_last_num", $edit["statistics_block_top_last_num"], array("0" => t("Disabled"), "1" => "1", "2" => "2", "3" => "3", "4" => "4", "5" => "5", "6" => "6", "7" => "7", "8" => "8", "9" => "9", "10" => "10", "15" => "15", "20" => "20", "25" => "25", "30" => "30", "40" => "40"), t("Set how many \"last viewed\" nodes to display on the block generated by this module."));
-
- $form .= "<hr />";
-
- $form .= form_submit("Submit \"top nodes\" block changes");
-
- return form($form);
-}
-
-
-/* Displays the block configuration administration form */
-function statistics_config_online_block($edit) {
-
- $form = form_textfield(t("Block name"), "statistics_block_online_title", $edit["statistics_block_online_title"], 20, 40, t("This module generates a block displaying how many users/guests are online. You may assign a name for this block."));
- $form .= form_textfield(t("Sub-block name"), "statistics_block_online_subtitle", $edit["statistics_block_online_subtitle"], 20, 40, t("This module generates a sub-block listing the names of currently online users. You may assign a name for this block."));
-
- $period = array(30 => format_interval(30), 60 => format_interval(60), 120 => format_interval(120), 180 => format_interval(180), 300 => format_interval(300), 600 => format_interval(600), 900 => format_interval(900), 1800 => format_interval(1800), 2700 => format_interval(2700), 3600 => format_interval(3600), 5400 => format_interval(5400), 7200 => format_interval(7200), 10800 => format_interval(10800), 21600 => format_interval(21600), 43200 => format_interval(43200), 86400 => format_interval(86400));
- $form .= form_select(t("Activity threshold"), "statistics_block_online_time", $edit["statistics_block_online_time"], $period, "How long ago a user (or guest) must have been active to be considered online.");
- $form .= form_select(t("Maximum characters of user's name to display"), "statistics_block_online_max_len", $edit["statistics_block_online_max_len"], array("1" => "1", "5" => "5", "10" => "10", "15" => "15", "20" => "20", "25" => "25", "30" => "30", "35" => "35", "40" => "40", "45" => "45", "50" => "50", "55" => "55", "60" => "60"), t("What is the maximum characters of a user's name to to display in the sub-block."));
- $form .= form_select(t("How many online users to list"), "statistics_block_online_max_cnt", $edit["statistics_block_online_max_cnt"], array("0" => "0", "1" => "1", "2" => "2", "3" => "3", "4" => "4", "5" => "5", "6" => "6", "7" => "7", "8" => "8", "9" => "9", "10" => "10", "15" => "15", "20" => "20", "50" => "50", "100" => "100"), t("How many online user's names to display in the sub-block."));
-
- $form .= form_submit("Submit \"who's online\" block changes");
-
- return form($form);
-}
-
-
-/* Displays the user page configuration administration form */
-function statistics_admin_userpage_config($edit) {
-
- $form = form_textfield(t("Name for link to user page"), "statistics_userpage_link", $edit["statistics_userpage_link"], 20, 40, t("This node generates a user page with top nodes. If you wish a link added automatically, specify a name."));
- $form .= "<hr />";
-
- $form .= form_textfield(t("Today's top nodes title"), "statistics_userpage_day_head", $edit["statistics_userpage_day_head"], 20, 40, t("Specify a name for the \"day's top\" section of the user page generated by this module."));
- $form .= form_select(t("Number of nodes to display for \"day's top\""), "statistics_userpage_day_cnt", $edit["statistics_userpage_day_cnt"], array("0" => t("Disabled"), "1" => "1", "2" => "2", "3" => "3", "4" => "4", "5" => "5", "6" => "6", "7" => "7", "8" => "8", "9" => "9", "10" => "10", "15" => "15", "20" => "20", "25" => "25"), t("Set how many \"day's top\" nodes to display on the user page generated by this module."));
- $form .= "<hr />";
-
- $form .= form_textfield(t("All time top nodes title"), "statistics_userpage_all_head", $edit["statistics_userpage_all_head"], 20, 40, "Specify a name for the \"all time top\" section of the user page generated by this module.");
- $form .= form_select(t("Number of nodes to display for \"all time\""), "statistics_userpage_all_cnt", $edit["statistics_userpage_all_cnt"], array("0" => t("Disabled"), "1" => "1", "2" => "2", "3" => "3", "4" => "4", "5" => "5", "6" => "6", "7" => "7", "8" => "8", "9" => "9", "10" => "10", "15" => "15", "20" => "20", "25" => "25"), t("Set how many \"all time top\" nodes to display on the user page generated by this module."));
- $form .= "<hr />";
-
- $form .= form_textfield(t("Last viewed nodes title"), "statistics_userpage_last_head", $edit["statistics_userpage_last_head"], 20, 40, "Specify a name for the \"last viewed\" section of the user page generated by this module.");
- $form .= form_select(t("Number of nodes to display for \"last views\""), "statistics_userpage_last_cnt", $edit["statistics_userpage_last_cnt"], array("0" => t("Disabled"), "1" => "1", "2" => "2", "3" => "3", "4" => "4", "5" => "5", "6" => "6", "7" => "7", "8" => "8", "9" => "9", "10" => "10", "15" => "15", "20" => "20", "25" => "25"), t("Set how many \"last viewed\" nodes to display on the user page generated by this module."));
- $form .= "<hr />";
-
- $form .= form_submit("Submit \"top nodes\" page changes");
-
- return form($form);
-}
-
-
-/* Adds configure option to the main configure site admin page */
-function statistics_settings() {
- /* access log options */
- $output = form_select(t("Enable access log"), "statistics_enable_access_log", variable_get("statistics_enable_access_log", 0), array("1" => t("Enabled"), "0" => t("Disabled")), t("Log each page access. Required for referrer statistics."));
- $period = array(3600 => format_interval(3600), 10800 => format_interval(10800), 21600 => format_interval(21600), 32400 => format_interval(32400), 43200 => format_interval(43200), 86400 => format_interval(86400), 172800 => format_interval(172800), 259200 => format_interval(259200), 604800 => format_interval(604800), 1209600 => format_interval(1209600), 2419200 => format_interval(2419200), 4838400 => format_interval(4838400), 9676800 => format_interval(9676800));
- $output .= form_select(t("Discard access logs older than"), "statistics_flush_accesslog_timer", variable_get("statistics_flush_accesslog_timer", 259200), $period, t("Older access log entries (including referrer statistics) will be automatically discarded. Requires crontab."));
-
- $output .= form_select(t("Enable node view counters"), "statistics_enable_node_counter", variable_get("statistics_enable_node_counter", 0), array("1" => t("Enabled"), "0" => t("Disabled")), t("Increment node view counter each time a node is viewed."));
- $output .= form_select(t("Display node view counters"), "statistics_display_counter", variable_get("statistics_display_counter", ""), array("1" => t("Enabled"), "0" => t("Disabled")), t("Display how many times each node has been viewed. User must have the 'access statistics' permissions."));
-
- return $output;
-}
-
-
-/* Saves the values entered in the "blockconfig" administration form */
-function statistics_save_topnodes_block($edit) {
- variable_set("statistics_block_top_title", $edit["statistics_block_top_title"]);
- variable_set("statistics_block_top_day_head", $edit["statistics_block_top_day_head"]);
- variable_set("statistics_block_top_day_num", $edit["statistics_block_top_day_num"]);
- variable_set("statistics_block_top_all_head", $edit["statistics_block_top_all_head"]);
- variable_set("statistics_block_top_all_num", $edit["statistics_block_top_all_num"]);
- variable_set("statistics_block_top_last_head", $edit["statistics_block_top_last_head"]);
- variable_set("statistics_block_top_last_num", $edit["statistics_block_top_last_num"]);
-}
-
-
-/* Saves the values entered in the "blockconfig" administration form */
-function statistics_save_online_block($edit) {
- variable_set("statistics_block_online_title", $edit["statistics_block_online_title"]);
- variable_set("statistics_block_online_subtitle", $edit["statistics_block_online_subtitle"]);
- variable_set("statistics_block_online_time", $edit["statistics_block_online_time"]);
- variable_set("statistics_block_online_max_len", $edit["statistics_block_online_max_len"]);
- variable_set("statistics_block_online_max_cnt", $edit["statistics_block_online_max_cnt"]);
-}
-
-
-/* Saves the values entered in the "userpage" administration form */
-function statistics_save_userconfig($edit) {
- variable_set("statistics_userpage_link", $edit["statistics_userpage_link"]);
- variable_set("statistics_userpage_day_head", $edit["statistics_userpage_day_head"]);
- variable_set("statistics_userpage_day_cnt", $edit["statistics_userpage_day_cnt"]);
- variable_set("statistics_userpage_all_head", $edit["statistics_userpage_all_head"]);
- variable_set("statistics_userpage_all_cnt", $edit["statistics_userpage_all_cnt"]);
- variable_set("statistics_userpage_last_head", $edit["statistics_userpage_last_head"]);
- variable_set("statistics_userpage_last_cnt", $edit["statistics_userpage_last_cnt"]);
-}
-
-
-/* Saves the values entered in the "config statistics" administration form */
-function statistics_save_statistics($edit) {
- variable_set("statistics_display_counter", $edit["statistics_display_counter"]);
-}
-
-
-/* cron hook, performs automatic functions */
-function statistics_cron() {
- $statistics_timestamp = variable_get("statistics_day_timestamp", "");
-
- if ((time() - $statistics_timestamp) >= 86400) {
- /* reset day counts */
- db_query("UPDATE statistics SET daycount='0'");
- variable_set("statistics_day_timestamp", time());
- }
-
- /* clean expired access logs */
- db_query("DELETE FROM accesslog WHERE ". time() ." - timestamp > ". variable_get("statistics_flush_accesslog_timer", 259200));
-
- $throttle = variable_get("statistics_throttle_level", 0);
- /* check if throttle is currently on and if it's time to drop level */
- if (($throttle) && ((time() - variable_get("statistics_throttle_cron_timer", 10800)) > variable_get("statistics_throttle_cron_timestamp", 0))) {
- /* If throttle is on, back off one notch to test server load */
- variable_set("statistics_throttle_level", $throttle - 1);
- variable_set("statistics_throttle_cron_timestamp", time());
- watchdog("warning", t("cron: decreasing throttle to level '%level' to test server load.", array("%level" => ($throttle - 1))));
- }
-}
-
-
-/* Displays the "Top nodes" block */
-function statistics_display_topnodes_block() {
-
- $content = array();
-
- $daytop = variable_get("statistics_block_top_day_num", "");
- if ($daytop) {
- $content[] = node_title_list(statistics_title_list("daycount", $daytop), variable_get("statistics_block_top_day_head", ""));
- }
-
- $alltimetop = variable_get("statistics_block_top_all_num", "");
- if ($alltimetop) {
- $content[] = node_title_list(statistics_title_list("totalcount", $alltimetop), variable_get("statistics_block_top_all_head", ""));
- }
-
- $lasttop = variable_get("statistics_block_top_last_num", "");
- if ($lasttop) {
- $content[] = node_title_list(statistics_title_list("timestamp", $lasttop), variable_get("statistics_block_top_last_head", ""));
- }
-
- $output = implode($content, "<br />");
-
- return $output;
-}
-
-
-/* This displays the "Who's online" block */
-function statistics_display_online_block() {
- global $id, $recent_activity;
-
- if (user_access("access content")) {
- $throttle = throttle_status();
- $multiplier = variable_get("statistics_throttle_multiplier", 60);
-
- /* don't do any database lookups if on maximum throttle */
- if ($throttle < 5) {
- /* count users with activity in the past defined period */
- $time_period = variable_get("statistics_block_online_time", 2700);
-
- /*
- ** This call gathers all the info we need on users/guests in a single
- ** database call, thus is quite efficient.
- */
- $result = db_query("SELECT COUNT(DISTINCT hostname) AS count, uid, MAX(timestamp) AS max_timestamp FROM accesslog WHERE timestamp >= %d GROUP BY uid ORDER BY max_timestamp DESC", (time() - $time_period));
-
- $users = $guests = 0;
- /* Count number of users & guests currently online based on db query */
- while ($users_online = db_fetch_array($result)) {
- if ($users_online["uid"]) {
- /* Has uid, so is a registered user */
- $user_list[$users] = $users_online[uid];
- $users++;
- }
- else {
- /*
- ** There's only going to be one return with a uid of 0, and that's
- ** the guest(s). Hence, the count of this field is the total number
- ** of guests currently online.
- */
- $guests = $users_online["count"];
- }
- }
-
- /* format the output with proper grammar */
- $output .= t("There %verb currently %members and %visitors online.", array("%verb" => (($users == 1) && ($guests == 1) ? "is" : "are"), "%members" => format_plural($users, "1 user", "%count users"), "%visitors" => format_plural($guests, "1 guest", "%count guests")));
-
- if (user_access("access userlist") && $users) {
- /* Display a list of currently online users */
- $max_users = variable_get("statistics_block_online_max_cnt", 10);
- $max_name_len = variable_get("statistics_block_online_max_len", 15);
- $uid = reset($user_list);
- while (($uid) && ($max_users)) {
- $user = user_load(array("uid" => $uid));
- /* When displaying name, be sure it's not more than defined max length */
- $items[] = l((strlen($user->name) > $max_name_len ? substr($user->name, 0, $max_name_len) ."..." : $user->name), "user/view/$user->uid");
- $uid = next($user_list);
- /*
- ** When $max_users reaches zero, we break out even if there are
- ** more online (as defined by the admin)
- */
- $max_users--;
- }
-
- $output .= "<br /><br />";
- $output .= theme("theme_item_list", $items, variable_get("statistics_block_online_subtitle", "Online users:"));
- }
- }
- else {
- /* default message when fully throttled */
- $output = t("This site is currently sustaining more than %total page views a minute.", array("%total" => ($throttle * $multiplier)));
- }
- return $output;
- }
-}
-
-
-/* Display linked title based on field name */
-function statistics_title_list($dbfield, $dbrows) {
- /* valid dbfields: totalcount, daycount, timestamp */
- return db_query_range("SELECT s.nid, n.title, u.uid, u.name FROM statistics s LEFT JOIN node n ON s.nid = n.nid LEFT JOIN users u ON n.uid = u.uid WHERE %s <> '0' AND n.status = 1 ORDER BY %s DESC", "s.". $dbfield, "s.". $dbfield, 0, $dbrows);
-}
-
-
-/* Function to retreive current page counter value. */
-function statistics_get($nid) {
-
- if ($nid > 0) {
- /* retrieves an array with both totalcount and daycount */
- $statistics = db_fetch_array(db_query("SELECT totalcount, daycount, timestamp FROM statistics WHERE nid = %d", $nid));
- }
-
- return $statistics;
-
-}
-
-
-/* Block hook */
-function statistics_block($op = "list", $delta = 0) {
- if ($op == "list") {
- if (variable_get("statistics_enable_node_counter", 0)) {
- $blocks[0]["info"] = t("Top nodes");
- }
- if (variable_get("statistics_enable_access_log", 0)) {
- $blocks[1]["info"] = t("Who's online");
- }
- return $blocks;
- }
- else if (user_access("access content")) {
- switch($delta) {
- case 0:
- $block["subject"] = variable_get("statistics_block_top_title", t("Popular content"));
- $block["content"] = statistics_display_topnodes_block();
- break;
-
- case 1:
- $block["subject"] = variable_get("statistics_block_online_title", t("Who's online"));
- $block["content"] = statistics_display_online_block();
- break;
- }
-
- return $block;
- }
-}
-
-
-function statistics_page() {
-
-
- if (user_access("access content")) {
- theme("header");
- statistics_page_user();
- theme("footer");
- }
- else {
- theme("header");
- theme("box", t("Access denied"), message_access());
- theme("footer");
- }
-}
-
-
-/* Generates the statistics user page */
-function statistics_page_user($uid = 0, $date = 0, $all = 0) {
-
- if (!$date) {
- $date = time();
- }
-
- if ($displaycount = variable_get("statistics_userpage_day_cnt", 10)) {
- $output = "<table border=\"0\" cellpadding=\"4\" cellspacing=\"4\" style=\"width: 100%;\">";
- $output .= statistics_summary("daycount", $displaycount);
- $output .= "</table>";
-
- theme("box", t(variable_get("statistics_userpage_day_head", "")), $output, "main");
- }
-
-
- if ($displaycount = variable_get("statistics_userpage_all_cnt", "10")) {
- $output = "<table border=\"0\" cellpadding=\"4\" cellspacing=\"4\" style=\"width: 100%;\">";
- $output .= statistics_summary("totalcount", $displaycount);
- $output .= "</table>";
-
- theme("box", t(variable_get("statistics_userpage_all_head", "")), $output, "main");
- }
-
- if ($displaycount = variable_get("statistics_userpage_last_cnt", "10")) {
- $output = "<table border=\"0\" cellpadding=\"4\" cellspacing=\"4\" style=\"width: 100%;\">";
- $output .= statistics_summary("timestamp", $displaycount);
- $output .= "</table>";
-
- theme("box", t(variable_get("statistics_userpage_last_head", "")), $output, "main");
- }
-}
-
-
-function statistics_summary($dbfield, $dbrows) {
- /* valid dbfields: totalcount, daycount, timestamp */
-
- $output = "";
- $result = db_query_range("SELECT n.nid, n.title FROM statistics s LEFT JOIN node n ON s.nid = n.nid ORDER BY %s DESC", $dbfield, 0, $dbrows);
- while ($nid = db_fetch_array($result)) {
- $content = node_load(array("nid" => $nid["nid"]));
- $links = link_node($content, 1);
-
- $output .= "<tr><td><b>". l($nid["title"], "node/view/". $nid["nid"], array("title" => t("View this posting."))) ."</b></td><td style=\"text-align: right;\"><small>". t("Submitted by %a on %b", array("%a" => format_name($content), "%b" => format_date($content->created, "large"))) ."</small></td></tr>";
- $output .= "<tr><td colspan=\"2\"><div style=\"margin-left: 20px;\">". check_output($content->teaser) ."</div></td></tr>";
- $output .= "<tr><td style=\"text-align: right;\" colspan=\"2\">[ ". theme("links", $links) ." ]<br /><br /></td></tr>";
- }
-
- return $output;
-}
-
-function statistics_nodeapi(&$node, $op, $arg = 0) {
- switch ($op) {
- case "delete":
- // clean up statistics table when node is deleted
- db_query("DELETE FROM statistics WHERE nid = %d", $node->nid);
- }
-}
-
-/* internal throttle function - do not call from other modules */
-function throttle_update($recent_activity) {
- $throttle = throttle_status();
- $multiplier = variable_get("statistics_throttle_multiplier", 60);
-
- for ($i = 0; $i <= 5; $i++) {
- if (($i * $multiplier) <= $recent_activity) {
- $throttle_new = $i;
- }
- }
-
- if ($throttle_new != $throttle) {
- /*
- ** reduce throttle if new throttle would be 3+ less than current throttle,
- ** (all other throttle reduction done by _cron hook), increase throttle if
- ** new throttle would be greater than current throttle.
- */
- if (($throttle_new < ($throttle - 2)) || ($throttle_new > $throttle)) {
- /* update throttle level */
- variable_set("statistics_throttle_level", $throttle_new);
- /*
- ** update the global timestamp, preventing cron.php from jumping in
- ** too quickly, allowing for user defined period to first pass.
- */
- variable_set("statistics_throttle_cron_timestamp", time());
- /* log the change */
- if ($throttle_new < $throttle) {
- watchdog("message", "message: '". $recent_activity ."' hits in past minute; throttle decreased to level ". $throttle_new);
- }
- else {
- watchdog("warning", "warning: '". $recent_activity ."' hits in past minute; throttle increased to level ". $throttle_new);
- }
- }
- }
-}
-
-/***********************
- * Auto-throttle API *
- ***********************/
-
-/* external throttle functions - call this from other modules, themes, etc */
-function throttle_status() {
- static $throttle;
-
- $throttle = variable_get("statistics_throttle_level", 0);
-
- return $throttle;
-}
-
-?>
diff --git a/modules/story/story.module b/modules/story/story.module
deleted file mode 100644
index 8434646..0000000
--- a/modules/story/story.module
+++ /dev/null
@@ -1,84 +0,0 @@
-<?php
-// $Id$
-
-function story_help() {
- $output .= "<p>The story module lets your users submit articles for consideration by the rest of the community, who can vote on them if moderation is enabled. Stories usually follow a publishing flow of <b>submit -&gt; moderate -&gt; post to the main page -&gt; comments</b>. Administrators are able to shortcut this flow as desired.</p>";
- $output .= "In ". l("site configuration &gt;&gt; modules &gt;&gt; story", "admin/system/modules/story") ." you can set up an introductory text for story authors, and a floor on the number of words which may be included in a story. This is designed to help discourage the submission of trivially short stories.";
- return $output;
-}
-
-function story_system($field){
- $system["description"] = t("Enables users to submit stories, articles or similar content.");
- $system["admin_help"] = t("Stories are like newspaper articles. They tend to follow a publishing flow of <b>submit -&gt; moderate -&gt; post to the main page -&gt; comments</b>. Below you may fix a minimum word count for stories and also write some submission or content guidelines for users wanting to post a story.");
- return $system[$field];
-}
-
-function story_settings() {
- $output .= form_textarea("Explanation or submission guidelines", "story_help", variable_get("story_help", ""), 70, 5, "This text will be displayed at the top of the story submission form. It is useful for helping or instructing your users.");
- $output .= form_select(t("Minimum number of words"), "minimum_story_size", variable_get("minimum_story_size", 0), array(0 => "0 words", 10 => "10 words", 25 => "25 words", 50 => "50 words", 75 => "75 words", 100 => "100 words", 125 => "125 words", 150 => "150 words", 175 => "175 words", 200 => "200 words"), t("The minimum number of words a story must be to be considered valid. This can be useful to rule out submissions that do not meet the site's standards, such as short test posts."));
-
- return $output;
-}
-
-function story_node($field) {
- $info["name"] = t("story");
- $info["description"] = t("A story is a post that is submitted to the attention of other users and is queued in the submission queue. Users and moderators vote on the posts they like or dislike, promoting or demoting them. When a post gets above a certain threshold it automatically gets promoted to the front page.");
- return $info[$field];
-}
-
-function story_perm() {
- return array("create stories");
-}
-
-function story_access($op, $node) {
- if ($op == "view") {
- return $node->status;
- }
-
- if ($op == "create") {
- return user_access("create stories");
- }
-}
-
-function story_link($type) {
- $links = array();
-
- if ($type == "menu.create" && user_access("create stories")) {
- $links[] = l(t("create story"), "node/add/story", array("title" => t("Add a new story.")));
- }
-
- return $links;
-}
-
-function story_form(&$node, &$help, &$error) {
-
- if (isset($node->body)) {
-
- /*
- ** Validate the size of the story:
- */
-
- if (count(explode(" ", $node->body)) < variable_get("minimum_story_size", 0)) {
- $error["body"] = "<div class=\"error\">". t("The body of your story is too short.") ."</div>";
- }
-
- }
- else {
-
- /*
- ** Carry out some explanation or submission guidelines:
- */
-
- $help = variable_get("story_help", "");
-
- }
-
- if (function_exists("taxonomy_node_form")) {
- $output .= implode("", taxonomy_node_form("story", $node));
- }
- $output .= form_textarea(t("Body"), "body", $node->body, 60, 15, $error["body"] ? $error["body"] : form_allowed_tags_text());
-
- return $output;
-}
-
-?>
diff --git a/modules/system/system.module b/modules/system/system.module
deleted file mode 100644
index a4c0dc9..0000000
--- a/modules/system/system.module
+++ /dev/null
@@ -1,334 +0,0 @@
-<?php
-// $Id$
-
-function system_help() {
- $output .= "<p>Drupal comes with system-wide defaults but the setting-module provides control over many Drupal preferences, behaviours including visual and operational settings.</p>";
- $output .= "<h3><a id=\"cron\">Cron</a></h3>". system_help_cron();
- $output .= "<h3><a id=\"cache\">Cache</a></h3>". system_help_cache();
- return t("$output");
-}
-
-function system_system($field) {
- $system["description"] = t("Configuration system that lets administrators modify the workings of the site.");
- return $system[$field];
-}
-
-function system_help_cache() {
- $output .= "<p>Drupal has a caching mechanism which stores dynamically generated web pages in a database. By caching a web page, Drupal does not have to create the page each time someone wants to view it, instead it takes only one SQL query to display it, reducing response time and the server's load. Only pages requested by \"anonymous\" users are cached.</p>";
- return $output;
-}
-
-function system_help_cron() {
- global $base_url;
-
- $output .= "<p>Some modules require regularly scheduled actions, such as cleaning up logfiles. Cron, which stands for chronograph, is a periodic command scheduler executing commands at intervals specified in seconds. It can be used to control the execution of daily, weekly and monthly jobs (or anything with a period measured in seconds). Automating tasks is one of the best ways to keep a system running smoothly, and if most of your administration does not require your direct involvement, cron is an ideal solution.</p>";
- $output .= "<p>Whenever <a href=\"$base_url/cron.php\">$base_url/cron.php</a> is accessed, cron will run: it calls the _cron hook in each module allowing the module to run tasks if they have not been executed in the last <i>n</i> seconds, where n is the period of that task. When all the tasks are finished, cron is done.</p>";
- $output .= "<p>The recommended way to set up your cron system is to set up a Unix/Linux crontab entry (see \"man crontab\") that frequently visits <a href=\"$base_url/cron.php\">$base_url/cron.php</a>. Note that cron does not guarantee the commands will be executed at the specified interval. However, Drupal will try its best to run the tasks as close to the specified intervals as possible. The more you visit cron.php, the more accurate cron will be.</p>";
- $output .= "<p>If your hosting company does not allow you to set up crontab entries, you can always ask someone else to set up an entry for you. After all, virtually any Unix/Linux machine with access to the internet can set up a crontab entry to frequently visit <a href=\"$base_url/cron.php\">$base_url/cron.php</a>.</p>";
- $output .= "<p>For the Unix/Linux crontab itself, use a browser like <i>lynx</i> or <i>wget</i> but make sure the process terminates: either use <code>/usr/bin/lynx -source $base_url/cron.php</code> or <code>/usr/bin/wget -o /dev/null -O /dev/null $base_url/cron.php</code>. Take a look at the example scripts in the <code>scripts</code>-directory. Make sure to adjust them to fit your needs. A good crontab line to run the cron script once every hour would be: <pre> 00 * * * * /home/www/drupal/scripts/cron-lynx.sh</pre>Note that it is essential to access <code>cron.php</code> using a browser on the web site's domain; do not run it using command line PHP and avoid using <code>localhost</code> or <code>127.0.0.1</code> or some of the environment varibles will not be set correctly and features may not work as expected.</p>";
-
- return $output;
-}
-
-function system_perm() {
- return array("administer site configuration", "access administration pages", "bypass input data check", "create php content");
-}
-
-function system_link($type) {
- if ($type == "admin" && user_access("administer site configuration")) {
- $help["general"] = t("General configuration options for your site. Set up the name of the site, e-mail address used in mail-outs, clean URL options, caching, etc.");
- $help["themes"] = t("Select which themes are available to your users and specify the default theme.");
- $help["modules"] = t("Modules are plugins for Drupal that extend its core functionality. Here you can select which modules are enabled. On the left hand side click on the name of the module for their individual configurations.");
- $help["filters"] = t("Filters fit between the raw text in a node and the HTML output. They allow you to replace text selectively. Uses include automatic conversion of emoticons into graphics and filtering HTML content from users' submissions.");
-
- menu("admin/system", "site configuration", "system_admin", $help["general"], 3);
- menu("admin/system/themes", "themes", "system_admin", $help["themes"], 2);
-
- foreach (theme_list(1) as $theme) {
- // NOTE: refresh the list because some themes might have been enabled/disabled.
- include_once "$theme->filename";
- $function = $theme->name ."_settings";
- if (function_exists($function)) {
- menu("admin/system/themes/$theme->name", $theme->name, "system_admin", $theme->description);
- }
- }
-
- menu("admin/system/modules", "modules", "system_admin", $help["modules"], 3);
- foreach (module_list(1) as $name) {
- // NOTE: refresh the list because some modules might have been enabled/disabled.
- if (module_hook($name, "settings")) {
- menu("admin/system/modules/$name", $name, "system_admin", module_invoke($name, "system", "admin_help"));
- }
- }
- menu("admin/system/filters", "filters", "system_admin", $help["filters"], 4);
- menu("admin/system/help", "help", "system_help", NULL, 9);
- }
-}
-
-function system_view_general() {
- global $conf, $cmodes, $corder;
-
- // general settings:
- $output .= "<h3>". t("General settings") ."</h3>\n";
- $output .= form_textfield(t("Name"), "site_name", variable_get("site_name", "drupal"), 70, 70, t("The name of this web site."));
- $output .= form_textfield(t("E-mail address"), "site_mail", variable_get("site_mail", ini_get("sendmail_from")), 70, 128, t("A valid e-mail address for this website, used by the auto-mailer during registration, new password requests, notifications, etc."));
- $output .= form_textfield(t("Slogan"), "site_slogan", variable_get("site_slogan", ""), 70, 128, t("The slogan of this website. Some themes display a slogan when available."));
- $output .= form_textarea(t("Mission"), "site_mission", variable_get("site_mission", ""), 70, 5, t("Your site's mission statement or focus."));
- $output .= form_textarea(t("Footer message"), "site_footer", variable_get("site_footer", ""), 70, 5, t("This text will be displayed at the bottom of each page. Useful for adding a copyright notice to your pages."));
- $output .= form_textfield(t("Anonymous user"), "anonymous", variable_get("anonymous", "Anonymous"), 70, 70, t("The name used to indicate anonymous users."));
- $output .= form_textfield(t("Default front page"), "site_frontpage", variable_get("site_frontpage", "node"), 70, 70, t("The home page displays content from this relative URL. If you are not using clean URLs, specify the part after '?q='. If unsure, specify 'node'."));
- $output .= form_select(t("Clean URLs"), "clean_url", variable_get("clean_url", 0), array(t("Disabled"), t("Enabled")), t("Enable or disable clean URLs. If enabled, you'll need <code>ModRewrite</code> support. See also the <code>.htaccess</code> file in Drupal's top-level directory."));
- $output .= "<hr />\n";
-
- // cron:
- $output .= "<h3>". t("Cron settings") ."</h3>\n";
- $output .= form_select(t("Cron support"), "cron", variable_get("cron", 1), array(t("Disabled"), t("Enabled")), t("Enable or disable cron support. Enable this setting if you have set up a cron job. Check the ". l("cron documentation", "admin/system/help#cron") ." for information on setting up a cron job."));
- $output .= "<hr />\n";
-
- // caching:
- $output .= "<h3>". t("Cache settings") ."</h3>\n";
- $output .= form_select(t("Cache support"), "cache", variable_get("cache", 0), array(t("Disabled"), t("Enabled")), t("Enable or disable the caching of rendered pages. When caching is enabled, Drupal will flush the cache when required to make sure updates take effect immediately. Check the ". l("cache documentation", "admin/system/help#cache") ." for information on Drupal's cache system."));
- $output .= "<hr />\n";
-
-
- // submission settings:
- $output .= "<h3>". t("Submission settings") ."</h3>\n";
- $rate = array(-10000 => "Disabled", 1 => "Maximum 1 every second", 5 => "Maximum 1 every 5 seconds", 15 => "Maximum 1 every 15 seconds", 30 => "Maximum 1 every 30 seconds", 60 => "Maximum 1 every minute", 300 => "Maximum 1 every 5 minutes", 900 => "Maximum 1 every 15 minutes", 1800 => "Maximum 1 every 30 minutes", 3600 => "Maximum 1 every hour", 21600 => "Maximum 1 every 6 hours", 43200 => "Maximum 1 every 12 hours");
- $output .= form_select(t("Maximum node rate"), "max_node_rate", variable_get("max_node_rate", 900), $rate, t("The maximum submission rate for nodes. Its purpose is to stop potential abuse or denial of service attacks."));
- $output .= form_select(t("Maximum comment rate"), "max_comment_rate", variable_get("max_comment_rate", 120), $rate, t("The maximum submission rate for comments. Its purpose is to stop potential abuse or denial of service attacks."));
- $output .= "<hr />\n";
-
- // date settings:
- $output .= "<h3>". t("Date format settings") ."</h3>\n";
-
- // date settings: possible date formats
- $dateshort = array("m/d/Y - H:i", "d/m/Y - H:i", "Y/m/d - H:i",
- "m/d/Y - g:ia", "d/m/Y - g:ia", "Y/m/d - g:ia",
- "M j Y - H:i", "j M Y - H:i", "Y M j - H:i",
- "M j Y - g:ia", "j M Y - g:ia", "Y M j - g:ia");
- $datemedium = array("D, m/d/Y - H:i", "D, d/m/Y - H:i", "D, Y/m/d - H:i",
- "F j, Y - H:i", "j F, Y - H:i", "Y, F j - H:i",
- "D, m/d/Y - g:ia", "D, d/m/Y - g:ia", "D, Y/m/d - g:ia",
- "F j, Y - g:ia", "j F, Y - g:ia", "Y, F j - g:ia");
- $datelong = array("l, F j, Y - H:i", "l, j F, Y - H:i", "l, Y, F j - H:i",
- "l, F j, Y - g:ia", "l, j F, Y - g:ia", "l, Y, F j - g:ia");
-
- // date settings: construct choices for user
- foreach ($dateshort as $f) {
- $dateshortchoices[$f] = format_date(time(), "custom", $f);
- }
- foreach ($datemedium as $f) {
- $datemediumchoices[$f] = format_date(time(), "custom", $f);
- }
- foreach ($datelong as $f) {
- $datelongchoices[$f] = format_date(time(), "custom", $f);
- }
-
- $output .= form_select(t("Date format (short)"), "date_format_short", variable_get("date_format_short", $dateshort[0]), $dateshortchoices, t("The short format of date display."));
- $output .= form_select(t("Date format (medium)"), "date_format_medium", variable_get("date_format_medium", $datemedium[0]), $datemediumchoices, t("The medium sized date display."));
- $output .= form_select(t("Date format (long)"), "date_format_long", variable_get("date_format_long", $datelong[0]), $datelongchoices, t("Longer date format used for detailed display."));
-
- return $output;
-}
-
-function system_view_module($name) {
- if (module_hook($name, "settings")) {
- $output .= "<h3><a id=\"$name\">". ucfirst(t("$name")) ." ". t("settings") ."</a></h3>". module_invoke($name, "settings") ."<hr />\n";
- }
- return $output;
-}
-
-function system_view_theme($name) {
- $themes = theme_list();
- $theme = $themes[$name];
- if ($theme) {
- include_once "$theme->filename";
-
- $function = $theme->name ."_settings";
- if (function_exists($function)) {
- $output .= $function();
- }
- }
- else {
- $output = "Invalid theme specified";
- }
- return $output;
-}
-
-function system_view_filters() {
- foreach (module_list() as $name) {
- if (module_hook($name, "conf_filters")) {
- $output .= module_invoke($name, "conf_filters");
- }
- }
- return $output;
-}
-
-function system_save_settings($edit = array()) {
-
- if ($edit["type"]) {
- db_query("UPDATE system SET status = '0' WHERE type = '%s'", $edit["type"]);
- foreach ($edit["status"] as $filename => $status) {
- db_query("UPDATE system SET status = %d WHERE filename = '$filename'", $status);
- }
- if ($edit["type"] == "theme") {
- variable_set("theme_default", $edit["theme_default"]);
- }
- }
- else {
- foreach ($edit as $name => $value) {
- variable_set($name, $value);
- }
- }
- cache_clear_all();
-
- return t("the configuration options have been saved.");
-}
-
-function system_reset_default($edit = array()) {
- foreach ($edit as $name => $value) {
- variable_del($name);
- }
-
- cache_clear_all();
-
- return t("the configuration options have been reset to their default values.");
-}
-
-function system_view($type, $arg = "") {
- $required = array("modules/admin.module", "modules/user.module", "modules/system.module", "modules/watchdog.module");
- $links = array();
- switch ($type) {
- case "filters":
- $form = system_view_filters();
- break;
- case "modules":
- if ($arg) {
- $form = system_view_module($arg);
- }
- else {
- $form = system_listing("module", "modules", $required);
- }
- break;
- case "themes":
- if ($arg) {
- $form = system_view_theme($arg);
- }
- else {
- $form = system_listing("theme", "themes", $required);
- }
- break;
- default:
- $form = system_view_general();
- break;
- }
-
- $form .= form_submit(t("Save configuration"));
- $form .= form_submit(t("Reset to defaults"));
-
- print form($form);
-}
-
-function system_dirscan($dir, $mask, $nomask = array(".", "..", "CVS")) {
- $files = array();
- if (is_dir($dir) && $handle = opendir($dir)) {
- while ($file = readdir($handle)) {
- if (!in_array($file, $nomask)) {
- if (is_dir("$dir/$file")) {
- $files = array_merge($files, system_dirscan("$dir/$file", $mask, $nomask));
- }
- elseif (ereg($mask, $file)) {
- $name = basename($file);
- $files["$dir/$file"]->filename = "$dir/$file";
- $files["$dir/$file"]->name = substr($name, 0, strrpos($name, '.'));
- }
- }
- }
- closedir($handle);
- }
- return $files;
-}
-
-function system_listing($type, $directory, $required = array()) {
- // Make sure we set $type correctly
- $type = $type != 'theme' ? "module" : "theme";
-
- // Find files in the directory.
- $files = system_dirscan($directory, "\.$type$");
-
- // Extract current files from database.
- $result = db_query("SELECT filename, type, status FROM system WHERE type = '%s'", $type);
- while ($file = db_fetch_object($result)) {
- if (is_object($files[$file->filename])) {
- foreach ($file as $key => $value) {
- $files[$file->filename]->$key = $value;
- }
- }
- }
-
- ksort($files);
-
- $header = array(t("name"), t("description"), t("status"));
-
- foreach ($files as $filename => $file) {
- include_once($filename);
- if ($type == "module") {
- $info->name = module_invoke($file->name, "system", "name") ? module_invoke($file->name, "system", "name") : $file->name;
- $info->description = module_invoke($file->name, "system", "description");
- }
- elseif ($type == "theme") {
- $class = "Theme_$file->name";
- if (class_exists($class)) {
- $theme =& new $class;
- $info->name = $theme->system("name") ? $theme->system("name") : $file->name;
- $info->description = $theme->system("description");
- $themes[] = $info->name;
- }
- else {
- unset($files[$filename]);
- }
- }
-
- // Update the contents of the system table:
- db_query("DELETE FROM system WHERE filename = '%s' AND type = '%s'", $filename, $type);
- db_query("INSERT INTO system (name, description, type, filename, status) VALUES ('%s', '%s', '%s', '%s', %d)", $info->name, $info->description, $type, $filename, $file->status);
-
- $rows[] = array($info->name, $info->description, array("data" => (in_array($filename, $required) ? form_hidden("status][$filename", 1) . t("required") : form_checkbox("", "status][$filename", 1, $file->status)), "align" => "center"));
- }
-
- $output = table($header, $rows);
-
- // If we're doing themes, stick the default one here...
- if ($type == "theme") {
- $output .= "<hr />\n";
- foreach ($themes as $theme)
- $options .= "<option value=\"$theme\"". (variable_get("theme_default", 0) == $theme ? " selected=\"selected\"" : "") .">$theme</option>\n";
- $output .= form_item(t("Default theme"), "<select name=\"edit[theme_default]\">$options</select>", t("The default theme as seen by visitors or anonymous users. Make sure a valid theme is selected here (i.e. one that has its box checked above.)"));
- }
- $output .= form_hidden("type", $type);
-
- return $output;
-}
-
-function system_admin() {
-
- $op = $_POST["op"];
- $edit = $_POST["edit"];
-
- if (user_access("administer site configuration")) {
- if ($op == t("Reset to defaults")) {
- print status(system_reset_default($edit));
- }
-
- if ($op == t("Save configuration")) {
- print status(system_save_settings($edit));
- }
-
- print system_view(arg(2), arg(3));
- }
- else {
- print message_access();
- }
-}
-
-?>
diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module
deleted file mode 100644
index 567a8e5..0000000
--- a/modules/taxonomy/taxonomy.module
+++ /dev/null
@@ -1,817 +0,0 @@
-<?php
-// $Id$
-
-function taxonomy_system($field){
- $system["description"] = t("Enables the organization of content into categories.");
- return $system[$field];
-}
-
-function taxonomy_feed($taxonomy) {
- global $id, $type;
-
- if ($type == "voc") {
- //TODO - vocabulary feed.
- }
- else {
- $result = taxonomy_select_nodes($taxonomy, 0);
- $term = taxonomy_get_term($taxonomy->tids[0]);
- $channel["link"] = url("taxonomy/view/$taxonomy->operator/$taxonomy->str_tids");
- $channel["title"] = variable_get("site_name", "drupal") ." - ". $term->name;
- $channel["description"] = $term->description;
- node_feed($result, $channel);
- }
-}
-
-function taxonomy_perm() {
- return array("administer taxonomy");
-}
-
-function taxonomy_link($type, $node = NULL) {
- if ($type == "admin" && user_access("administer taxonomy")) {
- $help["taxonomy"] = t("The taxonomy module allows you to classify content into categories and subcategories; it allows multiple lists of categories for classification (controlled vocabularies) and offers the possibility of creating thesauri (controlled vocabularies that indicate the relationship of terms) and taxonomies (controlled vocabularies where relationships are indicated hierarchically). To delete a term choose \"edit term\". To delete a vocabulary, and all its terms, choose \"edit vocabulary\".");
- $help["vocabulary"] = t("When you create a controlled vocabulary you are creating a set of terms to use for describing content (known as descriptors in indexing lingo). Drupal allows you to describe each node type (blog, story, etc.) using one or many of these terms. For simple implementations, you might create a set of categories without subcategories, similar to Slashdot.org's or Kuro5hin.org's sections. For more complex implementations, you might create a hierarchical list of categories.");
-
- menu("admin/taxonomy", "taxonomy", "taxonomy_admin", $help["taxonomy"], 3);
- menu("admin/taxonomy/add/vocabulary", "create new vocabulary", "taxonomy_admin", $help["vocabulary"]);
- menu("admin/taxonomy/help", "help", "taxonomy_admin", NULL, 9);
- }
- else if ($type == "taxonomy terms" && $node != NULL) {
-
- if ($node->taxonomy) {
- foreach ($node->taxonomy as $tid) {
- $term = taxonomy_get_term($tid);
- $links[] = l($term->name, "taxonomy/page/or/$term->tid", $term->description ? array("title" => $term->description) : array());
- }
- }
- else {
-
- /*
- ** Themes can print taxonomy links with:
- **
- ** if (module_exist("taxonomy")) {
- ** $this->links(taxonomy_link("taxonomy terms", $node));
- ** }
- */
-
- $links = array();
- foreach (taxonomy_node_get_terms($node->nid) as $term) {
- $links[] = l($term->name, "taxonomy/page/or/$term->tid", $term->description ? array("title" => $term->description) : array());
- }
-
- }
- return $links;
- }
-}
-
-/*
-** admin pages (form, save, overview)
-*/
-
-function taxonomy_form_vocabulary($edit = array()) {
- foreach (module_list() as $name) {
- if (module_hook($name, "node")) {
- $nodetypes[$name] = $name;
- }
- }
-
- $form .= form_textfield(t("Vocabulary name"), "name", $edit["name"], 50, 64, t("Required") . ". " . t("The name for this vocabulary. Example: 'Topic'") . ".");
- $form .= form_textarea(t("Description"), "description", $edit["description"], 60, 5, t("Optional") . ". " . t("Description of the vocabulary, can be used by modules."));
- $form .= form_select(t("Types"), "nodes", explode(",", $edit["nodes"]), $nodetypes, t("Required") . ". " . t("A list of node types you want to associate this vocabulary with."), "", 1);
- $form .= form_checkbox(t("Related terms"), "relations", 1, $edit["relations"], t("Optional") . ". " . t("Allows ". l("related terms", "admin/taxonomy/help#relatedterms") ." in this vocabulary."));
- $form .= form_select(t("Hierarchy"), "hierarchy", $edit["hierarchy"], array(t("Disabled"), t("Single"), t("Multiple")), t("Optional") . ". ". t("Allows ". l("a tree-like hierarchy", "admin/taxonomy/help#hierarchy") ." between terms of this vocabulary."), "", 0);
- $form .= form_checkbox(t("Multiple select"), "multiple", 1, $edit["multiple"], t("Optional") . ". " . t("Allows nodes to have more than one term in this vocabulary."));
- $form .= form_checkbox(t("Required"), "required", 1, $edit["required"], t("If enabled every node <b>must</b> have at least one term in this vocabulary"));
- $form .= form_weight(t("Weight"), "weight", $edit["weight"], 10, t("Optional. In listings, the heavier vocabularies will sink and the lighter vocabularies will be positioned nearer the top."));
- $form .= form_submit(t("Submit"));
-
- if ($edit["vid"]) {
- $form .= form_submit(t("Delete"));
- $form .= form_hidden("vid", $edit["vid"]);
- }
-
- return form($form);
-}
-
-function taxonomy_save_vocabulary($edit) {
- if (!$edit["nodes"]) {
- $edit["nodes"] = array();
- }
-
- $data = array("name" => $edit["name"], "nodes" => implode(",", $edit["nodes"]), "description" => $edit["description"], "multiple" => $edit["multiple"], "required" => $edit["required"], "hierarchy" => $edit["hierarchy"], "relations" => $edit["relations"], "weight" => $edit["weight"]);
- if ($edit["vid"] && $edit["name"]) {
- db_query("UPDATE vocabulary SET ". _prepare_update($data) ." WHERE vid = %d", $edit["vid"]);
- module_invoke_all("taxonomy", "update", "vocabulary", $edit);
- $message = t("updated vocabulary '%name'.", array("%name" => $edit["name"]));
- }
- else if ($edit["vid"]) {
- $message = taxonomy_del_vocabulary($edit["vid"]);
- }
- else {
- $data["vid"] = $edit["vid"] = db_next_id("vocabulary_vid");
- db_query("INSERT INTO vocabulary ". _prepare_insert($data, 1) ." VALUES ". _prepare_insert($data, 2));
- module_invoke_all("taxonomy", "insert", "vocabulary", $edit);
- $message = t("created new vocabulary '%name'.", array("%name" => $edit["name"]));
- }
-
- cache_clear_all();
-
- return $message;
-}
-
-function taxonomy_del_vocabulary($vid) {
- $vocabulary = taxonomy_get_vocabulary($vid);
-
- db_query("DELETE FROM vocabulary WHERE vid = %d", $vid);
- $result = db_query("SELECT tid FROM term_data WHERE vid = %d", $vid);
- while ($term = db_fetch_object($result)) {
- taxonomy_del_term($term->tid);
- }
-
- module_invoke_all("taxonomy", "delete", "vocabulary", $vocabulary);
-
- cache_clear_all();
-
- return t("deleted vocabulary '%name'.", array("%name" => $vocabulary->name));
-}
-
-function _taxonomy_confirm_del_vocabulary($vid) {
- $vocabulary = taxonomy_get_vocabulary($vid);
-
- $form .= form_hidden("confirm", 1);
- $form .= form_hidden("type", "vocabulary");
- $form .= form_hidden("vid", $vid);
- $form .= form_submit(t("Delete"));
- $form .= form_submit(t("Cancel"));
-
- return form(form_item(t("Delete vocabulary '%name'", array("%name" => $vocabulary->name)), $form, t("Are you sure you want to delete the vocabulary and all its terms?")));
-}
-
-function taxonomy_form_term($edit = array()) {
- $vocabulary_id = isset($edit["vid"]) ? $edit["vid"] : arg(4);
- $vocabulary = taxonomy_get_vocabulary($vocabulary_id);
-
- $form = form_textfield(t("Term name"), "name", $edit["name"], 50, 64, t("Required") . ". " . t("The name for this term. Example: 'Linux'."));
- $form .= form_textarea(t("Description"), "description", $edit["description"], 60, 5, t("Optional") . ". " . t("A description of the term."));
-
- if ($vocabulary->hierarchy) {
- $parent = array_keys(taxonomy_get_parents($edit["tid"]));
- $children = taxonomy_get_tree($vocabulary_id, $edit["tid"]);
-
- // you can't be son of yourself nor of your children
- foreach ($children as $child) {
- $exclude[] = $child->tid;
- }
- $exclude[] = $edit["tid"];
-
- if ($vocabulary->hierarchy == 1) {
- $form .= _taxonomy_term_select(t("Parent"), "parent", $parent, $vocabulary_id, t("Required") . ". " . l(t("Parent term"), "admin/taxonomy/help#parent") .".", 0, "<" . t("root") . ">", $exclude);
- }
- elseif ($vocabulary->hierarchy == 2) {
- $form .= _taxonomy_term_select(t("Parents"), "parent", $parent, $vocabulary_id, t("Required") . ". ". l(t("Parent terms"), "admin/taxonomy/help#parent") .".", 1, "<" . t("root") . ">", $exclude);
- }
- }
-
- if ($vocabulary->relations) {
- $form .= _taxonomy_term_select(t("Related terms"), "relations", array_keys(taxonomy_get_related($edit["tid"])), $vocabulary_id, t("Optional") . ". ", 1, "<" . t("none") . ">", array($edit["tid"]));
- }
-
- $form .= form_textarea(t("Synonyms"), "synonyms", implode("\n", taxonomy_get_synonyms($edit["tid"])), 30, 5, t("Optional") . ". ". t(l("Synonyms", "admin/taxonomy/help#synonyms") ." of this term, one synonym per line."));
- $form .= form_weight(t("Weight"), "weight", $edit["weight"], 10, t("Optional. In listings, the heavier terms will sink and the lighter terms will be positioned nearer the top."));
- $form .= form_hidden("vid", $vocabulary->vid);
- $form .= form_submit(t("Submit"));
-
- if ($edit["tid"]) {
- $form .= form_submit(t("Delete"));
- $form .= form_hidden("tid", $edit["tid"]);
- }
-
- return form($form);
-}
-
-function taxonomy_save_term($edit) {
- if ($edit["tid"] && $edit["name"]) {
- $data = array("name" => $edit["name"], "description" => $edit["description"], "weight" => $edit["weight"]);
-
- db_query("UPDATE term_data SET ". _prepare_update($data) ." WHERE tid = %d", $edit["tid"]);
- module_invoke_all("taxonomy", "update", "term", $edit);
- $message = t("the term '%a' has been updated.", array("%a" => $edit["name"]));
- }
- else if ($edit["tid"]) {
- return taxonomy_del_term($edit["tid"]);
- }
- else {
- $edit["tid"] = db_next_id("term_data_tid");
- $data = array("tid" => $edit["tid"], "name" => $edit["name"], "description" => $edit["description"], "vid" => $edit["vid"], "weight" => $edit["weight"]);
- db_query("INSERT INTO term_data ". _prepare_insert($data, 1) ." VALUES ". _prepare_insert($data, 2));
- module_invoke_all("taxonomy", "insert", "term", $edit);
- $message = t("created new term '%name'.", array("%name" => $edit["name"]));
- }
-
- // relations (seem very powerful, but I have to understand it completely)
- db_query("DELETE FROM term_relation WHERE tid1 = %d OR tid2 = %d", $edit["tid"], $edit["tid"]);
- if ($edit["relations"]) {
- foreach ($edit["relations"] as $related_id) {
- if ($related_id != 0) {
- db_query("INSERT INTO term_relation (tid1, tid2) VALUES (%d, %d)", $edit["tid"], $related_id);
- }
- }
- }
-
- // hierarchy
- db_query("DELETE FROM term_hierarchy WHERE tid = %d", $edit["tid"]);
- if (!isset($edit["parent"])) {
- $edit["parent"] = 0;
- }
- if (is_array($edit["parent"])) {
- foreach ($edit["parent"] as $parent) {
- db_query("INSERT INTO term_hierarchy (tid, parent) VALUES (%d, %d)", $edit["tid"], $parent);
- }
- }
- else {
- db_query("INSERT INTO term_hierarchy (tid, parent) VALUES (%d, %d)", $edit["tid"], $edit["parent"][0]);
- }
-
- db_query("DELETE FROM term_synonym WHERE tid = %d", $edit["tid"]);
- if ($edit["synonyms"]) {
- foreach (explode ("\n", str_replace("\r", "", $edit["synonyms"])) as $synonym) {
- if ($synonym) {
- db_query("INSERT INTO term_synonym (tid, name) VALUES (%d, '%s')", $edit["tid"], chop($synonym));
- }
- }
- }
-
- cache_clear_all();
-
- return $message;
-}
-
-function taxonomy_del_term($tid) {
- $term = taxonomy_get_term($tid);
-
- db_query("DELETE FROM term_data WHERE tid = %d", $tid);
- db_query("DELETE FROM term_hierarchy WHERE tid = %d", $tid);
- db_query("DELETE FROM term_relation WHERE tid1 = %d OR tid2 = %d", $tid, $tid);
- db_query("DELETE FROM term_synonym WHERE tid = %d", $tid);
- db_query("DELETE FROM term_node WHERE tid = %d", $tid);
-
- module_invoke_all("taxonomy", "delete", "term", $term);
-
- cache_clear_all();
-
- return t("deleted term '%name'.", array("%name" => $term->name));
-}
-
-function _taxonomy_confirm_del_term($tid) {
- $term = taxonomy_get_term($tid);
-
- $form .= form_hidden("confirm", 1);
- $form .= form_hidden("type", "term");
- $form .= form_hidden("tid", $tid);
- $form .= form_submit(t("Delete"));
- $form .= form_submit(t("Cancel"));
-
- return form(form_item(t("Delete term '%name'", array("%name" => $term->name)), $form, t("Are you sure you want to delete the term?")));
-}
-
-function taxonomy_overview() {
-
- $output .= "<h3>" . t("Vocabularies overview") . "</h3>";
-
- $header = array(t("name"), t("node types"), array("data" => t("operations"), "colspan" => 3));
-
- $vocabularies = taxonomy_get_vocabularies();
- foreach ($vocabularies as $vocabulary) {
- $links = array();
- $rows[] = array($vocabulary->name, array("data" => $vocabulary->nodes, "align" => "center"), l(t("edit vocabulary"), "admin/taxonomy/edit/vocabulary/$vocabulary->vid"), l(t("add term"), "admin/taxonomy/add/term/$vocabulary->vid"), l(t("preview form"), "admin/taxonomy/preview/vocabulary/$vocabulary->vid"));
-
- $tree = taxonomy_get_tree($vocabulary->vid);
- if ($tree) {
- unset($data);
- foreach ($tree as $term) {
- $data .= _taxonomy_depth($term->depth) ." ". $term->name ." (". l(t("edit term"), "admin/taxonomy/edit/term/$term->tid") .")<br />";
- }
- $rows[] = array(array("data" => $data, "colspan" => 5));
- }
- }
-
- return table($header, $rows);
-}
-
-function taxonomy_form($vocabulary_id, $value = 0) {
- $vocabulary = taxonomy_get_vocabulary($vocabulary_id);
- if ($vocabulary->required) {
- $verb = "must";
- $blank = 0;
- }
- else {
- $verb = "can";
- $blank = "<" . t("none") . ">";
- }
-
- if ($vocabulary->multiple) {
- $description = t("You $verb choose one or more terms for this node.");
- $multiple = 1;
- }
- else {
- $description = t("You $verb choose one term for this node.");
- $multiple = 0;
- }
- return _taxonomy_term_select($vocabulary->name, "taxonomy", $value, $vocabulary_id, $description, $multiple, $blank);
-}
-
-/*
-** API functions
-*/
-
-// return array of vocabularies, as objects
-function taxonomy_get_vocabularies($type = '', $key = "vid") {
- if ($type) {
- $result = db_query("SELECT * FROM vocabulary WHERE nodes LIKE '%%%s%%' ORDER BY weight, name", $type);
- }
- else {
- $result = db_query("SELECT * FROM vocabulary ORDER BY weight, name");
- }
- $vocabularies = array();
- while ($voc = db_fetch_object($result)) {
- $vocabularies[$voc->$key] = $voc;
- }
-
- return $vocabularies;
-}
-
-// return form with current term
-function taxonomy_node_form($type, $node = '') {
- if (!$node->taxonomy) {
- if ($node->nid) {
- $terms = array_keys(taxonomy_node_get_terms($node->nid));
- }
- else {
- $terms = 0;
- }
- }
- else {
- $terms = $node->taxonomy;
- }
-
- $c = db_query("SELECT * FROM vocabulary WHERE nodes LIKE '%%%s%%' ORDER BY weight, name", $type);
- while ($vocabulary = db_fetch_object($c)) {
- $result[] .= taxonomy_form($vocabulary->vid, $terms);
- }
- return $result ? $result : array();
-}
-
-// return 1 if node identified by $nid contains a taxonomy term identified by $tid in his body or title
-function taxonomy_node_has_term($nid, $tid) {
- $term_name = db_result(db_query("SELECT name FROM term_data WHERE tid = %d", $tid));
-
- return db_result(db_query("SELECT COUNT(n.nid) FROM node n WHERE n.nid = %d AND ((n.body LIKE '%%%s%%') OR (n.body LIKE '%%%s%%'))", $nid, $term_name, $term_name));
-}
-
-// return array of terms of a node beloging to a particular vocabulary identified by $vid
-function taxonomy_node_get_terms_by_vocabulary($nid, $vid, $key = "tid") {
- $result = db_query("SELECT t.* FROM term_data t, term_node r WHERE t.tid = r.tid AND t.vid = %d AND r.nid = %d ORDER BY weight", $vid, $nid);
- $terms = array();
- while ($term = db_fetch_object($result)) {
- $terms[$term->$key] = $term;
- }
- return $terms;
-}
-
-// return array of terms of a node
-function taxonomy_node_get_terms($nid, $key = "tid") {
- static $terms;
-
- if (!isset($terms[$nid])) {
- $result = db_query("SELECT t.* FROM term_data t, term_node r WHERE r.tid = t.tid AND r.nid = %d ORDER BY weight, name", $nid);
- $terms[$nid] = array();
- while ($term = db_fetch_object($result)) {
- $terms[$nid][$term->$key] = $term;
- }
- }
- return $terms[$nid];
-}
-
-// save terms of a node
-function taxonomy_node_save($nid, $terms) {
- taxonomy_node_delete($nid);
-
- if ($terms) {
- foreach ($terms as $term) {
- db_query("INSERT INTO term_node (nid, tid) VALUES (%d, %d)", $nid, $term);
- }
- }
-}
-
-// clean up terms
-function taxonomy_node_delete($nid) {
- db_query("DELETE FROM term_node WHERE nid = %d", $nid);
-}
-
-// relations: return array of related terms
-function taxonomy_get_related($tid, $key = "tid") {
- if ($tid) {
- $result = db_query("SELECT t.*, tid1, tid2 FROM term_relation, term_data t WHERE (t.tid = tid1 OR t.tid = tid2) AND (tid1 = %d OR tid2 = %d) AND t.tid != %d ORDER BY weight, name", $tid, $tid, $tid);
- $related = array();
- while ($term = db_fetch_object($result)) {
- $related[$term->$key] = $term;
- }
- return $related;
- }
- else {
- return array();
- }
-}
-
-// hierarchy: get parent terms
-function taxonomy_get_parents($tid, $key = "tid") {
- if ($tid) {
- $result = db_query("SELECT t.* FROM term_hierarchy h, term_data t WHERE h.parent = t.tid AND h.tid = %d ORDER BY weight, name", $tid);
- $parents = array();
- while ($parent = db_fetch_object($result)) {
- $parents[$parent->$key] = $parent;
- }
- return $parents;
- }
- else {
- return array();
- }
-}
-
-// hierarchy: get children
-function taxonomy_get_children($tid, $vid = 0, $key = "tid") {
- if ($vid) {
- $result = db_query("SELECT t.* FROM term_hierarchy h, term_data t WHERE t.vid = %d AND h.tid = t.tid AND h.parent = %d ORDER BY weight, name", $vid, $tid);
- }
- else {
- $result = db_query("SELECT t.* FROM term_hierarchy h, term_data t WHERE h.tid = t.tid AND parent = %d ORDER BY weight", $tid);
- }
- $children = array();
- while ($term = db_fetch_object($result)) {
- $children[$term->$key] = $term;
- }
- return $children;
-}
-
-// hierarchy: get whole family, with tid, parent and depth; useful to show
-function taxonomy_get_tree($vocabulary_id, $parent = 0, $depth = -1, $key = "tid") {
- static $children, $parents, $terms;
-
- $depth++;
-
- // we cache trees, so it's not cpu-intensive to call get_tree on a term and its children too
- if (!isset($children[$vocabulary_id])) {
- $children[$vocabulary_id] = array();
-
- $result = db_query("SELECT t.*, parent FROM term_data t, term_hierarchy h WHERE t.tid = h.tid AND t.vid = %d ORDER BY weight, name", $vocabulary_id);
- while ($term = db_fetch_object($result)) {
- $children[$vocabulary_id][$term->parent][] = $term->tid;
- $parents[$vocabulary_id][$term->tid][] = $term->parent;
- $terms[$vocabulary_id][$term->tid] = $term;
- }
- }
-
- if ($children[$vocabulary_id][$parent]) {
- foreach ($children[$vocabulary_id][$parent] as $child) {
- $terms[$vocabulary_id][$child]->depth = $depth;
- unset($terms[$vocabulary_id][$child]->parent); // this is not useful as it would show one parent only
- $terms[$vocabulary_id][$child]->parents = $parents[$vocabulary_id][$child];
- $tree[] = $terms[$vocabulary_id][$child];
-
- $tree = array_merge($tree, taxonomy_get_tree($vocabulary_id, $child, $depth));
- }
- }
-
- return $tree ? $tree : array();
-}
-
-// synonyms: return array of synonyms
-function taxonomy_get_synonyms($tid) {
- if ($tid) {
- $result = db_query("SELECT name FROM term_synonym WHERE tid = %d", $tid);
- while ($synonym = db_fetch_array($result)) {
- $synonyms[] = $synonym["name"];
- }
- return $synonyms ? $synonyms : array();
- }
- else {
- return array();
- }
-}
-
-// synonyms: return original term
-function taxonomy_get_synonym_root($term) {
- return db_fetch_object(db_query("SELECT * FROM term_synonym s, term_data t WHERE t.tid = s.tid AND s.name = '%s'", $term));
-}
-
-// given a term id, count number of published nodes in it
-function taxonomy_term_count_nodes($tid, $type = 0) {
- static $count;
-
- if (!isset($count[$type])) {
- // $type == 0 always evaluates true is $type is a string
- if (is_numeric($type)) {
- $result = db_query("SELECT t.tid, COUNT(*) AS c FROM term_node t LEFT JOIN node n ON t.nid = n.nid WHERE n.status = 1 GROUP BY t.tid");
- }
- else {
- $result = db_query("SELECT t.tid, COUNT(*) AS c FROM term_node t, node n WHERE t.nid = n.nid AND n.status = 1 AND n.type = '%s' GROUP BY t.tid", $type);
- }
- while ($term = db_fetch_object($result)) {
- $count[$type][$term->tid] = $term->c;
- }
- }
-
- foreach (_taxonomy_term_children($tid) as $c) {
- $children_count += taxonomy_term_count_nodes($c, $type);
- }
- return $count[$type][$tid] + $children_count;
-}
-
-// helper for above function
-function _taxonomy_term_children($tid) {
- static $children;
-
- if (!isset($children)) {
- $result = db_query("SELECT tid, parent FROM term_hierarchy");
- while ($term = db_fetch_object($result)) {
- $children[$term->parent][] = $term->tid;
- }
- }
- return $children[$tid] ? $children[$tid] : array();
-}
-
-/**
- * Try to map a string to existing vocabularies
- * Provide case insensitive and trimmed map so as to
- * maximize likelihood of successful mapping.
- *
- * @param string $name Name of the vocabulary to search
- * @return array array of matching vocabularies, as objects
- */
-function taxonomy_get_vocabulary_by_name($name) {
- // LOWER is ANSI SQL-92
- $db_result = db_query("SELECT * FROM vocabulary WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
- $result = array();
- while ($vocabulary = db_fetch_object($db_result)) {
- $result[] = $vocabulary;
- }
-
- return $result;
-}
-
-/**
- * Try to map a string to existing terms
- * Provide case insensitive and trimmed map so as to
- * maximize likelihood of successful mapping.
- *
- * @param string $name Name of the term to search
- * @return array array of matching terms, as objects
- */
-function taxonomy_get_term_by_name($name) {
- // LOWER is ANSI SQL-92
- $db_result = db_query("SELECT * FROM term_data WHERE LOWER('%s') LIKE LOWER(name)", trim($name));
- $result = array();
- while ($term = db_fetch_object($db_result)) {
- $result[] = $term;
- }
-
- return $result;
-}
-
-function taxonomy_get_vocabulary($vid) {
- // simple cache using a static var?
- return db_fetch_object(db_query("SELECT * FROM vocabulary WHERE vid = %d", $vid));
-}
-
-function taxonomy_get_term($tid) {
- // simple cache using a static var?
- return db_fetch_object(db_query("SELECT * FROM term_data WHERE tid = %d", $tid));
-}
-
-/*
-** service functions
-*/
-
-function _taxonomy_term_select($title, $name, $value, $vocabulary_id, $description, $multiple, $blank, $exclude = array()) {
- $tree = taxonomy_get_tree($vocabulary_id);
-
- if ($blank) {
- $options[] = array("tid" => 0, "name" => $blank);
- }
-
- if ($tree) {
- foreach ($tree as $term) {
- if (!in_array($term->tid, $exclude)) {
- $options[] = array("tid" => $term->tid, "name" => _taxonomy_depth($term->depth, '-').$term->name);
- }
- }
- if (!$blank && !$value) {
- // required but without a predefined value, so set first as predefined
- $value = $tree[0]->tid;
- }
- }
-
- if (count($options) > 0) {
- foreach ($options as $option) {
- $select .= "<option value=\"".$option["tid"]."\"". (is_array($value) ? (in_array($option["tid"], $value) ? " selected=\"selected\"" : "") : ($option["tid"] == $value ? " selected=\"selected\"" : "")) .">". check_form($option["name"]) ."</option>";
- }
-
- $size = min(12, count($options));
-
- return form_item($title, "<select name=\"edit[$name][]\"". ($multiple ? " multiple size=\"$size\"" : "") . ($extra ? " $extra" : "") .">$select</select>", $description);
- }
-}
-
-function _taxonomy_depth($depth, $graphic = '--') {
- for ($n = 0; $n < $depth; $n++) {
- $result .= $graphic;
- }
- return $result;
-}
-
-function _prepare_update($data) {
- foreach ($data as $key => $value) {
- $q[] = "$key = '". check_query($value) ."'";
- }
- $result = implode(", ", $q);
- return $result;
-}
-
-function _prepare_insert($data, $stage) {
- if ($stage == 1) {
- $result = implode(", ", array_keys($data));
- }
- else {
- foreach (array_values($data) as $value) {
- $q[] = "'". check_query($value) ."'";
- }
- $result = implode(", ", $q);
- }
- return "($result)";
-}
-
-/*
-** Accepts taxonomy conditions and returns a resource identifier. If
-** you intend to use the nodes without a pager (eg. in a XML feed),
-** then set $pager to false.
-*/
-function taxonomy_select_nodes($taxonomy, $pager = 1) {
- global $user;
-
- if ($taxonomy->str_tids) {
- if ($taxonomy->operator == "or") {
- $sql = "SELECT DISTINCT(n.nid), n.title, n.type, n.created, n.changed, n.uid, n.static, n.created, u.name FROM node n LEFT JOIN term_node r ON n.nid = r.nid LEFT JOIN users u ON n.uid = u.uid WHERE r.tid IN ($taxonomy->str_tids) AND n.status = '1' ORDER BY static DESC, created DESC";
- $sql_count = "SELECT COUNT(DISTINCT(n.nid)) FROM node n LEFT JOIN term_node r ON n.nid = r.nid LEFT JOIN users u ON n.uid = u.uid WHERE r.tid IN ($taxonomy->str_tids) AND n.status = '1'";
- }
- else {
- $sql = "SELECT n.nid, n.title, n.type, n.created, n.changed, n.uid, u.name FROM node n LEFT JOIN term_node r ON n.nid = r.nid LEFT JOIN users u ON n.uid = u.uid WHERE r.tid IN ($taxonomy->str_tids) AND n.status = '1' GROUP BY n.nid, n.title, n.type, n.created, n.changed, n.uid, u.name HAVING COUNT(n.nid) = ".count($taxonomy->tids)." ORDER BY static DESC, created DESC";
-
- // Special trick as we could not find anything better:
- $count = db_num_rows(db_query("SELECT n.nid FROM node n LEFT JOIN term_node r ON n.nid = r.nid WHERE r.tid IN ($taxonomy->str_tids) AND n.status = '1' GROUP BY n.nid HAVING COUNT(n.nid) = ". count($taxonomy->tids)));
- $sql_count = "SELECT $count";
- }
-
- if ($pager) {
- $result = pager_query($sql, variable_get("default_nodes_main", 10) , 0, $sql_count);
- }
- else {
- $result = db_query_range($sql, 0, 15);
- }
- }
-
- return $result;
-}
-
-/*
-** Accepts the result of a db_query() and formats each node along
-** with a pager.
-*/
-function taxonomy_render_nodes($result) {
-
- while ($node = db_fetch_object($result)) {
- node_view(node_load(array("nid" => $node->nid, "type" => $node->type)), 1);
- }
- print pager_display_default(NULL, variable_get("default_nodes_main", 10), 0);
-}
-
-function taxonomy_nodeapi($node, $op, $arg = 0) {
-
- switch ($op) {
- case "insert":
- taxonomy_node_save($node->nid, $node->taxonomy);
- break;
- case "update":
- taxonomy_node_save($node->nid, $node->taxonomy);
- break;
- case "delete":
- taxonomy_node_delete($node->nid);
- break;
- }
-}
-
-function taxonomy_page() {
-
-
- // taxonomy querystring always parsed here
- // TODO: support term *names* in URL (e.g. taxonomy/view/or/milk,beer,red+wine)
- $taxonomy->operator = arg(2);
- $taxonomy->str_tids = check_query(arg(3));
- $taxonomy->tids = explode(",", $taxonomy->str_tids);
-
- switch (arg(1)) {
- case "feed":
- taxonomy_feed($taxonomy);
- break;
- default:
- theme("header");
- taxonomy_render_nodes(taxonomy_select_nodes($taxonomy));
- theme("footer");
- break;
- }
-}
-
-/*
-** admin
-*/
-
-function taxonomy_admin() {
- $op = $_POST["op"];
- $edit = $_POST["edit"];
-
- if (user_access("administer taxonomy")) {
- if (empty($op)) {
- $op = arg(2);
- }
-
- switch ($op) {
- case "add":
- if (arg(3) == "vocabulary")
- $output .= taxonomy_form_vocabulary();
- else if (arg(3) == "term")
- $output .= taxonomy_form_term();
- break;
- case "edit":
- if (arg(3) == "vocabulary")
- $output .= taxonomy_form_vocabulary(object2array(taxonomy_get_vocabulary(arg(4))));
- else if (arg(3) == "term")
- $output .= taxonomy_form_term(object2array(taxonomy_get_term(arg(4))));
- break;
- case "preview":
- $output .= taxonomy_form(arg(4));
- break;
- case "help":
- $output .= taxonomy_help();
- break;
- case t("Delete"):
- if (!$edit["confirm"]) {
- if (arg(3) == "vocabulary") {
- $output .= _taxonomy_confirm_del_vocabulary($edit["vid"]);
- }
- else {
- $output .= _taxonomy_confirm_del_term($edit["tid"]);
- }
- break;
- }
- else {
- $edit["name"] = 0;
- // fall through:
- }
- case t("Submit"):
- if (arg(3) == "vocabulary") {
- $output .= status(taxonomy_save_vocabulary($edit));
- }
- else {
- $output .= status(taxonomy_save_term($edit));
- if (!$edit["tid"]) {
- // if INSERT show form again
- $output .= taxonomy_form_term();
- break;
- }
- // else (UPDATE or DELETE) fall through
- }
- // fall through:
- default:
- $output .= taxonomy_overview();
- }
- }
- else {
- $output .= message_access();
- }
-
- return $output;
-}
-
-function taxonomy_help() {
-
- $output .= "<h3>Background</h3><p>Taxonomy is the study of classification. Drupal's taxonomy module allows you to define categories which are used to classify content. The module supports hierarchical classification and association between terms, allowing for truly flexible information retrieval and classification. For more details about <a href=\"http://www.eleganthack.com/archives/002165.html#002165\">classification types</a> and insight into the development of the <i>taxonomy.module</i>, see this <a href=\"http://www.drupal.org/node/view/55\">drupal.org discussion</a>.</p>";
- $output .= "<h3>An example taxonomy: food</h3><ul><li>Dairy<ul><li>Milk</li></ul></li><li>Drink<ul><li>Alchohol<ul><li>Beer</li><li>Wine</li></ul></li><li>Pop</li><li>Milk</li></ul></li><li>Meat<ul><li>Beef</li><li>Chicken</li><li>Lamb</li></ul></li><li>Spices<ul><li>Sugar</li></ul></li></ul>";
- $output .= "<p><b>Notes</b></p><ul><li>The term <i>Milk</i> appears within both <i>Dairy</i> and <i>Drink</i>. This is an example of <i>multiple parents</i> for a term.</li><li>In Drupal the order of siblings (e.g. <i>Beef</i>, <i>Chicken</i>, <i>Lamb</i>) in a taxonomy may be controlled with the <i>weight</i> parameter.</li></ul>";
- $output .= "<h3>Vocabularies</h3><p>When you create a controlled vocabulary you are creating a set of terms to use for describing content (known as descriptors in indexing lingo). Drupal allows you to describe each node of content (blog, story, etc.) using one or many of these terms. For simple implementations, you might create a set of categories without subcategories, similar to <a href=\"http://www.slashdot.com/\">Slashdot's</a> sections. For more complex implementations, you might create a hierarchical list of categories such as <i>Food</i> taxonomy shown above.</p>";
- $output .= "<h4>Setting up a vocabulary</h4><p>When setting up a controlled vocabulary, if you select the <i>hierarchy</i> option, you will be defining a taxonomy or a thesaurus. If you select the <i>related terms</i> option, you are allowing the definition of related terms, think <i>see also</i>, as in a thesaurus. Selecting <i>multiple select</i> will allow you to describe a node using more than one term. That node will then appear in each term's page, thus increasing the chance that a user will find it.</p>";
- $output .= "<p>When setting up a controlled vocabulary you are asked for: <ul><li><b>Vocabulary name</b> (Required) -- The name for this vocabulary. Example: <i>Dairy</i>.</li><li><b>Description</b> (Optional) -- Description of the vocabulary, this can be used by modules and feeds.</li><li><b>Types</b> (Required) -- The list of node types you want to associate this vocabulary with. Some available types are: blog, book, forum, page, story.</li><li><a id=\"relatedterms\"></a><b>Related terms</b> -- Allows relationships between terms within this vocabulary. Think of these as <i>see also</i>-references.</li><li><a id=\"hierarchy\"></a><b>Hierarchy</b> -- Allows a tree-like taxonomy, as in our <i>Foods</i> example above</li><li><b>Multiple select</b> -- Allows nodes to be described using more than one term. Nodes may then appear on multiple taxonomy pages.</li><li><b>Required</b> -- Each node has to have a term in this vacabulary associated with it.</li><li><b>Weight</b> -- The over all weight for this vocaulary in listings with multiple vacabularies.</ul></p>";
- $output .= "<h4>Adding terms to a vocabulary</h4><p>Once done defining the vocabulary, you have to add terms to it to make it useful. The options you see when adding a term to a vocabulary will depend on what you selected for <i>related terms</i>, <i>hierarchy </i>and <i>multiple select</i>. These options are:</p>";
- $output .= "<p><ul><li><b>Term name</b> (Required) -- The name for this term. Example: <i>Milk</i></li><li><b>Description</b> (Optional) -- Description of the term that may be used by modules and feeds. This is synonymous with a 'scope note'.</li><li><b><a id=\"parent\"></a>Parent</b> (Required) -- Select the term under which this term is a subset -- the branch of the hierarchy that this term belongs under. This is also known as the \"Broader term\" indicator used in thesauri.</li><li><b><a id=\"synonyms\"></a>Synonyms</b> (Optional) -- Enter synonyms for this term, one synonym per line. Synonyms can be used for variant spellings, acronyms, and other terms that have the same meaning as the added term, but which are not explicitly listed in this thesaurus (i.e. <i>unauthorized terms</i>)</li><li><b>Weight</b> (Optional) -- The weight is used to sort the terms of this vocabulary.</li></ul></p>";
- $output .= "<h3><a id=\"taxonomyURL\"></a>Displaying nodes organized by term(s)</h3><p>In order to view the nodes associated with a term or a collection of terms, you should browse to a properly formed Taxonomy URL. For example, ". l("taxonomy/page/or/1,2","taxonomy/pages/or/1,2") .". Taxonomy URLs always contain one or more term IDs (tid) at the end of the URL (a.k.a the <i>querystring</i>). You may learn the term ID for a given term by hovering over that term in the ". l("taxonomy overview", "admin/taxonomy") ." page and noting the number at the end or the URL. To build a Taxonomy URL start with \"taxonomy/page\". Now add the querystring parameter, either <i>or</i>, which chooses nodes tagged with <b>any</b> of the given term IDs, or <i>and</i>, which chooses nodes tagged with <b>all</b> of the given Term IDs. Thus <i>or</i> is less specific than <i>and</i>. Finally add a comma seperated list of term IDs.</p>";
- $output .= "<h3>RSS feeds</h3><p>Every term, or collection of terms, provides an <a href=\"http://backend.userland.com/stories/rss\">RSS</a> feed to which interested users may subscribe. The URL format for a sample RSS feed is ". l("node/feed/or/1,2","node/feed/or/1,2") .". Built like a Taxonomy URL, ". l("see above", "admin/taxonomy/help#taxonomyURL") ." it starts with \"node/feed\", then has the querystring parameter, and finally the Term IDs.</p>";
- return t($output);
-}
-?>
diff --git a/modules/throttle/throttle.module b/modules/throttle/throttle.module
deleted file mode 100644
index fa1e202..0000000
--- a/modules/throttle/throttle.module
+++ /dev/null
@@ -1,126 +0,0 @@
-<?php
-
-/* System hook, sets description of module in admin page */
-function throttle_system($field) {
- $system["description"] = t("Allows configuration of congestion control auto-throttle mechanism.");
- $system["admin_help"] = t("If your site gets popular, or comes under a \"Denial of Service\" (DOS) attack, your hardware might become overwhelmed. These settings allow you to \"slow down\" the access to your site. To use throttle you need to have the <a href=\"%access\">access log</a> enabled. For Drupal to preform throttling it needs to do an extra database query. This extra query happens on page displays. <b>Auto-throttle probability limiter</b> tells Drupal to do this extra DB query once every \"x\" page displays, where \"x\" is the percentage. So if it is set to 10%, the default, then for every 100 web pages it displays, it will preform the extra query ten time. ", array("%access" => url("admin/system/modules/statistics")));
- return $system[$field];
-}
-
-
-/* Permissions hook, defines module's permissions */
-function throttle_perm() {
- /*
- ** throttle module defines the following permissions:
- ** access throttle box - see throttle statistics
- */
- return array("access throttle box");
-}
-
-
-/* Administrative help page */
-function throttle_help() {
- $output .= "<h3>Introduction</h3><p>This Drupal module allows you to enable and configure the auto-throttle congestion control mechanism offered by the ". l("statistics.module","admin/statistics") .". The auto-throttle mechanism allows your site to automatically adapt to different server levels.</p>";
- $output .= "<p>This module also adds a block that displays the current status of the throttle. You must have ". l("\"access throttle block\"","admin/user/permission") ." privileges to view the block. As a general rule of thumb, only site administrators should be granted access to this block.</p>";
- $output .= "<p>The auto-throttle mechanism performs an extra database query in order to determine what the current throttle level should be. Fortunately the throttle can be tuned so these database queries only occur on a fraction of all pages geenrated by your site, reducing the overhead to an insignificant amount. Additionally, when the top-most throttle level is reached, all throttle queries are suspended for a configurable period of time. More detail follows.</p>";
- $output .= "<p>As with any module, the <i>throttle.module</i> needs to be ". l("enabled","admin/system/modules") ." before you can use it. Also refer to the permissions section below if you wish to access the throttle statistics block.</p>";
- $output .= "<h3>Configuring the throttle module</h3><p>The ". l("configuration section", "admin/system/modules/throttle") ." for the throttle allows you to turn it on and off, as well as to fine-tune how sensitive it is.</p>";
- $output .= "<h4>enable auto-throttle:</h4><blockquote>This first option on the throttle module configuration screen allows you to enable or disable the auto-throttling mechanism. Note that the access-log must also be enabled via the ". l("statistics.module", "admin/system/modules/statistics") ." for the auto-throttling mechanism to have any affect.</blockquote>";
- $output .= "<h4>auto-throttle multiplier:</h4><blockquote><p>This second option allows you to tune the auto-throttle mechanism. The auto-throttle mechanism supports six throttle levels, from 0 (off) to 5 (maximum). The current throttle level is based upon how many pages have been accessed on your site in the past 60 seconds - the more pages being displayed, the higher the throttle level. This multiplier defines how many hits are required to switch from one throttle level to the next.</p>";
- $output .= "<p>For example, with a throttle multiplier of 20: Once 20 pages have been accessed on your site within a period of 60 seconds, the throttle level will be incremented to a level of 1. Once 40 pages have been accessed on your site within a period of 60 seconds, the throttle level will be incremented to a level of 2. And so on, until 100 pages are accessed on your site within a period of 60 seconds, at which time the throttle level will be set to a maximum level of 5.</p>";
- $output .= "<p>Upon reaching a throttle level of 5, access logs and the auto-throttle checking mechanism is automatically disabled. It is only renabled by cron after a period of time defined by \"auto-throttle cron test\", explained below.</p></blockquote>";
- $output .= "<h4>auto-throttle probability limiter:</h4><blockquote><p>This option allows you to minimize the performance impact of the auto-throttle. If we refer to the probability limiter as P, then P\% of all pages generated by your site will perform an extra database query to verify that the current throttle level is appropriate to the current server load.</p>";
- $output .= "<p>As a rule of thumb, the higher your multiplier, the lower your probability limiter should be. For example, if you have a multiplier of 100, then you logically don't need to check the throttle level more than once out of every 100 page views, so the probability limiter should be set to 1\%. As database queries are \"expensive\", it's recommended that you keep the probability limiter to the smallest percentage possible, while still high enough to react quickly to a change in server load.</p></blockquote>";
- $output .= "<h4>auto-throttle cron test:</h4><blockquote><p>The auto-throttle dynamically adjusts its level upward, but not downward. That is to say, if you have a multiplier of 20 and you get 45 hits in one minute, your throttle level will be adjusted to a level of 2. If a few minutes later you only get 35 hits in one minute, the throttle level will <b>NOT</b> be adjusted down to a level of 1. This prevents the throttle from bouncing back and forth between two levels.</p>";
- $output .= "<p>In order for the throttle level to be dropped, \"cron.php\" must be called regularly. This option then defines how often the level will be dropped by one to test the server load. If the server load is no longer as high as it was, the level will stay where it is, until the cron test period passes again and cron drops the throttle level again. This process repeats until the throttle is returned to a throttle level of 0.</p></blockquote>";
- $output .= "<h3>Throttle block</h3><p>This block displays some statistics regarding the current throttle and its configuration. It is recommended that only site administrators receive the ". l("\"access throttle block\"","admin/user/permission") ." permission bit required to view this block. It does not display information that would interest a normal site end-user.</p>";
- $output .= "<p>Don't forget to enable the block ". l("here", "admin/block") .".</p>";
- $output .= "<h3>Permissions</h3><p>This module has one permission that needs to be configured in ". l("user permissions", "admin/user/permission") .".</p>";
- $output .= "<ul><li><i>access throttle block</i> - enable for user roles that get to view the throttle block.</li></ul>";
- $output .= "<h3>For programmers: throttle_status()</h3><p>The function <code>throttle_status()</code> will return a number from 0 to 5. 0 means that there is no throttle enabled at this time. Each number above that is a progressively more throttled system... To disable a feature when a site first begins to get busy, disable it at a throttle of 2 or 3. To hold on to the bitter end, wait until 4 or 5.</p>";
- $output .= "<p>To implement the throttle, you should do something like this:";
- $output .= "<pre> \$throttle = 0;
- /* verify that the statitistics module is installed */
- if (function_exists(throttle_status) {
- \$throttle = throttle_status()
- }
- if (\$throttle >= \$my_throttle_value) {
- // throttle limit reached, disable stuff
- }
- else {
- // throttle limit not reached, execute normally
- }</pre></p>";
- return t($output);
-
-}
-
-
-/* Adds configure option to the main configure site admin page */
-function throttle_settings() {
- /* access log options */
- $output .= form_select(t("Enable auto-throttle"), "statistics_enable_auto_throttle", variable_get("statistics_enable_auto_throttle", 0), array("1" => t("enabled"), "0" => t("disabled")), "Enable auto-throttling congestion control mechanism. Allows your site to adapt under extreme user loads. Requires that 'access log' be enabled.");
- $throttles = array(1 => "1 (0,1,2,3,4,5)", 5 => "5 (0,5,10,15,20,25)", 10 => "10 (0,10,20,30,40,50)", 12 => "12 (0,12,24,36,48,60)", 15 => "15 (0,15,30,45,60,75)", 20 => "20 (0,20,40,60,80,100)", 30 => "30 (0,30,60,90,120,150)", 50 => "50 (0,50,100,150,200,250)", 60 => "60 (0,60,120,180,240,300)", 100 => "100 (0,100,200,300,400,500", 500 => "500 (0,500,1000,1500,2000,2500", 1000 => "1000 (0,1000,2000,3000,4000,5000)");
- $output .= form_select(t("Auto-throttle multiplier"), "statistics_throttle_multiplier", variable_get("statistics_throttle_multiplier", 60), $throttles, "Throttle tuning. Specify how many hits in the past 60 seconds triggers higher throttle level. Example: multiplier of 5 takes 5 hits for level 1, 25 hits for level 5.");
- $probabilities = array(0 => "100%", 1 => "50%", 2 => "33.3%", 3 => "25%", 4 => "20%", 5 => "16.6%", 7 => "12.5%", 9 => "10%", 19 => "5%", 99 => "1%", 199 => ".5%", 399 => ".25%", 989 => ".1%");
- $output .= form_select(t("Auto-throttle probability limiter"), "statistics_probability_limiter", variable_get("statistics_probability_limiter", 9), $probabilities, "Throttle tuning. Probability based efficiency mechanism specifying the probability, expressed in a percentage of page views, an extra database query is performed to adjust throttle level.");
- $period = array(1800 => format_interval(1800), 3600 => format_interval(3600), 7200 => format_interval(7200), 10800 => format_interval(10800), 14400 => format_interval(14400), 18000 => format_interval(18000), 21600 => format_interval(21600), 43200 => format_interval(43200), 64800 => format_interval(64800), 86400 => format_interval(86400), 172800 => format_interval(172800), 259200 => format_interval(259200), 604800 => format_interval(604800));
- $output .= form_select(t("Auto-throttle cron test"), "statistics_throttle_cron_timer", variable_get("statistics_throttle_cron_timer", 10800), $period, "Throttle tuning. Specify how often cron should drop the thottle level (if up) to test server load. Requires cron.");
- return $output;
-}
-
-
-/* This displays admin oriented "Throttle status" block */
-function throttle_display_throttle_block() {
- global $recent_activity;
-
- if (user_access("access throttle block")) {
- if (variable_get("statistics_enable_auto_throttle", 0)) {
- /* the throttle is enabled: display the status of all throttle config */
- if (function_exists("throttle_status")) {
- $throttle = throttle_status();
- }
- else {
- $throttle = 0;
- }
- $multiplier = variable_get("statistics_throttle_multiplier", 60);
- $minimum = $throttle * $multiplier;
- $limiter = variable_get("statistics_probability_limiter", 9);
- /* calculate probability limiter's odds of updating throttle */
- $probability = substr((($limiter / ($limiter + 1) * 100) - 100) * -1, 0, 4);
-
- $output .= "Throttle: ". l("Enabled", "admin/system#statistics") ."<br />\n";
- if ($throttle < 5) {
- $maximum = (($throttle + 1) * $multiplier) - 1;
- $output .= "Current Level: $throttle ($minimum - $maximum)<br />\n";
- }
- else {
- $output .= "Current Level: $throttle ($minimum+)<br />\n";
- }
- $output .= "Probability: $probability%<br />\n";
- if ($recent_activity["hits"]) {
- $output .= "<br />This site has served ";
- $output .= format_plural($recent_activity["hits"] , "1 page", "%count pages");
- $output .= " in the past minute.";
- }
- }
- else {
- $output .= "Throttle: ". l("Disabled", "admin/system#statistics") ."<br />\n";
- }
- }
- return $output;
-}
-
-/* Block hook */
-function throttle_block($op = "list", $delta = 0) {
- if ($op == "list") {
- $blocks[0]["info"] = t("Throttle status");
- return $blocks;
- }
- else {
- $block["subject"] = t("Throttle status");
- $block["content"] = throttle_display_throttle_block();
- return $block;
- }
-}
-
-?>
diff --git a/modules/tracker/tracker.module b/modules/tracker/tracker.module
deleted file mode 100644
index c4c3e96..0000000
--- a/modules/tracker/tracker.module
+++ /dev/null
@@ -1,93 +0,0 @@
-<?php
-// $Id$
-
-function tracker_help() {
- $output .= "<p>The tracker module is a handy module for displaying the most recent posts. By following the <i>view recent posts</i> link in the user block, a user may quickly review all recent postings.</p>";
- return $output;
-}
-
-function tracker_system($field) {
- $system["description"] = t("Enables tracking of recent posts for users.");
- return $system[$field];
-}
-
-function tracker_link($type) {
-
- $links = array();
-
- if ($type == "menu.view" && user_access("access content")) {
- $links[] = l(t("view recent posts"), "tracker", array("title" => t("Display an overview of the recent posts.")));
- }
-
- return $links;
-}
-
-function tracker_posts($id = 0) {
-
- if ($id) {
- $sresult = pager_query("SELECT n.nid, n.title, n.type, n.changed, n.uid, u.name, MAX(GREATEST(n.changed, c.timestamp)) AS last_activity FROM node n LEFT JOIN comments c ON n.nid = c.nid LEFT JOIN users u ON n.uid = u.uid WHERE n.uid = '". check_query($id) ."' AND n.status = 1 GROUP BY n.nid, n.title, n.type, n.changed, n.uid, u.name ORDER BY last_activity DESC", 10, 0, "SELECT COUNT(nid) FROM node WHERE status = 1 AND uid = '". check_query($id) ."'");
- }
- else {
- $sresult = pager_query("SELECT n.nid, n.title, n.type, n.changed, n.uid, u.name, MAX(GREATEST(n.changed, c.timestamp)) AS last_activity FROM node n LEFT JOIN comments c ON n.nid = c.nid LEFT JOIN users u ON n.uid = u.uid WHERE n.status = 1 GROUP BY n.nid, n.title, n.type, n.changed, n.uid, u.name ORDER BY last_activity DESC", 10, 0, "SELECT COUNT(nid) FROM node WHERE status = 1");
- }
-
- $header = array(t("Type"), t("Title"), t("Author"));
-
- while ($node = db_fetch_object($sresult)) {
- if ($id) {
- $cresult = db_query("SELECT c.*, u.name FROM comments c LEFT JOIN users u ON c.uid = u.uid WHERE c.uid = %d AND c.nid = %d AND c.status = 0 ORDER BY cid DESC", $id, $node->nid);
- }
- else {
- $cresult = db_query("SELECT c.*, u.name FROM comments c LEFT JOIN users u ON c.uid = u.uid WHERE c.nid = %d AND c.status = 0 ORDER BY cid DESC", $node->nid);
- }
-
- $type = ucfirst(module_invoke($node->type, "node", "name"));
- $title = l($node->title, "node/view/$node->nid") ." ". (node_is_new($node->nid, $node->changed) ? theme("theme_mark") : "");
- $author = format_name($node);
-
- $comments = array();
- while ($comment = db_fetch_object($cresult)) {
- $comments[] = "<li>". l($comment->subject, "node/view/$node->nid#$comment->cid") ." ". t("by") ." ". format_name($comment) ." ". (node_is_new($comment->nid, $comment->timestamp) ? theme("theme_mark") : "") ."</li>\n";
- }
-
- if ($comments) {
- $comments = "<ul>". implode("\n", $comments) ."</ul>";
- }
- else {
- $comments = "";
- }
-
- $rows[] = array(array("data" => $type, "class" => "type"), array("data" => $title . $comments, "class" => "content"), array("data" => $author, "class" => "author"));
- }
-
- if ($pager = pager_display(NULL, 10)) {
- $rows[] = array(array("data" => $pager, "colspan" => 3));
- }
-
- $output = "<div id=\"tracker\">";
- $output .= table($header, $rows);
- $output .= "</div>";
-
- return $output;
-}
-
-function tracker_user($type, &$edit, &$user) {
- switch ($type) {
- case "view_public":
- if (user_access("access content")) {
- return form_item(t("Recent posts"), l(t("view recent posts"), "tracker/$user->uid"));
- }
- }
-}
-
-function tracker_page() {
- global $user;
-
- if (user_access("access content")) {
- theme("header", t("Recent activity"));
- theme("box", t("Recent activity"), tracker_posts(arg(1)));
- theme("footer");
- }
-}
-
-?>
diff --git a/modules/user/user.module b/modules/user/user.module
deleted file mode 100644
index 8c78ee7..0000000
--- a/modules/user/user.module
+++ /dev/null
@@ -1,1876 +0,0 @@
-<?php
-// $Id$
-
-session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
-session_start();
-
-function user_system($field){
- $system["description"] = t("Enables the user registration and login system.");
- $system["admin_help"] = t("In order to use the full power of Drupal a visitor must sign up for an account. This page lets you setup how a user signs up, logs out, the guidelines from the system about user subscriptions, and the e-mails the system will send to the user.");
- return $system[$field];
-}
-
-/*** Session functions *****************************************************/
-
-function sess_open($save_path, $session_name) {
- return 1;
-}
-
-function sess_close() {
- return 1;
-}
-
-function sess_read($key) {
- global $user;
- $user = user_load(array("sid" => $key, "status" => 1));
-
- return !empty($user->session) ? $user->session : '';
-}
-
-function sess_write($key, $value) {
-
- db_query("UPDATE users SET hostname = '%s', session = '%s', timestamp = %d WHERE sid = '$key'", $_SERVER["REMOTE_ADDR"], $value, time());
-
- return '';
-}
-
-function sess_destroy($key) {
-
- db_query("UPDATE users SET hostname = '%s', timestamp = %d, sid = '' WHERE sid = '$key'", $_SERVER["REMOTE_ADDR"], time());
-}
-
-function sess_gc($lifetime) {
- return 1;
-}
-
-/*** Common functions ******************************************************/
-
-function user_external_load($authname) {
- $arr_uid = db_query("SELECT uid FROM authmap WHERE authname = '%s'", $authname);
-
- if (db_fetch_object($arr_uid)) {
- $uid = db_result($arr_uid);
- return user_load(array("uid" => $uid));
- }
- else {
- return 0;
- }
-}
-
-function user_load($array = array()) {
-
- /*
- ** Dynamically compose a SQL query:
- */
-
- $query = "";
-
- foreach ($array as $key => $value) {
- if ($key == "pass") {
- $query .= "u.$key = '". md5($value) ."' AND ";
- }
- else {
- $query .= "u.$key = '". check_query($value) ."' AND ";
- }
- }
- $result = db_query_range("SELECT u.*, r.name AS role FROM role r INNER JOIN users u ON r.rid = u.rid WHERE $query u.status < 3", 0, 1);
-
- $user = db_fetch_object($result);
- if ($user->data && $data = unserialize($user->data)) {
- foreach ($data as $key => $value) {
- if (!isset($user->$key)) {
- $user->$key = $value;
- }
- }
- }
-
- return $user;
-}
-
-function user_save($account, $array = array()) {
- /*
- ** Dynamically compose a SQL query:
- */
-
- $user_fields = user_fields();
- if ($account->uid) {
- $data = unserialize(db_result(db_query("SELECT data FROM users WHERE uid = %d", $account->uid)));
- foreach ($array as $key => $value) {
- if ($key == "pass") {
- $query .= "$key = '". md5($value) ."', ";
- }
- else if (substr($key, 0, 4) !== "auth") {
- if (in_array($key, $user_fields)) {
- // escape '%'s:
- $value = str_replace("%", "%%", $value);
- $query .= "$key = '". check_query($value) ."', ";
- }
- else {
- $data[$key] = $value;
- }
- }
- }
- $query .= "data = '". check_query(serialize($data)) ."', ";
-
- db_query("UPDATE users SET $query timestamp = %d WHERE uid = %d", time(), $account->uid);
-
- $user = user_load(array("uid" => $account->uid));
- }
- else {
- $array["timestamp"] = time();
-
- foreach ($array as $key => $value) {
- if ($key == "pass") {
- $fields[] = check_query($key);
- $values[] = "'". md5($value) ."'";
- }
- else if (substr($key, 0, 4) !== "auth") {
- if (in_array($key, $user_fields)) {
- $fields[] = check_query($key);
- $values[] = "'". check_query($value) ."'";
- }
- else {
- $data[$key] = $value;
- }
- }
- }
-
- $fields[] = "data";
- $values[] = "'". check_query(serialize($data)) ."'";
-
- db_query("INSERT INTO users (". implode(", ", $fields) .") VALUES (". implode(", ", $values) .")");
-
- $user = user_load(array("name" => $array["name"]));
- }
-
- foreach ($array as $key => $value) {
- if (substr($key, 0, 4) == "auth") {
- $authmaps[$key] = $value;
- }
- }
-
- if ($authmaps) {
- $result = user_set_authmaps($user, $authmaps);
- }
-
- return $user;
-}
-
-function user_set($account, $key, $value) {
- $account->data[$key] = $value;
- return $account;
-}
-
-function user_get($account, $key) {
- return $account->data[$key];
-}
-
-function user_validate_name($name) {
-
- /*
- ** Verify the syntax of the given name:
- */
-
- if (!$name) return t("You must enter a username.");
- if (ereg("^ ", $name)) return t("The username cannot begin with a space.");
- if (ereg(" \$", $name)) return t("The username cannot end with a space.");
- if (ereg(" ", $name)) return t("The username cannot contain multiple spaces in a row.");
- if (ereg("[^ a-zA-Z0-9@-@]", $name)) return t("The username contains an illegal character.");
- if (ereg('@', $name) && !eregi('@([0-9a-z](-?[0-9a-z])*\.)+[a-z]{2}([zmuvtg]|fo|me)?$', $name)) return t("The username is not a valid authentication ID.");
- if (strlen($name) > 56) return t("The username '%name' is too long: it must be less than 56 characters.", array("%name" => $name));
-}
-
-function user_validate_mail($mail) {
-
- if ($mail && !valid_email_address($mail)) {
- return t("The e-mail address '%mail' is not valid.", array("%mail" => $mail));
- }
-}
-
-function user_validate_authmap($account, $authname, $module) {
- $result = db_query("SELECT COUNT(*) from authmap WHERE uid != %d AND authname = '%s'", $account->uid, $authname);
- if (db_result($result) > 0) {
- $name = module_invoke($module, "info", "name");
- return t("The %u ID %s is already taken.", array("%u" => ucfirst($name), "%s" => "<i>$authname</i>"));
- }
-}
-
-function user_password($length = 10) {
-
- /*
- ** Generate a random alphanumeric password.
- */
-
- // This variable contains the list of allowable characters for the
- // password. Note that the number 0 and the letter 'O' have been
- // removed to avoid confusion between the two. The same is true
- // of 'I' and 1.
- $allowable_characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789";
- // We see how many characters are in the allowable list:
- $len = strlen($allowable_characters);
-
- // Seed the random number generator with the microtime stamp:
- mt_srand((double)microtime() * 1000000);
-
- // Declare the password as a blank string:
- $pass = "";
-
- // Loop the number of times specified by $length:
- for ($i = 0; $i < $length; $i++) {
-
- // Each iteration, pick a random character from the
- // allowable string and append it to the password:
- $pass .= $allowable_characters[mt_rand(0, $len - 1)];
- }
-
- return $pass;
-}
-
-function user_access($string) {
-
- global $user;
- static $perm;
-
- if ($user->uid == 1) {
- return 1;
- }
-
- /*
- ** To reduce the number of SQL queries, we cache the user's permissions
- ** in a static variable.
- */
-
- if (!$perm) {
- if ($user->uid) {
- $perm = db_result(db_query("SELECT p.perm FROM role r, permission p WHERE r.rid = p.rid AND name = '%s'", $user->role), 0);
- }
- else {
- $perm = db_result(db_query("SELECT p.perm FROM role r, permission p WHERE r.rid = p.rid AND name = 'anonymous user'"), 0);
- }
- }
-
- return strstr($perm, $string);
-}
-
-function user_mail($mail, $subject, $message, $header) {
- if (variable_get("smtp_library", "") && file_exists(variable_get("smtp_library", ""))) {
- include_once variable_get("smtp_library", "");
- return user_mail_wrapper($mail, $subject, $message, $header);
- }
- else {
- /*
- ** Note: if you are having problems with sending mail, or mails look wrong
- ** when they are recieved you may have to modify the str_replace to suit
- ** your systems.
- ** - \r\n will work under dos and windows.
- ** - \n will work for linux, unix and BSDs.
- ** - \r will work for macs.
- **
- ** According to RFC 2646, it's quite rude to not wrap your e-mails:
- **
- ** "The Text/Plain media type is the lowest common denominator of
- ** Internet email, with lines of no more than 997 characters (by
- ** convention usually no more than 80), and where the CRLF sequence
- ** represents a line break [MIME-IMT]."
- **
- ** CRLF === \r\n
- **
- ** http://www.rfc-editor.org/rfc/rfc2646.txt
- **
- */
- return mail($mail, $subject, str_replace("\r", "", $message), $header);
- }
-}
-
-function user_deny($type, $mask) {
-
- $allow = db_fetch_object(db_query("SELECT * FROM access WHERE status = '1' AND type = '%s' AND LOWER('%s') LIKE LOWER(mask)", $type, $mask));
-
- $deny = db_fetch_object(db_query("SELECT * FROM access WHERE status = '0' AND type = '%s' AND LOWER('%s') LIKE LOWER(mask)", $type, $mask));
-
- if ($deny && !$allow) {
- return 1;
- }
- else {
- return 0;
- }
-}
-
-function user_fields() {
- static $fields;
-
- if (!$fields) {
- $result = db_query("SELECT * FROM users WHERE uid = 1");
- if (db_num_rows($result)) {
- $fields = array_keys(db_fetch_array($result));
- }
- }
-
- // Make sure we return the default fields at least
- return is_array($fields) ? $fields: array("uid", "name", "pass", "mail", "homepage", "mode", "sort", "threshold", "theme", "signature", "timestamp", "hostname", "status", "timezone", "rating", "language", "sid", "init", "session", "data", "rid");
-}
-
-/*** Module hooks **********************************************************/
-
-function user_perm() {
- return array("administer users");
-}
-
-function user_search($keys) {
-
- $result = db_query_range("SELECT * FROM users WHERE name LIKE '%$keys%'", 0, 20);
- while ($account = db_fetch_object($result)) {
- $find[$i++] = array("title" => $account->name, "link" => (strstr(request_uri(), "admin") ? url("admin/user/edit/$account->uid") : url("user/view/$account->uid")), "user" => $account->name);
- }
- return $find;
-}
-
-function user_block($op = "list", $delta = 0) {
- global $user;
-
- $edit = $_POST["edit"];
-
- if ($op == "list") {
- $blocks[0]["info"] = t("User login");
- $blocks[1]["info"] = t("User information");
- $blocks[2]["info"] = t("Who's new");
-
- return $blocks;
- }
- else {
- switch ($delta) {
- case 0:
- if (!$user->uid) {
- /*
- ** For usability's sake, avoid showing two login forms on one
- ** page.
- */
-
- if (arg(0) == "user" && arg(1) != "view") {
- return;
- }
-
- $output = "<div class=\"user-login-block\">\n";
-
- /*
- ** Save the referer. We record where the user came from such
- ** that we/ can redirect him after having completed the login
- ** form.
- */
-
- if (empty($edit)) {
- $edit["destination"] = url($_GET["q"]);
- }
- // NOTE: special care needs to be taken because on pages with forms, such as node and comment submission pages, the $edit variable might already be set.
-
- $form = form_hidden("destination", $edit["destination"]);
- $form .= form_textfield(t("Username"), "name", $edit["name"], 15, 64);
- $form .= form_password(t("Password"), "pass", $pass, 15, 64);
-
- if (variable_get("user_remember", 0) == 0) {
- $form .= form_checkbox(t("Remember me"), "remember_me", 1, 0, 0);
- }
- elseif (variable_get("user_remember", 1) == 1) {
- $form .= form_hidden("remember_me", 1);
- }
-
- $form .= form_submit(t("Log in"));
-
- $output .= form($form, "post", url("user/login"));
-
- $output .= "</div>\n";
-
- if (variable_get("user_register", 1)) {
- $items[] = l(t("Create new account"), "user/register", array("title" => t("Create a new user account.")));
- }
- $items[] = l(t("Request new password"), "user/password", array("title" => t("Request new password via e-mail.")));
-
- $output .= theme("theme_item_list", $items);
-
- $block["subject"] = t("User login");
- $block["content"] = $output;
- return $block;
- }
- break;
- case 1:
- if ($user->uid) {
- $output = "<div class=\"user-information-block\">\n";
- $output .= theme("theme_menu_list", module_invoke_all("link", "menu.create"));
- $output .= theme("theme_menu_list", module_invoke_all("link", "menu.view"));
- $output .= theme("theme_menu_list", module_invoke_all("link", "menu.settings"));
- $output .= theme("theme_menu_list", module_invoke_all("link", "menu.misc"));
- $output .= "</div>\n";
-
- $block["subject"] = $user->name;
- $block["content"] = $output;
- return $block;
- }
- break;
- case 2:
- $result = db_query_range("SELECT uid, name FROM users WHERE status != '0' ORDER BY uid DESC", 0, 5);
- while ($account = db_fetch_object($result)) {
- $items[] = l((strlen($account->name) > 15 ? substr($account->name, 0, 15) . '...' : $account->name), "user/view/$account->uid");
- }
-
- $output = theme("theme_user_list", $items);
-
- $block["subject"] = t("Who's new");
- $block["content"] = $output;
- return $block;
- }
- }
-}
-
-function theme_user_list($items, $title = NULL) {
- return theme("theme_item_list",$items, $title);
-}
-
-function theme_menu_list($items, $title = NULL) {
- return theme("theme_item_list",$items, $title);
-}
-
-function user_link($type) {
-
- $links = array();
-
- if ($type == "page") {
- $links[] = l(t("user account"), "user", array("title" => t("Create a user account, request a new password or edit your account settings.")));
- }
-
- if ($type == "menu.settings") {
- $links[] = l(t("edit account"), "user/edit", array("title" => t("View and edit your account information.")));
- }
-
- if ($type == "menu.misc") {
- if (user_access("access administration pages")) {
- $links[] = l(t("administer %a", array("%a" => variable_get("site_name", "drupal"))), "admin", array("title" => t("Access administration pages.")));
- }
-
- $links[] = l(t("logout"), "user/logout", array("title" => t("Logout.")));
- }
-
- if ($type == "admin" && user_access("administer users")) {
- $help["user"] = t("Drupal allows users to register, login, logout, maintain user profiles, etc. No participant can use his own name to post content until he signs up for a user account.<br />Click on either the \"username\" or \"edit account\" to edit a user's information.");
- $help["create"] = t("This web page allows the administrators to register a new users by hand.<br />Note:<ul><li>You cannot have a user where either the E-Mail address or the username match another user in the system</li></ul>");
- $help["view"] = t("This page allows you to review and edit any user's profile. To edit a profile click on either the \"username\" or \"edit account\".");
- $help["view-active"] = t("This page allows you to review and edit an active user's profile. To edit a profile click on either the \"username\" or \"edit account\".");
- $help["view-new"] = t("This page allows you to review and edit a new user's profile. To edit a profile click on either the \"username\" or \"edit account\".");
- $help["view-block"] = t("This page allows you to review and edit a blocked user's profile. To edit a profile click on either the \"username\" or \"edit account\".");
- $help["view-role"] = "This page allows you to review and edit a user with role '%role's profile. To edit a profile click on either the \"username\" or \"edit account\".";
- $help["access-overview"] = t("Access rules allow Drupal administrators to choose usernames and E-Mail address that are prevented from using drupal. To enter the mask for E-Mail addresses click on <a href=\"%e-mail\">e-mail rules</a>, for the username mask click on <a href=\"%username\">username rules</a>", array("%e-mail" => url("admin/user/access/mail"), "%username" => url("admin/user/access/user")));
- $help["access-email"] = t("Setup and test the E-Mail access rules. The access function checks if you match a deny and <b>not</b> an allow. If you match <b>only</b> a deny then it is denied. Any other case, such as both a deny and an allow pattern matching, allows the pattern.<br />Notes: <ul><li>To delete a rule click on \"delete rule\".</li><li>The order of the rules does <b>not</b> matter.</li></ul>");
- $help["access-name"] = t("Setup and test the Username access rules. The access function checks if you match a deny and <b>not</b> an allow. If you do then it is denied. Any other case, such as a deny pattern and an allow pattern, allows the pattern.<br />Notes: <ul><li>To delete a rule click on \"delete rule\".</li><li>The order of the rules does <b>not</b> matter.</li></ul>");
- $help["permission"] = t("In this area you will define the <b>permissions</b> for each user role (Role names are defined in <a href=\"%role\">user roles</a>). Each permission describes a fine-grained logical operation, such as being able to access the administration pages, or adding/modifying a user account. You could say a permission represents access granted to a user to perform a set of operations.", array("%role" => url("admin/user/role")));
- $help["role"] = t("Roles allow you to fine tune the security and administration of drupal. A role defines a group of users that have certain privileges as defined in <a href=\"%permission\">user permissions</a>. Examples of roles include: anonymous user, authenticated user, moderator, administrator and so on. In this area you will define the <b>names</b> of the various roles. To delete a role choose \"edit role\"<br />By default, Drupal comes with two user roles: <ul><li>Anonymous user: this role is used for users that don't have a user account or that are not authenticated.</li><li>Authenticated user: this role is assigned automatically to authenticated users. Most registered users will belong to this user role unless specified otherwise.</li></ul>", array("%permission" => url("admin/user/permission")));
- $help["search"] = t("Enter a simple pattern ( '*' may be user as a wildcard match) to search for a username. For example, one may search for 'br' and Drupal might return 'brian', 'brad', and 'brenda'.");
-
- menu("admin/user", "user management", "user_admin", $help["user"], 2);
- menu("admin/user/create", "create new account", "user_admin", $help["create"], 1);
- menu("admin/user/account", "view user accounts", "user_admin", $help["view"], 2);
- menu("admin/user/access", "access rules", NULL, $help["access-overview"], 3);
- menu("admin/user/access/mail", "e-mail rules", "user_admin", $help["access-email"]);
- menu("admin/user/access/user", "username rules", "user_admin", $help["access-name"]);
- menu("admin/user/role", "user roles", "user_admin", $help["role"], 4);
- menu("admin/user/permission", "user permissions", "user_admin", $help["permission"], 5);
- menu("admin/user/search", "search accounts", "user_admin", $help["search"], 8);
- menu("admin/user/help", "help", "user_help", NULL, 9);
- menu("admin/user/edit", "edit user account", "user_admin", NULL, 0, 1); // hidden menu
- menu("admin/user/account/0", "active users", "user_admin", $help["view-active"], 1);
- menu("admin/user/account/1", "new users", "user_admin", $help["view-new"], 2);
- menu("admin/user/account/2", "blocked users", "user_admin", $help["view-block"], 3);
-
- $i = 3;
- foreach (user_roles(1) as $key => $value) {
- $help_msg = t($help["view-role"], array("%role" => $value));
- menu("admin/user/account/". $i++, "users with role '$value'", "user_admin", $help_msg, 4);
- }
- }
-
- return $links;
-}
-
-/*** Authentication methods ************************************************/
-
-function user_get_authname($account, $module) {
-
- /*
- ** Called by authentication modules in order to edit/view their authmap information.
- */
-
- $result = db_query("SELECT authname FROM authmap WHERE uid = %d AND module = '%s'", $account->uid, $module);
- return db_result($result);
-}
-
-
-function user_get_authmaps($authname = NULL) {
-
- /*
- ** Accepts an user object, $account, or an DA name and returns an
- ** associtive array of modules and DA names. Called at external login.
- */
-
- $result = db_query("SELECT authname, module FROM authmap WHERE authname = '%s'", $authname);
- if (db_num_rows($result) > 0) {
- while ($authmap = db_fetch_object($result)) {
- $authmaps[$authmap->module] = $authmap->authname;
- }
- return $authmaps;
- }
- else {
- return 0;
- }
-}
-
-function user_set_authmaps($account, $authmaps) {
- foreach ($authmaps as $key => $value) {
- $module = explode("_", $key, 2);
- if ($value) {
- $result = db_query("SELECT COUNT(*) from authmap WHERE uid = %d AND module = '%s'", $account->uid, $module["1"]);
- if (db_result($result) == 0) {
- $result = db_query("INSERT INTO authmap (authname, uid, module) VALUES ('%s', %d, '%s')", $value, $account->uid, $module[1]);
- }
- else {
- $result = db_query("UPDATE authmap SET authname = '%s' WHERE uid = %d AND module = '%s'", $value, $account->uid, $module["1"]);
- }
- }
- else {
- $result = db_query("DELETE FROM authmap WHERE uid = %d AND module = '%s'", $account->uid, $module["1"]);
- }
- }
- return $result;
-}
-
-function user_auth_help_links() {
- $links = array();
- foreach (module_list() as $module) {
- if (module_hook($module, "auth_help")) {
- $links[] = l(module_invoke($module, "info", "name"), "user/help#$module");
- }
- }
- return $links;
-}
-
-/*** User features *********************************************************/
-
-function user_login($edit = array(), $msg = "") {
- global $user, $base_url;
-
- /*
- ** If we are already logged on, go to the user page instead.
- */
-
- if ($user->uid) {
- drupal_goto(url("user"));
- }
-
- if (user_deny("user", $edit["name"])) {
- $error = t("The name '%s' has been denied access.", array("%s" => $edit["name"]));
- }
- else if ($edit["name"] && $edit["pass"]) {
-
- /*
- ** Try to log in the user locally:
- */
-
- if (!$user) {
- $name = $edit["name"];
- $pass = $edit["pass"];
- $user = user_load(array("name" => $name, "pass" => $pass, "status" => 1));
- }
-
- /*
- ** Strip name and server from ID:
- */
-
- if ($server = strrchr($edit["name"], "@")) {
- $name = substr($edit["name"], 0, strlen($edit["name"]) - strlen($server));
- $server = substr($server, 1);
- $pass = $edit["pass"];
- }
-
- /*
- ** When possible, determine corrosponding external auth source. Invoke source, and login user if successful:
- */
-
- if (!$user && $server && $result = user_get_authmaps("$name@$server")) {
- if (module_invoke(key($result), "auth", $name, $pass, $server)) {
- $user = user_external_load("$name@$server");
- watchdog("user", "external load: $name@$server, module: ". key($result));
- }
- else {
- $error = t("Invalid password for %s.", array("%s" => "<i>$name@$server</i>"));
- }
- }
-
- /*
- ** Try each external authentication source in series. Register user if successful.
- */
-
- else if (!$user && $server) {
- foreach (module_list() as $module) {
- if (module_hook($module, "auth")) {
- if (module_invoke($module, "auth", $name, $pass, $server)) {
- if (variable_get("user_register", 1) == 1 && !user_load(array("name" => "$name@$server"))) { //register this new user
- $user = user_save("", array("name" => "$name@$server", "pass" => user_password(), "init" => "$name@$server", "status" => 1, "authname_$module" => "$name@$server", "rid" => _user_authenticated_id()));
- watchdog("user", "new user: $name@$server ($module ID)", l("edit user", "admin/user/edit/$user->uid"));
- break;
- }
- }
- }
- }
- }
-
- if ($user->uid) {
- watchdog("user", "session opened for '$user->name'");
-
- /*
- ** Write session ID to database:
- */
-
- user_save($user, array("sid" => session_id()));
-
- /*
- ** If the user wants to be remembered, set the proper cookie such
- ** that the session won't expire.
- */
-
- $path = preg_replace("/.+\/\/[^\/]+(.*)/", "\$1/", $base_url);
- if ($edit["remember_me"]) {
- setcookie(session_name(), session_id(), time() + 3600 * 24 * 365, $path);
- }
- else {
- setcookie(session_name(), session_id(), FALSE, $path);
- }
-
- /*
- ** Redirect the user to the page he logged on from.
- */
-
- drupal_goto($edit["destination"]);
- }
- else {
- if (!$error) {
- $error = t("Sorry. Unrecognized username or password.") ." ". l(t("Have you forgotten your password?"), "user/password");
- }
- if ($server) {
- watchdog("user", "failed login for '$name@$server': $error");
- }
- else {
- watchdog("user", "failed login for '$name': $error");
- }
- }
- }
-
- /*
- ** Display error message (if any):
- */
-
- if ($error) {
- $output .= theme("theme_error", $error);
- }
-
- /*
- ** Save the referer. We record where the user came from such that we
- ** can redirect him after having completed the login form.
- */
-
- if (empty($edit)) {
- $edit["destination"] = url($_GET["q"]);
- }
- $output .= form_hidden("destination", $edit["destination"]);
-
- /*
- ** Display login form:
- */
-
- if ($msg) {
- $output .= "<p>$msg</p>";
- }
- if (count(user_auth_help_links()) > 0) {
- $output .= form_textfield(t("Username"), "name", $edit["name"], 30, 64, t("Enter your %s username, or an ID from one of our affiliates: %a.", array("%s" => variable_get("site_name", "local"), "%a" => implode(", ", user_auth_help_links()))));
- }
- else {
- $output .= form_textfield(t("Username"), "name", $edit["name"], 30, 64, t("Enter your %s username.", array("%s" => variable_get("site_name", "local"))));
- }
- $output .= form_password(t("Password"), "pass", $pass, 30, 64, t("Enter the password that accompanies your username."));
- $output .= form_checkbox(t("Remember me"), "remember_me", 1, 0, 0);
- $output .= form_submit(t("Log in"));
- $items[] = l(t("Request new password"), "user/password");
- if (variable_get("user_register", 1)) {
- $items[] = l(t("Create new account"), "user/register");
- }
- $output .= theme("theme_item_list", $items);
-
- return form($output, "post", url("user"));
-}
-
-function _user_authenticated_id() {
- return db_result(db_query("SELECT rid FROM role WHERE name = 'authenticated user'"));
-}
-
-function user_logout() {
- global $user;
-
- if ($user->uid) {
- watchdog("user", "session closed for user '$user->name'");
-
- /*
- ** Destroy the current session:
- */
-
- session_destroy();
- unset($user);
- }
-
- /*
- ** Redirect the user to his personal information page:
- */
-
- drupal_goto(url());
-
-}
-
-function user_pass($edit = array()) {
-
- global $base_url;
-
- if ($edit["name"]) {
- $account = db_fetch_object(db_query("SELECT uid, name, mail FROM users WHERE name = '%s'", $edit["name"]));
- if (!$account) $error = t("Sorry. The username <i>%s</i> is not recognized.", array("%s" => $edit["name"]));
- }
- else if ($edit["mail"]) {
- $account = db_fetch_object(db_query("SELECT uid, name, mail FROM users WHERE mail = '%s'", $edit["mail"]));
- if (!$account) $error = t("Sorry. The e-mail address <i>%s</i> is not recognized.", array("%s" => $edit["mail"]));
- }
- if ($account) {
-
- $from = variable_get("site_mail", ini_get("sendmail_from"));
- $pass = user_password();
-
- /*
- ** Save new password:
- */
-
- user_save($account, array("pass" => $pass));
-
- /*
- ** Mail new password:
- */
-
- $variables = array("%username" => $account->name, "%site" => variable_get("site_name", "drupal"), "%password" => $pass, "%uri" => $base_url, "%uri_brief" => substr($base_url, strlen("http://")), "%mailto" => $account->mail, "%date" => format_date(time()));
- $subject = strtr(variable_get("user_mail_pass_subject", _user_mail_text("pass_subject")), $variables);
- $body = strtr(variable_get("user_mail_pass_body", _user_mail_text("pass_body")), $variables);
- $headers = "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from";
- $mail_success = user_mail($account->mail, $subject, $body, $headers);
-
- if ($mail_success) {
- watchdog("user", "mail password: '". $account->name ."' &lt;". $account->mail ."&gt;");
- return t("Your password and further instructions have been sent to your e-mail address.");
- }
- else {
- watchdog("error", "error mailing new password: '". $account->name ."' &lt;". $account->mail ."&gt;");
- return t("Unable to send mail. Please contact the site admin.");
- }
- }
- else {
-
- // Display error message if necessary.
- if ($error) {
- $output .= theme("theme_error", $error);
- }
-
- /*
- ** Display form:
- */
-
- $output .= "<p>". sprintf(t("Enter your username %sor%s your e-mail address."), "<b><i>", "</i></b>") ."</p>";
- $output .= form_textfield(t("Username"), "name", $edit["name"], 30, 64);
- $output .= form_textfield(t("E-mail address"), "mail", $edit["mail"], 30, 64);
- $output .= form_submit(t("E-mail new password"));
- $items[] = l(t("Log in"), "user/login");
- if (variable_get("user_register", 1)) {
- $items[] = l(t("Create new account"), "user/register");
- }
- $output .= theme("theme_item_list", $items);
-
- return form($output, "post", url("user"));
- }
-}
-
-function user_register($edit = array()) {
- global $user, $base_url;
-
- $edit = $_POST["edit"];
- /*
- ** If we are already logged on, go to the user page instead.
- */
-
- if ($user->uid) {
- drupal_goto(url("user/edit"));
- }
-
- if ($edit["name"] && $edit["mail"]) {
- if ($error = user_validate_name($edit["name"])) {
- // do nothing
- }
- else if ($error = user_validate_mail($edit["mail"])) {
- // do nothing
- }
- else if (user_deny("user", $edit["name"])) {
- $error = t("The name '%s' has been denied access.", array("%s" => $edit["name"]));
- }
- else if (user_deny("mail", $edit["mail"])) {
- $error = t("The e-mail address '%s' has been denied access.", array("%s" => $edit["mail"]));
- }
- else if (db_num_rows(db_query("SELECT name FROM users WHERE LOWER(name) = LOWER('%s')", $edit["name"])) > 0) {
- $error = t("The name '%s' is already taken.", array("%s" => $edit["name"]));
- }
- else if (db_num_rows(db_query("SELECT mail FROM users WHERE LOWER(mail) = LOWER('%s')", $edit["mail"])) > 0) {
- $error = t("The e-mail address '%s' is already taken.", array("%s" => $edit["mail"]));
- }
- else if (variable_get("user_register", 1) == 0) {
- $error = t("Public registrations have been disabled by the site administrator.");
- }
- else {
- foreach (module_list() as $module) {
- if (module_hook($module, "user")) {
- $result = module_invoke($module, "user", "register_validate", $edit, $user);
- if (is_array($result)) {
- $data = array_merge($data, $result);
- }
- elseif (is_string($result)) {
- $error = $result;
- break;
- }
- }
- }
- if (!$error) {
- $success = 1;
- }
- }
- }
-
- if ($success) {
-
- $from = variable_get("site_mail", ini_get("sendmail_from"));
- $pass = user_password();
-
- // create new user account, noting whether administrator approval is required
- user_role_init();
- // TODO: is this necessary? Won't session_write replicate this?
- unset($edit["session"]);
- $account = user_save("", array_merge(array("name" => $edit["name"], "pass" => $pass, "init" => $edit["mail"], "mail" => $edit["mail"], "rid" => _user_authenticated_id(), "rating" => 0, "status" => (variable_get("user_register", 1) == 1 ? 1 : 0)), $data));
- watchdog("user", "new user: '". $edit["name"] ."' &lt;". $edit["mail"] ."&gt;", l("edit user", "admin/user/edit/$account->uid"));
-
- $variables = array("%username" => $edit["name"], "%site" => variable_get("site_name", "drupal"), "%password" => $pass, "%uri" => $base_url, "%uri_brief" => substr($base_url, strlen("http://")), "%mailto" => $edit["mail"], "%date" => format_date(time()));
-
- //the first user may login immediately, and receives a customized welcome e-mail.
- if ($account->uid == 1) {
- user_mail($edit["mail"], t("drupal user account details for %s", array("%s" => $edit["name"])), strtr(t("%username,\n\nYou may now login to %uri using the following username and password:\n\n username: %username\n password: %password\n\n". url("user/edit") ."\n\n--drupal"), $variables), "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
- // This should not be t()'ed. No point as its only shown once in the sites lifetime, and it would be bad to store the password
- $output .= "<p>Welcome to Drupal. You are user #1, which gives you full and immediate access. All future registrants will receive their passwords via e-mail, so please configure your e-mail settings using the Administration pages.</p><p> Your password is <b>$pass</b>. You may change your password on the next page.</p><p>Please login below.</p>";
- $output .= form_hidden("destination", url("user/edit"));
- $output .= form_hidden("name", $account->name);
- $output .= form_hidden("pass", $pass);
- $output .= form_submit(t("Log in"));
- return form($output);
- }
- else {
- if ($account->status) {
- /*
- ** Create new user account, no administrator approval required:
- */
-
- $subject = strtr(variable_get("user_mail_welcome_subject", _user_mail_text("welcome_subject")), $variables);
- $body = strtr(variable_get("user_mail_welcome_body", _user_mail_text("welcome_body")), $variables);
- user_mail($edit["mail"], $subject, $body, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
- return t("Your password and further instructions have been sent to your e-mail address.");
- }
- else {
- /*
- ** Create new user account, administrator approval required:
- */
- $subject = strtr(variable_get("user_mail_approval_subject", _user_mail_text("welcome_approval_subject")), $variables);
- $body = strtr(variable_get("user_mail_approval_body", _user_mail_text("welcome_approval_body")), $variables);
- user_mail($edit["mail"], $subject, $body, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
- user_mail(variable_get("site_mail", ini_get("sendmail_from")), $subject, t("%u has applied for an account.\n\n%uri", array("%u" => $account->name, "%uri" => url("admin/user/edit/$account->uid"))), "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
- return t("Thank you for applying for an account. Your account is currently pending approval by the site administrator.<br />In the meantime, your password and further instructions have been sent to your e-mail address.");
- }
- }
- }
- else {
- if ($error) {
- $output .= theme("theme_error", $error);
- }
- }
-
- // display the registration form
- $output .= variable_get("user_registration_help", "");
- $affiliates = user_auth_help_links();
- if (count($affiliates) > 0) {
- $affiliates = implode(", ", $affiliates);
- $output .= "<p>" . t("Note: If you have an account with one of our affiliates (%s), you may ". l("login now", "user/login") ." instead of registering.", array("%s" => $affiliates)) ."</p>";
- }
- $output .= form_textfield(t("Username"), "name", $edit["name"], 30, 64, t("Your full name or your preferred username: only letters, numbers and spaces are allowed."));
- $output .= form_textfield(t("E-mail address"), "mail", $edit["mail"], 30, 64, t("A password and instructions will be sent to this e-mail address, so make sure it is accurate."));
- foreach (module_list() as $module) {
- if (module_hook($module, "user")) {
- $output .= module_invoke($module, "user", "register_form", $edit, $user);
- }
- }
- $output .= form_submit(t("Create new account"));
- $items[] = l(t("Request new password"), "user/password");
- $items[] = l(t("Log in"), "user/login");
- $output .= theme("theme_item_list", $items);
-
- return form($output);
-}
-
-
-function user_delete() {
- global $user;
-
- $edit = $_POST["edit"];
-
- if ($edit["confirm"]) {
- watchdog("user","$user->name deactivated her own account.");
- db_query("UPDATE users SET mail = 'deleted', status = '0' WHERE uid = %d", $user->uid);
- $output .= t("Your account has been deactivated.");
- }
- else {
- $output .= form_item(t("Confirm Deletion"), t("You are about to deactivate your own user account. In addition, your e-mail address will be removed from the database."));
- $output .= form_hidden("confirm", 1);
- $output .= form_submit(t("Delete account"));
- $output = form($output);
- }
- return $output;
-}
-
-function user_edit($edit = array()) {
- global $user, $languages;
-
- if ($user->uid) {
- if ($edit["name"]) {
- if ($error = user_validate_name($edit["name"])) {
- // do nothing
- }
- else if ($error = user_validate_mail($edit["mail"])) {
- // do nothing
- }
- else if (db_num_rows(db_query("SELECT uid FROM users WHERE uid != '$user->uid' AND LOWER(name) = LOWER('%s')", $edit["name"])) > 0) {
- $error = t("The name '%s' is already taken.", array("%s" => $edit["name"]));
- }
- else if ($edit["mail"] && db_num_rows(db_query("SELECT uid FROM users WHERE uid != '$user->uid' AND LOWER(mail) = LOWER('%s')", $edit["mail"])) > 0) {
- $error = t("The e-mail address '%s' is already taken.", array("%s" => $edit["mail"]));
- }
- else if ($user->uid) {
- /*
- ** If required, check that proposed passwords match. If so,
- ** add new password to $edit.
- */
-
- if ($edit["pass1"]) {
- if ($edit["pass1"] == $edit["pass2"]) {
- $edit["pass"] = $edit["pass1"];
- }
- else {
- $error = t("The specified passwords do not match.");
- }
- }
- unset($edit["pass1"], $edit["pass2"]);
-
- /*
- ** Validate input fields to make sure users don't submit
- ** invalid form data.
- */
-
- if (!user_access("administer users")) {
- if (array_intersect(array_keys($edit), array("rid", "init", "rating", "session"))) {
- watchdog("warning", "detected malicious attempt to alter a protected database field");
- }
-
- $edit["rid"] = $user->rid;
- $edit["init"] = $user->init;
- $edit["rating"] = $user->rating;
- $edit["session"] = $user->session;
- }
-
- /*
- ** Have the modules that extend the user information validate
- ** their data.
- */
-
- foreach (module_list() as $module) {
- if (module_hook($module, "user")) {
- $result = module_invoke($module, "user", "edit_validate", $edit, $user);
- }
- if (is_array($result)) {
- $data = array_merge($data, $result);
- }
- elseif (is_string($result)) {
- $error = $result;
- break;
- }
- }
-
- if (!$error) {
- /*
- ** Save user information:
- */
-
- $user = user_save($user, array_merge($edit, $data));
-
- $output .= t("Your user information changes have been saved.");
- }
- }
- }
-
- if ($error) {
- $output .= theme("theme_error", $error);
- }
-
- if (!$edit) {
- $edit = object2array($user);
- }
-
- $output .= form_textfield(t("Username"), "name", $edit["name"], 30, 55, t("Your full name or your preferred username: only letters, numbers and spaces are allowed."));
- $output .= form_textfield(t("E-mail address"), "mail", $edit["mail"], 30, 55, t("Insert a valid e-mail address. All e-mails from the system will be sent to this address. The e-mail address is not made public and will only be used if you wish to receive a new password or wish to receive certain news or notifications by e-mail."));
-
- foreach (module_list() as $module) {
- if (module_hook($module, "user")) {
- $output .= module_invoke($module, "user", "edit_form", $edit, $user);
- }
- }
-
- $options = "<option value=\"\"". (("" == $key) ? " selected=\"selected\"" : "") .">". t("Default theme") ."</option>\n";
- foreach (theme_list() as $key => $value) {
- $options .= "<option value=\"$key\"". (($edit["theme"] == $key) ? " selected=\"selected\"" : "") .">$key - $value->description</option>\n";
- }
-
- $output .= form_item(t("Theme"), "<select name=\"edit[theme]\">$options</select>", t("Selecting a different theme will change the look and feel of the site."));
- for ($zone = -43200; $zone <= 46800; $zone += 3600) $zones[$zone] = date(variable_get("date_format_long", "l, F dS, Y - g:ia"), time() - date("Z") + $zone) ." (GMT ". $zone / 3600 .")";
- $output .= form_select(t("Time zone"), "timezone", $edit["timezone"], $zones, t("Select what time you currently have and your time zone settings will be set appropriate."));
- $output .= form_select(t("Language"), "language", $edit["language"], $languages, t("Selecting a different language will change the language of the site."));
- $output .= form_item(t("Password"), "<input type=\"password\" name=\"edit[pass1]\" size=\"12\" maxlength=\"24\" /> <input type=\"password\" name=\"edit[pass2]\" size=\"12\" maxlength=\"24\" />", t("Enter your new password twice if you want to change your current password or leave it blank if you are happy with your current password."));
- $output .= form_submit(t("Save user information"));
-
- $output = form($output, "post", 0, "enctype=\"multipart/form-data\"");
- // the "enctype" attribute is required to upload files such as avatars
- }
- else {
- $output = user_login();
- }
-
- return $output;
-}
-
-function user_menu() {
- $links[] = l(t("view user information"), "user/view");
- $links[] = l(t("edit user information"), "user/edit");
- $links[] = l(t("delete account"), "user/delete");
-
- return "<div style=\"text-align: center;\">". implode(" &middot; ", $links) ."</div>";
-}
-
-function user_view($uid = 0) {
- global $user;
-
- if (!$uid) {
- $uid = $user->uid;
- }
-
- if ($user->uid && $user->uid == $uid) {
- $output = form_item(t("Name"), "$user->name ($user->init)");
- $output .= form_item(t("E-mail address"), $user->mail, t("Please note that only you can see your own e-mail address - it is not publicly visible."));
-
- foreach (module_list() as $module) {
- if (module_hook($module, "user")) {
- $output .= module_invoke($module, "user", "view_private", "", $user);
- }
- }
-
- theme("header");
- theme("box", t("User account"), user_menu());
- theme("box", t("View user information"), $output);
- theme("footer");
- }
- else if ($uid && $account = user_load(array("uid" => $uid, "status" => 1))) {
- $output = form_item(t("Name"), $account->name);
-
- foreach (module_list() as $module) {
- if (module_hook($module, "user")) {
- $output .= module_invoke($module, "user", "view_public", "", $account);
- }
- }
-
- theme("header");
- theme("box", t("View user information"), $output);
- theme("footer");
- }
- else {
- $output = user_login();
- theme("header");
- theme("box", t("User login"), $output);
- if (variable_get("user_register", 1)) {
- theme("box", t("Create new user account"), user_register());
- }
- theme("box", t("Request new password"), user_pass());
- theme("footer");
- }
-}
-
-function user_page() {
-
- $edit = $_POST["edit"];
- $op = $_POST["op"];
-
- if (empty($op)) {
- $op = arg(1);
- }
-
- switch ($op) {
- case t("E-mail new password"):
- case "password":
- theme("header");
- theme("box", t("E-mail new password"), user_pass($edit));
- theme("footer");
- break;
- case t("Create new account"):
- case "register":
- $output = user_register($edit);
- theme("header");
- if (variable_get("user_register", 1)) {
- theme("box", t("Create new account"), $output);
- }
- else {
- print message_access();
- }
- theme("footer");
- break;
- case t("Log in"):
- case "login":
- $output = user_login($edit);
- theme("header");
- theme("box", t("Log in"), $output);
- theme("footer");
- break;
- case t("Delete account"):
- case "delete":
- $output = user_delete();
- theme("header");
- theme("box", t("User account"), user_menu());
- theme("box", t("Delete account"), $output);
- theme("footer");
- break;
- case t("Save user information"):
- case "edit":
- $output = user_edit($edit);
- $GLOBALS["theme"] = theme_init();
- theme("header");
- theme("box", t("User account"), user_menu());
- theme("box", t("Edit user information"), $output);
- theme("footer");
- break;
- case "view":
- user_view(arg(2));
- break;
- case t("Logout"):
- case "logout":
- print user_logout();
- break;
- case "help":
- theme("header");
- theme("box", t("Distributed authentication"), user_help_users_da());
- theme("footer");
- break;
- default:
- print user_view();
- }
-
-}
-
-/*** Administrative features ***********************************************/
-
-function _user_mail_text($message) {
- switch ($message) {
- case "welcome_subject":
- return "Account details for %username at %site";
-
- case "welcome_body":
- return t("%username,\n\nThank you for registering at %site. You may now log in to ". url("user/login") ." using the following username and password:\n\nusername: %username\npassword: %password\n\nAfter logging in, you may wish to change your password at ". url("user/edit") ."\n\nYour new %site membership also enables to you to login to other Drupal powered websites (e.g. http://www.drop.org/) without registering. Just use the following Drupal ID and password:\n\nDrupal ID: %username@%uri_brief\npassword: %password\n\n\n-- %site team");
-
- case "welcome_approval_subject":
- return "Account details for %username at %site (pending admin approval)";
-
- case "welcome_approval_body":
- return t("%username,\n\nThank you for registering at %site. Your application for an account is currently pending approval. Once it has been granted, you may log in to ". url("user/login") ." using the following username and password:\n\nusername: %username\npassword: %password\n\nAfter logging in, you may wish to change your password at ". url("user/edit") ."\n\nYour new %site membership also enables to you to login to other Drupal powered websites (e.g. http://www.drop.org/) without registering. Just use the following Drupal ID and password:\n\nDrupal ID: %username@%uri_brief\npassword: %password\n\n\n-- %site team");
-
- case "pass_subject":
- return "Replacement login information for %username at %site";
-
- case "pass_body":
- return t("%username,\n\nHere is your new password for %site. You may now login to ". url("user/login") ." using the following username and password:\n\nusername: %username\npassword: %password\n\nAfter logging in, you may wish to change your password at "). url("user/edit");
- }
-}
-
-function user_settings() {
- $output .= form_select(t("Public registrations"), "user_register", variable_get("user_register", 1), array(t("Only site administrators can create new user accounts."), t("Visitors can create accounts and no administrator approval is required."), t("Visitors can create accounts but administrator approval is required.")));
-
- $output .= form_select(t("Remember authenticated users"), "user_remember", variable_get("user_remember", 0), array(t("Let the user decide whether he should be logged out when leaving the site."), t("Authenticated users are not logged out upon leaving the site."), t("Authenticated users are logged out upon leaving the site.")));
-
- $output .= form_textarea(t("User registration guidelines"), "user_registration_help", variable_get("user_registration_help", ""), 70, 4, t("This text is displayed at the top of the user registration form. It's useful for helping or instructing your users."));
-
- $output .= form_textfield(t("Subject of welcome e-mail"), "user_mail_welcome_subject", variable_get("user_mail_welcome_subject", _user_mail_text("welcome_subject")), 70, 180, t("Customize the subject of your welcome e-mail, which is sent to new members upon registering.") . " " . t("Available variables are:") . " " . "%username, %site, %password, %uri, %uri_brief, %mailto, %date");
-
- $output .= form_textarea(t("Body of welcome e-mail"), "user_mail_welcome_body", variable_get("user_mail_welcome_body", _user_mail_text("welcome_body")), 70, 10, t("Customize the body of the welcome e-mail, which is sent to new members upon registering.") . " " . t("Available variables are:") . " " . "%username, %site, %password, %uri, %uri_brief, %mailto");
-
- $output .= form_textfield(t("Subject of welcome e-mail (awaiting admin approval)"), "user_mail_approval_subject", variable_get("user_mail_approval_subject", _user_mail_text("welcome_approval_subject")), 70, 180, t("Customize the subject of your awaiting approval welcome e-mail, which is sent to new members upon registering.") . " " . t("Available variables are:") . " " . "%username, %site, %password, %uri, %uri_brief, %mailto, %date");
-
- $output .= form_textarea(t("Body of welcome e-mail (awaiting admin approval)"), "user_mail_approval_body", variable_get("user_mail_approval_body", _user_mail_text("welcome_approval_body")), 70, 10, t("Customize the body of the awaiting approval welcome e-mail, which is sent to new members upon registering.") . " " . t("Available variables are:") . " " . "%username, %site, %password, %uri, %uri_brief, %mailto");
-
- $output .= form_textfield(t("Subject of password recovery e-mail"), "user_mail_pass_subject", variable_get("user_mail_pass_subject", _user_mail_text("pass_subject")), 70, 180, t("Customize the Subject of your forgotten password e-mail.") . " " . t("Available variables are:") . " " . "%username, %site, %password, %uri, %uri_brief, %mailto, %date");
-
- $output .= form_textarea(t("Body of password recovery e-mail"), "user_mail_pass_body", variable_get("user_mail_pass_body", _user_mail_text("pass_body")), 70, 10, t("Customize the body of the forgotten password e-mail.") . " " . t("Available variables are:") . " " . "%username, %site, %password, %uri, %uri_brief, %mailto");
-
- return $output;
-}
-
-function user_admin_create($edit = array()) {
-
- if ($edit["name"] || $edit["mail"]) {
- if ($error = user_validate_name($edit["name"])) {
- // do nothing
- }
- else if ($error = user_validate_mail($edit["mail"])) {
- // do nothing
- }
- else if (db_num_rows(db_query("SELECT name FROM users WHERE LOWER(name) = LOWER('%s')", $edit["name"])) > 0) {
- $error = t("The name '%s' is already taken.", array("%s" => $edit["name"]));
- }
- else if (db_num_rows(db_query("SELECT mail FROM users WHERE LOWER(mail) = LOWER('%s')", $edit["mail"])) > 0) {
- $error = t("The e-mail address '%s' is already taken.", array("%s" => $edit["mail"]));
- }
- else {
- $success = 1;
- }
- }
-
- if ($success) {
- watchdog("user", "new user: '". $edit["name"] ."' &lt;". $edit["mail"] ."&gt;");
-
- user_save("", array("name" => $edit["name"], "pass" => $edit["pass"], "init" => $edit["mail"], "mail" => $edit["mail"], "rid" => _user_authenticated_id(), "status" => 1));
-
- return "Created a new user '". $edit["name"] ."'. No e-mail has been sent.";
- }
- else {
-
- if ($error) {
- $output .= theme("theme_error", $error);
- }
-
- $output .= form_textfield(t("Username"), "name", $edit["name"], 30, 55, t("Provide the username of the new account."));
- $output .= form_textfield(t("E-mail address"), "mail", $edit["mail"], 30, 55, t("Provide the e-mail address associated with the new account."));
- $output .= form_textfield(t("Password"), "pass", $edit["pass"], 30, 55, t("Provide a password for the new account."));
- $output .= form_submit(t("Create account"));
-
- return form($output);
- }
-}
-
-function user_admin_access($edit = array()) {
-
- $op = $_POST["op"];
- $type = arg(3);
- $id = arg(4);
-
- if (empty($type)) {
- return;
- }
-
- if ($type == "mail") {
- $output .= "<h3>" . t("E-mail rules") . "</h3>";
- }
-
- if ($type == "user") {
- $output .= "<h3>" . t("Username rules") . "</h3>";
- }
-
- if ($op == t("Add rule")) {
- db_query("INSERT INTO access (mask, type, status) VALUES ('%s', '%s', %d)", $edit["mask"], $type, $edit["status"]);
- }
- else if ($op == t("Check")) {
- if (user_deny($type, $edit["test"])) {
- $message = "<b>'". $edit["test"] ."' is not allowed.</b><p />";
- }
- else {
- $message = "<b>'". $edit["test"] ."' is allowed.</b><p />";
- }
- }
- else if ($id) {
- db_query("DELETE FROM access WHERE aid = %d", $id);
- }
-
- $header = array(t("type"), t("mask"), t("operations"));
-
- $result = db_query("SELECT * FROM access WHERE type = '%s' AND status = '1' ORDER BY mask", $type);
-
- while ($rule = db_fetch_object($result)) {
- $rows[] = array(t("Allow"), $rule->mask, array("data" => l(t("delete rule"), "admin/user/access/$type/$rule->aid"), "align" => "center"));
- }
-
- $result = db_query("SELECT * FROM access WHERE type = '%s' AND status = '0' ORDER BY mask", $type);
-
- while ($rule = db_fetch_object($result)) {
- $rows[] = array(t("Deny"), $rule->mask, l(t("delete rule"), "admin/user/access/$type/$rule->aid"));
- }
-
- $rows[] = array("<select name=\"edit[status]\"><option value=\"1\">". t("Allow") ."</option><option value=\"0\">". t("Deny") ."</option></select>", "<input size=\"32\" maxlength=\"64\" name=\"edit[mask]\" />", "<input type=\"submit\" name=\"op\" value=\"" . t("Add rule") . "\" />");
-
- $output .= table($header, $rows);
-
- $output .= "<p><small>%: " . t("Matches any number of characters, even zero characters") . ".<br />_: " . t("Matches exactly one character.") . "</small></p>";
-
- if ($type != "user") {
- $output .= "<h3>" . t("Check e-mail address") . "</h3>";
- }
- else {
- $output .= "<h3>" . t("Check username") . "</h3>";
- }
-
- $output .= "$message<input type=\"text\" size=\"32\" maxlength=\"64\" name=\"edit[test]\" value=\"". $edit["test"] ."\" /><input type=\"submit\" name=\"op\" value=\"" . t("Check") . "\" />";
-
- return form($output);
-}
-
-function user_roles($membersonly = 0) {
- $result = db_query("SELECT * FROM role ORDER BY name");
- while ($role = db_fetch_object($result)) {
- if (!$membersonly || ($membersonly && $role->name != "anonymous user")) {
- $roles[$role->rid] = $role->name;
- }
- }
- return $roles;
-}
-
-function user_admin_perm($edit = array()) {
-
- if ($edit) {
-
- /*
- ** Save permissions:
- */
-
- $result = db_query("SELECT * FROM role");
- while ($role = db_fetch_object($result)) {
- // delete, so if we clear every checkbox we reset that role;
- // otherwise permissions are active and denied everywhere
- db_query("DELETE FROM permission WHERE rid = %d", $role->rid);
- $perm = $edit[$role->rid] ? implode(", ", array_keys($edit[$role->rid])) : "";
- if ($perm) {
- db_query("INSERT INTO permission (rid, perm) VALUES (%d, '%s')", $role->rid, $perm);
- }
-
- }
- }
-
- /*
- ** Compile permission array:
- */
-
- foreach (module_list() as $name) {
- if (module_hook($name, "perm")) {
- $perms = array_merge($perms, module_invoke($name, "perm"));
- }
- }
- asort($perms);
-
- /*
- ** Compile role array:
- */
-
- $result = db_query("SELECT r.rid, p.perm FROM role r LEFT JOIN permission p ON r.rid = p.rid ORDER BY name");
- $roles = array();
- while ($role = db_fetch_object($result)) {
- $role_perms[$role->rid] = $role->perm;
- }
-
- $result = db_query("SELECT rid, name FROM role ORDER BY name");
- $role_names = array();
- while ($role = db_fetch_object($result)) {
- $role_names[$role->rid] = $role->name;
- }
-
- /*
- ** Render roles / permission overview:
- */
-
- $header = array_merge(array("&nbsp;"), $role_names);
-
- foreach ($perms as $perm) {
- $row[] = t($perm);
- foreach ($role_names as $rid => $name) {
- $row[] = "<input type=\"checkbox\" name=\"edit[$rid][$perm]\"". (strstr($role_perms[$rid], $perm) ? " checked=\"checked\"" : "") ." />";
- }
- $rows[] = $row;
- unset($row);
- }
-
- $output = table($header, $rows);
- $output .= form_submit(t("Save permissions"));
-
- return form($output);
-}
-
-function user_admin_role($edit = array()) {
-
- $op = $_POST["op"];
- $id = arg(3);
-
- if ($op == t("Save role")) {
- db_query("UPDATE role SET name = '%s' WHERE rid = %d", $edit["name"], $id);
- }
- else if ($op == t("Delete role")) {
- db_query("DELETE FROM role WHERE rid = %d", $id);
- db_query("DELETE FROM permission WHERE rid = %d", $id);
- }
- else if ($op == t("Add role")) {
- db_query("INSERT INTO role (name) VALUES ('%s')", $edit["name"]);
- }
- else if ($id) {
- /*
- ** Display role form:
- */
-
- $role = db_fetch_object(db_query("SELECT * FROM role WHERE rid = %d", $id));
-
- $output .= form_textfield(t("Role name"), "name", $role->name, 32, 64, t("The name for this role. Example: 'moderator', 'editorial board', 'site architect'."));
- $output .= form_submit(t("Save role"));
- $output .= form_submit(t("Delete role"));
-
- $output = form($output);
- }
-
- if (!$output) {
- /*
- ** Render role overview:
- */
-
- $result = db_query("SELECT * FROM role ORDER BY name");
-
- $header = array(t("name"), t("operations"));
- while ($role = db_fetch_object($result)) {
- if ($role->name != "anonymous user" && $role->name != "authenticated user") {
- $rows[] = array($role->name, array("data" => l(t("edit role"), "admin/user/role/$role->rid"), "align" => "center"));
- }
- else {
- $rows[] = array($role->name, array("data" => "<span class=\"disabled\">". t("locked") ."</span>", "align" => "center"));
- }
- }
- $rows[] = array("<input type=\"text\" size=\"32\" maxlength=\"64\" name=\"edit[name]\" />", "<input type=\"submit\" name=\"op\" value=\"". t("Add role") ."\" />");
-
- $output = table($header, $rows);
- $output = form($output);
- }
-
- return $output;
-}
-
-function user_admin_edit($edit = array()) {
-
- $op = $_POST["op"];
- $id = arg(3);
-
- if ($account = user_load(array("uid" => $id))) {
-
- if ($op == t("Save account")) {
- foreach (module_list() as $module) {
- if (module_hook($module, "user")) {
- $result = module_invoke($module, "user", "edit_validate", $edit, $account);
- }
- if (is_array($result)) {
- $data = array_merge($data, $result);
- }
- elseif (is_string($result)) {
- $error = $result;
- break;
- }
- }
-
- // TODO: this display/edit/validate should be moved to a new profile.module implementing the _user hooks
- if ($error = user_validate_name($edit["name"])) {
- // do nothing
- }
- else if ($error = user_validate_mail($edit["mail"])) {
- // do nothing
- }
- else if (db_num_rows(db_query("SELECT uid FROM users WHERE uid != %d AND LOWER(name) = LOWER('%s')", $account->uid, $edit["name"])) > 0) {
- $error = t("The name '%s' is already taken.", array("%s" => $edit["name"]));
- }
- else if ($edit["mail"] && db_num_rows(db_query("SELECT uid FROM users WHERE uid != %d AND LOWER(mail) = LOWER('%s')", $account->uid, $edit["mail"])) > 0) {
- $error = t("The e-mail address '%s' is already taken.", array("%s" => $edit["mail"]));
- }
-
- /*
- ** If required, check that proposed passwords match. If so,
- ** add new password to $edit.
- */
-
- if ($edit["pass1"]) {
- if ($edit["pass1"] == $edit["pass2"]) {
- $edit["pass"] = $edit["pass1"];
- }
- else {
- $error = t("The specified passwords do not match.");
- }
- }
-
- unset($edit["pass1"], $edit["pass2"]);
- if (!$error) {
- $account = user_save($account, array_merge($edit, $data));
- $output .= status(t("your user information changes have been saved."));
- }
- else {
- $output .= theme("theme_error", $error);
- }
- }
- else if ($op == t("Delete account")) {
- if ($edit["status"] == 0) {
- db_query("DELETE FROM users WHERE uid = %d", $account->uid);
- db_query("DELETE FROM authmap WHERE uid = %d", $account->uid);
- $output .= t("The account has been deleted.");
- }
- else {
- $output .= t("Failed to delete account: the account has to be blocked first.");
- }
- }
-
- /*
- ** Display user form:
- */
-
- $output .= form_item(t("User ID"), $account->uid);
- $output .= form_textfield(t("Username"), "name", $account->name, 30, 55, t("Your full name or your preferred username: only letters, numbers and spaces are allowed."));
- $output .= form_textfield(t("E-mail address"), "mail", $account->mail, 30, 55, t("Insert a valid e-mail address. All e-mails from the system will be sent to this address. The e-mail address is not made public and will only be used if you wish to receive a new password or wish to receive certain news or notifications by e-mail."));
-
- foreach (module_list() as $module) {
- if (module_hook($module, "user")) {
- $output .= module_invoke($module, "user", "edit_form", $edit, $account);
- }
- }
-
- $options = "<option value=\"\"". (("" == $key) ? " selected=\"selected\"" : "") .">". t("Default theme") ."</option>\n";
- foreach (theme_list() as $key => $value) {
- $options .= "<option value=\"$key\"". (($edit["theme"] == $key) ? " selected=\"selected\"" : "") .">$key - $value->description</option>\n";
- }
- $output .= form_item(t("Theme"), "<select name=\"edit[theme]\">$options</select>", t("Selecting a different theme will change the look and feel of the site."));
- for ($zone = -43200; $zone <= 46800; $zone += 3600) $zones[$zone] = date("l, F dS, Y - h:i A", time() - date("Z") + $zone) ." (GMT ". $zone / 3600 .")";
- $output .= form_select(t("Time zone"), "timezone", $account->timezone, $zones, t("Select what time you currently have and your time zone settings will be set appropriate."));
- $output .= form_select(t("Language"), "language", $account->language, $languages, t("Selecting a different language will change the language of the site."));
- $output .= form_item(t("Password"), "<input type=\"password\" name=\"edit[pass1]\" size=\"12\" maxlength=\"24\" /> <input type=\"password\" name=\"edit[pass2]\" size=\"12\" maxlength=\"24\" />", t("Enter a new password twice if you want to change the current password for this user or leave it blank if you are happy with the current password."));
- $output .= form_select(t("Status"), "status", $account->status, array(t("Blocked"), t("Active")));
- $output .= form_select(t("Role"), "rid", $account->rid, user_roles(1));
-
- $output .= form_submit(t("Save account"));
- $output .= form_submit(t("Delete account"));
-
- $output = form($output, "post", 0, "enctype=\"multipart/form-data\"");
-
- }
- else {
- $output = t("No such user");
- }
-
- return $output;
-}
-
-function user_admin_account() {
- $query = arg(3);
-
- $queries = array("ORDER BY u.timestamp DESC", "ORDER BY u.uid DESC", "WHERE u.status = 0 ORDER BY u.uid DESC");
- foreach (user_roles(1) as $key => $value) {
- $queries[] = "WHERE r.name = '$value' ORDER BY u.uid DESC";
- }
-
- $result = pager_query("SELECT u.uid, u.name, u.timestamp FROM role r INNER JOIN users u ON r.rid = u.rid ". $queries[$query ? $query : 0], 50);
-
- $header = array(t("username"), t("last access"), t("operations"));
- while ($account = db_fetch_object($result)) {
- $rows[] = array(format_name($account), format_date($account->timestamp, "small"), l(t("edit account"), "admin/user/edit/$account->uid"));
- }
-
- $pager = pager_display(NULL, 50, 0, "admin");
- if (!empty($pager)) {
- $rows[] = array(array("data" => $pager, "colspan" => 3));
- }
- return table($header, $rows);
-}
-
-function user_role_init() {
- $role = db_fetch_object(db_query("SELECT * FROM role WHERE name = 'anonymous user'"));
- if (!$role) {
- db_query("INSERT INTO role (name) VALUES ('anonymous user')");
- }
-
- $role = db_fetch_object(db_query("SELECT * FROM role WHERE name = 'authenticated user'"));
- if (!$role) {
- db_query("INSERT INTO role (name) VALUES ('authenticated user')");
- }
-}
-
-function user_admin() {
-
- $op = $_POST["op"];
- $edit = $_POST["edit"];
-
- if (user_access("administer users")) {
- /*
- ** Initialize all the roles and permissions:
- */
-
- user_role_init();
-
- if (empty($op)) {
- $op = arg(2);
- }
-
- switch ($op) {
- case "search":
- print search_type("user", url("admin/user/search"), $_POST["keys"]);
- break;
- case t("Add rule"):
- case t("Check"):
- case "access":
- print user_admin_access($edit);
- break;
- case t("Save permissions"):
- case "permission":
- print user_admin_perm($edit);
- break;
- case t("Create account"):
- case "create":
- print user_admin_create($edit);
- break;
- case t("Add role"):
- case t("Delete role"):
- case t("Save role"):
- case "role":
- print user_admin_role($edit);
- break;
- case t("Delete account"):
- case t("Save account"):
- case "edit":
- print user_admin_edit($edit);
- break;
- default:
- print user_admin_account();
- }
- }
-}
-// this help is for end users
-function user_help_users_da() {
- $site = "<i>". variable_get("site_name", "this website"). "</i>";
-
- $output = "
- <h3>Distributed authentication<a id=\"da\"></a></h3>
- <p>One of the more tedious moments in visiting a new website is filling out the
- registration form. Here at %s, you do not have to fill out a registration form
- if you are already a member of ";
-
- $output .= implode(", ", user_auth_help_links());
- $output .= ". This capability is called <i>Distributed
- Authentication</i>, and is unique to <a href=\"http://www.drupal.org\">Drupal</a>,
- the software which powers %s.</p>
- <p>Distributed authentication enables a new user to input a username and password into the login box,
- and immediately be recognized, even if that user never registered at %s. This
- works because Drupal knows how to communicate with external registration databases.
- For example, lets say that new user 'Joe' is already a registered member of
- <a href=\"http://www.delphiforums.com\">Delphi Forums</a>. Drupal informs Joe
- on registration and login screens that he may login with his Delphi ID instead
- of registering with %s. Joe likes that idea, and logs in with a username
- of joe@remote.delphiforums.com and his usual Delphi password. Drupal then contacts
- the <i>remote.delphiforums.com</i> server behind the scenes (usually using <a href=\"http://www.xmlrpc.com\">XML-RPC</a>,
- <a href=\"http://www.w3.org/Protocols/\">HTTP POST</a>, or <a href=\"http://www.soapware.org\">SOAP</a>)
- and asks: \"Is the password for user Joe correct?\". If Delphi replies yes, then
- we create a new $site account for Joe and log him into it. Joe may keep
- on logging into %s in the same manner, and he will always be logged into the
- same account.</p>";
-
- $output = strtr($output, array("%s" => $site));
-
- foreach (module_list() as $module) {
- if (module_hook($module, "auth")) {
- $output .= "<h4><a id=\"$module\"></a>" . module_invoke($module, "info", "name") . "</h4>";
- $output .= module_invoke($module, "auth_help");
- }
- }
-
- return $output;
-}
-
-// the following functions comprise help for admins and developers
-function user_help() {
- $output .= user_help_admin();
- $output .= user_help_admin_da();
- $output .= user_help_devel_da();
- $output .= user_help_devel_userhook();
- return t($output);
-}
-
-function user_help_admin() {
- $output .= "<h3>Introduction</h3><p>Drupal offers a powerful access system that allows users to register, login, logout, maintain user profiles, etc. By using \"". l ("roles", "admin/user/role") ."\" you can setup fine grained ". l("permissions", "admin/user/permission") ." allowing each role to do only what you want them to. Each user is assigned to a role. By default there are two roles \"anonymous\" - a user who has not logged in, and \"authorized\" a user who has signed up and who has been authorized. As anonymous users, participants suffer numerous disadvantages, for example they cannot sign their names to nodes, and their moderated posts beginning at a lower score.</p>";
- $output .= "<p>In contrast, those with a user account can use their own name or handle and are granted various privileges: the most important is probably the ability to moderate new submissions, to rate comments, and to fine-tune the site to their personal liking, with saved personal settings. Drupal themes make fine tuning quite a pleasure.</p>";
- $output .= "<p>Registered users need to authenticate by supplying either a local username and password, or a remote username and password such as a ". l("jabber", "www.jabber.org") .", ". l("Delphi", "www.delphiforums.com") .", or one from another ". l("Drupal", "www.drupal.org") ." website. See ". l("distributed authentication", "#da") ." for more information on this innovative feature.";
- $output .= "The local username and password, hashed with Message Digest 5 (MD5), are stored in your database. When you enter a password it is also hashed with MD5 and compaired with what is in the database. If the hashes match, the username and password are correct. Once a user authenticated session is started, and until that session is over, the user won't have to re-authenticate. To keep track of the individual sessions, Drupal relies on ". l("PHP's session support", "www.php.net/manual/en/ref.session.php") .". A visitor accessing your website is assigned an unique ID, the so-called session ID, which is stored in a cookie. For security's sake, the cookie does not contain personal information but acts as a key to retrieve the information stored on your server's side. When a visitor accesses your site, Drupal will check whether a specific session ID has been sent with the request. If this is the case, the prior saved environment is recreated.</p>";
- $output .= "<h3>User preferences and profiles</h3><p>Each Drupal user has a profile, and a set of preferences which may be edited by clicking on the ". l("user account", "user") ." link. Of course, a user must be logged into reach those pages. There, users will find a page for changing their preferred time zone, language, username, e-mail address, password, theme, signature, homepage, and ". l("distributed authentication", "#da") ." names. Changes made here take effect immediately. Also, administrators may make profile and preferences changes in the ". l("Admin Center", "admin/user") ." on behalf of their users.</p>";
- $output .= "<p>Module developers are provided several hooks for adding custom fields to the user view/edit pages. These hooks are described in the Developer section of the ". l("Drupal Handbook", "drupal.org/node/view/316") .". For an example, see the <code>jabber_user()</code> function in <i>/modules/jabber.module</i>.</p>";
- return $output;
-}
-
-function user_help_admin_da() {
-
- $output .= "<h3>Distributed authentication<a id=\"da\"> </a></h3><p>One of the more tedious moments in visiting a new website is filling out the registration form. The reg form provides helpful information to the website owner, but not much value for the user. The value for the end user is usually the ability to post a messages or receive personalized news, etc. Distributed authentication (DA) gives the user what they want without having to fill out the reg form. Removing this obstacle yields more registered and active users for the website.</p>";
- $output .= "<p>DA enables a new user to input a username and password into the login box and immediately be recognized, even if that user never registered on your site. This works because Drupal knows how to communicate with external registration databases. For example, lets say that your new user 'Joe' is already a registered member of Delphi Forums. If your Drupal has delphi.module installed, then Drupal will inform Joe on the registration and login screens that he may login with his Delphi ID instead of registering with your Drupal instance. Joe likes that idea, and logs in with a username of joe@remote.delphiforums.com and his usual Delphi password. Drupal then communicates with remote.delphiforums.com (usually using ". l("XML-RPC","www.xmlrpc.com") ." ". l("HTTP POST", "www.w3.org/Protocols/") .", or ". l("SOAP", "www.soapware.org") .") behind the scenes and asks &quot;is this password for username=joe?&quot; If Delphi replies yes, then Drupal will create a new local account for joe and log joe into it. Joe may keep on logging into your Drupal instance in the same manner, and he will be logged into the same joe@remote.delphiforums.com account.</p>";
- $output .= "<p>One key element of DA is the 'authmap' table, which maps a user's authname (e.g. joe@remote.delphiforums.com) to his local UID (i.e. universal identification number). This map is checked whenever a user successfully logs into an external authentication source. Once Drupal knows that the current user is definately joe@remote.delphiforums.com (because Delphi says so), he looks up Joe's UID and logs Joe into that account.</p>";
- $output .= "<p>To disable distributed authentication, simply ". l("disable", "admin/system/modules") ." or remove all DA modules. For a virgin install, that means removing/disabling <i>jabber.module</i> and <i>drupal.module</i></p>";
- $output .= "<p>Drupal is setup so that it is very easy to add support for any external authentication source. You currently have the following authentication modules installed ...</p>";
-
- foreach (module_list() as $module) {
- if (module_hook($module, "auth")) {
- $output .= "<h4>" . module_invoke($module, "info", "name") . "</h4>";
- $output .= module_invoke($module, "auth_help");
- }
- }
- return $output;
-}
-
-function user_help_devel_da() {
- $output .= "<h3>Writing distributed authentication modules</h3><p>Drupal is specifically architected to enable easy authoring of new authentication modules. I'll deconstruct the ". l("Blogger", "www.blogger.com") ." authentication module, and hopefully provide all the details you'll need to write your own auth module. If you want to download the full text of this module, visit the ". l("Blogger source", "cvs.drupal.org/viewcvs.cgi/contributions/modules/authentication/Blogger/?cvsroot=contrib") ." in the ". l("Drupal contributions CVS repository", "cvs.drupal.org/viewcvs/contributions/?cvsroot=contrib") .".</p>";
- $output .= "<h4>Code review</h4><pre>&lt;?php</pre><p>The first line of every Drupal module, including the authentication modules, is the same. It is the standard processing instruction for any PHP file. Authentication modules are always written in PHP, although they typically interact with systems written in many different programming languages and operating systems languages.</p>";
- $output .= "<pre>function blogger_info(\$field = NULL) {
- \$info[\"name\"] = \"Blogger\";
- \$info[\"protocol\"] = \"XML-RPC\";
- \$info[\"link\"] = \"<a href=\\\"module.php?mod=user&op=sa_help#blogger\\\">Blogger</a>\";
- \$info[\"maintainer\"] = \"Moshe Weitzman\";
- \$info[\"maintaineremail\"] = \"weitzman at tejasa.com\";
- if (\$field) return \$info[\$field];
- else return \$info;
-}</pre>";
- $output .= "<p>The <i>_info</i> function is always the first function defined in your module. This function populates an array called <i>\$info</i> with various pieces of data. Some of this data is used by Drupal (&quot;name&quot;, &quot;link&quot;), and some of it just informs the users of your module. Simply copy the <i>blogger_info</i> function in your module - but wherever it says <i>blogger</i> here, substitute your own module name.</p>";
- $output .= "<pre>function blogger_auth(\$name, \$pass, \$server) {
- // user did not present a Blogger ID so don't bother trying.
- if (\$server !== &quot;blogger.com&quot;) {
- return 0;
- }
- //provided to Drupal by Ev@Blogger
- \$appkey = &quot;6D4A2D6811A6E1F75148DC1155D33C0C958107BC&quot;
-
- \$message = new xmlrpcmsg(&quot;blogger.getUsersBlogs&quot;,
- array(new xmlrpcval(\$appkey, &quot;string&quot;),
- new xmlrpcval(\$name, &quot;string&quot;),
- new xmlrpcval(\$pass, &quot;string&quot;)));
- \$client = new xmlrpc_client(&quot;/api/RPC2&quot;, &quot;plant.blogger.com&quot;);
- // \$client->setDebug(1);
- \$result = \$client-&gt;send(\$message, 5);
- // Since Blogger doesn't return a properly formed FaultCode, we just search for the string 'fault'.
- if (\$result &amp;&amp; !stristr(\$result-&gt;serialize(), &quot;fault&quot;)) {
- // watchdog(\"user\", \"Success Blogger Auth. Response: \" . \$result->serialize());
- return 1;
- }
- else if (\$result) {
- // watchdog(\"user\", \"Blogger Auth failure. Response was \" . \$result->serialize());
- return 0;
- }
- else {
- // watchdog(\"user\", \"Blogger Auth failure. Could not connect.\");
- return 0;
- }
-}</pre>";
- $output .= "<p>The <i>_auth</i> function is the heart of any authentication module. This function is called whenever a user is attempting to login using your authentication module. For successful authentications, this function returns TRUE. Otherwise, it returns FALSE. This function always accepts 3 parameters, as shown above. These parameters are passed by the user system (user.module). The user system parses the username as typed by the user into 2 substrings - \$name and \$server. The parsing rules are:</p>";
- $output .= "<table border=\"0\" cellspacing=\"4\" cellpadding=\"4\" style=\"margin: auto; width: 80%;\"><tr><th colspan=\"2\" style=\"text-align: left;\">_auth function parameters</th></tr><tr><th>\$name</th><td>The substring before the final <i>'@'</i> character in the username field</td></tr><tr><th>\$pass</th><td>The whole string submitted by the user in the password field</td></tr><tr><th>\$server</th><td>The substring after the final <i>'@'</i> symbol in the username field</td></tr></table>";
- $output .= "<p>So now lets use that \$name, \$pass, and \$server which was passed to our <i>_auth</i> function. Blogger authenticates users via ". l("XML-RPC", "www.xmlrpc.org") .". Your module may authenticate using a different technique. Drupal doesn't reallly care how your module communicates with its registration source. It just <b>trusts</b> the module.</p>";
- $output .= "<p>The lines above illustrate a typical ". l("XML-RPC", "www.xmlrpc.org") ." method call. Here we build up a message and send it to Blogger, storing the response in a variable called <i>\$response</i>. The message we pass conforms to the published ". l("Blogger XML-RPC Application Programmers Interface (API)", "plant.blogger.com/API") .". Your module will no doubt implement a different API. One peculiarity of this module is that we don't actually use the $server parameter. Blogger only accepts authentication at <i>plant.blogger.com</i>, so we hard-code that value into the <i>xmlrpc_client()</i> function. A more typical example might be the jabber module, which uses the <i>\$server</i> parameter to determine where to send the authentication request. Also of note is the '5' parameter in the <i>\$client-&gt;send\(\)</i> call. This is a timeout value in seconds. All authentication modules should implement a timeout on their external calls. This makes sure to return control to the user.module if your registration database has become inoperable or unreachable.</p>";
- $output .= "<pre>
- if (\$result &amp;&amp; !stristr(\$result-&gt;serialize(), &quot;fault&quot;)) {
- // watchdog(\"user\", \"Success Blogger Auth. Response: \" . \$result->serialize());
- return 1;
- }
- else if (\$result) {
- // watchdog(\"user\", \"Blogger Auth failure. Response was \" . \$result->serialize());
- return 0;
- }
- else {
- // watchdog(\"user\", \"Blogger Auth failure. Could not connect.\");
- return 0;
- }
-</pre>";
- $output .= "<p>This second half of the <i>_auth</i> function examines the <i>\$response</i> from plant.blogger.com and returns a TRUE (1) or FALSE (0) as appropriate. This is a critical decision, so be sure that you have good logic here, and perform sufficient testing for all cases. In the case of Blogger, we search for the string 'fault' in the response. If that string is present, or there is no repsonse, our function returns FALSE. Otherwise, Blogger has returned valid data to our method request and we return TRUE. Note: Everything starting with \"//\" is a comment and is not executed.</p>";
- $output .= "<pre>function blogger_page() {
-
- theme(&quot;header&quot;);
- theme(&quot;box&quot;, &quot;Blogger&quot;, blogger_auth_help());
- theme(&quot;footer&quot;);
-}</pre>";
- $output .= "<p>The _page function is not currently used, but it might be in the future. For now, just copy what you see here, substituting your module name for <i>blogger</i>.</p>";
- $output .= "<code>function blogger_auth_help() {<br />
- \$site = variable_get(&quot;site_name&quot;, &quot;this web site&quot;);<br />
- \$html_output = &quot;<blockquote>
- &lt;p&gt;You may login to &lt;i&gt;%s&lt;/i&gt; using a &lt;b&gt;Blogger ID&lt;/b&gt; and password. A Blogger ID consists of your Blogger username followed by &lt;i&gt;@blogger.com&lt;/i&gt;. So a valid blogger ID is mwlily@blogger.com. If you are a Blogger member, go ahead and login now.&lt;/p&gt;
- &lt;p&gt;Blogger offers you instant communication power by letting you post your thoughts to the web whenever the urge strikes.
- Blogger will publish to your current web site or help you create one. &lt;a href=\&quot;http://www.blogger.com/about.pyra\&quot;&gt;Learn more about it&lt;/a&gt;.&quot;;</blockquote>
- return sprintf(t(\$html_output), \$site);<br />
-}</code>";
- $output .= "<p>The <i>_auth_help</i> function is prominently linked within Drupal, so you'll want to write the best possible user help here. You'll want to tell users what a proper username looks like and you may also want to advertise a bit about your service at the end. Note that your help text is passed through a t() function in the last line. This is Drupal's localization function. Translators may localize your help text just like any other text in Drupal.</p>";
- $output .= "<h4>Publishing your module</h4><p>Once you've written and tested your authentication module, you'll usually want to share it with the world. The best way to do this is to add the module to the ". l("Drupal contributions CVS repository", "cvs.drupal.org/viewcvs.cgi/contributions/modules/authentication?cvsroot=contrib") .". You'll need to request priveleges to this repository - see ". l("the README file", "cvs.drupal.org/viewcvs.cgi/contributions/README?rev=HEAD&amp;cvsroot=contrib&amp;content-type=text/vnd.viewcvs-markup") ." for the details. Then you should announce your contribution on the ". l("drupal-devel and drupal-support mailing lists", "drupal.org/node/view/322") .". You might also want to post a story on ". l("Drupal.org", "www.drupal.org") .".</p>";
- return $output;
-}
-
-function user_help_devel_userhook() {
-
- $output .= "<h3><a id=\"userhook\">module_user()</a></h3><p>The <b>_user()</b> hook provides a mechanism for inserting text and form fields into the ". l("registration","user/register") .", ". l("user account view/edit", "user") .", and ". l("administer users", "admin/user") ." pages. This is useful if you want to add a custom field for your particular community. This is best illustrated by the ". l("profile.module", "cvs.drupal.org/viewcvs/drupal/modules/profile.module") .". The profile.module is meant to be customized for your needs. Please download it and hack away until it does what you need.</p>";
-
- $output .= "<p>Consider this simpler example from a fictional recipe community web site called Julia's Kitchen. Julia customizes her Drupal powered site by creating a new file called <i>julia.module</i>. That file does the following:<ul><li>new members must agree to Julia's Privacy Policy on the reg page.</li><li>members may list their favorite ingredients on their public user profile page</li></ul></p>";
-
- $output .= "<p>Julia achieves this with the following code. The comments below should help you understand what is going on.</p>";
-
- $output .= "<pre>
-function julia_user(\$type, \$edit, &\$user) {
- // What type of registration action are we taking?
- switch (\$type) {
- case t(\"register_form\"):
- // Add two items to the resigtration form.
- \$output .= form_item(\"Privacy Policy\",
- \"Julia would never sell your user information. She is just a nice \".
- \"old French chef who lives near me in Cambridge, Massachussetts USA.\");
- \$output .= form_checkbox(\"Accept <i>Julia's Kitchen</i> privacy policy.\",
- julia_accept, 1, \$edit[\"julia_accept\"]);
- return \$output;
- case t(\"register_validate\"):
- // The user has filled out the form and checked the \"accept\" box.
- if (\$edit[\"julia_accept\"] == \"1\") {
- // on success return the values you want to store
- return array(\"julia_accept\" => 1);
- }
- else {
- // on error return an error message
- return \"You must accept the Julia's Kitchen privacy policy to register.\";
- }
- case t(\"view_public\"):
- // when others look at user data
- return form_item(\"Favorite Ingredient\", \$user->julia_favingredient);
- case t(\"view_private\"):
- // when user tries to view his own user page.
- return form_item(\"Favorite Ingredient\", \$user->julia_favingredient);
- case t(\"edit_form\"):
- // when user tries to edit his own user page.
- return form_textfield(\"Favorite Ingredient\", \"julia_favingredient\",
- \$user->julia_favingredient, 50, 65,
- \"Tell everyone your secret spice\");
- case t(\"edit_validate\"): // Make sure the data they edited is \"valid\".
- return user_save(\$user, array(\"julia_favingredient\" => \$edit[\"julia_favingredient\"]));
- }
- }
-</pre>";
- return $output;
-}
-
-?>
diff --git a/modules/watchdog/watchdog.module b/modules/watchdog/watchdog.module
deleted file mode 100644
index 957aae8..0000000
--- a/modules/watchdog/watchdog.module
+++ /dev/null
@@ -1,110 +0,0 @@
-<?php
-// $Id$
-
-function watchdog_help() {
-
- $output .= "<p>Watchdog module monitors your web site, capturing system events in a log to be reviewed by an authorized individual at a later time. The Watchdog log is simply a list of recorded events containing usage data, performance data, errors, warnings and operational information. It is vital to ". l("check the Watchdog report", "admin/watchdog") ." on a regular basis as it is often the only way to tell what is going on.</p>";
- $output .= "<p>To ease administration, the watchdog will automatically discard old log entries, ". l("as configured", "admin/system/modules/watchdog") .". Needs \"cron.php\" to discard the entries.</p>";
- return t($output);
-}
-
-function watchdog_system($field){
- $system["description"] = t("Logs and records system events.");
- $system["admin_help"] = t("Watchdog logs your system events. Too see these logs go to <a href=\"%watchdog\">Site monitoring</a>. Since these logs can grow out of control if kept around forever, below set how long an item should be kept in the log.<br />Note:<ul><li>To discard entries as set below you must run \"cron.php\" regularly.</li></ul>", array("%watchdog" => url("admin/watchdog")));
- return $system[$field];
-}
-
-function watchdog_perm() {
- return array("administer watchdog");
-}
-
-function watchdog_link($type) {
- if ($type == "admin" && user_access("administer watchdog")) {
-- $help["general"] = t("The watchdog module monitors your web site, captures system events in a log and records them to be reviewed by an authorized individual at a later time. The watchdog log is simply a list of events recorded during operation and contains usage data, performance data, errors, warnings and operational information. It is vital to check the watchdog report on a regular basis as it is often the only way to tell what is going on.");
-- $help["user"] = t("Watchdog events that have to do with users. Most of these come from the user.module.");
-- $help["regular"] = t("Watchdog events that are \"normal\" and have no other classification.");
-- $help["httpd"] = t("Watchdog events that are from the web server.<br />Note: At this time this logging level is <b>not</b> used.");
-- $help["special"] = t("Watchdog events about adding, changing, and moderating nodes and comments.");
-- $help["error"] = t("Watchdog general error events, such as invalid login, permission denied, and database errors.");
-- $help["warning"] = t("Watchdog warning events. These events don't stop Drupal from running, but are things you should no to correct.");
-
- menu("admin/watchdog", "site monitoring", "watchdog_admin", $help["general"], 6);
- menu("admin/watchdog/user", "user messages", "watchdog_admin", $help["user"]);
- menu("admin/watchdog/regular", "regular messages", "watchdog_admin", $help["regular"]);
- menu("admin/watchdog/special", "special messages", "watchdog_admin", $help["special"]);
- menu("admin/watchdog/warning", "warning messages", "watchdog_admin", $help["warning"]);
- menu("admin/watchdog/error", "error messages", "watchdog_admin", $help["error"]);
- menu("admin/watchdog/httpd", "httpd messages", "watchdog_admin", $help["http"]);
- menu("admin/watchdog/view", "view details", "watchdog_admin", $help["general"], 0, 1); // hidden menu
- }
-}
-
-function watchdog_settings() {
- $period = array(3600 => format_interval(3600), 10800 => format_interval(10800), 21600 => format_interval(21600), 32400 => format_interval(32400), 43200 => format_interval(43200), 86400 => format_interval(86400), 172800 => format_interval(172800), 259200 => format_interval(259200), 604800 => format_interval(604800), 1209600 => format_interval(1209600), 2419200 => format_interval(2419200), 1000000000 => t("Never"));
- $output .= form_select(t("Discard entries older than"), "watchdog_clear", variable_get("watchdog_clear", 604800), $period, t("The time watchdog entries should be kept. Older entries will be automatically discarded. Requires crontab."));
- return $output;
-}
-
-function watchdog_cron() {
- db_query("DELETE FROM watchdog WHERE ". time() ." - timestamp > ". variable_get("watchdog_clear", 604800));
-}
-
-function watchdog_overview($type) {
- $color = array("user" => "#FFEEAA", "message" => "#FFFFFF", "special" => "#A49FFF", "warning" => "#FFAA22", "httpd" => "#99DD99", "error" => "#EE4C4C");
- $query = array("user" => "WHERE type = 'user'", "regular" => "WHERE type = 'message'", "special" => "WHERE type = 'special'", "warning" => "WHERE type = 'warning'", "error" => "WHERE type = 'error'", "httpd" => "WHERE type = 'httpd'", "actions" => "WHERE link != ''");
-
- $result = pager_query("SELECT w.*, u.name, u.uid FROM watchdog w LEFT JOIN users u ON w.uid = u.uid ". ($type ? $query[$type] : "") ." ORDER BY w.timestamp DESC", 50);
-
- while ($watchdog = db_fetch_object($result)) {
- if ($background = $color[$watchdog->type]) {
- $data .= " <tr style=\"background-color: $background\"><td>". format_date($watchdog->timestamp, "small") ."</td><td>". substr(strip_tags($watchdog->message), 0, 64) ."</td><td style=\"text-align: center;\">". format_name($watchdog) ."</td><td style=\"text-align: center;\">$watchdog->link</td><td style=\"text-align: center;\">". l(t("view details"), "admin/watchdog/view/$watchdog->wid") ."</td></tr>";
- }
- }
-
- $output .= "<table>";
- $output .= " <tr><th>" . t("date") . "</th><th>" . t("event") . "</th><th>" . t("user") . "</th><th colspan=\"2\">" . t("operations") . "</th></tr>";
- $output .= ($data ? $data : "<tr><td style=\"text-align: center;\" colspan=\"4\">". t("No system messages currently available.") ."</td></tr>");
- $output .= (($pager = pager_display(NULL, 50, 0, "admin")) ? "<tr><td style=\"text-align: center;\" colspan=\"4\">$pager</td></tr>" : "");
- $output .= "</table>";
-
- return $output;
-}
-
-function watchdog_view($id) {
-
- $result = db_query("SELECT w.*, u.name, u.uid FROM watchdog w LEFT JOIN users u ON w.uid = u.uid WHERE w.wid = %d", $id);
-
- if ($watchdog = db_fetch_object($result)) {
- $output .= "<table border=\"1\" cellpadding=\"2\" cellspacing=\"2\">";
- $output .= " <tr><th>". t("Type") ."</th><td>$watchdog->type</td></tr>";
- $output .= " <tr><th>". t("Date") ."</th><td>". format_date($watchdog->timestamp, "large") ."</td></tr>";
- $output .= " <tr><th>". t("User") ."</th><td>". format_name($watchdog) ."</td></tr>";
- $output .= " <tr><th>". t("Location") ."</th><td>$watchdog->location</td></tr>";
- $output .= " <tr><th>". t("Message") ."</th><td>$watchdog->message</td></tr>";
- $output .= " <tr><th>". t("Hostname") ."</th><td>$watchdog->hostname</td></tr>";
- $output .= "</table>";
-
- return $output;
- }
-}
-
-function watchdog_admin() {
-
- if (user_access("administer watchdog")) {
- switch (arg(2)) {
- case "help":
- watchdog_help();
- break;
- case "view":
- print watchdog_view(arg(3));
- break;
- default:
- print watchdog_overview(arg(2));
- }
- }
- else {
- print message_access();
- }
-}
-
-?>