diff --git a/CHANGELOG b/CHANGELOG index 7d1fb333565e22749cda5b074cba1bdb49be9c12..50384f28ba98929c122b8e14f3c4364912e66e27 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -Drupal x.x.x, xxxx-xx-xx (to be released) +Drupal 4.3.0, 2003-11-01 ------------------------ - added support for configurable URLs. diff --git a/database/database.mssql b/database/database.mssql index 027ca668cf85bb52c7d00057dee83c462baf3003..ff47002f9421e787f59822e97a6026a1efa8336f 100644 --- a/database/database.mssql +++ b/database/database.mssql @@ -500,7 +500,7 @@ INSERT INTO system VALUES ('modules/story.module','story','module','',1); INSERT INTO system VALUES ('modules/taxonomy.module','taxonomy','module','',1); INSERT INTO system VALUES ('themes/marvin/marvin.theme','marvin','theme','Internet explorer, Netscape, Opera',1); -INSERT INTO variable(name,value) VALUES('update_start', 's:10:"2003-10-22";'); +INSERT INTO variable(name,value) VALUES('update_start', 's:10:"2003-10-27";'); INSERT INTO variable(name,value) VALUES('theme_default','s:6:"marvin";'); INSERT INTO users(uid,name,mail,rid) VALUES(0,'','','1'); diff --git a/database/database.mysql b/database/database.mysql index 2e7581083867c867139400118e6d1c579b3a7804..448e1acf8b790d26bdca9412acf20fa9084130bf 100644 --- a/database/database.mysql +++ b/database/database.mysql @@ -590,7 +590,7 @@ INSERT INTO system VALUES ('modules/taxonomy.module','taxonomy','module','',1); INSERT INTO system VALUES ('themes/marvin/marvin.theme','marvin','theme','Internet explorer, Netscape, Opera',1); INSERT INTO users (uid, name, mail, rid) VALUES ('0', '', '', '1'); -REPLACE variable SET name='update_start', value='s:10:"2003-10-22;"'; +REPLACE variable SET name='update_start', value='s:10:"2003-10-27;"'; REPLACE variable SET name='theme_default', value='s:6:"marvin";'; REPLACE blocks SET module = 'user', delta = '0', status = '1'; diff --git a/database/database.pgsql b/database/database.pgsql index 0e3bfd96ee728f86d22e26e1ff91feccef2a673f..1b10822fbb60dc7ab5fa470082c95504aa96daba 100644 --- a/database/database.pgsql +++ b/database/database.pgsql @@ -590,7 +590,7 @@ INSERT INTO system VALUES ('modules/story.module','story','module','',1); INSERT INTO system VALUES ('modules/taxonomy.module','taxonomy','module','',1); INSERT INTO system VALUES ('themes/marvin/marvin.theme','marvin','theme','Internet explorer, Netscape, Opera',1); -INSERT INTO variable(name,value) VALUES('update_start', 's:10:"2003-10-22";'); +INSERT INTO variable(name,value) VALUES('update_start', 's:10:"2003-10-27";'); INSERT INTO variable(name,value) VALUES('theme_default','s:6:"marvin";'); INSERT INTO users(uid,name,mail,rid) VALUES(0,'','', '1'); diff --git a/modules/aggregator.module b/modules/aggregator.module deleted file mode 100644 index f5ec428c465f686e42e10b2a59ceef0ba66ae99a..0000000000000000000000000000000000000000 --- a/modules/aggregator.module +++ /dev/null @@ -1,841 +0,0 @@ -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 %amphetadesk

"; - $output .= "

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.

"; - $output .= "

What do I need to subscribe to a feed?

"; - $output .= "

The standard method of syndication is using the XML-based %rss (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: %slashdot-rss.

"; - $output .= "

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.

"; - $output .= "

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 %syndic8.

"; - $output .= "

To learn much more about RSS, read Mark Pilgrim's %rss-what and WebReference.com's %rss-evolution.

"; - $output .= "

NOTE: Enable your site's XML syndication button by turning on the Syndicate block in block management.

"; - $output .= "

Configuring news feeds

"; - $output .= "

To subscribe to an RSS feed on another site, use the %admin-news shortcut at the top of the news aggregation page. The link leads directly to the news aggregation configuration section of Drupal site administration.

"; - $output .= "

Once there, select %new-feed from the left hand menu. Drupal will then ask for the following:

"; - $output .= ""; - $output .= "

Once you submit your new feed, check to see if it is working properly. Select %update-items on the %admin-news page. If you do not see any items listed for that feed, edit the feed and make sure that the URL was entered correctly.

"; - $output .= "

Adding bundles

"; - $output .= "

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.

"; - $output .= "

When adding a bundle, Drupal will ask for:

"; - $output .= ""; - $output .= "

Using the news aggregator

"; - $output .= "

The news aggregator has a number of ways that it displays your subscribed content:

"; - $output .= ""; - $output .= "

RSS feed blocks

"; - $output .= "

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.

"; - $output = t($output, array("%amphetadesk" => "AmphetaDesk", "%rss" => "Rich Site Summary", "%slashdot-rss" => "http://slashdot.org/slashdot.rdf", "%syndic8" => "Syndic8", "%rss-what" => "What is RSS", "%rss-evolution" => "The Evolution of RSS", "%admin-news" => l(t("RSS/RDF"), "admin/node/syndication/news"), "%new-feed" => l(t("new feed"), "admin/node/syndication/news/add/feed"), "%update-items" => l(t("update items"), "admin/node/syndication/news"))); - break; - case 'admin/system/modules#description': - $output = t("Used to aggregate syndicated content (RSS and RDF)."); - break; - case 'admin/system/modules/import': - $output = 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."); - break; - case 'admin/node/syndication/news': - $output = 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 must run \"cron.php\". To display the feed in a block you must turn on the %block.
", array("%block" => l(t("feed's block"), "admin/system/block"))); - break; - case 'admin/node/syndication/news/add/feed': - $output = t("Add a site that has an RSS/RDF feed. The URL is the full path to the RSS feed file. For the feed to update automatically you must run \"cron.php\". The \"Attributes\" are used to bundle this feed with other feeds (See %bundle), and to tag articles from this feed.
Note: If you already have a feed with the URL you are planning to use, the system will not accept another feed with the same URL.", array("%bundle" => l(t("add new bundle"), "admin/node/syndication/news/add/bundle"))); - break; - case 'admin/node/syndication/news/add/bundle': - $output = 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 Sport. If an article from a feed has been \"tag\"-ged (See %tag too look at and change tags.) with a matching \"Attribute\" then it will be added to the bundle.", array("%tag" => l(t("tag news item"), "admin/node/syndication/news/tag"))); - break; - case 'admin/node/syndication/news/tag': - $output = t("This allows you to see and change an news item's \"tag\". All articles are originally tagged with the \"Attributes\" of their feed."); - break; - } - - return $output; -} - -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(t("Items per block"), "import_block_limit", variable_get("import_block_limit", 15), $number, t("The maximum number of news items displayed in one block.")); - $output .= form_select(t("Items per page"), "import_page_limit", variable_get("import_page_limit", 75), $number, t("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 == "system") { - if (user_access("administer news feeds")) { - - menu("admin/node/syndication", t("syndication"), NULL, 5); - menu("admin/node/syndication/news", t("RSS/RDF"), "import_admin"); - menu("admin/node/syndication/news/add/feed", t("new feed"), "import_admin", 2); - menu("admin/node/syndication/news/add/bundle", t("new bundle"), "import_admin", 3); - menu("admin/node/syndication/news/tag", t("tag items"), "import_admin", 4); - menu("admin/node/syndication/news/help", t("help"), "import_help", 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_theme_format_item($item, $feed = 0) { - global $user; - - if ($user->uid && module_exist("blog") && user_access("maintain personal blog")) { - $output .= "
". l("\"".", "node/add/blog", array("title" => t("Comment on this news item in your personal blog."), "class" => "blog-it"), "iid=$item->iid") ."
"; - } - - // external link - $output .= "link\">$item->title"; - - 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[] = theme("import_theme_format_item", $item); - } - - $output = "
"; - $output .= theme("theme_item_list", $items); - $output .= "
"; - - 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[] = theme("import_theme_format_item", $item); - } - - $output = "
"; - $output .= theme("theme_item_list", $items); - $output .= "
"; - - 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) ."
". l(t("more"), "import/feed/$feed->fid", array("title" => t("View this feed's recent news."))) ."
"; - 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) ."
". l(t("more"), "import/bundle/$bundle->bid", array("title" => t("View this bundle's recent news."))) ."
"; - 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) ."
". l(t("more"), "import/bundle/$bundle->bid", array("title" => t("View this bundle's recent news."))) ."
"; - $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) ."
". l(t("more"), "import/feed/$feed->fid", array("title" => t("View this feed's recent news."))) ."
"; - $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("%site" => $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: - if (!valid_input_data($data)) { - return t("failed to parse RSS feed '%site': suspicious input data.", array("%site" => $feed["title"])); - } - - // 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["'"] = "'"; - - 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(t("Title"), "title", $edit["title"], 50, 64, t("The name of the bundle.")); - $form .= form_textfield(t("Attributes"), "attributes", $edit["attributes"], 50, 128, t("A comma-separated list of keywords describing the bundle.")); - - $form .= form_submit(t("Submit")); - - if ($edit["bid"]) { - $form .= form_submit(t("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(t("Title"), "title", $edit["title"], 50, 64, t("The name of the feed; typically the name of the web site you syndicate content from.")); - $form .= form_textfield(t("URL"), "url", $edit["url"], 50, 128, t("The fully-qualified URL of the feed.")); - $form .= form_textfield(t("Attributes"), "attributes", $edit["attributes"], 50, 128, t("A comma-separated list of keywords describing the feed.")); - $form .= form_select(t("Update interval"), "refresh", $edit["refresh"], $period, t("The refresh interval indicating how often you want to update this feed. Requires crontab.")); - - $form .= form_submit(t("Submit")); - - if ($edit["fid"]) { - $form .= form_submit(t("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 t("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 .= "

". t("Feed overview") ."

"; - - $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/node/syndication/news/edit/feed/$feed->fid"), l(t("remove items"), "admin/node/syndication/news/remove/$feed->fid"), l(t("update items"), "admin/node/syndication/news/update/$feed->fid")); - } - $output .= table($header, $rows); - - $result = db_query("SELECT * FROM {bundle} ORDER BY title"); - - $output .= "

". t("Bundle overview") ."

"; - - $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/node/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 INNER 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/node/syndication/news/edit/feed/$item->fid"), "valign" => "top"), "link\">$item->title". ($item->description ? "
$item->description" : "") ."
iid]\" value=\"". check_form($item->attributes) ."\" size=\"50\" />"); - } - - $output .= table($header, $rows); - $output .= "\n"; - - return form($output); -} - -function import_admin() { - $op = $_POST["op"]; - $edit = $_POST["edit"]; - - if (user_access("administer news feeds")) { - - if (empty($op)) { - $op = arg(4); - } - - switch ($op) { - case "add": - if (arg(5) == "bundle") { - $output = import_form_bundle(); - } - else { - $output = import_form_feed(); - } - break; - case "edit": - if (arg(5) == "bundle") { - $output = import_form_bundle(import_get_bundle(arg(6))); - } - else { - $output = import_form_feed(import_get_feed(arg(6))); - } - break; - case "remove": - $output = status(import_remove(import_get_feed(arg(5)))); - $output .= import_view(); - break; - case "update": - $output = status(import_refresh(import_get_feed(arg(5)))); - $output .= import_view(); - break; - case "tag": - $output = import_tag(); - break; - case t("Save attributes"): - $output = status(import_save_attributes($edit)); - $output .= import_tag(); - break; - case t("Delete"): - $edit["title"] = 0; - // fall through: - case t("Submit"): - if (arg(5) == "bundle") { - $output = status(import_save_bundle($edit)); - } - else { - $output = status(import_save_feed($edit)); - } - // fall through: - default: - $output .= import_view(); - } - return $output; - - } - else { - return 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/node/syndication/news", array("title" => t("View the news feed administrative pages."))); - } - - return "
". theme("links", $links) ."
"; -} - -function import_page_last() { - - - $result = db_query_range("SELECT i.*, f.title AS ftitle, f.link AS flink FROM {item} i INNER JOIN {feed} f ON i.fid = f.fid ORDER BY i.iid DESC", 0, variable_get("import_page_limit", 75)); - - $output .= ""; - 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 .= "\n"; - } - - if ($item->description) { - $output .= ""; - } - - unset($links); - } - $output .= "
link\">$item->title · ". l($item->ftitle, "import/feed/$item->fid", array("title" => t("View more information about this feed."))) ."". theme("links", $links) ."
$item->description

\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 .= "

". t("Website") .":

link\">$feed->link

"; - $header .= "

". t("Description") .":

$feed->description

"; - $header .= "

". t("Last update") .":

". format_interval(time() - $feed->timestamp) ." ". t("ago") ." url\">\"\"

\n"; - - $result = db_query_range("SELECT * FROM {item} WHERE fid = %d ORDER BY iid DESC", $fid, 0, variable_get("import_page_limit", 75)); - - $output .= ""; - 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[] = "link\">". t("visit") .""; - - if ($item->link) { - $output .= "\n"; - } - if ($item->description) { - $output .= ""; - } - - unset($links); - } - $output .= "
link\">$item->title". theme("links", $links) ."
$item->description

\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 .= "

". t("Website") .":

". l($bundle->title, "import/bundle/$bundle->bid") ."

"; - $header .= "

". t("Description") .":

". t("A composite news feed about") ." $bundle->attributes.

"; - - $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 .= ""; - 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[] = "link\">". t("visit") .""; - - if ($item->link) { - $output .= "\n"; - } - - if ($item->description) { - $output .= ""; - } - - unset($links); - } - $output .= "
link\">$item->title · ". l($item->ftitle, "import/feed/$item->fid", array("title" => t("View more information about this feed."))) ."". theme("links", $links) ."
$item->description

\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 .= "
$feed->description

"; - } - - $output .= "
". l("", "import/fd", array("title" => t("View the list of syndicated web sites in XML format."))) ."

"; - - 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 .= "\n\n"; - $output .= "\n\n"; - - while ($feed = db_fetch_object($result)) { - $output .= "\n"; - $output .= " ". drupal_specialchars($feed->title) ."\n"; - $output .= " ". drupal_specialchars($feed->url) ."\n"; - $output .= "\n\n"; - } - - $output .= "\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 "\n"; - print " \n"; - - for ($t = 0; $t < 3; $t++) { - $i = 1; - print " \n"; - } - - print " \n"; - print "
\n"; - while ($block = each($blocks)) { - theme("box", $block["value"]["subject"], $block["value"]["content"]); - if ($i == ceil(count($blocks) / 3)) { - break; - } - $i++; - } - print "
\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 f5ec428c465f686e42e10b2a59ceef0ba66ae99a..0000000000000000000000000000000000000000 --- a/modules/aggregator/aggregator.module +++ /dev/null @@ -1,841 +0,0 @@ -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 %amphetadesk

"; - $output .= "

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.

"; - $output .= "

What do I need to subscribe to a feed?

"; - $output .= "

The standard method of syndication is using the XML-based %rss (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: %slashdot-rss.

"; - $output .= "

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.

"; - $output .= "

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 %syndic8.

"; - $output .= "

To learn much more about RSS, read Mark Pilgrim's %rss-what and WebReference.com's %rss-evolution.

"; - $output .= "

NOTE: Enable your site's XML syndication button by turning on the Syndicate block in block management.

"; - $output .= "

Configuring news feeds

"; - $output .= "

To subscribe to an RSS feed on another site, use the %admin-news shortcut at the top of the news aggregation page. The link leads directly to the news aggregation configuration section of Drupal site administration.

"; - $output .= "

Once there, select %new-feed from the left hand menu. Drupal will then ask for the following:

"; - $output .= ""; - $output .= "

Once you submit your new feed, check to see if it is working properly. Select %update-items on the %admin-news page. If you do not see any items listed for that feed, edit the feed and make sure that the URL was entered correctly.

"; - $output .= "

Adding bundles

"; - $output .= "

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.

"; - $output .= "

When adding a bundle, Drupal will ask for:

"; - $output .= ""; - $output .= "

Using the news aggregator

"; - $output .= "

The news aggregator has a number of ways that it displays your subscribed content:

"; - $output .= ""; - $output .= "

RSS feed blocks

"; - $output .= "

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.

"; - $output = t($output, array("%amphetadesk" => "AmphetaDesk", "%rss" => "Rich Site Summary", "%slashdot-rss" => "http://slashdot.org/slashdot.rdf", "%syndic8" => "Syndic8", "%rss-what" => "What is RSS", "%rss-evolution" => "The Evolution of RSS", "%admin-news" => l(t("RSS/RDF"), "admin/node/syndication/news"), "%new-feed" => l(t("new feed"), "admin/node/syndication/news/add/feed"), "%update-items" => l(t("update items"), "admin/node/syndication/news"))); - break; - case 'admin/system/modules#description': - $output = t("Used to aggregate syndicated content (RSS and RDF)."); - break; - case 'admin/system/modules/import': - $output = 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."); - break; - case 'admin/node/syndication/news': - $output = 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 must run \"cron.php\". To display the feed in a block you must turn on the %block.
", array("%block" => l(t("feed's block"), "admin/system/block"))); - break; - case 'admin/node/syndication/news/add/feed': - $output = t("Add a site that has an RSS/RDF feed. The URL is the full path to the RSS feed file. For the feed to update automatically you must run \"cron.php\". The \"Attributes\" are used to bundle this feed with other feeds (See %bundle), and to tag articles from this feed.
Note: If you already have a feed with the URL you are planning to use, the system will not accept another feed with the same URL.", array("%bundle" => l(t("add new bundle"), "admin/node/syndication/news/add/bundle"))); - break; - case 'admin/node/syndication/news/add/bundle': - $output = 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 Sport. If an article from a feed has been \"tag\"-ged (See %tag too look at and change tags.) with a matching \"Attribute\" then it will be added to the bundle.", array("%tag" => l(t("tag news item"), "admin/node/syndication/news/tag"))); - break; - case 'admin/node/syndication/news/tag': - $output = t("This allows you to see and change an news item's \"tag\". All articles are originally tagged with the \"Attributes\" of their feed."); - break; - } - - return $output; -} - -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(t("Items per block"), "import_block_limit", variable_get("import_block_limit", 15), $number, t("The maximum number of news items displayed in one block.")); - $output .= form_select(t("Items per page"), "import_page_limit", variable_get("import_page_limit", 75), $number, t("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 == "system") { - if (user_access("administer news feeds")) { - - menu("admin/node/syndication", t("syndication"), NULL, 5); - menu("admin/node/syndication/news", t("RSS/RDF"), "import_admin"); - menu("admin/node/syndication/news/add/feed", t("new feed"), "import_admin", 2); - menu("admin/node/syndication/news/add/bundle", t("new bundle"), "import_admin", 3); - menu("admin/node/syndication/news/tag", t("tag items"), "import_admin", 4); - menu("admin/node/syndication/news/help", t("help"), "import_help", 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_theme_format_item($item, $feed = 0) { - global $user; - - if ($user->uid && module_exist("blog") && user_access("maintain personal blog")) { - $output .= "
". l("\"".", "node/add/blog", array("title" => t("Comment on this news item in your personal blog."), "class" => "blog-it"), "iid=$item->iid") ."
"; - } - - // external link - $output .= "link\">$item->title"; - - 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[] = theme("import_theme_format_item", $item); - } - - $output = "
"; - $output .= theme("theme_item_list", $items); - $output .= "
"; - - 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[] = theme("import_theme_format_item", $item); - } - - $output = "
"; - $output .= theme("theme_item_list", $items); - $output .= "
"; - - 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) ."
". l(t("more"), "import/feed/$feed->fid", array("title" => t("View this feed's recent news."))) ."
"; - 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) ."
". l(t("more"), "import/bundle/$bundle->bid", array("title" => t("View this bundle's recent news."))) ."
"; - 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) ."
". l(t("more"), "import/bundle/$bundle->bid", array("title" => t("View this bundle's recent news."))) ."
"; - $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) ."
". l(t("more"), "import/feed/$feed->fid", array("title" => t("View this feed's recent news."))) ."
"; - $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("%site" => $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: - if (!valid_input_data($data)) { - return t("failed to parse RSS feed '%site': suspicious input data.", array("%site" => $feed["title"])); - } - - // 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["'"] = "'"; - - 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(t("Title"), "title", $edit["title"], 50, 64, t("The name of the bundle.")); - $form .= form_textfield(t("Attributes"), "attributes", $edit["attributes"], 50, 128, t("A comma-separated list of keywords describing the bundle.")); - - $form .= form_submit(t("Submit")); - - if ($edit["bid"]) { - $form .= form_submit(t("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(t("Title"), "title", $edit["title"], 50, 64, t("The name of the feed; typically the name of the web site you syndicate content from.")); - $form .= form_textfield(t("URL"), "url", $edit["url"], 50, 128, t("The fully-qualified URL of the feed.")); - $form .= form_textfield(t("Attributes"), "attributes", $edit["attributes"], 50, 128, t("A comma-separated list of keywords describing the feed.")); - $form .= form_select(t("Update interval"), "refresh", $edit["refresh"], $period, t("The refresh interval indicating how often you want to update this feed. Requires crontab.")); - - $form .= form_submit(t("Submit")); - - if ($edit["fid"]) { - $form .= form_submit(t("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 t("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 .= "

". t("Feed overview") ."

"; - - $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/node/syndication/news/edit/feed/$feed->fid"), l(t("remove items"), "admin/node/syndication/news/remove/$feed->fid"), l(t("update items"), "admin/node/syndication/news/update/$feed->fid")); - } - $output .= table($header, $rows); - - $result = db_query("SELECT * FROM {bundle} ORDER BY title"); - - $output .= "

". t("Bundle overview") ."

"; - - $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/node/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 INNER 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/node/syndication/news/edit/feed/$item->fid"), "valign" => "top"), "link\">$item->title". ($item->description ? "
$item->description" : "") ."
iid]\" value=\"". check_form($item->attributes) ."\" size=\"50\" />"); - } - - $output .= table($header, $rows); - $output .= "\n"; - - return form($output); -} - -function import_admin() { - $op = $_POST["op"]; - $edit = $_POST["edit"]; - - if (user_access("administer news feeds")) { - - if (empty($op)) { - $op = arg(4); - } - - switch ($op) { - case "add": - if (arg(5) == "bundle") { - $output = import_form_bundle(); - } - else { - $output = import_form_feed(); - } - break; - case "edit": - if (arg(5) == "bundle") { - $output = import_form_bundle(import_get_bundle(arg(6))); - } - else { - $output = import_form_feed(import_get_feed(arg(6))); - } - break; - case "remove": - $output = status(import_remove(import_get_feed(arg(5)))); - $output .= import_view(); - break; - case "update": - $output = status(import_refresh(import_get_feed(arg(5)))); - $output .= import_view(); - break; - case "tag": - $output = import_tag(); - break; - case t("Save attributes"): - $output = status(import_save_attributes($edit)); - $output .= import_tag(); - break; - case t("Delete"): - $edit["title"] = 0; - // fall through: - case t("Submit"): - if (arg(5) == "bundle") { - $output = status(import_save_bundle($edit)); - } - else { - $output = status(import_save_feed($edit)); - } - // fall through: - default: - $output .= import_view(); - } - return $output; - - } - else { - return 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/node/syndication/news", array("title" => t("View the news feed administrative pages."))); - } - - return "
". theme("links", $links) ."
"; -} - -function import_page_last() { - - - $result = db_query_range("SELECT i.*, f.title AS ftitle, f.link AS flink FROM {item} i INNER JOIN {feed} f ON i.fid = f.fid ORDER BY i.iid DESC", 0, variable_get("import_page_limit", 75)); - - $output .= ""; - 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 .= "\n"; - } - - if ($item->description) { - $output .= ""; - } - - unset($links); - } - $output .= "
link\">$item->title · ". l($item->ftitle, "import/feed/$item->fid", array("title" => t("View more information about this feed."))) ."". theme("links", $links) ."
$item->description

\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 .= "

". t("Website") .":

link\">$feed->link

"; - $header .= "

". t("Description") .":

$feed->description

"; - $header .= "

". t("Last update") .":

". format_interval(time() - $feed->timestamp) ." ". t("ago") ." url\">\"\"

\n"; - - $result = db_query_range("SELECT * FROM {item} WHERE fid = %d ORDER BY iid DESC", $fid, 0, variable_get("import_page_limit", 75)); - - $output .= ""; - 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[] = "link\">". t("visit") .""; - - if ($item->link) { - $output .= "\n"; - } - if ($item->description) { - $output .= ""; - } - - unset($links); - } - $output .= "
link\">$item->title". theme("links", $links) ."
$item->description

\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 .= "

". t("Website") .":

". l($bundle->title, "import/bundle/$bundle->bid") ."

"; - $header .= "

". t("Description") .":

". t("A composite news feed about") ." $bundle->attributes.

"; - - $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 .= ""; - 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[] = "link\">". t("visit") .""; - - if ($item->link) { - $output .= "\n"; - } - - if ($item->description) { - $output .= ""; - } - - unset($links); - } - $output .= "
link\">$item->title · ". l($item->ftitle, "import/feed/$item->fid", array("title" => t("View more information about this feed."))) ."". theme("links", $links) ."
$item->description

\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 .= "
$feed->description

"; - } - - $output .= "
". l("", "import/fd", array("title" => t("View the list of syndicated web sites in XML format."))) ."

"; - - 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 .= "\n\n"; - $output .= "\n\n"; - - while ($feed = db_fetch_object($result)) { - $output .= "\n"; - $output .= " ". drupal_specialchars($feed->title) ."\n"; - $output .= " ". drupal_specialchars($feed->url) ."\n"; - $output .= "\n\n"; - } - - $output .= "\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 "\n"; - print " \n"; - - for ($t = 0; $t < 3; $t++) { - $i = 1; - print " \n"; - } - - print " \n"; - print "
\n"; - while ($block = each($blocks)) { - theme("box", $block["value"]["subject"], $block["value"]["content"]); - if ($i == ceil(count($blocks) / 3)) { - break; - } - $i++; - } - print "
\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 49130bdbf4c86d1bf38bc89d1a639883503ef755..0000000000000000000000000000000000000000 --- a/modules/archive/archive.module +++ /dev/null @@ -1,256 +0,0 @@ -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\n"; - $output .= "
"; - $output .= "\n"; - $output .= " \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 .= " "; - for ($i = 0; $i < 7; $i++) { - $output .= ""; - } - $output .= "\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 .= " \n"; - $first = $weekstart; - } - // Start every week on a new line: - if ($sday == $weekstart) { - $output .= " \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 = "
$nday
"; - $dayclass = "day-normal"; - } - if ($date == $requested) { - $output .= " \n"; - } - else if ($date == $start_of_today) { - $output .= " \n"; - } - else if ($date > $end_of_today) { - $output .= " \n"; - } - else { - $output .= " \n"; - } - - // Start every week on a new line: - if ($sday == $lastday) { - $output .= " \n"; - } - - // Update temporary variables: - $sday++; - $sday = $sday % 7; - $nday++; - } - - // Complete the calendar: - if ($sday != $weekstart) { - $end = (7 - $sday + $weekstart) % 7; - $output .= " \n \n"; - } - - $output .= "
". l("«", "archive/". date("Y/m/d", $prev)) ." ". date("F Y", $requested) ." ". ($nextmonth <= time() ? l("»", "archive/". date("Y/m/d", $next)) : " ") ."
". t(substr(ucfirst(date("l", $firstcolumn + $i * 86400)), 0, 2)) ."
 
$daytext$daytext$daytext$daytext
 
\n\n"; - - cache_set("archive:calendar:$start_of_month", $output, 1); - - 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 = "
"; - $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 .= "
"; - 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 64f2d1b8b5d6afb47172b3cf8dda21d5d0525e9b..0000000000000000000000000000000000000000 --- a/modules/block/block.module +++ /dev/null @@ -1,349 +0,0 @@ -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.

"; - $output .= "

The sidebar each block appears in depends on both which theme you're using (some are left-only, some right, some both), and on the settings in block management.

Whether a block is visible in the first place depends on three things:

"; - $output .= "

The block management screen also lets you specify the vertical sort-order of the blocks within a sidebar. You do this by assigning a weight 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.

"; - $output .= "

The path setting lets you define the pages on which a specific block is visable. If you leave the path blank it will appear on all pages. The path uses a regular expression syntax so remember to escape special characters!

"; - $output .= "

In case you do 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 %pcre.

"; - $output .= "

However, for basic tasks it is sufficient to look at the following examples:

"; - $output .= "

If the block should only show up on blog pages, use </blog>. To display on all node views use </node/view>. The angular brackets are used as delimiters of the regular expression. To show up on either forum or book pages use <(/forum|/book)>. 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 </node/add/(story|blog|image)>. Blocks which have their paths set to this expression will show up on story, block, or image composition pages. If you want to show a block an all pages, but not the search page, use <(^/$|[^(search)$/]+)>

"; - $output .= "

Custom Blocks

"; - $output .= "

A custom block 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 containing text, HTML, or PHP code which can be as long as you wish. The Drupal engine will 'render' the content of the custom block.

"; - $output .= "

PHP in custom blocks

"; - $output .= "

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 when the page is viewed 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.

"; - $output .= "

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.

"; - $output .= "

Notes:

"; - $output .= "

A basic example:

"; - $output .= "

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:

"; - $output .= "
-  return t(\"Welcome visitor, ... welcome message goes here ...\");
-
"; - $output .= "

If we are however dealing with a registered user, we can customize the message by using:

"; - $output .= "
-  if (\$user->uid) {
-    return t(\"Welcome \$user->name, ... welcome message goes here ...\");
-  }
-  else {
-    return t(\"Welcome visitor, ... welcome message goes here ...\");
-  }";
-      $output .= "
"; - $output .= "

For more in-depth examples, we recommend that you check the existing boxes and use them as a starting point.

"; - $output = t($output, array("%pcre" => "". t("Perl-Compatible Regular Expressions (PCRE)") ."")); - break; - case 'admin/system/modules#description': - $output = t("Controls the boxes that are displayed around the main content."); - break; - case 'admin/system/block': - $output = t("Blocks are the boxes in the left- and right- side bars of the web site, depending on the choosen theme. They are created by active 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 lets you define which pages you want a block to be shown on. The custom checkbox lets your users hide the block using their account setting. You can also create your own blocks, where you specify the content of the block rather than its 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("new block"), "admin/system/block/add"))); - break; - case 'admin/system/block/add': - $output = 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 %overview. The title is used when displaying the block. The description is used in the \"block\" column on the %overview page. If you are going to place PHP code in the block, and you have create php content permission (see the %permission page) you must change the type to PHP to make your code active.", array("%overview" => l(t("blocks"), "admin/system/block"), "%permission" => l(t("permissions"), "admin/user/permission"))); - break; - case 'admin/system/block/preview': - $output = t("This page show you the placement of your blocks in different themes types. The numbers are the weight of each block, which is used to sort them within the sidebars."); - break; - } - - return $output; -} - -function block_perm() { - return array("administer blocks"); -} - -function block_link($type) { - if ($type == "system" && user_access("administer blocks")) { - - menu("admin/system/block", t("blocks"), "block_admin", 3); - menu("admin/system/block/add", t("new block"), "block_admin", 2); - menu("admin/system/block/preview", t("preview placement"), "block_admin", 3); - menu("admin/system/block/help", t("help"), "block_help", 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/system/block/edit/". $block["delta"]); - $delete = l(t("delete"), "admin/system/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")); - - return form($output); -} - -function block_admin_preview() { - - $result = db_query("SELECT * FROM {blocks} WHERE status > 0 AND region = 0 ORDER BY weight"); - $lblocks .= "\n"; - while ($block = db_fetch_object($result)) { - $block_data = module_invoke($block->module, "block", "list"); - $name = $block_data[$block->delta]["info"]; - $lblocks .= " \n"; - } - $lblocks .= "
". ($block->status == 2 ? "$name" : $name) ."$block->weight
\n"; - - $result = db_query("SELECT * FROM {blocks} WHERE status > 0 AND region = 1 ORDER BY weight"); - $rblocks .= "\n"; - while ($block = db_fetch_object($result)) { - $block_data = module_invoke($block->module, "block", "list"); - $name = $block_data[$block->delta]["info"]; - $rblocks .= " \n"; - } - $rblocks .= "
". ($block->status == 2 ? "$name" : $name) ."$block->weight
\n"; - - $output .= "

". t("Themes with both left and right sidebars") .":

\n"; - $output .= "\n"; - $output .= " \n"; - $output .= " \n"; - $output .= " \n"; - $output .= "
". t("header") ."
\n". ($lblocks ? $lblocks : " ") ." \n". ($rblocks ? $rblocks : " ") ."
". t("footer") ."
\n"; - - $result = db_query("SELECT * FROM {blocks} WHERE status > 0 ORDER BY weight"); - $blocks .= "\n"; - while ($block = db_fetch_object($result)) { - $block_data = module_invoke($block->module, "block", "list"); - $name = $block_data[$block->delta]["info"]; - $blocks .= " \n"; - } - $blocks .= "
". ($block->status == 2 ? "$name" : $name) ."$block->weight
\n"; - - $output .= "

". t("Themes with right-sidebar only") .":

\n"; - $output .= "\n"; - $output .= " \n"; - $output .= " \n"; - $output .= " \n"; - $output .= "
". t("header") ."
 \n". ($blocks ? $blocks : " ") ."
". t("footer") ."
\n"; - - $output .= "

". t("Themes with left-sidebar only") .":

\n"; - $output .= "\n"; - $output .= " \n"; - $output .= " \n"; - $output .= " \n"; - $output .= "
". t("header") ."
\n". ($blocks ? $blocks : " ") ." 
". t("footer") ."
\n"; - - return $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")); - - return 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(3); - } - - switch ($op) { - case "preview": - $output = block_admin_preview(); - break; - case "add": - $output = block_box_form(); - break; - case "edit": - $output = block_box_form(block_box_get(arg(4))); - break; - case "delete": - $output = status(block_box_delete(arg(4))); - cache_clear_all(); - $output .= block_admin_display(); - break; - case t("Save block"): - $output = status(block_box_save($edit)); - cache_clear_all(); - $output .= block_admin_display(); - break; - case t("Save blocks"): - $output = status(block_admin_save($edit)); - cache_clear_all(); - // fall through - default: - $output .= block_admin_display(); - } - - return $output; - } - else { - return 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 .= "". $data[$block->delta]["info"] ."". form_checkbox(NULL, "block][$block->module][$block->delta", 1, $user->block[$block->module][$block->delta]) ."\n"; - } - } - - if (isset($form)) { - return form_item(t("Block configuration"), "". $form ."
", 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 b72bb7719d4598d9b1487b0b53439d18d2c63942..0000000000000000000000000000000000000000 --- a/modules/blog/blog.module +++ /dev/null @@ -1,296 +0,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[] = ""; - } - - 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($section) { - $output =""; - - switch ($section) { - case 'admin/help#blog': - $output .= "

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.

"; - $output .= "

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 and/or agree/disagree with. A typical example of a long term blog can be seen at %scripting-com.

"; - $output .= "

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.

"; - $output .= "

If a user has the ability to post blogs, then the import module (news aggregator) will display a blog-it link (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.

"; - $output = t($output, array("%scripting-com" => "http://www.scripting.com/" )); - break; - case 'admin/system/modules#description': - $output .= t("Enables keeping a blog or easily and regularly updated web page."); - break; - case 'admin/system/modules/blog': - $output .= 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"); - break; - } - - return $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 INNER 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 INNER 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) { - $account = user_load(array((is_numeric($uid) ? "uid" : "name") => $uid, "status" => 1)); - - // Breadcrumb navigation: - $breadcrumb[] = l(t("Home"), NULL); - $breadcrumb[] = l(t("Blogs"), "blog"); - $breadcrumb[] = t("%name's blog", array("%name" => $account->name)); - theme("breadcrumb", $breadcrumb); - - $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 "
" . l("\"\"", "blog/feed/$account->uid", array("title" => t("View the XML version of %username's blog", array("%username" => $account->name)))) . "
"; -} - -function blog_page_last() { - global $user; - - // Breadcrumb navigation: - $breadcrumb[] = l(t("Home"), NULL); - $breadcrumb[] = t("Blogs"); - theme("breadcrumb", $breadcrumb); - - $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)) { - node_view(node_load(array("nid" => $node->nid)), 1); - } - print pager_display(NULL, variable_get("default_nodes_main", 10)); - print "
". l("\"\"", "blog/feed", array("title" => t("Read the XML version of all blogs."))) ."
"; -} - -function blog_validate(&$node) { - - /* - ** Validate the size of the blog: - */ - - if (isset($node->body) && count(explode(" ", $node->body)) < variable_get("minimum_blog_size", 0)) { - $error["body"] = theme("theme_error", t("The body of your blog is too short.")); - } - - return $error; -} - -function blog_form(&$node, &$help, &$error) { - global $nid; - $iid = $_GET["iid"]; - - /* - ** Carry out some explanation or submission guidelines: - */ - - $help = variable_get("blog_help", ""); - - if (empty($node->body)) { - /* - ** 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 = "". $blog->body ." [". 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 = "link\">$item->title - ". check_output($item->description) ." [flink\">$item->ftitle]\n"; - } - } - - 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 { - blog_page_last(); - } - theme("footer"); - } - } - else { - theme("header"); - theme("box", t("Access denied"), message_access()); - theme("footer"); - } - -} - -function blog_content($node) { - $node->teaser = check_output($node->teaser); - $node->body = check_output($node->body); - return $node; -} - -function blog_view($node, $main = 0) { - if ($main == 0) { - // Breadcrumb navigation - $breadcrumb[] = l(t("Home"), NULL); - $breadcrumb[] = l(t("%name's blog", array("%name" => $node->name)), "blog/$node->uid"); - // print the breadcrumb - theme("breadcrumb", $breadcrumb); - } - // prepair the node content - $node = blog_content($node); - // print the node - theme("node", $node, $main); -} - -function blog_link($type, $node = 0, $main) { - global $user; - - $links = array(); - - if ($type == "system") { - if (user_access("maintain personal blog")) { - menu("node/add/blog", t("blog entry"), "blog_page", 0); - } - if (user_access("maintain personal blog")) { - menu("blog/" . $user->uid, t("my blog"), "user_page", 1); - } - } - - if ($type == "page" && user_access("access content")) { - $links[] = l(t("blogs"), "blog", array("title" => t("Read the 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"] .= "
". l(t("more"), "blog", array("title" => t("Read the latest blog entries."))) ."
"; - $block["subject"] = t("Blogs"); - } - return $block; - } -} - -?> diff --git a/modules/book/book.module b/modules/book/book.module deleted file mode 100644 index 678e8834585ea6703c92a603a9542386ff2236bb..0000000000000000000000000000000000000000 --- a/modules/book/book.module +++ /dev/null @@ -1,868 +0,0 @@ -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 update 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("books"), "book", array("title" => t("Read and contribute to the collaborative books."))); - } - - 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 == "system") { - if (user_access("maintain books")) { - menu("node/add/book", t("book page"), "book_page", 0); - menu("admin/node/book", t("books"), "book_admin", 4); - menu("admin/node/book/orphan", t("orphan pages"), "book_admin_orphan", 8); - menu("admin/node/book/help", t("help"), "book_help", 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", t("'%title' book", array("%title" => $book->title)), "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. - */ - - 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 .= "

". t("Edit book outline for node %booktitle", array("%booktitle" => $node->title)) ."

"; - - 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_content($node) { - $op = $_POST["op"]; - - /* - ** 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 ($op != t("Preview") && $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. - */ - - 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); - $node->teaser = $node->body = ob_get_contents(); - ob_end_clean(); - } - else { - $node->teaser = check_output($node->teaser); - $node->body = check_output($node->body); - } - - return $node; -} - -function book_view($node, $main = 0) { - $node = book_content($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 { - if ($node->moderate) { - $node->body = $node->body . "
". t("Log") .":
$node->log
"; - } - // Add the navigation and the breadcrumb if we view a page - if (arg(1) == "view") { - $node = book_navigation($node); - // Print the breadcrumb - theme("breadcrumb", $node->breadcrumb); - } - // Print the node - theme("node", $node, $main); - } -} - -function book_show($node, $cid) { - - if (node_access("view", $node)) { - - if ($node->type == "book") { - book_view($node, 0); - } - else { - - if (module_hook($node->type, "content")) { - $node = node_invoke($node, "content"); - - /* - ** Add the book navigation if the node is in the book. - */ - - $book = db_fetch_object(db_query("SELECT * FROM {book} WHERE nid = %d", $node->nid)); - - if ($book) { - foreach ($book as $key => $value) { - $node->$key = $value; - } - $node = book_navigation($node); - } - - /* - ** make $node->type a book. This is for the links. - */ - - $node->type = "book"; - - /* - ** View the node - */ - theme("breadcrumb", $node->breadcrumb); - theme("node", $node, 0); - } - else { - - /* - ** We can't get the content of the node and just view the node. - ** We don't add breadcrums or links. - */ - node_view($node, 0); - } - } - 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 book_navigation($node) { - - $path = book_location($node); - - /* - ** Construct the breadcrumb: - */ - - $node->breadcrumb = ""; // Overwrite the trail with a book trail. - $node->breadcrumb[] = l(t("Home"), ""); - $node->breadcrumb[] = l(t("Books"), "book"); - foreach ($path as $level) { - $node->breadcrumb[] = l($level->title, "book/view/$level->nid"); - } - - /* - ** Construct the "next" and "previous" links: - */ - - if ($node->nid) { - $prev = book_prev($node); - $next = book_next($node); - } - - if ($node->nid) { - $output .= "
"; - $output .= "
". book_tree($node->nid) ."
"; - if ($prev) { - $links .= "
"; - $links .= l(t("previous"), "book/view/$prev->nid", array("title" => t("View the previous page in this book."))); - $links .= "
"; - $titles .= "
$prev->title
"; - } - if ($next) { - $links .= "
"; - $links .= l(t("next"), "book/view/$next->nid", array("title" => t("View the next page in this book."))); - $links .= "
"; - $titles .= "
$next->title
"; - } - else { - $links .= "
 
"; // make an empty div to fill the space - } - if ($node->parent) { - $links .= "
"; - $links .= l(t("up"), "book/view/$node->parent", array("title" => t("View this page's parent section."))); - //if ($node->parent != $path[0]->nid) { - // $links .= " | "; - // $links .= l(t("index"), "node/view/".$path[0]->nid."", array("title" => t("View this book's table of contents."))); - //} - $links .= "
"; - } - $output .= "
"; - $output .= "
$links
"; - $output .= "
$titles
"; - $output .= "
"; - $output .= "
"; - } - $node->body = $node->body.$output; - return $node; -} - -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 .= "
  • "; - $output .= l($node->title, "book/view/$node->nid"); - if ($tree = book_tree_recurse($node->nid, $depth - 1, $children)) { - $output .= ""; - } - $output .= "
  • "; - } - } - } - - 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 = ""; - - 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)); - - if ($node) { - // take the most recent approved revision, extract the page and check output: - $node = book_content($node); - // output the content: - $output .= "
    "; - $output .= "
    ". l($node->title, "book/view/$node->nid") ."
    "; - $output .= "
    ". $node->body ."
    "; - $output .= "
    "; - } - } - - theme("header"); - theme("box", t("Books"), "$output"); - theme("footer"); -} - -function book_page() { - - if (user_access("access content")) { - switch (arg(1)) { - case "view": - $node = node_load(array("nid" => arg(2))); - theme("header"); - book_show($node, arg(3)); - theme("footer"); - break; - 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)); - - if ($node) { - // output the content: - if (module_hook($node->type, "content")) { - $node = node_invoke($node, "content"); - } - $output .= "

    nid\" name=\"$node->nid\" class=\"book-h$depth\">$node->title

    "; - - if ($node->body) { - $output .= $node->body; - } - } - } - - $output .= book_print_recurse($id, $depth); - - $html = "$node->title"; - $html .= ""; - $html .= ""; - $html .= "". $output .""; - - 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: - if (module_hook($node->type, "content")) { - $node = node_invoke($node, "content"); - } - $output .= "

    nid\" name=\"$node->nid\" class=\"book-h$depth\">$node->title

    "; - - if ($node->body) { - $output .= ""; - } - - $output .= book_print_recurse($node->nid, $depth + 1); - } - } - - return $output; -} - -function book_admin_view_line($node, $depth = 0) { - - $row = array("
    ". form_textfield(NULL, "$node->nid][title", $node->title, 64, 255) ."
    ", 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 .= "

    $node->title

    "; - - $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 .= "

    Orphan pages

    "; - $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"): - $output = book_node_link(); - break; - case "orphan": - $output = book_admin_orphan(); - break; - case t("Save book pages"): - $output = status(book_admin_save(arg(3), $edit)); - // fall through: - default: - $output .= book_admin_view(arg(3)); - break; - } - return $output; - } -} - -function book_help($section = "admin/help#book") { - $output = ""; - - switch ($section) { - case 'admin/help#book': - $output .= "

    The book organises content into a nested hierarchical structure. It is particularly good for manuals, Frequently Asked Questions (FAQs) and the like, allowing you to have chapters, sections, etc.

    "; - $output .= "

    A book is simply a collection of nodes that have been linked together. These nodes are usually of type book page, but you can insert nodes of any type into a book outline. Every node in the book has a parent 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 weight that you give them.

    "; - $output .= "

    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 log message 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.

    "; - $output .= "

    Like other node types, book submissions and edits may be subject to moderation, depending on your configuration. Similarly, books use %permissions 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 <root>. 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 edit book outline 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 %create link.

    "; - $output .= "

    Administrators may review the hierarchy of their books by clicking on the %collaborative-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 orphans. Administrators should periodically %orphans-book and reaffiliate those pages as desired. Finally, administrators may also %export-book to a single, flat HTML page which is suitable for printing.

    "; - $output .= "

    Maintaining a FAQ using a collaborative book

    "; - $output .= "

    Collaborative books let you easily set up a Frequently Asked Questions (FAQ) 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!

    "; - $output .= "

    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 the %create link. 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 <root> as the parent of this page. Leave the log message and type 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.

    "; - $output .= "

    Whenever you come across a post which you want to include in your FAQ, click on the administer link. Then click on the edit book outline button at the bottom of the page. Then place the relevant post wherever is most appropriate in your book by selecting a parent. Books are quite flexible. They can have sections like Flying to Estonia, Eating in Estonia and so on. As you get more experienced with the book module, you can reorganize posts in your book so that it stays organized.

    "; - $output .= "

    Notes:

    "; - $output = t($output, array("%permissions" => l(t("permissions"), "admin/user/permission"), "%create" => l(t("submit content") ." » ". t("book page"), "node/add/book"), "%collaborative-book" => l(t("collaborative book"), "admin/node/book"), "%orphans-book" => l(t("review their books for orphans"), "admin/node/book/orphan"), "%export-book" => l(t("export their books"), "book/print"))); - break; - case 'admin/system/modules#description': - $output = t("Allows users to collaboratively author a book."); - break; - case 'admin/node/book': - $output = t("The book module offers a mean to organize content, authored by many users, in an online manual, outline or FAQ."); - break; - case 'admin/node/book/orphan': - $output = t("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."); - break; - - } - - return $output; -} -?> diff --git a/modules/comment/comment.module b/modules/comment/comment.module deleted file mode 100644 index d5513965a2e4a590f0092168818901fefcae8030..0000000000000000000000000000000000000000 --- a/modules/comment/comment.module +++ /dev/null @@ -1,1662 +0,0 @@ -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.

    "; - $output .= "

    User control of comment display

    "; - $output .= "

    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:

    "; - $output .= ""; - $output .= "

    When a user chooses save settings, the comments are then redisplayed using the user's new choices. Administrators can set the default settings for the comment control panel, along with other comment defaults, in %comment-config.

    "; - $output .= "

    NOTE: When comment moderation is enabled, users will have another control panel option to control thresholds (see below).

    "; - - $output .= "

    Additional comment configurations

    "; - $output .= "

    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 %site-config under Submission settings.

    "; - $output .= "

    Administrators can control access to various comment module functions through %user-permissions. 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.

    "; - $output .= "

    The following permissions can be enabled for anonymous users, authenticated users, or any other user roles that the administrator chooses to define:

    "; - $output .= ""; - - $output .= "

    Notification of new comments

    "; - $output .= "

    Drupal provides specific features to inform site members when new comments have been posted:

    "; - $output .= ""; - - $output .= "

    Comment moderation

    "; - $output .= "

    On sites with active commenting from users, the administrator can turn over comment moderation to the community.

    "; - $output .= "

    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 the comments they wish to view. Those comments with ratings lower than the set threshold will not be shown.

    "; - $output .= "

    To enable moderation, the administrator must grant %permission permissions. Then, a number of options in %comment-moderation must be configured.

    "; - - $output .= "

    Moderation votes

    "; - $output .= "

    The first step is to create moderation labels which allow users to rate a comment. Go to %comment-votes. In the vote field, enter the textual labels which users will see when casting their votes. Some examples are

    "; - $output .= ""; - $output .= "

    So that users know how their votes affect the comment, these examples include the vote value as part of the label, although that is optional.

    "; - $output .= "

    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.

    "; - - $output .= "

    Moderator vote/values matrix

    "; - - $output .= "

    Next go to %comment-matrix. Enter the values for the vote labels for each permission role in the vote matrix. The values entered here will be used to create the rating for each comment.

    "; - $output .= "

    NOTE: Comment ratings are calculated by averaging user votes with the initial rating.

    "; - $output .= "

    Creating comment thresholds

    "; - $output .= "

    In %comment-thresholds, 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 their 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.

    "; - $output .= "

    When creating the thresholds, note that the Minimum score is asking you for the lowest rating that a comment can have in order to be displayed.

    "; - $output .= "

    To see a common example of how thresholds work, you might visit %slashdot and view one of their comment boards associated with a story. You can reset the thresholds in their comment control panel.

    "; - - $output .= "

    Initial comment scores

    "; - $output .= "

    Finally, you may want to enter some initial comment scores. In %comment-inital 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 0 as the default.

    "; - $output = t($output, array("%comment-config" => l(t("administer") ." » ". t("configuration") ." » ". t("modules") ." » ". t("comment"), "admin/system/modules/comment"), "%site-config" => l(t("administer") ." » ". t("configuration"), "admin/system"), "%user-permissions" => l(t("administer") ." » ". t("accounts") ." » ". t("permissions"), "admin/user/permission"), "%tracker" => l(t("recent posts"), "tracker"), "%download-notify" => "". t("download") ."", "%permission" => l(t("moderate comments"), "admin/user/permissions"), "%comment-moderation" => l(t("administer") ." » ". t("comments") ." » ". t("moderation"), "admin/comment/moderation"), "%comment-votes" => l(t("administer") ." » ". t("comments") ." » ". t("moderation") ." » ". t("votes"), "admin/comment/moderation/votes"), "%comment-matrix" => l(t("administer") ." » ". t("comments") ." » ". t("moderation") ." » ". t("matrix"), "admin/comment/moderation/matrix"), "%comment-thresholds" => l(t("administer") ." » ". t("comments") ." » ". t("moderation") ." » ". t("thresholds"), "admin/comment/moderation/thresholds"), "%slashdot" => "Slashdot", "%comment-inital" => l(t("administer") ." » ". t("comments") ." » ". t("initial comment scores"), "admin/comments/moderation/roles"))); - break; - case 'admin/system/modules#description': - $output = t("Enables user to comment on content (nodes)."); - break; - case 'admin/system/modules/comment': - $output = 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 and slightly indented forming an outline. They also come in two styles: \"expanded\", where you see both the title and the contents, and \"collapsed\" where you only see the title. To set the default threshold you first have to set up thresholds in the %threshold area. Preview comment forces a user to look at their comment by clicking on a \"Preview\" button before they can actually add the comment. 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" => l(t("administer") ." » ". t("comments") ." » ". t("moderation") ." » ". t("thresholds"), "admin/comment/moderation/filters"))); - break; - case 'admin/comment': - $output = t("Comments let users give feedback to content authors. Here you may review/approve/deny recent comments, and configure moderation if desired."); - break; - case 'admin/comment/comments': - $output = t("Click on %nup to see your latest comments, or %queue to approve new comments.", array("%nup" => l(t("new or updated comments"), "admin/comment/0"), "%queue" => l(t("comment approval queue"), "admin/comment/1"))); - break; - case 'admin/comment/comments/0': - $output = 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."); - break; - case 'admin/comment/comments/1': - $output = t("Below is a list of the comments posted to your site that need approval. To approve a comment click on \"edit comment\" and then change it's moderation status to Approved.
    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."); - break; - case 'admin/comments/moderation': - $output = 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. %votes sets up the names in the dropdown menu, and the order in which they appear, using weights. %matrix sets up the value of each user's vote, and %threshold sets up the levels at which a comment will be displayed.", array("%votes" => l(t("Votes"), "admin/comment/moderation/votes"), "%matrix" => l(t("Matrix"), "admin/comment/moderation/matrix"), "%threshold" => l(t("threshold"), "admin/comment/moderation/threshold"))); - break; - case 'admin/comment/moderation/votes': - $output = 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 edit to edit a current vote weight.
    Notes: "); - break; - case 'admin/comment/moderation/matrix': - $output = t("Here is where you assign a value to each item in the dropdown menu. 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.
    Notes:"); - break; - case 'admin/comment/moderation/filters': - $output = t("Optional 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 delete a threshold click on \"edit\"."); - break; - case 'admin/comment/moderation/roles': - $output = t("Here you can setup the initial vote value of a comment posted by each user role. This value is used before any other users vote on the comment.
    Note: Blank entries are valued at zero"); - break; - case ' admin/comment/search': - $output = 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'."); - break; - } - return $output; -} - -function comment_settings() { - - $output .= form_select(t("Default display mode"), "comment_default_mode", variable_get("comment_default_mode", 4), _comment_get_modes(), 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), _comment_get_orders(), 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", $user->signature, 70, 3, t("Your signature will be publicly displayed at the end of your comments.") ."
    ". 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_referer_save() { - $_SESSION["comment_referer"] = arg(0) ."/". arg(1) ."/". arg(2); -} - -/* -** Restores the referer from a persistent variable: -*/ - -function comment_referer_load() { - return $_SESSION["comment_referer"]; -} - -function comment_form($edit) { - global $user; - - $form .= "\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 INNER 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 INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d AND c.status = 0", $pid)); - comment_view($comment); - } - else if (user_access("access content")) { - node_view(node_load(array("nid" => $nid))); - $pid = 0; - } - - /* - ** If possible, show reply form - */ - - if (node_comment_mode($nid) != 2) { - theme("box", t("Reply"), t("This discussion is closed: you can't post new comments.")); - } - else if (user_access("post comments")) { - 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 INNER 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)); - - /* - ** Here we are building the thread field. See the comment - ** in comment_render(). - */ - - if ($edit["pid"] == 0) { - /* - ** This is a comment with no parent comment (depth 0): we start - ** by retrieving the maximum thread level. - */ - - $max = db_result(db_query("SELECT MAX(thread) FROM {comments} WHERE nid = %d", $edit["nid"])); - - // Strip the "/" from the end of the thread - $max = rtrim($max, "/"); - - /* - ** Next, we increase this value by one. Note that we can't - ** use 1, 2, 3, ... 9, 10, 11 because we order by string and - ** 10 would be right after 1. We use 1, 2, 3, ..., 9, 91, - ** 92, 93, ... instead. Ugly but fast. - */ - - $decimals = (string)substr($max, 0, strlen($max) - 1); - $units = substr($max, -1, 1); - if ($units) { - $units++; - } - else { - $units = 1; - } - - if ($units == 10) { - $units = "90"; - } - - // Finally build the thread field for this new comment - $thread = "$decimals$units/"; - } - else { - /* - ** This is comment with a parent comment: we increase - ** the part of the thread value at the proper depth. - */ - - // Get the parent comment: - $parent = db_fetch_object(db_query("SELECT * FROM {comments} WHERE cid = '%d'", $edit["pid"])); - - // Strip the "/" from the end of the parent thread: - $parent->thread = (string)rtrim((string)$parent->thread, "/"); - - // Get the max value in _this_ thread: - $max = db_result(db_query("SELECT MAX(thread) FROM {comments} WHERE thread LIKE '%s.%%' AND nid = '%d'", $parent->thread, $edit["nid"])); - - if ($max == "") { - // First child of this parent - $thread = "$parent->thread.1/"; - } - else { - // Strip the "/" at the end of the thread: - $max = rtrim($max, "/"); - - // We need to get the value at the correct depth: - $parts = explode(".", $max); - $parent_depth = count(explode(".", $parent->thread)); - $last = $parts[$parent_depth]; - - /* - ** Next, we increase this value by one. Note that we can't - ** use 1, 2, 3, ... 9, 10, 11 because we order by string and - ** 10 would be right after 1. We use 1, 2, 3, ..., 9, 91, - ** 92, 93, ... instead. Ugly but fast. - */ - - $decimals = (string)substr($last, 0, strlen($last) - 1); - $units = substr($last, -1, 1); - $units++; - if ($units == 10) { - $units = "90"; - } - - // Finally build the thread field for this new comment: - $thread = "$parent->thread.". $decimals.$units ."/"; - } - } - - - $edit["cid"] = db_next_id("{comments}_cid"); - - db_query("INSERT INTO {comments} (cid, nid, pid, uid, subject, comment, hostname, timestamp, status, score, users, thread) VALUES (%d, %d, %d, %d, '%s', '%s', '%s', %d, %d, %d, '%s', '%s')", $edit["cid"], $edit["nid"], $edit["pid"], $user->uid, $edit["subject"], $edit["comment"], getenv("REMOTE_ADDR"), time(), $status, $score, $users, $thread); - - /* - ** 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"), comment_referer_load() ."#$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 "\n"; - } - - print "cid\">\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 : ($_SESSION["comment_mode"] ? $_SESSION["comment_mode"] : variable_get("comment_default_mode", 4)); - } - - if (empty($order)) { - $order = $user->sort ? $user->sort : ($_SESSION["comment_sort"] ? $_SESSION["comment_sort"] : variable_get("comment_default_order", 1)); - } - - if (empty($threshold)) { - $threshold = $user->threshold ? $user->threshold : ($_SESSION["comment_threshold"] ? $_SESSION["comment_threshold"] : variable_get("comment_default_threshold", 0)); - } - $threshold_min = db_result(db_query("SELECT minimum FROM {moderation_filters} WHERE fid = %d", $threshold)); - - if (empty($comments_per_page)) { - $comments_per_page = $user->comments_per_page ? $user->comments_per_page : ($_SESSION["comment_comments_per_page"] ? $_SESSION["comment_comments_per_page"] : variable_get("comment_default_per_page", "50")); - } - - print "\n"; - - - if ($cid) { - - /* - ** Single comment view - */ - - print "
    \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 INNER 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 "
    ". form_submit(t("Moderate comment")) ."

    "; - } - print "
    "; - } - 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, c.thread FROM {comments} c INNER 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, c.thread"; - - /* - ** We want to use the standard pager, but threads would need every - ** comment to build the thread structure, so we need to store some - ** extra info. - ** - ** We use a "thread" field to store this extra info. The basic idea - ** is to store a value and to order by that value. The "thread" field - ** keeps this data in a way which is easy to update and convenient - ** to use. - ** - ** A "thread" value starts at "1". If we add a child (A) to this - ** comment, we assign it a "thread" = "1.1". A child of (A) will have - ** "1.1.1". Next brother of (A) will get "1.2". Next brother of the - ** parent of (A) will get "2" and so on. - ** - ** First of all note that the thread field stores the depth of the - ** comment: depth 0 will be "X", depth 1 "X.X", depth 2 "X.X.X", etc. - ** - ** Now to get the ordering right, consider this example: - ** - ** 1 - ** 1.1 - ** 1.1.1 - ** 1.2 - ** 2 - ** - ** If we "ORDER BY thread ASC" we get the above result, and this is - ** the natural order sorted by time. However, if we "ORDER BY thread - ** DESC" we get: - ** - ** 2 - ** 1.2 - ** 1.1.1 - ** 1.1 - ** 1 - ** - ** Clearly, this is not a natural way to see a thread, and users - ** will get confused. The natural order to show a thread by time - ** desc would be: - ** - ** 2 - ** 1 - ** 1.2 - ** 1.1 - ** 1.1.1 - ** - ** which is what we already did before the standard pager patch. To - ** achieve this we simply add a "/" at the end of each "thread" value. - ** This way out thread fields will look like depicted below: - ** - ** 1/ - ** 1.1/ - ** 1.1.1/ - ** 1.2/ - ** 2/ - ** - ** we add "/" since this char is, in ASCII, higher than every number, - ** so if now we "ORDER BY thread DESC" we get the correct order. Try - ** it, it works ;). However this would spoil the "ORDER BY thread ASC" - ** Here, we do not need to consider the trailing "/" so we use a - ** substring only. - */ - - if ($order == 1) { - if ($mode == 1 || $mode == 2) { - $query .= " ORDER BY c.timestamp DESC"; - } - else { - $query .= " ORDER BY c.thread DESC"; - } - } - else if ($order == 2) { - if ($mode == 1 || $mode == 2) { - $query .= " ORDER BY c.timestamp"; - } - else { - - /* - ** See comment above. Analysis learns that this doesn't cost - ** too much. It scales much much better than having the whole - ** comment structure. - */ - - $query .= " ORDER BY SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))"; - } - } - - /* - ** Start a form, to use with comment control and moderation. - */ - - $result = pager_query($query, $comments_per_page, 0, "SELECT COUNT(*) FROM {comments} WHERE nid = '". check_query($nid) ."'"); - - if (db_num_rows($result) && (variable_get("comment_controls", 0) == 0 || variable_get("comment_controls", 0) == 2)) { - print "
    \n"; - theme("comment_controls", $threshold, $mode, $order, $comments_per_page); - print form_hidden("nid", $nid); - print "
    "; - } - - print "
    \n"; - print form_hidden("nid", $nid); - - while ($comment = db_fetch_object($result)) { - $comment->depth = count(explode(".", $comment->thread)) - 1; - - if ($mode == 1) { - theme("comment_flat_collapsed", $comment, $threshold_min); - } - else if ($mode == 2) { - theme("comment_flat_expanded", $comment, $threshold_min); - } - else if ($mode == 3) { - theme("comment_thread_min", $comment, $threshold_min); - } - else if ($mode == 4) { - theme("comment_thread_max", $comment, $threshold_min); - } - } - - /* - ** Use the standard pager, $pager_total is the number of returned rows, - ** is global and defined in pager.inc - */ - if ($pager = pager_display(NULL, $comments_per_page, 0, "default", array("comments_per_page" => $comments_per_page))) { - print $pager; - } - - if (db_num_rows($result) && comment_user_can_moderate($node)) { - print "
    ". form_submit(t("Moderate comments")) ."

    "; - } - - print "
    "; - - if (db_num_rows($result) && (variable_get("comment_controls", 0) == 1 || variable_get("comment_controls", 0) == 2)) { - print "
    \n"; - theme("comment_controls", $threshold, $mode, $order, $comments_per_page); - print form_hidden("nid", $nid); - print "
    "; - } - } - - /* - ** 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))); - } - - /* - ** Save were we come from so we can go back after a reply - */ - - comment_referer_save(); - } -} - -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 ($node->comment == 2) { - 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"); - } - } - } - } - - if ($type == "system") { - if (user_access("administer comments")) { - - menu("admin/comment", t("comments"), "comment_admin", 1); - menu("admin/comment/comments", t("overview"), NULL, 2); - menu("admin/comment/comments/0", t("new/updated"), "comment_admin", 1); - menu("admin/comment/comments/1", t("approval queue"), "comment_admin", 2); - menu("admin/comment/search", t("search"), "comment_admin", 8); - menu("admin/comment/help", t("help"), "comment_help", 9); - menu("admin/comment/edit", t("edit comment"), "comment_admin", 0, 1); - - // comment settings: - if (user_access("administer moderation")) { - menu("admin/comment/moderation", t("moderation"), NULL, 3); - menu("admin/comment/moderation/votes", t("votes"), "comment_admin"); - menu("admin/comment/moderation/matrix", t("matrix"), "comment_admin"); - menu("admin/comment/moderation/filters", t("thresholds"), "comment_admin"); - menu("admin/comment/moderation/roles", t("initial scores"), "comment_admin", 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(comment_referer_load())); - 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(comment_referer_load())); - } - 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(comment_referer_load(), "mode=$mode&order=$order&threshold=$threshold&comments_per_page=$comments_per_page")); - drupal_goto(url(comment_referer_load())); - 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 INNER 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 = "

    ". t("Edit comments") ."

    "; - $output .= table($header, $rows); - } - - return $output; - } -} - -function comment_admin_edit($id) { - - $result = db_query("SELECT c.*, u.name, u.uid FROM {comments} c INNER 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) { - - $header = array( - array("data" => t("subject"), "field" => "subject"), - array("data" => t("author"), "field" => "u.name"), - array("data" => t("status"), "field" => "status"), - array("data" => t("time"), "field" => "c.timestamp", "sort" => "desc"), - array("data" => t("operations"), "colspan" => 2) - ); - - $sql = "SELECT c.*, u.name, u.uid FROM {comments} c INNER JOIN {users} u ON u.uid = c.uid WHERE c.status = ". check_query($status); - $sql .= tablesort_sql($header); - $result = pager_query($sql, 50); - - 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")) ."". format_date($comment->timestamp, "small") ."". 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", tablesort_pager())) { - $rows[] = array(array("data" => $pager, "colspan" => 6)); - } - - return table($header, $rows); -} - -function comment_mod_matrix($edit) { - - $output .= "

    Moderation vote/value matrix

    "; - - 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)); - $output = status("Vote values saved"); - } - - $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 .= "
    ". form_submit(t("Submit votes")); - - return form($output); -} - -function comment_mod_roles($edit) { - - $output .= "

    Initial comment scores

    "; - - if ($edit) { - variable_set("comment_roles", $edit); - $output = status("Comment scores saved"); - } - - $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 .= "
    ". 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; - $output = status("Vote saved"); - } - 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; - $output = status("Vote deleted"); - } - 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 = status("Vote added"); - } - - $output .= "

    ". t("Moderation votes overview") ."

    "; - $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 .= "

    ". (isset($mid) ? "Edit" : "Add new") ." moderation option

    "; - $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; - $output = status("Saved threshold"); - } - else if ($op == t("Delete threshold")) { - db_query("DELETE FROM {moderation_filters} WHERE fid = %d", $fid); - $fid = 0; - $output = status("Deleted threshold"); - } - 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 = status("Added threshold"); - } - - $output .= "

    Comment threshold overview

    "; - - $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 .= "

    ". (isset($fid) ? "Edit" : "Add new") ." threshold

    "; - $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 == "moderation") { - $op = arg(3); - } - - if (user_access("administer comments")) { - switch ($op) { - case "edit": - $output = comment_admin_edit(arg(3)); - break; - case "search": - $output = 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")) { - $output = comment_mod_votes($edit); - } - break; - case "roles": - case t("Save scores"): - if (user_access("administer moderation")) { - $output = comment_mod_roles($edit); - } - break; - case "matrix": - case t("Submit votes"): - if (user_access("administer moderation")) { - $output = 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")) { - $output = comment_mod_filters($edit); - } - break; - case "delete": - $output = comment_delete(array("cid" => arg(3))); - break; - case t("Delete"): - $output = status(comment_delete($edit)); - $output .= comment_admin_overview(0); - break; - case t("Submit"): - $output = status(comment_save(check_query(arg(3)), $edit)); - $output .= comment_admin_overview(0); - break; - default: - if (arg(3) == 1) { - $output = comment_admin_overview(1); - } - else { - $output = comment_admin_overview(0); - } - } - return $output; - } - else { - return message_access(); - } -} - -/* -** Renderer or visualization functions this can be optionally -** overridden by themes. -*/ - -function comment_mode_form($mode) { - - $modes = _comment_get_modes(); - foreach ($modes as $key => $value) { - $options .= " \n"; - } - - return "\n"; -} - -function comment_order_form($order) { - - $orders = _comment_get_orders(); - foreach ($orders as $key=>$value) { - $options .= " \n"; - } - - return "\n"; -} - -function comment_per_page_form($comments_per_page) { - for ($i = 10; $i < 100; $i = $i + 20) { - $options .= " "; - } - return "\n"; -} - -function comment_threshold($threshold) { - $result = db_query("SELECT fid, filter FROM {moderation_filters} "); - $options .= " "; - while ($filter = db_fetch_object($result)) { - $filters .= " "; - } - if ($filters) { - return "\n"; - } -} - -function comment_controls($threshold = 1, $mode = 3, $order = 1, $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(NULL, $output, t("Select your preferred way to display the comments and click 'Save settings' to activate your changes.")); - } - - return theme("box", t("Comment viewing options"), $output); -} - -function comment_moderation_form($comment) { - global $comment_votes, $user, $node; - static $votes; - - $op = $_POST["op"]; - - if ($op == "reply") { - // preview comment: - $output .= " "; - } - 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 .= " \n"; - if ($votes) { - foreach ($votes as $vote) { - $options .= " \n"; - } - } - - if (user_access("administer comments")) { - $options .= " \n"; - $options .= " \n"; - } - - $output .= "\n"; - } - - return $output; -} - -function comment($comment, $links = 0) { - $output .= "
    "; - $output .= "
    $comment->subject". ($comment->new ? " ". theme("theme_mark") : "") ."
    "; - $output .= "
    ". $comment->moderation ."
    "; - $output .= "
    ". t("by %a on %b", array("%a" => format_name($comment), "%b" => format_date($comment->timestamp))) ."
    "; - $output .= "
    ". check_output($comment->comment) ."
    "; - $output .= "
    $links
    "; - $output .= "
    "; - print $output; -} - -function comment_folded($comment) { - print "
    ". l($comment->subject, comment_referer_load() ."/$comment->cid#$comment->cid") ." ". t("by") ." ". format_name($comment) ."
    "; -} - -function comment_flat_collapsed($comment, $threshold) { - if (comment_visible($comment, $threshold)) { - print comment_view($comment, "", 0); - } -} - -function comment_flat_expanded($comment, $threshold) { - comment_view($comment, comment_links($comment, 0), comment_visible($comment, $threshold)); -} - -function comment_thread_min($comment, $threshold, $pid = 0) { - if (comment_visible($comment, $threshold)) { - print "
    depth * 25) ."\">
    \n"; - print comment_view($comment, "", 0); - - print "
    \n"; - } -} - -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 ($comment->depth) { - print "
    depth * 25) ."\"> \n"; - } - - comment_view($comment, comment_links($comment, 0), comment_visible($comment, $threshold)); - - if ($comment->depth) { - print "
    \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 $user; - - $moderation = $_POST["moderation"]; - - 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) { - $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)); - } - else { - $_SESSION["comment_mode"] = $mode; - $_SESSION["comment_sort"] = $order; - $_SESSION["comment_threshold"] = $threshold; - $_SESSION["comment_comments_per_page"] = $comments_per_page; - } -} - -function comment_num_all($nid) { - static $cache; - - if (!isset($cache[$nid])) { - $cache[$nid] = db_result(db_query("SELECT COUNT(cid) FROM {comments} WHERE nid = %d AND status = 0", $nid)); - } - return $cache[$nid]; -} - -function comment_num_replies($pid) { - static $cache; - - if (!isset($cache[$pid])) { - $cache[$pid] = db_result(db_query("SELECT COUNT(cid) FROM {comments} WHERE pid = %d AND status = 0", $pid)); - } - - return $cache[$pid]; -} - -/** - * 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 INNER 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_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 INNER 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(t("Disabled"), t("Read only"), t("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; - } -} - -function _comment_get_modes() { - /* - ** We can't use a global variable array because the locale system - ** is not initialized yet when the comment module is loaded. - */ - - return array(1 => t("Flat list - collapsed"), 2 => t("Flat list - expanded"), 3 => t("Threaded list - collapsed"), 4 => t("Threaded list - expanded")); -} - -function _comment_get_orders() { - /* - ** We can't use a global variable array because the locale system - ** is not initialized yet when the comment module is loaded. - */ - return array(1 => t("Date - newest first"), 2 => t("Date - oldest first")); -} - -?> diff --git a/modules/drupal/drupal.module b/modules/drupal/drupal.module deleted file mode 100644 index f360b2c4625dabeefe50aadb8edd37c4aceea69e..0000000000000000000000000000000000000000 --- a/modules/drupal/drupal.module +++ /dev/null @@ -1,198 +0,0 @@ -The \"Drupal\" module features a capability whereby other drupal sites may call home to report their existence. In turn, this enables a pod of Drupal sites to find, cooperate and advertise each other.

    "; - $output .= "

    Currently, the main application of this feature is the %drupal-sites. By default, fresh Drupal installations can use %Drupal as their directory server and report their existence. This reporting occurs via scheduled %xml-rpc pings.

    "; - $output .= "

    Drupal administrators should simply enable this feature to get listed on the %drupal-sites; just set your site's name, e-mail address, slogan and mission statement. Then make sure that the field called Drupal XML-RPC server on the %drupal-settings page is set to http://www.drupal.org/xmlrpc.php, and enable this feature using the dropdown directly below.

    "; - $output .= "

    The listing of your site will occur shortly after your site's next %cron. Note that cron.php should be called using the domain name which you want to have listed at %Drupal. 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.

    "; - $output .= "

    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.

    "; - $output = t($output, array("%drupal-sites" => "". t("Drupal sites page") ."", "%Drupal" => "drupal.org", "%xml-rpc" => "XLM-RPC", "%drupal-settings" => l(t("administer") ." » ". t("configuration") ." » ". t("modules") ." » ". t("drupal"), "admin/system/modules/drupal"), "%cron" => l(t("cron run"), "admin/system/help#cron"))); - break; - case 'admin/system/modules#description': - $output = t("Lets users log in using a Drupal ID and can notify drupal.org about your site."); - break; - case 'admin/system/modules/drupal': - $output = 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-setting setting -- but the directory server has to be able to handle Drupal XML. To get a full site listing go to the %general and set:", array("%Drupal-setting" => l(t("Drupal XML-RPC server"), "admin/system/modules/drupal"), "%general" => l(t("site configuration"), "admin/system"))); - break; - case 'user/help#drupal': - $site = variable_get("site_name", "this web site"); - - $output = "

    %drupal is the name of the software which powers %site. 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 Drupal ID.

    \n"; - $output .= "

    So please feel free to login to your account here at %site with a username from another Drupal site. The format of a Drupal ID is similar to an email address: username@server. An example of valid Drupal ID is mwlily@www.drupal.org.

    "; - - $output = t($output, array("%drupal" => "Drupal", "%site" => "$site")); - break; - } - - return $output; -} - -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 http://www.drupal.org/. 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 .= "link\">$site->name - $site->slogan
    $site->mission

    "; - } - - 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_help("user/help#drupal")); - 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_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 60691455fcbd221a15d7173b1f46a9f4dc43ed30..0000000000000000000000000000000000000000 --- a/modules/forum/forum.module +++ /dev/null @@ -1,674 +0,0 @@ -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("")); - $output .= form_textfield(t("Forum icon path"), "forum_icon_path", variable_get("forum_icon_path", ""), 30, 255, t("The path to the forum icons. Leave blank to disable icons. Don't add a trailing slash. Default icons are available in the 'misc' directory.")); - $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 hot.")); - $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 Forum topics-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")) { - $content = node_title_list(db_query_range("SELECT n.nid, n.title, GREATEST(n.created, MAX(c.timestamp)) AS sort FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid WHERE n.type = 'forum' AND n.status = 1 GROUP BY n.nid, n.title, n.created ORDER BY sort DESC", 0, variable_get("forum_block_num", "5")), t("Active forum topics:")); - - $content .= node_title_list(db_query_range("SELECT nid, title FROM {node} WHERE type = 'forum' ORDER BY nid DESC", 0, variable_get("forum_block_num", "5")), t("New forum topics:")); - - if ($content) { - $content .= "
    ". l(t("more"), "forum", array("title" => t("Read the latest forum topics."))) ."
    "; - } - - $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("forums"), "forum"); - } - - if ($type == "system" && user_access("create forum topics")) { - menu("node/add/forum",t("forum topic"), "forum_page"); - } - - if (!$main && $type == "node" && $node->type == "forum") { - // get previous and next topic - - $result = db_query("SELECT n.nid, n.title, GREATEST(n.created, MAX(c.timestamp)) AS date_sort, COUNT(c.nid) AS num_comments FROM {node} n INNER JOIN {forum} f ON n.nid = f.nid INNER 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.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; - break; - } - if ($topic->nid == $node->nid) { - $stop = 1; - } - else { - $prev->nid = $topic->nid; - $prev->title = $topic->title; - } - } - - if ($prev) { - $links[] = l(t("previous forum topic"), "node/view/$prev->nid", array("title" => $prev->title)); - } - - if ($next) { - $links[] = l(t("next forum topic"), "node/view/$next->nid", array("title" => $next->title)); - } - } - - return $links; -} - -function forum_content($node) { - $node->teaser = check_output($node->teaser); - $node->body = check_output($node->body); - return $node; -} - -function forum_view($node, $main = 0) { - - if ($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); - // Breadcrumb navigation - $breadcrumb[] = l(t("Home"), NULL); - $breadcrumb[] = l(t("Forums"), "forum"); - $breadcrumb[] = l($term_data->name, "forum/$term_data->tid"); - // print the breadcrumb - theme("breadcrumb", $breadcrumb); - } - // prepair the node content - $node = forum_content($node); - // print the node - 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.")); - } - - $output .= form_textarea(t("Body"), "body", $node->body, 60, 10); - - return $output; -} - -function forum_insert($node) { - db_query("INSERT INTO {forum} (nid, shadow, tid) VALUES (%d, %d, %d)", $node->nid, $node->shadow, $node->tid[0]); -} - -function forum_update($node) { - db_query("UPDATE {forum} SET shadow = %d, tid = %d WHERE nid = %d", $node->shadow, $node->tid[0], $node->nid); -} - -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") : " "; -} - -function _forum_last_reply($nid) { - $value = db_fetch_object(db_query_range("SELECT c.timestamp, u.name, u.uid FROM {comments} c INNER 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 t("%date
    by %author", array("%date" => format_date($topic->timestamp, "small"), "%author" => format_name($topic))); - } - 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; - } - $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), 1); - } - 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 INNER 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 INNER JOIN {node} n ON n.nid = c.nid INNER 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 INNER JOIN {node} n ON n.nid = h.nid INNER 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 INNER JOIN {node} n ON n.nid = f.nid INNER 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 INNER JOIN {node} n ON n.nid = f.nid INNER JOIN {comments} c ON n.nid = c.nid INNER 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, $forum_topic_list_header; - - $forum_topic_list_header = array( - array("data" => " "), - array("data" => t("Topic"), "field" => "n.title"), - array("data" => t("Replies"), "field" => "num_comments"), - array("data" => t("Created"), "field" => "n.created"), - array("data" => t("Last reply"), "field" => "date_sort", "sort" => "desc"), - ); - - $sql_sortby = _forum_get_topic_order($sortby); - for ($i = 0; $i < count($forum_topic_list_header); $i++) { - if ($forum_topic_list_header[$i]["field"] == $sql_sortby) { - $forum_topic_list_header[$i]["order"] = $sql_sortby; - } - } - - $term = taxonomy_get_term($tid); - $voc = taxonomy_get_vocabulary($term->vid); - $check_tid = $tid ? "'". check_query($tid). "'" : "NULL"; - - // 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, n.comment AS comment_mode, f.tid FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid INNER JOIN {users} u ON n.uid = u.uid LEFT JOIN {comments} c ON n.nid = c.nid INNER JOIN {forum} f ON n.nid = f.nid WHERE n.nid = r.nid AND ((r.tid = $check_tid AND f.shadow = 1) OR f.tid = $check_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"; - $sql .= tablesort_sql($forum_topic_list_header); - - $sql_count = "SELECT COUNT(DISTINCT(n.nid)) FROM {node} n INNER JOIN {forum} f ON n.nid = f.nid INNER JOIN {term_node} r ON n.nid = r.nid WHERE n.nid = r.nid AND ( (r.tid = $check_tid AND f.shadow = 1) OR f.tid = $check_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 INNER 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 INNER 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 - - - /* - ** Breadcrumb navigation: - */ - - $breadcrumb[] = l(t("Home"), ""); - $breadcrumb[] = l(t("Forums"), "forum"); - - if ($parents) { - $parents = array_reverse($parents); - foreach ($parents as $p) { - if ($p->tid == $tid) { - $title = $p->name; - } - else { - $breadcrumb[] = l($p->name, "forum/$p->tid"); - } - } - } - - $output = "
    "; - $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); - } - - $output .= "
    "; - - theme("header"); - theme("breadcrumb", $breadcrumb); - theme("box", $title, $output); - theme("footer"); -} - -function forum_theme_list($forums, $parents, $tid) { - global $user; - - if ($forums) { - - $header = array(t("Forum"), t("Topics"), t("Posts"), t("Last post")); - - foreach ($forums as $forum) { - if ($forum->container) { - $forum->num_topics = ""; - $forum->num_posts = ""; - $forum->last_post = ""; - } - else { - if ($user->uid) { - $new_topics = $forum->num_topics - $forum->old_topics; - } - - $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"); - } - } - - $description = "
    depth * 30) ."px;\">\n"; - $description .= "
    ". l($forum->name, "forum/$forum->tid") ."
    \n"; - - if ($forum->description) { - $description .= "
    $forum->description
    \n"; - } - if ($links) { - $description .= "
    ". t("Jump to: %links", array("%links" => implode(", ", $links))) .".
    \n"; - } - $description .= "
    \n"; - - $rows[] = array( - array("data" => $description, "class" => "description"), - array("data" => $forum->num_topics . ($new_topics ? "
    (".t("%a new", array("%a" => $new_topics)).")" : ""), "class" => "topics"), - array("data" => $forum->num_posts, "class" => "posts"), - array("data" => ($forum->container ? "" : _forum_format($forum->last_post)), "class" => "last-reply") - - ); - - } - } - - return table($header, $rows); -} - - -function forum_theme_topic_list($tid, $topics, $sortby, $forum_per_page, $offset) { - global $id, $status, $user, $pager_total, $forum_topic_list_header; - - if ($topics) { - - foreach ($topics as $topic) { - // folder is new if topic is new or there are new comments since last visit - if ($topic->tid != $tid) { - $rows[] = array( - array("data" => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode), "class" => "icon"), - array("data" => $topic->title, "class" => "title"), - array("data" => l(t("This topic has been moved"), "forum/$topic->tid"), "colspan" => "3") - ); - } - else { - $rows[] = array( - array("data" => _forum_icon($topic->new, $topic->num_comments, $topic->comment_mode), "class" => "icon"), - array("data" => l($topic->title, "node/view/$topic->nid"), "class" => "topic"), - array("data" => $topic->num_comments . ($topic->new_replies ? "
    (".t("%a new", array("%a" => $topic->new_replies)).")" : ""), "class" => "replies"), - array("data" => _forum_format($topic), "class" => "created"), - array("data" => _forum_format($topic->last_reply), "class" => "last-reply") - ); - } - } - - if ($pager = pager_display(NULL, $forum_per_page, 0, "default", tablesort_pager())) { - $rows[] = array(array("data" => $pager, "colspan" => "5", "class" => "pager")); - } - } - - - if (user_access("create forum topics")) { - $output = l(t("create new forum topic"), "node/add/forum/$tid") ."

    "; - } - - $output .= table($forum_topic_list_header, $rows); - - return $output; -} - -function _forum_icon($new_posts, $num_posts = 0, $comment_mode = 0) { - - $base_path = variable_get("forum_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 ."/forum-$icon.gif"; - - return "\"\""; - } - else { - return " "; - } -} - -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($section = "admin/help#forum") { - $output = ""; - - switch ($section) { - case 'admin/help#forum': - $output .= "

    Creating a forum

    "; - $output .= "

    The forum module uses taxonomy to organize itself. To create a forum you first have to create a %taxonomy. 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, %taxo-terms 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.\"

    "; - $output .= "

    When you are happy with your vocabulary, go to %forums and set Forum vocabulary 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 the \"create forum topics\" %permission. These permissions can be set in the %permission pages.

    "; - $output .= "

    Icons

    "; - $output .= "

    To disable icons, set the icon path as blank in %forums.

    "; - $output .= "

    All files in the icon directory are assumed to be images. You may use images of whatever size you wish, but it is recommended to use 15x15 or 16x16.

    "; - $output = t($output, array("%taxonomy" => l(t("taxonomy vocabulary"), "admin/taxonomy/add/vocabulary"), "%taxo-terms" => l(t("add some terms"), "admin/taxonomy"), "%forums" => l(t("administer") ." » ". t("configutation") ." » ". t("modules") ." » ". t("forum"), "admin/system/modules/forum"), "%permission" => l(t("permission"), "admin/user/permission"))); - break; - case 'admin/system/modules#description': - $output = t("Enable threaded discussions about general topics."); - break; - case 'admin/system/modules/forum': - $output = t("Forums are threaded discussions based on the taxonomy system so you must first %taxonomy-create of type \"forum\" to place the forum tree in. Then %taxonomy-add 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" => l(t("create a taxonomy"), "admin/taxonomy/add/vocabulary"), "%taxonomy" => l(t("add terms"), "admin/taxonomy"))); - break; - } - - return $output; -} - -?> diff --git a/modules/help/help.module b/modules/help/help.module deleted file mode 100644 index f7477a2ab752cf13ad069b1e4200ccd23916d3e1..0000000000000000000000000000000000000000 --- a/modules/help/help.module +++ /dev/null @@ -1,62 +0,0 @@ -Glossary
    "; - $output .= "
    Block
    A small box containing information or content placed in the left-hand or right-hand sidebar of a web page.
    "; - $output .= "
    Comment
    A note attached to a node. Usually intended to clarify, explain, criticize, or express an opinion on the original material.
    "; - $output .= "
    Moderation
    The activity of making sure a post to a Drupal site fits in with what is expected for that Drupal site.
    "; - $output .= "
    Approved
    A moderated post which has been accepted by the moderators for publication. (See published).
    "; - $output .= "
    Waiting
    A moderated post which is still being voted on to be accepted for publication. (See published.)
    "; - $output .= "
    Moderators
    The group of Drupal users that reviews posts before they are published. These users have the \"access submission queue\" permission. (See Published).
    "; - $output .= "
    Node
    The basic data unit in Drupal. Everything is a node or an extention of a node.
    "; - $output .= "
    Public
    See published.
    "; - $output .= "
    Published
    A node that is viewable by everyone. (See unpublished.)
    "; - $output .= "
    Role
    A classification users are placed into for the purpose of setting users' permissions.
    "; - $output .= "
    Taxonomy
    A division of a collection of things into ordered, classified groups. (See %taxonomy.)
    "; - $output .= "
    Unpublished
    A node that is only viewable by administrators and moderators.
    "; - $output .= "
    User
    A person who has an account at your Drupal site, and is logged in with that account.
    "; - $output .= "
    Visitor
    A person who does not have an account at your Drupal site or a person who has an account at your Drupal site but is not logged in with that account. Also termed \"anonymous user\".
    "; - $output .= "
    "; - $output = t($output, array("%taxonomy" => l(t("taxonomy help"), "admin/taxonomy/help"))); - - return $output; -} - -function help_help($section = "admin/help#help") { - $output = ""; - - switch ($section) { - - case 'admin/help#help': - foreach (module_list() as $name) { - if ($name == 'help') { - continue; - } - else if (module_hook($name, "help")) { - $temp = module_invoke($name, "help", "admin/help#$name"); - if (!empty($temp)) { - $links[] = l($name, "admin/help#$name"); - $output .= "

    ". ucfirst($name) ." module

    "; - $output .= $temp; - } - } - } - $output = "". implode(" · ", $links) ."
    ". $output; - break; - case 'admin/system/modules#description': - $output = t("Manages displaying online help."); - break; - } - return $output; -} - -?> diff --git a/modules/locale/locale.module b/modules/locale/locale.module deleted file mode 100644 index 18baa7dd696abfbae4941c6e0fde02fbc3d33b3d..0000000000000000000000000000000000000000 --- a/modules/locale/locale.module +++ /dev/null @@ -1,357 +0,0 @@ -Most programs are written and documented in English, and use English to interact with users. This is also true for a great deal of web sites. However, most people are less comfortable with English than with their 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 English, and far more of their own language.

    "; - $output .= "

    Therefore Drupal provides a framework to setup a multi-lingual web site, or to overwrite the default English texts. We explored the various alternatives to support internationalization (I18N) and decided to design the framework in such a way that the impact of internationalization on drupal's sources is minimized, modular and 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.

    "; - $output .= "

    How to translate texts

    "; - $output .= "

    The actual translation starts at the %overview page of the locale section in the administration pages. In the menu on the left under \"localization\" 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.

    "; - $output .= "

    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.

    "; - $output .= "

    Below the text you can see an example URI where this text shows up one your site. Chances are most of these texts will be used and displayed on more than one page, though only one example URI is presented.

    "; - $output .= "

    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 this, it means that this entry still needs to be translated into that language. If not, it has been translated already.

    "; - $output .= "

    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.

    "; - $output .= "

    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.

    "; - $output .= "

    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.

    "; - $output .= "

    How to add new languages

    "; - $output .= "

    Adding a new language requires you to edit your configuration file and 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 \$languages-variable:

    "; - $output .= "
    -    \$languages = array(\"nl\" => \"Dutch / Nederlands\", \"fr\" => \"French / Francais\");
    -  
    "; - - $output .= "

    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\"):

    "; - $output .= "
    -    \$languages = array(\"en\" => \"English\", \"nl\" => \"Dutch / Nederlands\", \"fr\" => \"French / Francais\");
    -  
    "; - $output .= "

    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:

    "; - $output .= "
    -    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;
    -  
    "; - $output = t($output, array("%overview" => l(t("overview"), "admin/locale"))); - break; - case 'admin/system/modules#description': - $output = t("Enables the translation of the user interface to languages other than English."); - break; - case 'admin/locale': - $output = 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."); - break; - case 'admin/locale/search': - $output = t("Search the localization database. ('*' can be used as a wildcard)"); - break; - case 'admin/locale/translated': - $output = t("Start by searching the translated strings."); - break; - case 'admin/locale/untranslated': - $output = t("Start by searching the untranslated strings."); - break; - } - - return $output; -} - -function locale_perm() { - return array("administer locales"); -} - -function locale_link($type) { - global $languages; - - if ($type == "system") { - if (user_access("administer locales")) { - - menu("admin/locale", t("localization"), NULL, 5); - menu("admin/locale/search", t("search string"), "locale_admin", 8); - menu("admin/locale/help", t("help"), "locale_help", 9); - menu("admin/locale/edit", t("edit string"), "locale_admin", 0, 1); // hidden menu - menu("admin/locale/delete", t("delete string"), "locale_admin", 0, 1); // hidden menu - - foreach ($languages as $key => $value) { - menu("admin/locale/$key", "$value", NULL); - menu("admin/locale/$key/translated", t("translated strings"), "locale_admin"); - menu("admin/locale/$key/untranslated", t("untranslated strings"), "locale_admin"); - } - } - } -} - -function locale_user($type, &$edit, &$user) { - global $languages; - if ($type == "edit_form" && count($languages) > 1) { - $output = form_select(t("Language"), "language", $user->language, $languages, t("Selecting a different language will change the language of the site.")); - } - return $output; -} - -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) ? "$key ."\">$key " : "$key "; - } - - return $output; -} - -function locale_seek_query() { - $fields = array("string", "language", "status"); - if (is_array($_REQUEST["edit"])) { - foreach ($_REQUEST["edit"] as $key => $value) { - if (!empty($value) && in_array($key, $fields)) { - $query->$key = $value; - } - } - } - else { - foreach ($_REQUEST as $key => $value) { - if (!empty($value) && in_array($key, $fields)) { - $query->$key = strpos(",", $value) ? explode(",", $value) : $value; - } - } - } - return $query; -} - -function locale_seek() { - global $id, $languages; - $op = $_POST["op"]; - $query = locale_seek_query(); - - if ($query) { - - if ($query->status) { - switch ($query->language) { - case "all": - foreach ($languages as $key=>$value) { - $tmp[] = $key . (check_query($query->status) == 1 ? " !=" : " =") ." ''"; - } - $sql[] = implode(" AND ", $tmp); - break; - case "any": - foreach ($languages as $key=>$value) { - $tmp[] = $key . (check_query($query->status) == 1 ? " !=" : " =") ." ''"; - } - $sql[] = "(". implode(" || ", $tmp) .")"; - break; - default: - $sql[] = check_query($query->language) . (check_query($query->status) == 1 ? " !=" : " =") ." ''"; - } - } - - if ($query->string) { - $string_query[] = "string LIKE '%". check_query($query->string) ."%'"; - if ($query->status != 2) { - if (strlen($query->language) == 2) { - $string_query[] = check_query($query->language) ." LIKE '%". check_query($query->string) ."%'"; - } - else { - foreach ($languages as $key=>$value) { - $string_query[] = check_query($key) ." LIKE '%". check_query($query->string) ."%'"; - } - } - } - $sql[] = "(". implode(" || ", $string_query) .")"; - } - - $result = pager_query("SELECT * FROM {locales} ". (count($sql) ? " WHERE ". implode(" && ", $sql) : "") ." ORDER BY string", 50); - - $header = array(t("string"), (($query->status != 2 && strlen($query->language) == 2) ? t("translated string") : t("languages")), array("data" => t("operations"), "colspan" => "2")); - while ($locale = db_fetch_object($result)) { - $rows[] = array("$locale->string
    $locale->location", array("data" => (($query->status != 2 && strlen($query->language) == 2) ? $locale->{$query->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")); - } - - $request = array(); - if (count($query)) { - foreach ($query as $key => $value) { - $request[$key] = (is_array($value)) ? implode(",", $value) : $value; - } - } - - if ($pager = pager_display(NULL, 50, 0, "admin", $request)) { - $rows[] = array(array("data" => "$pager", "colspan" => "5")); - } - - $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": - $output = status(locale_delete(check_query(arg(3)))); - $output .= locale_seek(); - break; - case "edit": - $output = locale_edit(check_query(arg(3))); - break; - case "search": - if (locale_seek_query()) { - $output = locale_seek(); - } - $output .= locale_seek_form(); - break; - case t("Search"): - $output = locale_seek(); - $output .= locale_seek_form(); - break; - case t("Save translations"): - $output = status(locale_save(check_query(arg(3)))); - $output .= locale_seek(); - break; - default: - if (arg(3) == "translated") { - $edit["status"] = 1; - $edit["language"] = arg(2); - } - else { - $edit["status"] = 2; - $edit["language"] = arg(2); - } - $output = locale_seek(); - $output .= locale_seek_form(); - } - return $output; - } - else { - return 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 (is_array($locale_t) && array_key_exists($string, $locale_t)) { - $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 3049a751411fbc4104e5c36c9492794235ede59b..0000000000000000000000000000000000000000 --- a/modules/node/node.module +++ /dev/null @@ -1,1569 +0,0 @@ -Nodes"; - $output .= "

    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:

    "; - $output .= "
    A Title
    Up to 128 characters of text that titles the node.
    "; - $output .= "
    A Teaser
    A small block of text that is meant to get you interested in the rest of node. Drupal will automatically pull a small amount of the body of the node to make the teaser (To configure how long the teaser will be %teaser). The teaser can be changed if you don't like what Drupal grabs.
    "; - $output .= "
    The Body
    The main text that comprises your content.
    "; - $output .= "
    A Type
    What kind of node is this? Blog, book, forum, comment, unextended, etc.
    "; - $output .= "
    An Author
    The author's name. It will either be \"anonymous\" or a valid user. You cannot set it to an arbitrary value.
    "; - $output .= "
    Authored on
    The date the node was written.
    "; - $output .= "
    Changed
    The last time this node was changed.
    "; - $output .= "
    Static on front page
    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 %teaser), but if you think a node is important enough that you want it to stay on the front page enable this.
    "; - $output .= "
    Allow user comments
    A node can have comments. These comments can be written by other users (Read-write), or only by admins (Read-only).
    "; - $output .= "
    Attributes
    A way to sort nodes.
    "; - $output .= "
    Revisions
    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.
    "; - $output .= "
    Promote to front page
    To get people to look at the new stuff on your site you can choose to move it to the front page.
    "; - $output .= "
    In moderation queue
    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.
    "; - $output .= "
    Votes
    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."; - $output .= "
    Score
    The score of the node is gotten by the votes it is given.
    "; - $output .= "
    Users
    The list of users who have voted on a moderated node.
    "; - $output .= "
    Published
    When using Drupal's moderation system a node remains unpublished -- unavaliable to non-moderators -- until it is marked Published.
    "; - $output .= "

    Now that you know what is in a node, here are some of the types of nodes available.

    "; - - $output = t($output, array("%teaser" => l(t("click here"), "admin/system/modules/node"))); - - if ($mod == "admin") { - foreach (module_list() as $name) { - if (module_hook($name, "node") && $name != "node") { - $output .= "

    ". t("Node type: %module", array("%module" => module_invoke($name, "node", "name"))) ."

    "; - $output .= module_invoke($name, "node", "description"); - } - } - } - break; - - case 'admin/system/modules#description': - $output = t("The core that allows content to be submitted to the site."); - break; - case 'admin/system/modules/node': - $output = t("Settings for the core of Drupal. Almost everything is a node so these settings will affect most of the site."); - break; - case 'admin/node': - $output = t("Below is a list of all of the nodes in your site. Other forms of content are listed elsewhere (e.g. %comments).
    Clicking a title views that node, while clicking an author's name edits their user information.
    Other node-related tasks are available from the menu on the left.", array("%comments" => l(t("comments"), "admin/comment"))); - break; - case 'admin/node/search': - $output = t("Enter a simple pattern to search for a post. This can include the wildcard character *.
    For example, a search for \"br*\" might return \"bread bakers\", \"our daily bread\" and \"brenda\"."); - break; - case 'admin/node/settings': - $output = t("This page lets you set the defaults used during creation of nodes for all the different node types.
    comment: Read/write setting for comments.
    publish: Is this node publicly viewable, has it been published?
    promote: Is this node to be promoted to the front page?
    moderate: Does this node need approval before it can be viewed?
    static: Is this node always visible on the front page?
    revision: Will this node go into the revision system allowing multiple versions to be saved?"); - break; - - } - - return $output; -} - -/* -** 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 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, ""); - if ($delimiter > 0) { - return substr($body, 0, $delimiter); - } - - /* - ** If we have a short body, return the entire body: - */ - - if (strlen($body) < $size) { - return $body; - } - - /* - ** 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, "
    ", $size)) { - return substr($body, 0, $length); - } - - if ($length = strpos($body, "
    ", $size)) { - return substr($body, 0, $length); - } - - if ($length = strpos($body, "

    ", $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, $a2 = NULL, $a3 = NULL, $a4 = NULL) { - 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 ($function($node, $a2, $a3, $a4)); - } -} - -function node_invoke_nodeapi(&$node, $op, $arg = 0) { - $return = array(); - foreach (module_list() as $name) { - $function = $name ."_nodeapi"; - if (function_exists($function)) { - $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 INNER 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 = node_invoke($node, "load")) { - 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_nodeapi($node, "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[] = $value; - $s[] = "'%s'"; - } - } - - $keysfmt = implode(", ", $s); - // need to quote the placeholders for the values - $valsfmt = "'". implode("', '", $s) ."'"; - - // Insert the node into the database: - db_query("INSERT INTO {node} (". implode(", ", $k) .") VALUES(". implode(", ", $s) .")", $v); - - // Call the node specific callback (if any): - node_invoke($node, "insert"); - node_invoke_nodeapi($node, "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) ." = '%s'"; - $v[] = $value; - } - } - - // Update the node in the database: - db_query("UPDATE {node} SET ". implode(", ", $q) ." WHERE nid = '$node->nid'", $v); - - // Call the node specific callback (if any): - node_invoke($node, "update"); - node_invoke_nodeapi($node, "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 '' also. - */ - - $node->body = str_replace("", "", $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; - } - - // Can't use node_invoke: - // the access hook takes the $op parameter before the $node parameter. - return module_invoke($type, "access", $op, $node); -} - -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 INNER 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(0 => t("Do not filter"), 1 => t("Strip tags"), 2 => t("Escape tags")), t("How to deal with HTML and PHP tags in user-contributed content. If set to \"Strip tags\", dangerous tags are removed. If set to \"Escape tags\", all HTML is escaped and presented as it was typed.")); - $output .= form_textfield(t("Allowed HTML tags"), "allowed_html", variable_get("allowed_html", "
      • "), 64, 255, t("If \"Strip tags\" is selected, 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 mod_rewrite is available on your system, use the rewrite rules in Drupal's .htaccess file instead as these will also correct external referrers.")); - $output .= "
        "; - return $output; -} - -function node_escape_html($text) { - return htmlspecialchars($text); -} - -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) == 1) { - $text = node_filter_html($text); - } - - if (variable_get("rewrite_old_urls", 0)) { - $text = rewrite_old_urls($text); - } - - if (variable_get("filter_html", 0) == 2) { - $text = node_escape_html($text); - } - - return trim($text); -} - -function node_link($type, $node = 0, $main = 0) { - - $links = array(); - - if ($type == "node") { - if ($node->links) { - $links = $node->links; - } - - if ($main == 1 && $node->teaser && strlen($node->teaser) != strlen($node->body)) { - $links[] = l(t("read more"), "node/view/$node->nid", array("title" => t("Read the rest of this posting."), "class" => "read-more")); - } - - if (user_access("administer nodes")) { - $links[] = l(t("administer"), "admin/node/edit/$node->nid", array("title" => t("Administer this node."))); - } - } - - if ($type == "system") { - menu("node/add", t("create content"), NULL, 1); - - if (user_access("administer nodes")) { - menu("admin/node", t("content"), "node_admin"); - menu("admin/node/search", t("search"), "node_admin", 8); - menu("admin/node/help", t("help"), "node_help", 9); - menu("admin/node/edit", t("edit post"), "node_admin", 0, 1); - menu("admin/node/settings", t("settings"), "node_admin", 8); - } - } - - return $links; -} - -function node_admin_edit($node) { - - if (is_numeric($node)) { - $node = node_load(array("nid" => $node)); - } - - $output .= node_form($node); - - /* - ** Edit revisions: - */ - - if ($node->revisions) { - $output .= "

        ". t("Edit revisions") ."

        "; - - $header = array(t("older revisions"), array("colspan" => "3", "data" => t("operations"))); - - foreach ($node->revisions as $key => $revision) { - $rows[] = array(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"] ? "
        ". $revision["history"] ."" : ""), l(t("view revision"), "node/view/$node->nid", array(), "revision=$key"), l(t("rollback revision"), "admin/node/rollback+revision/$node->nid/$key"), l(t("delete revision"), "admin/node/delete+revision/$node->nid/$key")); - } - $output .= table($header, $rows); - } - - /* - ** Display the node form extensions: - */ - $output .= implode("\n", module_invoke_all("node_link", $node)); - - return $output; - -} - -function node_admin_nodes() { - $filters = array( - array(t("View posts that are new or updated"), "ORDER BY n.changed DESC"), - array(t("View posts that need approval"), "WHERE n.status = 0 OR n.moderate = 1 ORDER BY n.changed DESC"), - array(t("View posts that are promoted"), "WHERE n.status = 1 AND n.promote = 1 ORDER BY n.changed DESC"), - array(t("View posts that are not promoted"), "WHERE n.status = 1 AND n.promote = 0 ORDER BY n.changed DESC"), - array(t("View posts that are static"), "WHERE n.status = 1 AND n.static = 1 ORDER BY n.changed DESC"), - array(t("View posts that are unpublished"), "WHERE n.status = 0 AND n.moderate = 0 ORDER BY n.changed DESC") - ); - - $operations = array( - array(t("Approve the selected posts"), "UPDATE {node} SET status = 1, moderate = 0 WHERE nid = %d"), - array(t("Promote the selected posts"), "UPDATE {node} SET status = 1, promote = 1 WHERE nid = %d"), - array(t("Make the selected posts static"), "UPDATE {node} SET status = 1, static = 1 WHERE nid = %d"), - array(t("Demote the selected posts"), "UPDATE {node} SET promote = 0 WHERE nid = %d"), - array(t("Unpublish the selected posts"), "UPDATE {node} SET status = 0 WHERE nid = %d") - ); - - /* - ** Handle operations: - */ - - if (empty($_SESSION["node_overview_filter"])) { - $_SESSION["node_overview_filter"] = 0; - } - - if (isset($_POST["edit"]["filter"])) { - $_SESSION["node_overview_filter"] = $_POST["edit"]["filter"]; - } - - if (isset($_POST["edit"]["operation"])) { - $operation = $operations[$_POST["edit"]["operation"]][1]; - foreach ($_POST["edit"]["status"] as $nid => $value) { - if ($value) { - db_query($operation, $nid); - } - } - - $output = status(t("the update has been performed.")); - } - - $filter = $_SESSION["node_overview_filter"]; - - /* - ** Render filter form: - */ - - $options = array(); - foreach ($filters as $key => $value) { - $options[] = $value[0]; - } - - $form = form_select(NULL, "filter", $filter, $options); - $form .= form_submit(t("Go")); - - $output .= "

        ". t("Filter options") ."

        "; - $output .= "
        $form
        "; - - /* - ** Render operations form: - */ - - $options = array(); - foreach ($operations as $key => $value) { - $options[] = $value[0]; - } - - $form = form_select(NULL, "operation", 0, $options); - $form .= form_submit(t("Go")); - - $output .= "

        ". t("Update options") ."

        "; - $output .= "
        $form
        "; - - /* - ** Overview table: - */ - - $result = pager_query("SELECT n.*, u.name, u.uid FROM {node} n INNER JOIN {users} u ON n.uid = u.uid ". $filters[$filter][1], 50); - $header = array(NULL, t("title"), t("type"), t("author"), t("status"), array("data" => t("operations"), "colspan" => 2)); - - while ($node = db_fetch_object($result)) { - $rows[] = array(form_checkbox(NULL, "status][$node->nid", 1, 0), 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" => 7)); - } - - $output .= "

        ". $filters[$filter][0] ."

        "; - $output .= table($header, $rows); - return form($output); -} - -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_nodeapi($node, "settings"))); - foreach (module_list() as $name) { - if (module_hook($name, "node")) { - $node->type = $name; - $cols = array(); - foreach (node_invoke_nodeapi($node, "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_nodeapi($node, "settings")); - $cols = array(); - foreach (node_invoke_nodeapi($node, "settings") as $setting) { - $cols[] = array("data" => $setting, "align" => "center", "width" => 75); - } - - $output .= "

        ". module_invoke($name, "node", "name") ."

        "; - $output .= table($header, array($cols)); - $output .= "

        "; - } - } - */ - - $output .= form_submit(t("Save configuration")); - $output .= form_submit(t("Reset to defaults")); - - return 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": - $output = search_type("node", url("admin/node/search"), $_POST["keys"]); - break; - case "edit": - $output = node_admin_edit(arg(3)); - break; - case "delete": - $output = node_delete(array("nid" => arg(3))); - break; - case "rollback revision": - $output = node_revision_rollback(node_load(array("nid" => arg(3))), arg(4)); - $output .= node_admin_edit(arg(3)); - break; - case "delete revision": - $output = node_revision_delete(node_load(array("nid" => arg(3))), arg(4)); - $output .= node_admin_edit(arg(3)); - break; - case t("Preview"): - $edit = node_validate($edit, $error); - $output = node_preview($edit, $error); - break; - case t("Submit"): - $output = node_submit($edit); - break; - case t("Delete"): - $output = node_delete($edit); - break; - case t("Save configuration"): - case t("Reset to defaults"): - case "settings": - $output = node_admin_settings($edit); - break; - default: - $output = node_admin_nodes(); - } - return $output; - } - else { - return 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"] = "
        ". l("\"XML\"", "node/feed", array("title" => t("Read the XML version of this page."))) ."
        "; - - 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)) { - /* - ** Load the specified node: - */ - - $item = node_load(array("nid" => $node->nid)); - $link = url("node/view/$node->nid"); - $items .= format_rss_item($item->title, $link, ($item->teaser ? $item->teaser : $item->body), array("pubDate" => date("r", $item->changed))); - } - - $output .= "\n"; - $output .= "]>\n"; - if (!$channel["version"]) $channel["version"] = "0.92"; - 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 .= "\n"; - $output .= format_rss_channel($channel["title"], $channel["link"], $channel["description"], $items, $channel["language"]); - $output .= "\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) || empty($node->uid)){ - /* - ** 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_nodeapi($node, "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_nodeapi($edit, "form pre", $error)); - - // Get the node specific bits: - - // Can't use node_invoke: - // $error and $param must be passed by reference. - $function = $edit->type ."_form"; - if (function_exists($function)) { - $form .= $function($edit, $help, $error, $param); - } - - // Append extra node form: - $form .= implode("", node_invoke_nodeapi($edit, "form post", $error)); - - /* - ** Add the help text: - */ - - if ($help) { - $output .= "

        $help

        "; - } - - $output .= "
        "; - - /* - ** Add the admin specific parts: - */ - - if (user_access("administer nodes")) { - $output .= "
        "; - $output .= "
        "; - $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 .= "
        "; - - $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 .= "
        "; - $output .= form_item(t("Options"), $options); - $output .= "
        "; - - $extras .= implode("
        ", node_invoke_nodeapi($edit, "form admin")); - $output .= $extras ? "
        $extras
        " : "
        "; - } - - /* - ** Add the default fields: - */ - $output .= "
        "; - $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 (!$error) { - if ($edit->title && $edit->type) { - $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 .= "
        "; - - return form($output, ($param["method"] ? $param["method"] : "post"), $param["action"], array_merge($param["options"], array("id" => "node-form"))); -} - -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 .= "
      • "; - $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 .= "
        ". module_invoke($name, "node", "description") ."
        "; - $output .= "
      • "; - } - } - - $output = t("Choose the appropriate item from the list:") ."
          $output
        "; - - } - - 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 "

        ". t("Preview trimmed version") ."

        "; - node_view($view, 1); - print "

        ". 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 '<!--break-->' (without the quotes) to fine-tune where your post gets split.") ."

        "; - print "

        ". t("Preview full version") ."

        "; - 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)) { - $node->nid = node_save($node); - watchdog("special", "$node->type: updated '$node->title'", l(t("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)); - - $node->nid = node_save($node); - watchdog("special", "$node->type: added '$node->title'", l(t("view post"), "node/view/$node->nid")); - $output = t("Thanks for your submission."); - } - } - - /* - ** Reload the node from the database: - */ - - $node = node_load(array("nid" => $node->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[] = "
        ". t("return") .""; - } - - if ($node->nid && node_access("view", $node)) { - $links[] = l(t("view"), "node/view/$node->nid"); - } - - if ($node->nid && node_access("update", $node)) { - $links[] = l(t("edit"), "node/edit/$node->nid"); - } - - $output .= "

        ". theme("links", $links) ."

        "; - - 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_nodeapi($node, "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("Submit %name", array("%name" => $name)), node_add(arg(2))); - break; - case "edit": - theme("box", t("Edit %name", array("%name" => $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", array("%name" => $name)), node_preview($edit, $error)); - break; - case t("Submit"): - theme("box", t("Submit %name", array("%name" => $name)), node_submit($edit)); - break; - case t("Delete"): - theme("box", t("Delete %name", array("%name" => $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 0dd8489967b181bcc6dd6058d0b3baf0d3a8cf4f..0000000000000000000000000000000000000000 --- a/modules/page/page.module +++ /dev/null @@ -1,150 +0,0 @@ -The page module is used to create a static page. 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 -> moderate -> post -> 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 link text field.

        "; - $output .= "

        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.

        "; - $output = t($output); - break; - case 'admin/system/modules#description': - $output = t("Enables the creation of a static pages that can be added to the navigation system."); - break; - - } - - return $output; -} - -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 INNER 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 == "system") { - if (user_access("maintain static pages")) { - menu("node/add/page", t("static page"), "page_page", 0); - } - } - - return $links; -} - -function page_content($node) { - /* - ** 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(); - } - return $node; -} - -function page_view($node, $main) { - // prepair the node content - $node = page_content($node); - // print the node - theme("node", $node, $main); -} - -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/path/path.module b/modules/path/path.module deleted file mode 100644 index 5ab2ebea54f830693f2cad62c5610b20d5946451..0000000000000000000000000000000000000000 --- a/modules/path/path.module +++ /dev/null @@ -1,269 +0,0 @@ -Background

        URL aliasing gives users the ability to have control over all Drupal paths. This functionality integrates seamlessly into node forms and also provides the administrator an interface to view all aliases that have been created.

        Aliases have a 1 to 1 relationship with their original Drupal URLs. In other words you cannot have an alias map to more than one path. Likewise, a Drupal URL can't be mapped to more than one alias.

        "; - $output .= "

        Permissions

        Two new permissions are introduced for aliasing URLs: create url aliases and administer url aliases.

        "; - $output .= "
          "; - $output .= "
        1. create url aliases - Allows users to create aliases for nodes. Enabling this permission will display a new path field to the user in any node form, allowing them to enter an alias for that node. They will be able to edit/delete the alias after it is created using the same form.
        2. "; - $output .= "
        3. administer url aliases - Allows users to access the alias administration interface. They must also have the access administration pages permission set as well. This interface displays all aliases and provides a way to create and modify them as well. This is also the location to build aliases for things other than nodes. For example, you can create an alias for a taxonomy URL or even re-map the admin path (although the original admin path will still be accessible since aliases do not cancel out original paths).
        4. "; - $output .= "
        "; - $output = t($output); - break; - } - - return $output; -} - -function path_link($type, $node = NULL) { - if ($type == "system" && user_access("administer url aliases")) { - menu("admin/path", t("url aliasing"), "path_admin", 4); - menu("admin/path/add", t("new alias"), "path_admin"); - menu("admin/path/help", t("help"), "path_admin", 9); - } -} - -function path_nodeapi(&$node, $op, $arg) { - if (user_access("create url aliases") || user_access("administer url aliases")) { - - switch ($op) { - case "validate": - // is_null provides a mechanism for us to determine if this is the first - // viewing of the form. If it is the first time, load the alias, if it isn't - // (i.e., user has clicked preview) let them work with their current form alias. - if (is_null($node->path)) { - $node->path = drupal_get_path_alias("node/view/$node->nid"); - } - else { - $node->path = trim($node->path); - if ($node->path && !valid_url($node->path)) { - $error["path"] = t("The path is invalid."); - return $error; - } - else if (db_result(db_query("SELECT COUNT(dst) FROM {url_alias} WHERE dst = '%s' AND src != '%s'", $node->path, "node/view/$node->nid"))) { - $error["path"] = t("The path is already in use."); - return $error; - } - } - break; - - case "form pre": - return form_textfield(t("Path alias"), "path", $node->path, 60, 250, t("Optionally specify an alternative URL by which this node can be accessed. For example, type 'about' when writing an about page. Use a relative path and don't add a trailing slash or the URL alias won't work.") . theme_error($arg["path"])); - - case "insert": - /* - ** Don't try to insert if path is NULL. We may have already set - ** the alias ahead of time. - */ - if ($node->path) { - path_set_alias("node/view/$node->nid", $node->path); - } - break; - case "update": - path_set_alias("node/view/$node->nid", $node->path); - break; - - case "delete": - if ($alias = drupal_get_path_alias("node/view/$node->nid")) { - path_set_alias("node/view/$node->nid"); - } - break; - } - } -} - -function path_perm() { - return array("create url aliases", "administer url aliases"); -} - -function path_overview() { - $sql = "SELECT * FROM {url_alias}"; - $header = array( - array ("data" => t("alias"), "field" => "dst", "sort" => "asc"), - array ("data" => t("normal"), "field" => "src"), - array ("data" => t("operations"), "colspan" => 2) - ); - $sql .= tablesort_sql($header); - $result = pager_query($sql, 50); - - while ($data = db_fetch_object($result)) { - $rows[] = array($data->dst, $data->src, l(t("edit"), "admin/path/edit/$data->pid"), l(t("delete"), "admin/path/delete/$data->pid")); - } - - if ($pager = pager_display(NULL, 50, 0, "admin", tablesort_pager())) { - $rows[] = array(array("data" => $pager, "colspan" => "4")); - } - - if (!$rows) { - $rows[] = array(array("data" => t("No URL aliases available."), "colspan" => "4")); - } - - return table($header, $rows); -} - -function path_load($pid) { - return db_fetch_array(db_query("SELECT * FROM {url_alias} WHERE pid = '%d'", $pid)); -} - -function path_delete($pid) { - db_query("DELETE FROM {url_alias} WHERE pid = '%d'", $pid); - return t("the alias has been deleted."); -} - -function path_save($edit) { - $src = $edit["src"]; - $dst = $edit["dst"]; - $pid = $edit["pid"]; - - if (!valid_url($src)) { - $error[] = t("the normal path '%src' is invalid.", array("%src" => $src)); - } - - if (db_result(db_query("SELECT COUNT(src) FROM {url_alias} WHERE pid != '%d' AND src = '%s'", $pid, $src))) { - $error[] = t("the normal path '%src' is already aliased.", array("%src" => $src)); - } - - if (!valid_url($dst)) { - $error[] = t("the alias '%dst' is invalid.", array("%dst" => $dst)); - } - - if (db_result(db_query("SELECT COUNT(dst) FROM {url_alias} WHERE pid != '%d' AND dst = '%s'", $pid, $dst))) { - $error[] = t("the alias '%dst' is already in use.", array("%dst" => $dst)); - } - - if ($error) { - return path_form($edit, $error); - } - else { - /* - ** Normally, you would use path_set_alias to update the paths table, - ** but this is a special case. We want to modify a specific row and the only - ** way to do that is with pid. - */ - - if ($pid) { - db_query("UPDATE {url_alias} SET src = '%s', dst = '%s' WHERE pid = '%d'", $src, $dst, $pid); - } - else { - path_set_alias($src, $dst); - } - } - - return t("the alias has been saved.") . path_overview(); -} - -?> diff --git a/modules/ping/ping.module b/modules/ping/ping.module deleted file mode 100644 index b8c7107874096d3bae5109bcf1be0742b1eaa44d..0000000000000000000000000000000000000000 --- a/modules/ping/ping.module +++ /dev/null @@ -1,81 +0,0 @@ -Drupal can pings sites automatically to notify them that your site has changed. It can ping the following sites:

        "; - $output .= "

        %weblogs, 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 %weblogs system. The ping module automatically notifies weblogs.com when your site is updated. To do so, Drupal implements the %weblogs-XML.

        "; - $output .= "

        %weblogs-RSS, a web site that tracks and displays links to recently changed RSS feeds in XML format. To get your Drupal site listed, %weblogs-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 %weblogs-RSS-changes system. The ping module automatically notifies %weblogs-RSS when your site is updated.

        "; - $output .= "

        %blo-gs, a directory of recently updated weblogs and tools for tracking interesting weblogs, in the spirit of services like %weblogs, %blogtracker and %blogrolling. 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 %blo-gs system. The ping module automatically notifies blo.gs when your site is updated. To do so, Drupal implements the %blo-gs-XML.

        "; - // for optional modules that ping other sites - // $output .= module_invoke_all("ping_help"); - $output .= "

        The ping feature requires crontab.

        "; - $output = t($output, array("%weblogs" => "Weblogs.com", "%weblogs-XML" => "". t("XML-RPC interface of weblogs.com") ."", "%weblogs-RSS" => "". t("Weblogs.Com for RSS") ."", "%weblogs-RSS-changes" => "". t("the weblogs.com for RSS") ."", "%blo-gs" => "blo.gs", "%blogtracker" => "blogtracker", "%blogrolling" => "blogtolling.com", "%blo-gs-XML" => "". t("XML-RPC interface of blo.gs") ."" )); - break; - - case 'admin/system/modules#description': - $output = t("Alerts other site(s) that your site has been updated."); - break; - } - - return t($output); -} - -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.module b/modules/poll.module index 72deda17e16dbf371dafd6e82b9128f950d62992..c1ec279596e155edc0241a727e796eac5b043f0b 100644 --- a/modules/poll.module +++ b/modules/poll.module @@ -328,7 +328,7 @@ function poll_view_results(&$node, $main, $block, $links) { } $output .= "
        ". t("Total votes") .": $votestotal
        "; - $output .= ($block ? "
        ". theme("links", $links) ."
        " : "") .""; + $output .= ($block ? "
        ". theme("links", $links) ."
        " : "") .""; return $output; } diff --git a/modules/poll/poll.module b/modules/poll/poll.module deleted file mode 100644 index 72deda17e16dbf371dafd6e82b9128f950d62992..0000000000000000000000000000000000000000 --- a/modules/poll/poll.module +++ /dev/null @@ -1,405 +0,0 @@ -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"); - $block["content"] = "
        $poll->title
        $poll->body"; - return $block; - } - } -} - -function poll_cron() { - // Close polls that have exceeded their allowed runtime - $result = db_query("SELECT p.nid FROM {poll} p INNER 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_validate(&$node) { - 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.")); - } - } - - $node->teaser = poll_teaser($node); - - return $error; -} - -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); - - $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")) ."


        "; - - for ($a = 0; $a < $node->choices; $a++) { - $output .= form_textfield(t("Choice %n", array("%n" => ($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($section = "admin/help#poll") { - $output = ""; - - switch ($section) { - - case 'admin/help#poll': - $output .= "

        Users with the correct %permissions can create and/or vote on polls.

        "; - $output .= "
          "; - $output .= "
        • To create a poll a user needs the \"create polls\" permission.
        • "; - $output .= "
        • To vote on a poll question a user must have the \"vote on polls\" permission.
        • "; - $output .= "
        • To view the results one needs the \"access content\" permission.
        • "; - $output .= "
        • To administer polls you need the \"administer nodes\" permission.
        • "; - $output .= "
        "; - $output .= "

        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.

        The %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.

        "; - $output = t($output, array("%permissions" => l(t("permissions"), "admin/user/permission"), "%poll" => l(t("Poll"), "poll"))); - break; - case 'admin/system/modules#description': - $output = t("Enables your site to capture votes on different topics in the form of multiple choice questions."); - break; - } - - return $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 == "system") { - if (user_access("create polls")) { - menu("node/add/poll", t("poll"), "poll_page", 0); - } - } - 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[] = "". t("voting form") . ""; - } - 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(), "?") ? "&" : "?") ."pollresults[$node->nid]=1"; - } - - $links[] = "". t("view results") . ""; - } - } - } - - 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 INNER JOIN {poll} p ON n.nid=p.nid INNER 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 = "
          "; - while ($node = db_fetch_object($result)) { - $output .= "
        • ".l($node->title, "node/view/$node->nid") ." - ". format_plural($node->votes, "1 vote", "%count votes") ." - ". ($node->active ? t("open") : t("closed")) ."
        • "; - } - $output .= "
        "; - theme("box", t("Polls"), $output); - theme("footer"); -} - -function poll_perm() { - return array("create polls", "vote on polls"); -} - -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 .= "
        "; - - $output .= "
        "; - $output .= "
        "; - if ($node->choice) { - foreach ($node->choice as $key => $value) { - if ($value != "") { - $output .= "
        nid]\" value=\"$key\" />". filter($value) ."
        "; - } - } - } - $output .= "
        ". form_submit(t("Vote"), "vote") ."
        "; - $output .= $block ? "
        ". theme("links", $links) ."
        " : ""; - $output .= "
        "; - - 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 .= "
        "; - if ($node->choice) { - foreach ($node->choice as $key => $value) { - if ($value != "") { - $width = round($node->chvotes[$key] * 100 / max($votestotal, 1)); - $percentage = round($node->chvotes[$key] * 100 / max($votestotal, 1)); - $output .= "
        ". filter($value) ."
        "; - $output .= "
        "; - $output .= "
        "; - $output .= "
        "; - $output .= "
        "; - $output .= "
        $percentage%". (!$block ? " (". format_plural($node->chvotes[$key], "1 vote", "%count votes") .")" : "") ."
        "; - } - } - } - $output .= "
        ". t("Total votes") .": $votestotal
        "; - - $output .= ($block ? "
        ". theme("links", $links) ."
        " : "") ."
        "; - - 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 < count($node->choice); $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); - } - } -} - -?> diff --git a/modules/profile/profile.module b/modules/profile/profile.module deleted file mode 100644 index 74de3729a0ffe398c166c5bde334ecfca03fb2f1..0000000000000000000000000000000000000000 --- a/modules/profile/profile.module +++ /dev/null @@ -1,303 +0,0 @@ - array("textfield", t("Name"), "", 64, 64, ""), - "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_help($section) { - $output = ""; - - switch ($section) { - case 'admin/system/modules#description': - $output = t("Support for configurable user profiles."); - break; - case 'admin/system/modules/profile': - $output = t("When a user creates an account you can ask for some extra information, as well as letting the user have a small picture, called an avatar.
        Notes:
        • In order for a user to enter information you must check \"enable\".
        • In order for other people too see the entered information you must make it \"public\".
        • If an item is \"public\", but not enabled, the user can never give it a value and it will never be seen. Public does not imply \"enable\".
        • If an item is enabled, but not shown in the registration form the user will have to %edit to place information in the field.
        ", array("%edit" => l(t("edit their account"), "user/edit"))); - break; - } - return $output; -} - -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()); - - $header = array (t("field"), t("enable"), t("public"), t("required"), t("show in registration form")); - $i=0; - foreach ($profile_fields as $key => $field) { - $row[$i][] = $field[1]; - $row[$i][] = form_checkbox("", "profile_private_fields][", $key, in_array($key, $profile_private_fields)); - $row[$i][] = form_checkbox("", "profile_public_fields][", $key, in_array($key, $profile_public_fields)); - $row[$i][] = form_checkbox("", "profile_required_fields][", $key, in_array($key, $profile_required_fields)); - $row[$i][] = form_checkbox("", "profile_register_fields][", $key, in_array($key, $profile_register_fields)); - $i++; - } - $output .= table($header, $row); - - $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 .= "\"\"
        "; - } - } - $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 ."
        "; - } - - if (in_array("avatar", $enabled_fields) && ($avatar_error = _profile_validate_avatar($edit, $user))) { - $error .= $avatar_error ."
        "; - } - - 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])) ."
        "; - } - } - } - - 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") ? "$t) ."\">". check_output($user->$t) ."" : 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"), "\"\""); - } - } - - 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
        " : ""; -} - -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 .= " "; - $output .= _profile_select("profile_birthmonth", $edit->profile_birthmonth, $profile_months); - $output .= " "; - $output .= "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.") ."
        "; - } -} - -function _profile_select($name, $value, $options, $extra = 0, $multiple = 0) { - if (count($options) > 0) { - foreach ($options as $key=>$choice) { - $select .= ""; - } - return ""; - } -} - -?> diff --git a/modules/search/search.module b/modules/search/search.module deleted file mode 100644 index 6a2d5eee42b0303e706b561d41bd69be5c8d5224..0000000000000000000000000000000000000000 --- a/modules/search/search.module +++ /dev/null @@ -1,404 +0,0 @@ -Search guidelines
        "; - $output .= "

        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.

        "; - $output .= "Words excluded from the search"; - $output .= "

        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.

        "; - $output = t($output, array("%number" => variable_get("minimum_word_size", 2))); - break; - case 'admin/system/modules#description': - $output = t("Enables site wide keyword searching."); - break; - case 'admin/system/modules/search': - $output = 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."); - break; - } - return $output; -} - -/** - * 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(); - $output = t("index invalidated") ."
        \n"; - search_cron(); - $output .= t("index recreated") ."

        \n"; - return $output; - } - } -} - -/** - * perform a regularly run action across all modules that have the - * _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 _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 = str_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 _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
        $node_type
        $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) { - $word = trim($word); - $wordlist = trim(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. "
        ". $form; - break; - case "4": - $form .= "
        ". $help_link; - } - - theme("header", t("Search")); - - 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", t("Access denied")); - 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 032f642f0dadae8e0d04adfc1abca6e28a7bd4f5..0000000000000000000000000000000000000000 --- a/modules/statistics/statistics.module +++ /dev/null @@ -1,881 +0,0 @@ -= %d", (time() - 60)); - $recent_activity = db_fetch_array($result); - throttle_update($recent_activity["hits"]); - } - } -} - -// Exit 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 {node_counter} 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 {node_counter} (nid, daycount, totalcount, timestamp) VALUES(%d, 1, 1, %d)", arg(2), time()); - } - } - } - - 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()); - } - } -} - -/* 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 == "system") { - if ((user_access("administer statistics module") || (user_access("administer statistics")))) { - - menu("admin/statistics", t("statistics"), "statistics_admin", 6); - menu("admin/statistics/referrers", t("referrer log"), "statistics_admin"); - menu("admin/statistics/referrers/internal", t("internal referrers only"), "statistics_admin"); - menu("admin/statistics/referrers/external", t("external referrers only"), "statistics_admin"); - menu("admin/statistics/log", t("access log"), "statistics_admin"); - menu("admin/statistics/log/node", t("track node"), "statistics_admin", 0, 1); //hidden - menu("admin/statistics/log/user", t("track user"), "statistics_admin", 0, 1); //hidden - menu("admin/statistics/log/host", t("track host"), "statistics_admin", 0, 1); //hidden - menu("admin/statistics/top nodes page", t("configure 'top nodes' page"), "statistics_admin", 5); - menu("admin/statistics/help", t("help"), "statistics_help", 9); - - // block configuration: - menu("admin/system/block/top nodes block", t("configure 'top nodes' block"), "statistics_admin", 5); - menu("admin/system/block/whos online block", t("configure 'who is online' block"), "statistics_admin", 5); - } - } - - return $links; -} - - -function statistics_help($section = "admin/help#statistics") { - $output = ""; - - switch ($section) { - case 'admin/help#statistics': - $output .= "

        Introduction

        "; - $output .= "

        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.

        "; - $output .= "

        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:"; - $output .= "

          "; - $output .= "
        • The count can be displayed in the node's link section next to \"# comments\".
        • "; - $output .= "
        • 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
        • "; - $output .= "
        • 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.
        • "; - $output .= "
        • 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.
        • "; - $output .= "
        • An auto-throttle, congestion controling mechanism can be used on your site if you have enabled the %throttle.
        • "; - $output .= "
        "; - $output .= "

        Notes on using the statistics:

        "; - $output .= "
          "; - $output .= "
        • 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).
        • "; - $output .= "
        • 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.
        • "; - $output .= "
        "; - $output .= "

        As with any new module, the statistics module needs to be %modules before you can use it. Also refer to the %permissions, as this module supports four separate permissions.

        "; - $output .= "

        %referers

        This admin page shows you site-wide referrer statistics. You can see 'all' statistics, 'external' statistics or 'internal' statistics. Default is 'all'.

        "; - $output .= "

        %access

        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.

        "; - $output .= "

        Configuring the statistics module

        There are some configuration options added to the main %configuration section:

        "; - $output .= "
          "; - $output .= "
        • enable access log -- 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.
        • "; - $output .= "
        • discard access logs older than -- 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\"
        • "; - $output .= "
        • enable node view counter -- 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.
        • "; - $output .= "
        • display node view counters -- allows you to globally disable the displaying of node view counters. Additionally, a user group must have 'access statistics' permissions to view the counters.
        • "; - $output .= "
        "; - $output .= "

        Top nodes block

        "; - $output .= "

        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.

        "; - $output .= "

        The administrative \"top nodes block\" screen also allows you to assign a name to the block.

        "; - $output .= "

        Don't forget to enable the block %here-block.

        "; - - $output .= "

        Top nodes page

        "; - $output .= "

        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.

        "; - $output .= "

        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.

        "; - $output .= "

        Who's online block

        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.

        "; - $output .= "

        Don't forget to enable the block %here-block.

        "; - $output .= "

        Permissions

        This module has four permissions that need to be configured in %permissions.

        "; - $output .= "
          "; - $output .= "
        • access statistics - enable for user roles that get to see individual node counts. (This does not define access to the block)
        • "; - $output .= "
        • access userlist - enable for user roles that get to see the list of user's that are currently online within the \"Who's online\" block.
        • "; - $output .= "
        • administer statistics module - enable for user roles that get to configure the statistics module.
        • administer statistics - enable for user roles that get to view the referrer statistics.
        • "; - $output .= "
        "; - $output .= "

        If 'administer statistics' and 'access statistics' are both enabled, the user will see a link from each node to that node's referrer statistics (if enabled).

        "; - $output .= "

        Statistics module (for developers)

        Accessing statistics

        To get a node's \"view statistics\" make a call to the function statistics_get(\$nid). 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.

        "; - $output .= "
          "; - $output .= "
        • The totalcount is a count of the total number of times that node has been viewed.
        • "; - $output .= "
        • The daycount 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.
        • "; - $output .= "
        • The timestamp is a timestamp of when that node was last viewed.
        • "; - $output .= "
        "; - $output .= "

        The module automatically adds '# reads' to each node's link section (if enabled).

        "; - $output .= "

        Top stories

        The statistics module provides a function 'statistics_title_list(\$dbfield, \$dbrows)' 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:

        "; - $output .= "
          "; - $output .= "
        • totalcount - This will return an array with links to the top viewed nodes of all time.
          Example: statistics_title_list(\"totalcount\", \"5\");

        • "; - $output .= "
        • daycount - This will return an array with links to the top viewed nodes for today.
          Example: statistics_title_list(\"daycount\",\"5\");

        • "; - $output .= "
        • timestamp - This will return a array with links to the last viewed node.
          Example: statistics_title_list(\"timestamp\",\"5\");
        • "; - $output .= "
        "; - $output .= "

        \$dbrows is the number or rows you want returned in your array.

        "; - $output .= "

        Throttle

        The function throttle_status() 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.

        "; - $output .= "

        To implement the throttle, you should do something like this:

               \$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
        -       }

        "; - $output .= "

        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 %here-help if you have enabled the throttle module).

        "; - $output = t($output, array("%throttle" => l(t("throttle module"), "admin/system/modules"), "%modules" => l(t("enabled"), "admin/system/modules"), "%permissions" => l(t("permissions section"), "admin/user/permission"), "%referers" => l(t("referrers log"), "admin/statistics/referrers"), "%access" => l(t("access log"), "admin/statistics/log"), "%configuration" => l(t("administer") ." » ". t("configuration"), "admin/system/modules/statistics"), "%here-block" => l(t("here"), "admin/system/block"), "%here-help" => l(t("here"), "admin/help#throttle"))); - break; - case 'admin/system/modules#description': - $output = t("Logs access statistics for your site."); - break; - case 'admin/system/modules/statistics': - $output = t("Settings for the statistical information that Drupal will keep about the site. See %statistics for the actual information.", array("%statistics" => l(t("site statistics"), "admin/statistics"))); - break; - case 'admin/statistics': - $output = 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."); - break; - case 'admin/statistics/referrers': - $output = t("This page shows you site-wide referrer statistics. You can see 'all referrers', 'external referrers' or 'internal referrers'. Referrers are web sites, both your site, and other peoples, that point to your web site."); - break; - case 'admin/statistics/referrers/internal': - $output = t("This page shows you only 'internal referrers'. Links pointing to your web site, from within your web site."); - break; - case 'admin/statistics/referrers/external': - $output = t("This page shows you only 'external referrers'. Links pointing to your web site from outside your web site."); - break; - case 'admin/statistics/log': - case 'admin/statistics/log/node': - case 'admin/statistics/log/user': - case 'admin/statistics/log/host': - $output = 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 on track user."); - break; - case 'admin/statistics/top nodes page': - $output = 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."); - break; - case 'admin/system/block/top nodes block': - $output = 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."); - break; - case 'admin/system/block/whos online block': - $output = 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."); - break; - } - return $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_topnodes(); - case "referrers": - return statistics_top_refer(); - case "log": - return statistics_admin_displaylog(); - } - - /* configuration admin pages */ - if (user_access("administer statistics module")) { - switch (stripslashes($op)) { - case t("Submit \"top nodes\" block changes"): - statistics_save_topnodes_block($edit); - $output .= status(t("saved 'top nodes' block changes.")); - case t("Submit \"who's online\" block changes"): - statistics_save_online_block($edit); - $output .= status(t("saved 'who's online' block changes.")); - case t("Submit \"top nodes\" page changes"): - statistics_save_userconfig($edit); - $output .= status(t("saved 'top nodes' page changes.")); - case "top nodes page": - $output .= 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) - )); - break; - case "block": - if (arg(3) == "top nodes block") { - $output .= 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", "Todays top:"), - "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", "All time top:"), - "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" ,"Last:"), - "statistics_block_top_last_num" => variable_get("statistics_block_top_last_num", 0) - )); - } - elseif (arg(3) == "whos online block") { - $output .= 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) - )); - break; - } - default: - $output .= statistics_admin_topnodes(); - } - } - return $output; - } -} - - -function statistics_admin_topnodes_table() { - - $header = array( - array("data" => t("title"), "field" => "n.title"), - array("data" => t("today"), "field" => "s.daycount", "sort" => "desc"), - array("data" => t("all time"), "field" => "s.totalcount"), - array("data" => t("last hit"), "field" => "s.timestamp"), - array("data" => t("operations")) - ); - $sql = "SELECT s.nid, s.daycount, s.totalcount, s.timestamp, n.title FROM {node_counter} s INNER JOIN {node} n ON s.nid = n.nid"; - $sql .= tablesort_sql($header); - $result = pager_query($sql, 20); // WHERE s.%s <> '0' - - 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]")); - } - if ($pager = pager_display(NULL, 20, 0, "admin", tablesort_pager())) { - $rows[] = array(array("data" => $pager, "colspan" => 5)); - } - - 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 */ - $sql = "SELECT a.nid, a.url, a.hostname, a.uid, a.timestamp, n.title FROM {accesslog} a LEFT JOIN {node} n ON a.nid = n.nid WHERE a.uid = ". check_query($id); - } - else { - /* retrieve recent access logs for all users */ - $sql = "SELECT a.nid, a.url, a.hostname, a.uid, MAX(a.timestamp) AS timestamp, n.title FROM {accesslog} a LEFT JOIN {node} n ON a.nid = n.nid WHERE a.uid <> '0' GROUP BY a.uid, a.nid, a.url, a.hostname"; - } - } - else if ($type == 2) { - /* retrieve recent access logs for node $id */ - $sql = "SELECT a.nid, a.url, a.hostname, a.uid, a.timestamp, n.title FROM {accesslog} a LEFT JOIN {node} n ON a.nid = n.nid WHERE a.nid = ". check_query($id); - } - else if ($type == 3) { - /* retrieve recent access logs for hostname $id */ - $sql = "SELECT a.nid, a.url, a.hostname, a.uid, a.timestamp, n.title FROM {accesslog} a LEFT JOIN {node} n ON a.nid = n.nid WHERE a.hostname = '". check_query($id) ."'"; - } - else { - /* retrieve all recent access logs */ - $sql = "SELECT a.nid, a.url, a.hostname, a.uid, a.timestamp, n.title FROM {accesslog} a LEFT JOIN {node} n ON a.nid = n.nid"; - } - - $header = array( - array("data" => t("timestamp"), "field" => "timestamp", "sort" => "desc"), - array("data" => t("post"), "field" => "nid"), - array("data" => t("user"), "field" => "uid"), - array("data" => t("hostname"), "field" => "hostname"), - array("data" => t("referrer"), "field" => "url"), - array("data" => t("operations"), "colspan" => "3") - ); - - $sql .= tablesort_sql($header); - - $result = pager_query($sql, 50); - while ($log = db_fetch_object($result)) { - $user = user_load(array("uid" => $log->uid)); - - if ($log->url) { - $url = "url\" title=\"$log->url\">". (strlen($log->url) > 28 ? substr($log->url, 0, 28) . '...' : $log->url) .""; - } - else { - $url = message_na(); - } - - $rows[] = array(array("data" => format_date($log->timestamp, "small"), "nowrap" => "nowrap"), ($log->nid ? l($log->title, "node/view/$log->nid") : message_na()), format_name($user), $log->hostname ? $log->hostname : message_na(), $url, ($log->nid ? l(t("track node"), "admin/statistics/log/node/$log->nid") : ""), ($user->uid ? l(t("track user"), "admin/statistics/log/user/$user->uid") : ""), ($log->hostname ? l(t("track host"), "admin/statistics/log/host/$log->hostname") : "")); - } - - if ($pager = pager_display(NULL, 50, 0, "admin", tablesort_pager())) { - $rows[] = array(array("data" => $pager, "colspan" => 8)); - } - - return table($header, $rows); -} - -function statistics_top_refer() { - - $view = arg(3) ? arg(3) : "all"; - - if ($view == "all") { - $query = "SELECT url, MAX(timestamp) AS last_view, COUNT(url) AS count FROM {accesslog} WHERE url <> '' GROUP BY url"; - $query_cnt = "SELECT COUNT(DISTINCT(url)) FROM {accesslog} WHERE url <> ''"; - } - elseif ($view == "internal") { - $query = "SELECT url, MAX(timestamp) AS last_view, COUNT(url) AS count FROM {accesslog} WHERE url LIKE '%". check_query($_SERVER["HTTP_HOST"]) ."%' GROUP BY url"; - $query_cnt = "SELECT COUNT(DISTINCT(url)) FROM {accesslog} WHERE url <> '' AND url LIKE '%". check_query($_SERVER["HTTP_HOST"]) ."%'"; - $describe = "internal "; - } - else { - /* default to external */ - $query = "SELECT url, MAX(timestamp) AS last_view, COUNT(url) AS count FROM {accesslog} WHERE url NOT LIKE '%". check_query($_SERVER["HTTP_HOST"]) ."%' AND url <> '' GROUP BY url"; - $query_cnt = "SELECT COUNT(DISTINCT(url)) FROM {accesslog} WHERE url <> '' AND url NOT LIKE '%". check_query($_SERVER["HTTP_HOST"]) ."%'"; - $describe = "external "; - } - - $output = "

        ". t("Top $describe referrers of the past %interval", array("%interval" => format_interval(variable_get("statistics_flush_accesslog_timer", 259200)))) ."

        "; - - $header = array( - array("data" => t("URL"), "field" => "url"), - array("data" => t("last view"), "field" => "last_view"), - array("data" => t("count"), "field" => "count", "sort" => "desc") - ); - $query .= tablesort_sql($header); - - $result = pager_query($query, 50, 0, $query_cnt); - - while ($referrer = db_fetch_array($result)) { - $rows[] = array("". substr($referrer["url"], 0, 100) ."", format_date($referrer["last_view"], "small"), $referrer["count"]); - } - if ($pager = pager_display(NULL, 50, 0, "admin", tablesort_pager())) { - $rows[] = array(array("data" => $pager, "colspan" => 3)); - } - - $output .= table($header, $rows); - - return $output; - -} - - -function statistics_admin_topnodes() { - - $output = "

        ". t("Top nodes") ."

        \n"; - $output .= statistics_admin_topnodes_table(); - - return $output; -} - - -function statistics_admin_displaylog() { - - $type = arg(3); - $value = arg(4); - - switch ($type) { - case "user": - $user = user_load(array("uid" => $value)); - $output = "

        ". t("Recent access logs for '%name'", array("%name" => $user->name)) ."

        \n"; - $output .= statistics_admin_accesslog_table(1, $user->uid); - break; - case "node": - $node = node_load(array("nid" => $value)); - $output = "

        ". t("Recent access logs for '%title'", array("%title" => $node->title)) ."

        \n"; - $output .= statistics_admin_accesslog_table(2, $value); - break; - case "host": - $output = "

        ". t("Recent access logs for '%hostname'", array("%hostname" => $value)) ."

        \n"; - $output .= statistics_admin_accesslog_table(3, $value); - break; - default: - $output = "

        ". t("Recent access logs") ."

        \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 .= "
        "; - - $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 .= "
        "; - - $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 .= "
        "; - - $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 .= "
        "; - - $form .= form_submit(t("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(t("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 .= "
        "; - - $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 .= "
        "; - - $form .= form_textfield(t("All time top nodes title"), "statistics_userpage_all_head", $edit["statistics_userpage_all_head"], 20, 40, t("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 .= "
        "; - - $form .= form_textfield(t("Last viewed nodes title"), "statistics_userpage_last_head", $edit["statistics_userpage_last_head"], 20, 40, t("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 .= "
        "; - - $form .= form_submit(t("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 {node_counter} 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, "
        "); - - 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); - - $guests = db_fetch_object(db_query("SELECT COUNT(DISTINCT sid) AS count FROM {sessions} WHERE timestamp >= %d AND uid = 0", time() - $time_period)); - $users = db_query("SELECT DISTINCT uid, MAX(timestamp) AS max_timestamp FROM {sessions} WHERE timestamp >= %d AND uid != 0 GROUP BY uid ORDER BY max_timestamp DESC", time() - $time_period ); - $total_users = db_affected_rows(); - - /* format the output with proper grammar */ - if ($total_users == 1 && $guests->count == 1) { - $output .= t("There is currently %members and %visitors online.", array("%members" => format_plural($total_users, "1 user", "%count users"), "%visitors" => format_plural($guests->count, "1 guest", "%count guests"))); - } - else { - $output .= t("There are currently %members and %visitors online.", array("%members" => format_plural($total_users, "1 user", "%count users"), "%visitors" => format_plural($guests->count, "1 guest", "%count guests"))); - } - - if (user_access("access userlist") && $total_users) { - /* Display a list of currently online users */ - $max_users = variable_get("statistics_block_online_max_cnt", 10); - $items = array(); - while ($uid = db_fetch_object($users)) { - $user = user_load(array("uid" => $uid->uid)); - /* Display only max_length characters of username */ - $items[] = format_name($user); - } - - if ($items) { - $output .= "

        "; - $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 {node_counter} s INNER JOIN {node} n ON s.nid = n.nid INNER 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 {node_counter} 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 = ""; - $output .= statistics_summary("daycount", $displaycount); - $output .= "
        "; - - theme("box", t(variable_get("statistics_userpage_day_head", "")), $output, "main"); - } - - - if ($displaycount = variable_get("statistics_userpage_all_cnt", "10")) { - $output = ""; - $output .= statistics_summary("totalcount", $displaycount); - $output .= "
        "; - - theme("box", t(variable_get("statistics_userpage_all_head", "")), $output, "main"); - } - - if ($displaycount = variable_get("statistics_userpage_last_cnt", "10")) { - $output = ""; - $output .= statistics_summary("timestamp", $displaycount); - $output .= "
        "; - - 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 {node_counter} s INNER 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 .= "". l($nid["title"], "node/view/". $nid["nid"], array("title" => t("View this posting."))) ."". t("Submitted by %a on %b", array("%a" => format_name($content), "%b" => format_date($content->created, "large"))) .""; - $output .= "
        ". check_output($content->teaser) ."
        "; - $output .= "[ ". theme("links", $links) ." ]

        "; - } - - 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 {node_counter} 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 17ea3b6c2ac871d9a66346430dedd9994455b0ef..0000000000000000000000000000000000000000 --- a/modules/story/story.module +++ /dev/null @@ -1,99 +0,0 @@ -submit -> moderate -> post to the main page -> comments. 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."); - break; - case 'admin/help#story': - $output = "

        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 submit -> moderate -> post to the main page -> comments. Administrators are able to shortcut this flow as desired.

        "; - $output .= "In %story-config 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."; - $output = t($output, array("%story-config" => l(t("administer") ." » ". t("configuration") ." » ". t("modules") ." » ". t("story"), "admin/system/modules/story"))); - break; - } - - return $output; -} - -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 == "system") { - if (user_access("create stories")) { - menu("node/add/story", t("story"), "story_page", 0); - } - } - - return $links; -} - -function story_validate(&$node) { - - /* - ** Validate the size of the story: - */ - - if (isset($node->body) && count(explode(" ", $node->body)) < variable_get("minimum_story_size", 0)) { -print "body : $node->body"; - $error["body"] = "
        ". t("The body of your story is too short.") ."
        "; - } - - return $error; -} - -function story_form(&$node, &$help, &$error) { - - /* - ** 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; -} - -function story_content($node) { - $node->teaser = check_output($node->teaser); - $node->body = check_output($node->body); - return $node; -} -?> diff --git a/modules/system/system.module b/modules/system/system.module deleted file mode 100644 index a32c00ac3723f44f7b43409bc8f1754c0853b72f..0000000000000000000000000000000000000000 --- a/modules/system/system.module +++ /dev/null @@ -1,359 +0,0 @@ - l("permissions", "admin/user/permission"))); - break; - case 'admin/system/filters': - $output = 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."); - break; - case 'admin/help#system': - case 'admin/system/help': - $output .= "

        Drupal comes with system-wide defaults but the setting-module provides control over many Drupal preferences, behaviours including visual and operational settings.

        "; - $output .= "

        Cron

        "; - // Start of system_help_cron - $output .= "

        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.

        "; - $output .= "

        Whenever %cron-link 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 n seconds, where n is the period of that task. When all the tasks are finished, cron is done.

        "; - $output .= "

        The recommended way to set up your cron system is to set up a Unix/Linux crontab entry (see \"man crontab\") that frequently visits %cron-link. 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.

        "; - $output .= "

        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 %cron-link.

        "; - $output .= "

        For the Unix/Linux crontab itself, use a browser like %lynx or %wget but make sure the process terminates: either use /usr/bin/lynx -source $base_url/cron.php or /usr/bin/wget -o /dev/null -O /dev/null %cron-link. Take a look at the example scripts in the scripts-directory. Make sure to adjust them to fit your needs. A good crontab line to run the cron script once every hour would be:"; - $output .= "

             00 * * * * /home/www/drupal/scripts/cron-lynx.sh
        "; - $output .= "Note that it is essential to access cron.php using a browser on the web site's domain; do not run it using command line PHP and avoid using localhost or 127.0.0.1 or some of the environment varibles will not be set correctly and features may not work as expected.

        "; - // End of system_help_cron - $output .= "

        Cache

        "; - // Start of system_help_cache - $output .= "

        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.

        "; - // End of system_help_cache - $output = t($output, array("%cron-link" => "$base_url/cron.php", "%lynx" => "lynx", "%wget" => "wget" )); - break; - case 'admin/system/modules#description': - $output = t("Configuration system that lets administrators modify the workings of the site."); - break; - } - - 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 == "system") { - if (user_access("administer site configuration")) { - - menu("admin/system", t("configuration"), "system_admin", 3); - menu("admin/system/themes", t("themes"), "system_admin", 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"); - } - } - - menu("admin/system/modules", t("modules"), "system_admin", 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", t($name), "system_admin"); - } - } - menu("admin/system/filters", t("filters"), "system_admin", 4); - menu("admin/system/help", t("help"), "system_help", 9); - } - } -} - -function system_user($type, &$edit, $user) { - $options = "\n"; - if ($type == "edit_form" && count($themes = theme_list()) > 1) { - foreach ($themes as $key => $value) { - $options .= "\n"; - } - $output .= form_item(t("Theme"), "", t("Selecting a different theme will change the look and feel of the site.")); - } - if ($type == "edit_form") { - $zonelist = array(-11, -10, -9.5, -9, -8, -7, -6, -5, -4, -3.5, -3, -2, -1, 0, 1, 2, 3, 3.5, 4, 5, 5.5, 5.75, 6, 6.5, 7, 8, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.75, 13, 14); - foreach ($zonelist as $offset) { - $zone = $offset * 3600; - $zones["$zone"] = date(variable_get("date_format_long", "l, F dS, Y - g:ia"), time() - date("Z") + $zone) . sprintf(" (GMT %s%02d:%02d)\n", ($offset >= 0) ? "+" : "-", floor(abs($offset)), (abs($offset) * 60) % 60); - } - $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.")); - } - - return $output; -} - -function system_view_general() { - global $conf; - - // general settings: - $output .= "

        ". t("General settings") ."

        \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 ModRewrite support. See also the .htaccess file in Drupal's top-level directory.")); - $output .= "
        \n"; - - // caching: - $output .= "

        ". t("Cache settings") ."

        \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 %documentation for information on Drupal's cache system.", array("%documentation" => l(t("cache documentation"), "admin/system/help#cache")))); - $output .= "
        \n"; - - - // submission settings: - $output .= "

        ". t("Submission settings") ."

        \n"; - $rate = array(-10000 => t("Disabled"), 1 => t("Maximum 1 every second"), 5 => t("Maximum 1 every 5 seconds"), 15 => t("Maximum 1 every 15 seconds"), 30 => t("Maximum 1 every 30 seconds"), 60 => t("Maximum 1 every minute"), 300 => t("Maximum 1 every 5 minutes"), 900 => t("Maximum 1 every 15 minutes"), 1800 => t("Maximum 1 every 30 minutes"), 3600 => t("Maximum 1 every hour"), 21600 => t("Maximum 1 every 6 hours"), 43200 => t("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 .= "
        \n"; - - // date settings: - $output .= "

        ". t("Date format settings") ."

        \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 .= "

        ". ucfirst(t("$name")) ." ". t("settings") ."

        ". module_invoke($name, "settings") ."
        \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 = t("Invalid theme specified"); - } - return $output; -} - -function system_view_filters() { - return implode("\n", module_invoke_all("conf_filters")); -} - -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")); - - return 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, "help", "admin/system/modules#name") ? module_invoke($file->name, "help", "admin/system/modules#name") : module_invoke($file->name, "system", "name") ? module_invoke($file->name, "system", "name") : $file->name; - $info->description = module_invoke($file->name, "help", "admin/system/modules#description") ? module_invoke($file->name, "help", "admin/system/modules#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 .= "
        \n"; - foreach ($themes as $theme) - $options .= "\n"; - $output .= form_item(t("Default theme"), "", 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")) { - $output = status(system_reset_default($edit)); - } - - if ($op == t("Save configuration")) { - $output = status(system_save_settings($edit)); - } - - $output .= system_view(arg(2), arg(3)); - return $output; - } - else { - return message_access(); - } -} - -?> diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module deleted file mode 100644 index 86ff7ae6cc0759d00da98f182594496382d257b2..0000000000000000000000000000000000000000 --- a/modules/taxonomy/taxonomy.module +++ /dev/null @@ -1,843 +0,0 @@ -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 == "system") { - if (user_access("administer taxonomy")) { - menu("admin/taxonomy", t("taxonomy"), "taxonomy_admin", 3); - menu("admin/taxonomy/add/vocabulary", t("create new vocabulary"), "taxonomy_admin"); - menu("admin/taxonomy/help", t("help"), "taxonomy_admin", 9); - } - } - else if ($type == "taxonomy terms" && $node != NULL) { - $links = array(); - if ($node->taxonomy) { - foreach ($node->taxonomy as $tid) { - $term = taxonomy_get_term($tid); - $links[] = l($term->name, "taxonomy/page/or/$term->tid"); - } - } - 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"); - } - - } - 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] = module_invoke($name, "node", "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 must 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 .= "

        ". t("Vocabularies overview") ."

        "; - - $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" => module_invoke($vocabulary->nodes, "node", "name"), "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") .")
        "; - } - $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 INNER 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 .= ""; - } - - $size = min(12, count($options)); - - return form_item($title, "", $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 INNER JOIN {term_node} r ON n.nid = r.nid INNER 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 INNER JOIN {term_node} r ON n.nid = r.nid INNER 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 INNER JOIN {term_node} r ON n.nid = r.nid INNER 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 INNER 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($section = "admin/help#taxonomy") { - $output = ""; - - switch ($section) { - case 'admin/system/modules#description': - $output = t("Enables the organization of content into categories."); - break; - case 'admin/taxonomy': - $output = 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\"."); - break; - case 'admin/taxonomy/add/vocabulary': - $output = 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."); - break; - case 'admin/help#taxonomy': - $output .= "

        Background

        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 %classification-types and insight into the development of the taxonomy.module, see this %drupal-dis.

        "; - $output .= "

        An example taxonomy: food

        • Dairy
          • Milk
        • Drink
          • Alchohol
            • Beer
            • Wine
          • Pop
          • Milk
        • Meat
          • Beef
          • Chicken
          • Lamb
        • Spices
          • Sugar
        "; - $output .= "

        Notes

        • The term Milk appears within both Dairy and Drink. This is an example of multiple parents for a term.
        • In Drupal the order of siblings (e.g. Beef, Chicken, Lamb) in a taxonomy may be controlled with the weight parameter.
        "; - $output .= "

        Vocabularies

        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 %slashdot's sections. For more complex implementations, you might create a hierarchical list of categories such as Food taxonomy shown above.

        "; - $output .= "

        Setting up a vocabulary

        When setting up a controlled vocabulary, if you select the hierarchy option, you will be defining a taxonomy or a thesaurus. If you select the related terms option, you are allowing the definition of related terms, think see also, as in a thesaurus. Selecting multiple select 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.

        "; - $output .= "

        When setting up a controlled vocabulary you are asked for:

          "; - $output .= "
        • Vocabulary name (Required) -- The name for this vocabulary. Example: Dairy.
        • "; - $output .= "
        • Description (Optional) -- Description of the vocabulary, this can be used by modules and feeds.
        • "; - $output .= "
        • Types (Required) -- The list of node types you want to associate this vocabulary with. Some available types are: blog, book, forum, page, story.
        • "; - $output .= "
        • Related terms -- Allows relationships between terms within this vocabulary. Think of these as see also-references.
        • "; - $output .= "
        • Hierarchy -- Allows a tree-like taxonomy, as in our Foods example above
        • "; - $output .= "
        • Multiple select -- Allows nodes to be described using more than one term. Nodes may then appear on multiple taxonomy pages.
        • "; - $output .= "
        • Required -- Each node has to have a term in this vacabulary associated with it.
        • "; - $output .= "
        • Weight -- The over all weight for this vocaulary in listings with multiple vacabularies.
        • "; - $output .= "

        "; - $output .= "

        Adding terms to a vocabulary

        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 related terms, hierarchy and multiple select. These options are:

        "; - $output .= "

          "; - $output .= "
        • Term name (Required) -- The name for this term. Example: Milk
        • "; - $output .= "
        • Description (Optional) -- Description of the term that may be used by modules and feeds. This is synonymous with a 'scope note'.
        • "; - $output .= "
        • Parent (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.
        • "; - $output .= "
        • Synonyms (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. unauthorized terms)
        • "; - $output .= "
        • Weight (Optional) -- The weight is used to sort the terms of this vocabulary.
        • "; - $output .= "

        "; - $output .= "

        Displaying nodes organized by term(s)

        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, %taxo-example. Taxonomy URLs always contain one or more term IDs (tid) at the end of the URL (a.k.a the querystring). You may learn the term ID for a given term by hovering over that term in the %taxo-overview 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 or, which chooses nodes tagged with any of the given term IDs, or and, which chooses nodes tagged with all of the given Term IDs. Thus or is less specific than and. Finally add a comma seperated list of term IDs.

        "; - $output .= "

        RSS feeds

        Every term, or collection of terms, provides an %userland-rss feed to which interested users may subscribe. The URL format for a sample RSS feed is %sample-rss. Built like a Taxonomy URL, %taxo-help it starts with \"node/feed\", then has the querystring parameter, and finally the Term IDs.

        "; - $output = t($output, array("%classification-types" => "classification types", "%drupal-dis" => "drupal.org discussion", "%slashdot" => "Slashdot", "%taxo-example" => l("taxonomy/page/or/1,2", "taxonomy/page/or/1,2"), "%taxo-overview" => l(t("taxonomy overview"), "admin/taxonomy"), "%userland-rss" => "RSS", "%sample-rss" => l("node/feed/or/1,2", "node/feed/or/1,2"), "%taxo-help" => l(t("see above"), "admin/taxonomy/help#taxonomyURL") )); - break; - } - - return $output; -} -?> diff --git a/modules/throttle/throttle.module b/modules/throttle/throttle.module deleted file mode 100644 index e2469b7552b049049f633f44d58dc99ebca1da50..0000000000000000000000000000000000000000 --- a/modules/throttle/throttle.module +++ /dev/null @@ -1,127 +0,0 @@ -Auto-throttle probability limiter 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" => l(t("access log"), "admin/system/modules/statistics"))); - case "admin/help#throttle": - $output .= "

        Introduction

        This Drupal module allows you to enable and configure the auto-throttle congestion control mechanism offered by the %statistics-module. The auto-throttle mechanism allows your site to automatically adapt to different server levels.

        "; - $output .= "

        This module also adds a block that displays the current status of the throttle. You must have \"%throttle-block\" privileges to view the block. As a general rule of thumb, only site administrators should be granted access to this block.

        "; - $output .= "

        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 generated 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.

        "; - $output .= "

        As with any module, the throttle module needs to be %modules-enable before you can use it. Also refer to the permissions section below if you wish to access the throttle statistics block.

        "; - $output .= "

        Configuring the throttle module

        The %throttle-config for the throttle allows you to turn it on and off, as well as to fine-tune how sensitive it is.

        "; - $output .= "

        enable auto-throttle:

        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 %statistics-config for the auto-throttling mechanism to have any effect.
        "; - $output .= "

        auto-throttle multiplier:

        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.

        "; - $output .= "

        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.

        "; - $output .= "

        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.

        "; - $output .= "

        auto-throttle probability limiter:

        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.

        "; - $output .= "

        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.

        "; - $output .= "

        auto-throttle cron test:

        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 NOT be adjusted down to a level of 1. This prevents the throttle from bouncing back and forth between two levels.

        "; - $output .= "

        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.

        "; - $output .= "

        Throttle block

        This block displays some statistics regarding the current throttle and its configuration. It is recommended that only site administrators receive the \"%throttle-access\" permission bit required to view this block. It does not display information that would interest a normal site end-user.

        "; - $output .= "

        Don't forget to enable the block %throttle-block-enable.

        "; - $output .= "

        Permissions

        This module has one permission that needs to be configured in %permissions.

        "; - $output .= "
        • access throttle block - enable for user roles that get to view the throttle block.
        "; - $output .= "

        For programmers: throttle_status()

        The function throttle_status() 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.

        "; - $output .= "

        To implement the throttle, you should do something like this:"; - $output .= "

               \$throttle = 0;
        -        /* verify that the statistics 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
        -       }

        "; - $output = t($output, array("%statistics-module" => l(t("statistics module"), "admin/statistics"), "%throttle-block" => l(t("access throttle block"), "admin/user/permission"), "%modules-enable" => l(t("enabled"), "admin/system/modules"), "%throttle-config" => l(t("configuration section"), "admin/system/modules/throttle"), "%statistics-config" => l(t("statistics module"), "admin/system/modules/statistics"), "%throttle-access" => l(t("access throttle block"), "admin/user/permission"), "%throttle-block-enable" => l(t("here"), "admin/block"), "%permissions" => l(t("user permissions"), "admin/user/permission"))); - break; - } - - return $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") ."
        \n"; - if ($throttle < 5) { - $maximum = (($throttle + 1) * $multiplier) - 1; - $output .= "Current Level: $throttle ($minimum - $maximum)
        \n"; - } - else { - $output .= "Current Level: $throttle ($minimum+)
        \n"; - } - $output .= "Probability: $probability%
        \n"; - if ($recent_activity["hits"]) { - $output .= "
        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") ."
        \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 cb75d04e2e1a7c661e93d842333293167328e983..0000000000000000000000000000000000000000 --- a/modules/tracker/tracker.module +++ /dev/null @@ -1,113 +0,0 @@ -The tracker module is a handy module for displaying the most recent posts. By following the recent posts link in the user block, a user may quickly review all recent postings.

        "); - break; - case 'admin/system/modules#description': - $output = t("Enables tracking of recent posts for users."); - break; - } - - return $output; -} - -function tracker_link($type) { - - $links = array(); - - if ($type == "system") { - if (user_access("access content")) { - menu("tracker", t("recent posts"), "tracker_page", 1); - } - } - - return $links; -} - -function tracker_posts($id = 0) { - - $header = array( - array("data" => t("Type"), "field" => "type"), - array("data" => t("Title"), "field" => "title"), - array("data" => t("Author"), "field" => "u.name"), - array("data" => t("Last Post"), "field" => "last_activity", "sort" => "desc") - ); - if ($id) { - - $sql = "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 INNER 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"; - $sql .= tablesort_sql($header); - $sresult = pager_query($sql, 10, 0, "SELECT COUNT(nid) FROM {node} WHERE status = 1 AND uid = '". check_query($id) ."'"); - - } - else { - - $sql = "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 INNER 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"; - $sql .= tablesort_sql($header); - $sresult = pager_query($sql, 10, 0, "SELECT COUNT(nid) FROM {node} WHERE status = 1"); - - } - - while ($node = db_fetch_object($sresult)) { - if ($id) { - $cresult = db_query("SELECT c.*, u.name FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.uid = %d AND c.nid = %d AND c.status = 0 ORDER BY c.cid DESC", $id, $node->nid); - } - else { - $cresult = db_query("SELECT c.*, u.name FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.nid = %d AND c.status = 0 ORDER BY c.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[] = "
      • ". t("%subject by %author", array("%subject" => l($comment->subject, "node/view/$node->nid#$comment->cid"), "%author" => format_name($comment))) ." ". (node_is_new($comment->nid, $comment->timestamp) ? theme("theme_mark") : "") ."
      • \n"; - } - - if ($comments) { - $comments = "
          ". implode("\n", $comments) ."
        "; - } - else { - $comments = ""; - } - - $rows[] = array(array("data" => $type, "class" => "type"), array("data" => $title . $comments, "class" => "content"), array("data" => $author, "class" => "author"), array("data" => format_date($node->last_activity, "small"), "class" => "last_post")); - } - - if ($pager = pager_display(NULL, 10, 0, "default", tablesort_pager())) { - $rows[] = array(array("data" => $pager, "colspan" => 4)); - } - - $output = "
        "; - $output .= table($header, $rows); - $output .= "
        "; - - return $output; -} - -function tracker_user($type, &$edit, &$user) { - switch ($type) { - case "view_private": - case "view_public": - if (user_access("access content")) { - return form_item(t("Recent posts"), l(t("recent posts"), "tracker/$user->uid")); - } - } -} - -function tracker_page() { - global $user; - - if (user_access("access content")) { - theme("header", t("Recent posts")); - theme("box", t("Recent posts"), tracker_posts(arg(1))); - theme("footer"); - } -} - -?> diff --git a/modules/user.module b/modules/user.module index 15efff2feb10d2f277f640bc9c44ca24975ad389..84f068c8f0aa6facf4ab460fec444df53110a260 100644 --- a/modules/user.module +++ b/modules/user.module @@ -1493,9 +1493,6 @@ function user_admin_edit($edit = array()) { } // TODO: this display/edit/validate should be moved to a new profile module implementing the _user hooks - if ($error) { - // do nothing - } if ($error = user_validate_name($edit["name"])) { // do nothing } @@ -1526,7 +1523,7 @@ function user_admin_edit($edit = array()) { 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.")); + $output .= status(t("user information changes have been saved.")); } else { $output .= theme("theme_error", $error); @@ -1544,6 +1541,10 @@ function user_admin_edit($edit = array()) { } } + if (!$edit) { + $edit = object2array($account); + } + /* ** Display user form: */ diff --git a/modules/user/user.module b/modules/user/user.module deleted file mode 100644 index 15efff2feb10d2f277f640bc9c44ca24975ad389..0000000000000000000000000000000000000000 --- a/modules/user/user.module +++ /dev/null @@ -1,1886 +0,0 @@ -data && $data = unserialize($user->data)) { - foreach ($data as $key => $value) { - if (!isset($user->$key)) { - $user->$key = $value; - } - } - } - - return !empty($user->session) ? $user->session : ''; -} - -function sess_write($key, $value) { - global $user; - - db_query("UPDATE {sessions} SET uid = %d, hostname = '%s', session = '%s', timestamp = %d WHERE sid = '$key'", $user->uid, $_SERVER["REMOTE_ADDR"], $value, time()); - - if (!db_affected_rows()) { - db_query("INSERT INTO {sessions} (uid, sid, hostname, session, timestamp) values(%d, '%s', '%s', '%s', %d)", $user->uid, $key, $_SERVER["REMOTE_ADDR"], $value, time()); - } - - return ''; -} - -function sess_destroy($key) { - - db_query("DELETE FROM {sessions} WHERE sid = '$key'"); - -} - -function sess_gc($lifetime) { - - /* - ** Be sure to adjust 'php_value session.gc_maxlifetime' to a large enough - ** value. For example, if you want user sessions to stay in your database - ** for three weeks before deleting them, you need to set gc_maxlifetime - ** to '1814400'. At that value, only after a user doesn't log in after - ** three weeks (1814400 seconds) will his/her session be removed. - */ - db_query("DELETE FROM {sessions} WHERE timestamp < %d", time() - $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 = '%s', "; - $v[] = md5($value); - } - else if (substr($key, 0, 4) !== "auth") { - if (in_array($key, $user_fields)) { - // escape '%'s: - $value = str_replace("%", "%%", $value); - $query .= "$key = '%s', "; - $v[] = $value; - } - else { - $data[$key] = $value; - } - } - } - $query .= "data = '%s', "; - $v[] = serialize($data); - - db_query("UPDATE {users} SET $query timestamp = %d WHERE uid = %d", array_merge($v, array(time(), $account->uid))); - - $user = user_load(array("uid" => $account->uid)); - } - else { - $array["timestamp"] = time(); - $array["uid"] = db_next_id("{users}_uid"); - - foreach ($array as $key => $value) { - if ($key == "pass") { - $fields[] = check_query($key); - $values[] = md5($value); - $s[] = "'%s'"; - } - else if (substr($key, 0, 4) !== "auth") { - if (in_array($key, $user_fields)) { - $fields[] = check_query($key); - $values[] = $value; - $s[] = "'%s'"; - } - else { - $data[$key] = $value; - } - } - } - - $fields[] = "data"; - $values[] = serialize($data); - $s[] = "'%s'"; - - db_query("INSERT INTO {users} (". implode(", ", $fields) .") VALUES (". implode(", ", $s) .")", $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" => "$authname")); - } -} - -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; - static $cache; - - // User #1 has all priveleges: - if ($user->uid == 1) { - return 1; - } - - /* - ** To reduce the number of SQL queries, we cache the user's permissions - ** in a static variable. - */ - - if (!$cache) { - 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); - } - - /* - ** We use a separate $cache variable because $perm might be empty when a - ** user has no access rights. - */ - - $cache = 1; - } - - 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, - user_mail_encode($subject), - str_replace("\r", "", $message), - "MIME-Version: 1.0\nContent-type: text/plain; charset=UTF-8; format=flowed\nContent-transfer-encoding: 8Bit\n" . $header - ); - } -} - -function user_mail_encode($string, $charset = "UTF-8") { - /* - ** Used to encodes mail headers that contain non US- ASCII - ** characters. - ** http://www.rfc-editor.org/rfc/rfc2047.txt - ** - ** Notes: - ** - The chunks come in groupings of 4 bytes when using base64 - ** encoded. - ** - trim() is used to ensure that no extra spacing is added by - ** chunk_split() or preg_replace(). - ** - Using \n as the chunk separator may cause problems on some - ** systems and may have to be changed to \r\n or \r. - */ - $chunk_size = 75 - 7 - strlen($charset); - $chunk_size -= $chunk_size % 4; - $string = trim(chunk_split(base64_encode($string), $chunk_size, "\n")); - $string = trim(preg_replace('/^(.*)$/m', " =?$charset?B?\\1?=", $string)); - return $string; -} - -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", "mode", "sort", "threshold", "theme", "signature", "timestamp", "status", "timezone", "language", "init", "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 '%". check_query($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("Navigation"); - $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 = "\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"] = ""; - } - return $block; - case 1: - if ($menu = menu_tree()) { - $block["subject"] = $user->uid ? $user->name : t("Navigation"); - $block["content"] = "
        ". $menu ."
        "; - } - - return $block; - case 2: - if (user_access("access content")) { - $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("my account"), "user", array("title" => t("Create a user account, request a new password or edit your account settings."))); - } - - if ($type == "system") { - global $user; - if ($user->uid) { - menu("user/edit", t("my account"), "user_page", 8); - menu("user/logout", t("log out"), "user_page", 10); - } - if (user_access("administer users")) { - menu("admin/user", t("accounts"), "user_admin", 2); - menu("admin/user/create", t("new user"), "user_admin", 1); - menu("admin/user/access", t("access rules"), NULL, 3); - menu("admin/user/access/mail", t("e-mail rules"), "user_admin"); - menu("admin/user/access/user", t("name rules"), "user_admin"); - menu("admin/user/role", t("roles"), "user_admin", 4); - menu("admin/user/permission", t("permissions"), "user_admin", 5); - menu("admin/user/search", t("search"), "user_admin", 8); - menu("admin/user/help", t("help"), "user_help", 9); - menu("admin/user/edit", t("edit user account"), "user_admin", 0, 1); // hidden menu - } - } - - 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")) { - $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->uid) { - $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->uid && $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" => "$name@$server")); - } - } - - /* - ** Try each external authentication source in series. Register user if successful. - */ - - else if (!$user->uid && $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(t("edit user"), "admin/user/edit/$user->uid")); - break; - } - } - } - } - } - - if ($user->uid) { - watchdog("user", "session opened for '$user->name'"); - - // update the user table timestamp noting user has logged in - db_query("UPDATE {users} SET timestamp = '%d' WHERE uid = '%s'", time(), $user->uid); - - /* - ** 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 .= "

        $msg

        "; - } - 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 %s 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 %s 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 ."' <". $account->mail .">"); - return t("Your password and further instructions have been sent to your e-mail address."); - } - else { - watchdog("error", "error mailing new password: '". $account->name ."' <". $account->mail .">"); - 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 .= "

        ". sprintf(t("Enter your username %sor%s your e-mail address."), "", "") ."

        "; - $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') OR LOWER(init) = LOWER('%s')", $edit["mail"], $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(), "status" => (variable_get("user_register", 1) == 1 ? 1 : 0)), $data)); - watchdog("user", "new user: '". $edit["name"] ."' <". $edit["mail"] .">", l(t("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 .= "

        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.

        Your password is $pass. You may change your password on the next page.

        Please login below.

        "; - $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.
        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 .= "

        ". 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)) ."

        "; - } - $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; - - 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", "session"))) { - watchdog("warning", "detected malicious attempt to alter a protected database field"); - } - - $edit["rid"] = $user->rid; - $edit["init"] = $user->init; - $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 .= status(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.")); - - $output .= implode("\n", module_invoke_all("user", "edit_form", $edit, $user)); - - $output .= form_item(t("Password"), " ", 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, array("enctype" => "multipart/form-data")); - // the "enctype" attribute is required to upload files such as avatars - } - else { - $output = user_login(); - } - - return $output; -} - -function user_menu() { - global $theme; - - $links[] = l(t("view user information"), "user/view"); - $links[] = l(t("edit user information"), "user/edit"); - $links[] = l(t("delete account"), "user/delete"); - - return "
        ". theme("links", $links) ."
        "; -} - -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.")); - - $output .= implode("\n", module_invoke_all("user", "view_private", "", $user)); - - theme("header", $user->name); - theme("box", t("User account"), user_menu()); - theme("box", $user->name, $output); - theme("footer"); - } - else if ($uid && $account = user_load(array("uid" => $uid, "status" => 1))) { - $output = form_item(t("Name"), $account->name); - - $output .= implode("\n", module_invoke_all("user", "view_public", "", $account)); - - if (user_access("administer users")) { - $output .= form_item(t("Administration"), l(t("edit account"), "admin/user/edit/$account->uid")); - } - - theme("header", $account->name); - theme("box", $account->name, $output); - theme("footer"); - } - else { - $output = user_login(); - theme("header", t("User login")); - 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", t("E-mail new password")); - 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", t("Create new account")); - 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", t("Log in")); - theme("box", t("Log in"), $output); - theme("footer"); - break; - case t("Delete account"): - case "delete": - $output = user_delete(); - theme("header", t("Delete account")); - 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", t("Edit user information")); - 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("user/help#user")); - 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"] ."' <". $edit["mail"] .">"); - - 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 ($op == t("Add rule")) { - $aid = db_next_id("{access}_aid"); - db_query("INSERT INTO {access} (aid, mask, type, status) VALUES ('%s', '%s', '%s', %d)", $aid, $edit["mask"], $type, $edit["status"]); - $output .= status(t("access rule added.")); - } - else if ($op == t("Check")) { - if (user_deny($type, $edit["test"])) { - $output .= status(t("%test is not allowed.", array ("%test" => $edit["test"]))); - } - else { - $output .= status(t("%test is allowed.", array ("%test" => $edit["test"]))); - } - } - else if ($id) { - db_query("DELETE FROM {access} WHERE aid = %d", $id); - $output .= status(t("access rule deleted.")); - } - - $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")); - } - - $options = array ("1" => t("Allow"), "0" => t("Deny")); - $rows[] = array(form_select(NUll, "status", $edit["status"], $options), form_textfield(NULL, "mask", $edit["mask"], 32, 64), form_submit(t("Add rule"))); - $output .= table($header, $rows); - - $output .= "

        %: ". t("Matches any number of characters, even zero characters") .".
        _: ". t("Matches exactly one character.") ."

        "; - - if ($type != "user") { - $title = t("Check e-mail address"); - } - else { - $title = t("Check username"); - } - $output .= form_textfield($title, "test", $edit["test"], 32, 64). form_submit(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: - */ - - $perms = module_invoke_all("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(" "), $role_names); - - foreach ($perms as $perm) { - $row[] = t($perm); - foreach ($role_names as $rid => $name) { - $row[] = ""; - } - $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" => "". t("locked") ."", "align" => "center")); - } - } - $rows[] = array("", ""); - - $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) { - // do nothing - } - 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 .= status(t("the account has been deleted.")); - } - else { - $error = t("Failed to delete account: the account has to be blocked first."); - $output .= theme("theme_error", $error); - } - } - - /* - ** 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.")); - - $output .= implode("\n", module_invoke_all("user", "edit_form", $edit, $account)); - - $output .= form_item(t("Password"), " ", 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, array("enctype" => "multipart/form-data")); - } - else { - $output = t("No such user"); - } - - return $output; -} - -function user_admin_account() { - - $header = array( - array ("data" => t("ID"), "field" => "u.uid"), - array ("data" => t("username"), "field" => "u.name"), - array ("data" => t("status"), "field" => "u.status"), - array ("data" => t("role"), "field" => "u.rid"), - array ("data" => t("last access"), "field" => "u.timestamp", "sort" => "desc"), - t("operations") - ); - $sql = "SELECT u.uid, u.name, u.status, u.timestamp, r.name AS rolename FROM {role} r INNER JOIN {users} u ON r.rid = u.rid WHERE uid != 0"; - $sql .= tablesort_sql($header); - $result = pager_query($sql, 50); - - $status = array (t("blocked"), t("active")); - while ($account = db_fetch_object($result)) { - $rows[] = array($account->uid, format_name($account), $status[$account->status], $account->rolename, format_date($account->timestamp, "small"), l(t("edit account"), "admin/user/edit/$account->uid")); - } - - $pager = pager_display(NULL, 50, 0, "admin", tablesort_pager()); - if (!empty($pager)) { - $rows[] = array(array("data" => $pager, "colspan" => 6)); - } - 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": - $output = search_type("user", url("admin/user/search"), $_POST["keys"]); - break; - case t("Add rule"): - case t("Check"): - case "access": - $output .= user_admin_access($edit); - break; - case t("Save permissions"): - $output = status(t("user permissions saved.")); - case "permission": - $output .= user_admin_perm($edit); - break; - case t("Create account"): - case "create": - $output = user_admin_create($edit); - break; - case t("Add role"): - case t("Delete role"): - case t("Save role"): - $output = status(t("your role changes were saved.")); - case "role": - $output .= user_admin_role($edit); - break; - case t("Delete account"): - case t("Save account"): - case "edit": - $output = user_admin_edit($edit); - break; - default: - if ($op == "account" && arg(3) == "create") { - $output = user_admin_create($edit); - } - else { - $output = user_admin_account(); - } - } - return $output; - } -} -// the following functions comprise help for admins and developers -function user_help($section = "admin/help#user") { - $output = ""; - - switch ($section) { - case 'admin/user': - $output .= 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.

        "); - $output .= t("

        Click on either the username or edit account to edit a user's information.

        "); - $output .= t("

        Sort accounts by registration time by clicking on the ID header.

        "); - break; - case 'admin/user/create': - case 'admin/user/account/create': - $output .= t("This web page allows the administrators to register a new users by hand.
        Note:
        • You cannot have a user where either the e-mail address or the username match another user in the system.
        "); - break; - case 'admin/user/access': - $output .= 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 %e-mail, for the username mask click on %username.", array("%e-mail" => l(t("e-mail rules"), "admin/user/access/mail"), "%username" => l(t("name rules"), "admin/user/access/user"))); - break; - case 'admin/user/access/mail': - $output .= t("Setup and test the e-mail access rules. The access function checks if you match a deny and not an allow. If you match only a deny then it is denied. Any other case, such as both a deny and an allow pattern matching, allows the pattern.
        Notes:
        • To delete a rule click on \"delete rule\".
        • The order of the rules does not matter.
        "); - break; - case 'admin/user/access/user': - $output .= t("Setup and test the Username access rules. The access function checks if you match a deny and not an allow. If you do then it is denied. Any other case, such as a deny pattern and an allow pattern, allows the pattern.
        Notes:
        • To delete a rule click on \"delete rule\".
        • The order of the rules does not matter.
        "); - break; - case 'admin/user/permission': - $output .= t("In this area you will define the permissions for each user role (role names are defined on the %role). 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" => l(t("user roles page"), "admin/user/role"))); - break; - case 'admin/user/role': - $output .= "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 %permission. Examples of roles include: anonymous user, authenticated user, moderator, administrator and so on. In this area you will define the names of the various roles. To delete a role choose \"edit role\"
        By default, Drupal comes with two user roles:"; - $output .= "
          "; - $output .= "
        • Anonymous user: this role is used for users that don't have a user account or that are not authenticated.
        • "; - $output .= "
        • Authenticated user: this role is assigned automatically to authenticated users. Most registered users will belong to this user role unless specified otherwise.
        • "; - $output .= "
        "; - $output = t($output, array("%permission" => l(t("user permissions"), "admin/user/permission"))); - break; - case 'admin/user/search': - $output .= 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'."); - break; - case 'admin/system/modules#description': - $output .= t("Enables the user registration and login system."); - break; - case 'admin/system/modules/user': - $output .= 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."); - break; - case 'user/help#user': - $site = variable_get("site_name", "this website"); - - $output .= "

        Distributed authentication

        "; - $output .= "

        One of the more tedious moments in visiting a new website is filling out the registration form. Here at %site, you do not have to fill out a registration form if you are already a member of %help-links. This capability is called Distributed Authentication, and is unique to %drupal, the software which powers %site.

        "; - $output .= "

        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 %site. 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 %delphi-forums. Drupal informs Joe on registration and login screens that he may login with his Delphi ID instead of registering with %site. Joe likes that idea, and logs in with a username of joe@remote.delphiforums.com and his usual Delphi password. Drupal then contacts the remote.delphiforums.com server behind the scenes (usually using %xml, %http-post, or %soap) 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 %site in the same manner, and he will always be logged into the same account.

        "; - - $output = t($output, array("%help-links" => (implode(", ", user_auth_help_links())), "%site" => "$site", "%drupal" => "Drupal", "%delphi-forums" => "Delphi Forums", "%xml" => "XML-RPC", "%http-post" => "HTTP POST", "%soap" => "SOAP")); - - foreach (module_list() as $module) { - if (module_hook($module, "auth")) { - $output .= "

        ". module_invoke($module, "info", "name") ."

        "; - $output .= module_invoke($module, "help", "user/help#$module"); - } - } - break; - case 'admin/help#user': - - // Start of user_help_admin - $output .= "

        Introduction

        Drupal offers a powerful access system that allows users to register, login, logout, maintain user profiles, etc. By using \"%user-role\" you can setup fine grained %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.

        "; - $output .= "

        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.

        "; - $output .= "

        Registered users need to authenticate by supplying either a local username and password, or a remote username and password such as a %jabber, %delphiforums, or one from another %drupal website. See %da-auth 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 %php-sess. 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. 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.

        "; - $output .= "

        User preferences and profiles

        Each Drupal user has a profile, and a set of preferences which may be edited by clicking on the %user-prefs 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, and %da-auth names. Changes made here take effect immediately. Also, administrators may make profile and preferences changes in %admin-user on behalf of their users.

        "; - $output .= "

        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 %da-devel. For an example, see the jabber_user() function in /modules/jabber.module.

        "; - //end of user_help_admin - - //start of user_help_admin_da - $output .= "

        Distributed authentication

        "; - $output .= "

        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.

        "; - $output .= "

        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 the 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 %xml, %http-post, or %soap) behind the scenes and asks "is this password for username=joe?" 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.

        "; - $output .= "

        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. user 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.

        "; - $output .= "

        To disable distributed authentication, simply %dis-module or remove all DA modules. For a virgin install, that means removing/disabling the jabber module and the drupal module.

        "; - $output .= "

        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 ...

        "; - $output .= "%module-list"; - // end of user_help_admin_da - - // start of user_help_devel_da - $output .= "

        Writing distributed authentication modules

        Drupal is specifically architected to enable easy authoring of new authentication modules. I'll deconstruct the %blogger 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 %blogger-source in the %contrib-cvs.

        "; - $output .= "

        Code review

        "; - $output .= "
        function blogger_auth(\$name, \$pass, \$server) {
        -  // user did not present a Blogger ID so don't bother trying.
        -  if (\$server !== "blogger.com") {
        -    return 0;
        -  }
        -  //provided to Drupal by Ev@Blogger
        -  \$appkey = "6D4A2D6811A6E1F75148DC1155D33C0C958107BC"
        -
        -  \$message = new xmlrpcmsg("blogger.getUsersBlogs",
        -                           array(new xmlrpcval(\$appkey, "string"),
        -                           new xmlrpcval(\$name, "string"),
        -                           new xmlrpcval(\$pass, "string")));
        -  \$client = new xmlrpc_client("/api/RPC2", "plant.blogger.com");
        -  // \$client->setDebug(1);
        -  \$result = \$client->send(\$message, 5);
        -  // Since Blogger doesn't return a properly formed FaultCode, we just search for the string 'fault'.
        -  if (\$result && !stristr(\$result->serialize(), "fault")) {
        -    // 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;
        -  }
        -}
        "; - $output .= "

        The _auth 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:

        "; - $output .= "
        _auth function parameters
        \$nameThe substring before the final '@' character in the username field
        \$passThe whole string submitted by the user in the password field
        \$serverThe substring after the final '@' symbol in the username field
        "; - $output .= "

        So now lets use that \$name, \$pass, and \$server which was passed to our _auth function. Blogger authenticates users via %xml. Your module may authenticate using a different technique. Drupal doesn't reallly care how your module communicates with its registration source. It just trusts the module.

        "; - $output .= "

        The lines above illustrate a typical %xml method call. Here we build up a message and send it to Blogger, storing the response in a variable called \$response. The message we pass conforms to the published %blogger-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 plant.blogger.com, so we hard-code that value into the xmlrpc_client() function. A more typical example might be the jabber module, which uses the \$server parameter to determine where to send the authentication request. Also of note is the '5'th parameter in the \$client->send\(\) 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.

        "; - $output .= "
        -  if (\$result && !stristr(\$result->serialize(), "fault")) {
        -    // 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;
        -  }
        -
        "; - $output .= "

        This second half of the _auth function examines the \$response 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.

        "; - $output .= "
        function blogger_page() {
        -
        -  theme("header");
        -  theme("box", "Blogger", blogger_help(\"user/help\"));
        -  theme("footer");
        -}
        "; - $output .= "

        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 blogger.

        "; - $output .= "
        function blogger_help(\$section) {
        -  \$output = "";
        -
        -  switch (\$section) {
        -    case 'user/help':
        -      \$site = variable_get("site_name", "this web site");
        - \$output .= "<p>You may login to %site using a <b>Blogger ID</b> and password. A Blogger ID consists of your Blogger username followed by <i>@blogger.com</i>. So a valid blogger ID is <i>mwlily</i>@<b>blogger.com</b>. If you are a Blogger member, go ahead and login now.</p>"; - \$output .= "<p>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. <a href=\"http://www.blogger.com/about.pyra\">Learn more about it</a>."; - \$output = t(\$output, array(\"%site\" => \"<i>\$site</i>\")); - } - - return output; -}
        "; - $output .= "

        The _help 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.

        "; - $output .= "

        Publishing your module

        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 %contrib-cvs. You'll need to request priveleges to this repository - see %cvs for the details. Then you should announce your contribution on the %drupal-lists. You might also want to post a story on %drupal-org.

        "; - // end of user_help_devel_da - - // start of user_help_devel_userhook - $output .= "

        module_user()

        The _user() hook provides a mechanism for inserting text and form fields into the %registration, %user-acct, and %user-admin pages. This is useful if you want to add a custom field for your particular community. This is best illustrated by the %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.

        "; - - $output .= "

        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 julia.module. That file does the following:

          "; - $output .= "
        • new members must agree to Julia's Privacy Policy on the reg page.
        • "; - $output .= "
        • members may list their favorite ingredients on their public user profile page
        • "; - $output .= "

        "; - $output .= "

        Julia achieves this with the following code. The comments below should help you understand what is going on.

        "; - - $output .= "
        -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 Julia's Kitchen 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\"]));
        -    }
        -  }
        -
        "; - // end of user_help_devel_userhook - $output = t($output, array("%user-role" => l(t("roles"), "admin/user/role"), "%user-permission" => l(t("permission"), "admin/user/permission"), "%jabber" => "jabber", "%delphiforums" => "Delphi Forums", "%drupal" => "Drupal", "%da-auth" => l(t("distributed authentication"), "user/help#da"), "%php-sess" => "". t("PHP's session support") ."", "%user-prefs" => l(t("my account"), "user/edit"), "%admin-user" => l(t("administer") ." » ". t("accounts") ." » ". t("users"), "admin/user"), "%da-devel" => "". t("Drupal documentation") ."", "%xml" => "XML-RPC", "%http-post" => "HTTP POST", "%soap" => "SOAP", "%dis-module" => l(t("disable"), "admin/system/modules"), "%blogger" => "Blogger", "%blogger-source" => "". t("Bloggar source") ."", "%contrib-cvs" => "". t("Drupal contributions CVS repository") ."", "%blogger-api" => "". t("Blogger XML-RPC Application Programmers Interface (API)") ."", "%cvs" => "the CVS README file", "%drupal-lists" => "drupal-devel and drupal-support mailing lists", "%drupal-org" => "Drupal.org", "%registration" => l(t("registration"), "user/register"), "%user-acct" => l(t("user account view/edit"), "user"), "%user-admin" => l(t("administer") ." » ". t("acounts"), "admin/user"), "%profile-module" => "profile module")); - - foreach (module_list() as $module) { - if (module_hook($module, "auth")) { - $output = strtr($output, array("%module-list" => "

        ". module_invoke($module, "info", "name") ."

        \n%module-list")); - $output = strtr($output, array("%module-list" => module_invoke($module, "help", "user/help") . "\n%module-list")); - } - } - $output = strtr($output, array("%module-list" => "")); - break; - } - - return $output; -} - -?> diff --git a/modules/watchdog/watchdog.module b/modules/watchdog/watchdog.module deleted file mode 100644 index b6037f5f608e7d2f493ae491d444cce442cd7e5c..0000000000000000000000000000000000000000 --- a/modules/watchdog/watchdog.module +++ /dev/null @@ -1,149 +0,0 @@ -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 %watchdog on a regular basis as it is often the only way to tell what is going on.

        "; - $output .= "

        To ease administration, the watchdog will automatically discard old log entries, %log-entry. Needs \"cron.php\" to discard the entries.

        "; - $output = t($output, array("%watchdog" => l(t("check the watchdog report"), "admin/watchdog"), "%log-entry" => l(t("as configured"), "admin/system/modules/watchdog"))); - break; - case 'admin/watchdog': - $output = 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."); - break; - case 'admin/watchdog/user': - $output = t("Watchdog events that have to do with users."); - break; - case 'admin/watchdog/regular': - $output = t("Watchdog events that are \"normal\" and have no other classification."); - break; - case 'admin/watchdog/httpd': - $output = t("Watchdog events that are from the web server."); - break; - case 'admin/watchdog/special': - $output = t("Watchdog events about adding, changing, and moderating nodes and comments."); - break; - case 'admin/watchdog/error': - $output = t("Watchdog general error events, such as invalid login, permission denied, and database errors."); - break; - case 'admin/watchdog/warning': - $output = t("Watchdog warning events. These events don't stop Drupal from running, but are things you should know."); - break; - case 'admin/system/modules#description': - $output = t("Logs and records system events."); - break; - case 'admin/system/modules/watchdog': - $output = t("Watchdog logs your system events. To see these logs go to %watchdog. Since these logs can grow out of control if kept around forever, below set how long an item should be kept in the log.
        Note:
        • To discard entries as set below you must run \"cron.php\" regularly.
        ", array("%watchdog" => l(t("Site monitoring"), "admin/watchdog"))); - break; - } - - return $output; -} - -function watchdog_perm() { - return array("administer watchdog"); -} - -function watchdog_link($type) { - if ($type == "system") { - if (user_access("administer watchdog")) { - menu("admin/watchdog", t("messages"), "watchdog_admin", 6); - menu("admin/watchdog/user", t("user"), "watchdog_admin"); - menu("admin/watchdog/regular", t("regular"), "watchdog_admin"); - menu("admin/watchdog/special", t("special"), "watchdog_admin"); - menu("admin/watchdog/warning", t("warning"), "watchdog_admin"); - menu("admin/watchdog/error", t("error"), "watchdog_admin"); - menu("admin/watchdog/httpd", t("httpd"), "watchdog_admin"); - menu("admin/watchdog/view", t("view details"), "watchdog_admin", 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 != ''"); - - $header = array( - array("data" => t("date"), "field" => "w.timestamp", "sort" => "desc"), - array("data" => t("event"), "field" => "w.message"), - array("data" => t("user"), "field" => "u.name"), - array("data" => t("operations"), "colspan" => "2") - ); - $sql = "SELECT w.*, u.name, u.uid FROM {watchdog} w INNER JOIN {users} u ON w.uid = u.uid ". ($type ? $query[$type] : ""); - $sql .= tablesort_sql($header); - $result = pager_query($sql, 50); - - while ($watchdog = db_fetch_object($result)) { - if ($background = $color[$watchdog->type]) { - $rows[] = array( - array("data" => format_date($watchdog->timestamp, "small"), "style" => "background-color: $background"), - array("data" => substr(strip_tags($watchdog->message), 0, 64), "style" => "background-color: $background"), - array("data" => format_name($watchdog), "style" => "background-color: $background"), - array("data" => $watchdog->link, "style" => "background-color: $background"), - array("data" => l(t("view details"), "admin/watchdog/view/$watchdog->wid"), "style" => "background-color: $background") - ); - } - } - - if (!$rows) { - $rows[] = array(array("data" => t("No log messages available."), "colspan" => "5")); - } - - $pager = pager_display(NULL, 50, 0, "admin", tablesort_pager()); - if (!empty($pager)) { - $rows[] = array(array("data" => $pager, "colspan" => "5")); - } - return table($header, $rows); -} - -function watchdog_view($id) { - - $result = db_query("SELECT w.*, u.name, u.uid FROM {watchdog} w INNER JOIN {users} u ON w.uid = u.uid WHERE w.wid = %d", $id); - - if ($watchdog = db_fetch_object($result)) { - $output .= ""; - $output .= " "; - $output .= " "; - $output .= " "; - $output .= " "; - $output .= " "; - $output .= " "; - $output .= "
        ". t("Type") ."$watchdog->type
        ". t("Date") ."". format_date($watchdog->timestamp, "large") ."
        ". t("User") ."". format_name($watchdog) ."
        ". t("Location") ."$watchdog->location
        ". t("Message") ."$watchdog->message
        ". t("Hostname") ."$watchdog->hostname
        "; - - return $output; - } -} - -function watchdog_admin() { - - if (user_access("administer watchdog")) { - switch (arg(2)) { - case "help": - $output = watchdog_help(); - break; - case "view": - $output = watchdog_view(arg(3)); - break; - default: - $output = watchdog_overview(arg(2)); - } - return $output; - } - else { - return message_access(); - } -} - -?>