/** * get config entry * @param $name * @return mixed */ public function get($name) { if (oneof($name, 'pref', 'spam', 'data', 'min')) { trigger_error("Usage of config value env/{$name} is deprecated.", E_USER_DEPRECATED); } return $this->config[$name]; }
/** * Function: __construct * Parse the URL and to determine what to do. * * Parameters: * $controller - The controller to use. */ private function __construct($controller) { $this->controller = $controller; $config = Config::current(); $this->action =& $_GET['action']; if (isset($_GET['feed'])) { $this->feed = true; } # Parse the current URL and extract information. $parse = parse_url($config->url); fallback($parse["path"], "/"); if (isset($controller->base)) { $parse["path"] = trim($parse["path"], "/") . "/" . trim($controller->base, "/") . "/"; } $this->safe_path = str_replace("/", "\\/", $parse["path"]); $this->request = $parse["path"] == "/" ? $_SERVER['REQUEST_URI'] : preg_replace("/{$this->safe_path}?/", "", $_SERVER['REQUEST_URI'], 1); $this->arg = array_map("urldecode", explode("/", trim($this->request, "/"))); if (method_exists($controller, "parse")) { $controller->parse($this); } Trigger::current()->call("parse_url", $this); $this->try[] = isset($this->action) ? oneof($this->action, "index") : (!substr_count($this->arg[0], "?") ? oneof(@$this->arg[0], "index") : "index"); # Guess the action initially. # This is only required because of the view_site permission; # it has to know if they're viewing /login, in which case # it should allow the page to display. fallback($this->action, end($this->try)); }
public function main_index($main) { $config = Config::current(); if ($config->disable_aggregation or time() - $config->last_aggregation < $config->aggregate_every * 60) { return; } $aggregates = (array) $config->aggregates; if (empty($aggregates)) { return; } foreach ($aggregates as $name => $feed) { $xml_contents = preg_replace(array("/<(\\/?)dc:date>/", "/xmlns=/"), array("<\\1date>", "a="), get_remote($feed["url"])); $xml = simplexml_load_string($xml_contents, "SimpleXMLElement", LIBXML_NOCDATA); if ($xml === false) { continue; } # Flatten namespaces recursively $this->flatten($xml); $items = array(); if (isset($xml->entry)) { foreach ($xml->entry as $entry) { array_unshift($items, $entry); } } elseif (isset($xml->item)) { foreach ($xml->item as $item) { array_unshift($items, $item); } } else { foreach ($xml->channel->item as $item) { array_unshift($items, $item); } } foreach ($items as $item) { $date = oneof(@$item->pubDate, @$item->date, @$item->updated, 0); $updated = strtotime($date); if ($updated > $feed["last_updated"]) { # Get creation date ('created' in Atom) $created = @$item->created ? strtotime($item->created) : 0; if ($created <= 0) { $created = $updated; } # Construct the post data from the user-defined XPath mapping: $data = array("aggregate" => $name); foreach ($feed["data"] as $attr => $field) { $field = !empty($field) ? $this->parse_field($field, $item) : ""; $data[$attr] = is_string($field) ? $field : YAML::dump($field); } if (isset($data["title"]) or isset($data["name"])) { $clean = sanitize(oneof(@$data["title"], @$data["name"])); } Post::add($data, $clean, null, $feed["feather"], $feed["author"], false, "public", datetime($created), datetime($updated)); $aggregates[$name]["last_updated"] = $updated; } } } $config->set("aggregates", $aggregates); $config->set("last_aggregation", time()); }
function display_error($string) { $thumbnail = imagecreatetruecolor(oneof(@$_GET['max_width'], 100), 18); imagestring($thumbnail, 1, 5, 5, $string, imagecolorallocate($thumbnail, 255, 255, 255)); header("Content-type: image/png"); header("Content-Disposition: inline; filename=error.png"); imagepng($thumbnail); exit; }
/** * Function: __construct * See Also: * <Model::grab> */ public function __construct($group_id = null, $options = array()) { $options["left_join"][] = array("table" => "permissions", "where" => "group_id = groups.id"); $options["select"][] = "groups.*"; $options["select"][] = "permissions.id AS permissions"; parent::grab($this, $group_id, $options); $this->permissions = (array) oneof(@$this->permissions, array()); if ($this->no_results) { return false; } Trigger::current()->filter($this, "group"); }
/** * Function: add * Adds a type to the database. * * Calls the add_type trigger with the inserted type. * * Parameters: * $name - The title of the new type. * $description - The description of the new type. * * Returns: * $type - The newly created type. * * See Also: * <update> */ static function add($name, $description = "", $color = "0a0a0a", $clean = null, $url = null) { $sql = SQL::current(); $clean = oneof($clean, sanitize($name)); $sql->insert("types", array("name" => $name, "description" => $description, "color" => $color, "clean" => $clean, "url" => oneof($url, self::check_url($clean)))); $type = new self($sql->latest()); Trigger::current()->call("add_type", $type); if (module_enabled("cacher")) { Modules::$instances["cacher"]->regenerate(); } return $type; }
/** * Function: add * Adds a page to the database. * * Calls the @add_page@ trigger with the new <Page>. * * Parameters: * $title - The Title for the new page. * $body - The Body for the new page. * $body - The <User> or <User.id> of the page's author. * $parent_id - The ID of the new page's parent page (0 for none). * $show_in_list - Whether or not to show it in the pages list. * $list_order - The order of the page in the list. * $clean - The clean URL. * $url - The unique URL. * $created_at - The new page's "created" timestamp. * $updated_at - The new page's "last updated" timestamp. * * Returns: * The newly created <Page>. * * See Also: * <update> */ static function add($title, $body, $user = null, $parent_id = 0, $show_in_list = true, $list_order = 0, $clean = "", $url = "", $created_at = null, $updated_at = "0000-00-00 00:00:00") { $user_id = $user instanceof User ? $user->id : $user; $sql = SQL::current(); $visitor = Visitor::current(); $trigger = Trigger::current(); $new_values = array("title" => $title, "body" => $body, "user_id" => oneof($user_id, $visitor->id), "parent_id" => oneof($parent_id, 0), "show_in_list" => oneof($show_in_list, true), "list_order" => oneof($list_order, 0), "clean" => oneof($clean, sanitize($title)), "url" => oneof($url, self::check_url($clean)), "created_at" => oneof($created_at, datetime()), "updated_at" => oneof($updated_at, "0000-00-00 00:00:00")); $trigger->filter($new_values, "before_add_page"); $sql->insert("pages", $new_values); $page = new self($sql->latest()); $trigger->call("add_page", $page); return $page; }
public function format_dialogue($text, $post = null) { if (isset($post)) { $post->dialogue_unformatted = $text; } $split = explode("\n", $text); $return = '<ul class="dialogue">'; $count = 0; $my_name = ""; $links = array(); foreach ($split as $line) { # Remove the timstamps $line = preg_replace("/[ ]?[\\[|\\(]?[0-9]{1,2}:[0-9]{2}(:[0-9]{2})?[ ]?(pm|am)?[\\]|\\)]?[ ]?/i", "", $line); preg_match("/(<?)(.+)(:|>)\\s*(.+)/i", $line, $matches); if (empty($matches)) { continue; } if (preg_match("/\\s*\\(([^\\)]+)\\)\$/", $matches[2], $attribution)) { if ($attribution[1] == "me") { $my_name = $matches[2] = str_replace($attribution[0], "", $matches[2]); } else { $matches[2] = str_replace($attribution[0], "", $matches[2]); $links[$matches[2]] = $attribution[1]; } } $link = oneof(@$links[$matches[2]], ""); $me = $my_name == $matches[2] ? " me" : ""; $username = $matches[1] . $matches[2] . $matches[3]; $class = $count % 2 ? "even" : "odd"; $return .= '<li class="' . $class . $me . '">'; if (!empty($link)) { $return .= '<span class="label">' . $matches[1] . '<a href="' . $link . '">' . fix($matches[2], false) . '</a>' . $matches[3] . '</span> ' . $matches[4] . "\n"; } else { $return .= '<span class="label">' . fix($username, false) . '</span> ' . $matches[4] . "\n"; } $return .= '</li>'; $count++; } $return .= "</ul>"; # If they're previewing. if (!isset($post)) { $return = preg_replace("/(<li class=\"(even|odd) me\"><span class=\"label\">)(.+)(<\\/span> (.+)\n<\\/li>)/", "\\1<strong>\\3</strong>\\4", $return); } return $return; }
/** * Function: __construct * Prepares an array for pagination. * * Parameters: * $array - The array to paginate. * $per_page - Number of items per page. * $name - The name of the $_GET parameter to use for determining the current page. * $model - If this is true, each item in $array that gets shown on the page will be * initialized as a model of whatever is passed as the second argument to $array. * The first argument of $array is expected to be an array of IDs. * $page - Page number to start at. * * Returns: * A paginated array of length $per_page or smaller. */ public function __construct($array, $per_page = 5, $name = "page", $model = null, $page = null) { self::$names[] = $name; $this->array = (array) $array; $this->per_page = $per_page; $this->name = $name; $this->model = fallback($model, count($this->array) == 2 and is_array($this->array[0]) and is_string($this->array[1]) and class_exists($this->array[1])); if ($model) { list($this->array, $model_name) = $this->array; } $this->total = count($this->array); $this->page = oneof($page, @$_GET[$name], 1); if ($this->per_page != 0) { $this->pages = ceil($this->total / $this->per_page); } else { $this->pages = 0; } $offset = ($this->page - 1) * $this->per_page; $this->result = array(); if ($model) { for ($i = $offset; $i < $offset + $this->per_page; $i++) { if (isset($this->array[$i])) { $this->result[] = new $model_name(null, array("read_from" => $this->array[$i])); } } } else { $this->result = array_slice($this->array, $offset, $this->per_page); } $shown_dates = array(); if ($model) { foreach ($this->result as &$result) { if (isset($result->created_at)) { $pinned = (isset($result->pinned) and $result->pinned); $shown = in_array(when("m-d-Y", $result->created_at), $shown_dates); $result->first_of_day = (!$pinned and !$shown and !AJAX); if (!$pinned and !$shown) { $shown_dates[] = when("m-d-Y", $result->created_at); } } } } $this->paginated = $this->paginate = $this->list =& $this->result; }
/** * Function: __construct * The class constructor is private so there is only one connection. * * Parameters: * $settings - Settings to load instead of the config. */ private function __construct($settings = array()) { if (!UPGRADING and !INSTALLING and !isset(Config::current()->sql)) { error(__("Error"), __("Database configuration is not set. Please run the upgrader.")); } $database = !UPGRADING ? oneof(@Config::current()->sql, array()) : Config::get("sql"); if (is_array($settings)) { fallback($database, $settings); } elseif ($settings === true) { $this->silence_errors = true; } if (!empty($database)) { foreach ($database as $setting => $value) { $this->{$setting} = $value; } } $this->connected = false; # We really don't need PDO anymore, since we have the two we supported with it hardcoded (kinda). # Keeping this here for when/if we decide to add support for more database engines, like Postgres and MSSQL. # if (class_exists("PDO") and (in_array("mysql", PDO::getAvailableDrivers()) or in_array("sqlite", PDO::getAvailableDrivers()))) # return $this->method = "pdo"; if (isset($this->adapter)) { if ($this->adapter == "mysql" and class_exists("MySQLi")) { $this->method = "mysqli"; } elseif ($this->adapter == "mysql" and function_exists("mysql_connect")) { $this->method = "mysql"; } elseif (class_exists("PDO") and ($this->adapter == "sqlite" and in_array("sqlite", PDO::getAvailableDrivers()) or $this->adapter == "pgsql" and in_array("pgsql", PDO::getAvailableDrivers()))) { $this->method = "pdo"; } } else { if (class_exists("MySQLi")) { $this->method = "mysqli"; } elseif (function_exists("mysql_connect")) { $this->method = "mysql"; } elseif (class_exists("PDO") and in_array("mysql", PDO::getAvailableDrivers())) { $this->method = "pdo"; } } }
/** * Function: login * Process logging in. If the username and password are incorrect or if the user is already logged in, it will error. */ public function login() { if (logged_in()) { error(__("Error"), __("You're already logged in.")); } if (!empty($_POST)) { fallback($_POST['login']); fallback($_POST['password']); $trigger = Trigger::current(); if ($trigger->exists("authenticate")) { return $trigger->call("authenticate"); } if (!User::authenticate($_POST['login'], $_POST['password'])) { if (!count(User::find(array("where" => array("login" => $_POST['login']))))) { Flash::warning(__("There is no user with that login name.")); } else { Flash::warning(__("Password incorrect.")); } } if (!Flash::exists("warning")) { $user = new User(array("login" => $_POST['login'])); $_SESSION['user_id'] = $user->id; $redirect = @$_SESSION['redirect_to']; unset($_SESSION['redirect_to']); Flash::notice(__("Logged in."), oneof($redirect, "/")); } } $this->display("forms/user/login", array(), __("Log In")); }
public function parse($route) { $config = Config::current(); if ($this->feed) { $this->post_limit = $config->feed_items; } else { $this->post_limit = $config->posts_per_page; } if (empty($route->arg[0]) and !isset($config->routes["/"])) { # If they're just at /, don't bother with all this. return $route->action = "index"; } # Protect non-responder functions. if (in_array($route->arg[0], array("__construct", "parse", "display", "current"))) { show_404(); } # Feed if (preg_match("/\\/feed\\/?\$/", $route->request)) { $this->feed = true; $this->post_limit = $config->feed_items; if ($route->arg[0] == "feed") { # Don't set $route->action to "feed" (bottom of this function). return $route->action = "index"; } } # Feed with a title parameter if (preg_match("/\\/feed\\/([^\\/]+)\\/?\$/", $route->request, $title)) { $this->feed = true; $this->post_limit = $config->feed_items; $_GET['title'] = $title[1]; if ($route->arg[0] == "feed") { # Don't set $route->action to "feed" (bottom of this function). return $route->action = "index"; } } # Paginator if (preg_match_all("/\\/((([^_\\/]+)_)?page)\\/([0-9]+)/", $route->request, $page_matches)) { foreach ($page_matches[1] as $key => $page_var) { $_GET[$page_var] = (int) $page_matches[4][$key]; } if ($route->arg[0] == $page_matches[1][0]) { # Don't fool ourselves into thinking we're viewing a page. return $route->action = isset($config->routes["/"]) ? $config->routes["/"] : "index"; } } # Viewing a type if ($route->arg[0] == "type") { $_GET['url'] = $route->arg[1]; return $route->action = "type"; } # Viewing a type (backwards-compatible URL) if ($route->arg[0] == "browse") { $_GET['url'] = depluralize($route->arg[1]); return $route->action = "type"; } # Viewing an extension if ($route->arg[0] == "view") { $_GET['url'] = $route->arg[1]; $_GET['version'] = @$route->arg[2]; return $route->action = "view"; } # Downloading an extension if ($route->arg[0] == "download") { $_GET['url'] = $route->arg[1]; $_GET['version'] = @$route->arg[2]; return $route->action = "download"; } # Loving an extension if ($route->arg[0] == "love") { $_GET['url'] = $route->arg[1]; $_GET['version'] = @$route->arg[2]; return $route->action = "love"; } # Adding an extension if ($route->arg[0] == "new_extension") { $_GET['type'] = oneof(@$route->arg[1], "module"); return $route->action = "new_extension"; } # Adding a new version of an extension if ($route->arg[0] == "new_version") { $_GET['url'] = $route->arg[1]; return $route->action = "new_version"; } if (in_array($route->arg[0], array("edit_version", "delete_version", "edit_note", "delete_note", "delete_extension"))) { $_GET['id'] = $route->arg[1]; return $route->action = $route->arg[0]; } # Searching if ($route->arg[0] == "search") { if (isset($route->arg[1])) { $_GET['query'] = $route->arg[1]; } return $route->action = "search"; } # Viewing a tag if ($route->arg[0] == "tag") { $_GET['url'] = $route->arg[1]; return $route->action = "tag"; } # Custom pages added by Modules, Feathers, Themes, etc. foreach ($config->routes as $path => $action) { if (is_numeric($action)) { $action = $route->arg[0]; } preg_match_all("/\\(([^\\)]+)\\)/", $path, $matches); if ($path != "/") { $path = trim($path, "/"); } $escape = preg_quote($path, "/"); $to_regexp = preg_replace("/\\\\\\(([^\\)]+)\\\\\\)/", "([^\\/]+)", $escape); if ($path == "/") { $to_regexp = "\$"; } if (preg_match("/^\\/{$to_regexp}/", $route->request, $url_matches)) { array_shift($url_matches); if (isset($matches[1])) { foreach ($matches[1] as $index => $parameter) { $_GET[$parameter] = urldecode($url_matches[$index]); } } $params = explode(";", $action); $action = $params[0]; array_shift($params); foreach ($params as $param) { $split = explode("=", $param); $_GET[$split[0]] = fallback($split[1], "", true); } $route->try[] = $action; } } }
public function metaWeblog_editPost($args) { $this->auth($args[1], $args[2], 'edit'); global $user; if (!Post::exists($args[0])) { return new IXR_Error(500, __("Post not found.")); } # Support for extended body $body = $args[3]['description']; if (!empty($args[3]['mt_text_more'])) { $body .= '<!--more-->' . $args[3]['mt_text_more']; } # Add excerpt to body so it isn't lost if (!empty($args[3]['mt_excerpt'])) { $body = $args[3]['mt_excerpt'] . "\n\n" . $body; } if (trim($body) === '') { return new IXR_Error(500, __("Body can't be blank.")); } $post = new Post($args[0], array('filter' => false)); # More specific permission check if (!$post->editable($user)) { return new IXR_Error(500, __("You don't have permission to edit this post.")); } # Enforce post status when necessary if (!$user->group->can('edit_own_post', 'edit_post')) { $status = 'draft'; } else { if ($post->status !== 'public' and $post->status !== 'draft') { $status = $post->status; } else { $status = $args[4] ? 'public' : 'draft'; } } $trigger = Trigger::current(); $trigger->call('metaWeblog_editPost_preQuery', $args[3], $post); $post->update(array('title' => $args[3]['title'], 'body' => $body), null, null, $status, sanitize(oneof(@$args[3]['mt_basename'], $args[3]['title'])), oneof($this->convertFromDateCreated($args[3]), $post->created_at)); $trigger->call('metaWeblog_editPost', $args[3], $post); return true; }
exit("Chyrp requires PHP 5.1.3 or greater. Installation cannot continue."); } require_once INCLUDES_DIR . "/helpers.php"; require_once INCLUDES_DIR . "/lib/gettext/gettext.php"; require_once INCLUDES_DIR . "/lib/gettext/streams.php"; require_once INCLUDES_DIR . "/lib/YAML.php"; require_once INCLUDES_DIR . "/lib/PasswordHash.php"; require_once INCLUDES_DIR . "/class/Config.php"; require_once INCLUDES_DIR . "/class/SQL.php"; require_once INCLUDES_DIR . "/class/Model.php"; require_once INCLUDES_DIR . "/model/User.php"; # Prepare the Config interface. $config = Config::current(); # Atlantic/Reykjavik is 0 offset. Set it so the timezones() function is # always accurate, even if the server has its own timezone settings. $default_timezone = oneof(ini_get("date.timezone"), "Atlantic/Reykjavik"); set_timezone($default_timezone); # Sanitize all input depending on magic_quotes_gpc's enabled status. sanitize_input($_GET); sanitize_input($_POST); sanitize_input($_COOKIE); sanitize_input($_REQUEST); $url = "http://chyrp.net/demos/" . $num; $index = parse_url($url, PHP_URL_PATH) ? "/" . trim(parse_url($url, PHP_URL_PATH), "/") . "/" : "/"; $htaccess = "<IfModule mod_rewrite.c>\nRewriteEngine On\nRewriteBase {$index}\nRewriteCond %{REQUEST_FILENAME} !-f\n" . "RewriteCond %{REQUEST_FILENAME} !-d\nRewriteRule ^.+\$ index.php [L]\n</IfModule>"; $path = preg_quote($index, "/"); $htaccess_has_chyrp = (file_exists(MAIN_DIR . "/.htaccess") and preg_match("/<IfModule mod_rewrite\\.c>\n([\\s]*)RewriteEngine On\n([\\s]*)RewriteBase {$path}\n" . "([\\s]*)RewriteCond %\\{REQUEST_FILENAME\\} !-f\n([\\s]*)RewriteCond %\\{REQUEST_FILENAME\\}" . " !-d\n([\\s]*)RewriteRule \\^\\.\\+\\\$ index\\.php \\[L\\]\n([\\s]*)<\\/IfModule>/", file_get_contents(MAIN_DIR . "/.htaccess"))); $errors = array(); $installed = false; if (file_exists(INCLUDES_DIR . "/config.yaml.php") and file_exists(MAIN_DIR . "/.htaccess")) { $sql = SQL::current(true);
/** * Function: login * Process logging in. If the username and password are incorrect or if the user is already logged in, it will error. */ public function login() { if (logged_in()) { error(__("Error"), __("You're already logged in.")); } if (!empty($_POST)) { fallback($_POST['login']); fallback($_POST['password']); $trigger = Trigger::current(); if ($trigger->exists("authenticate")) { return $trigger->call("authenticate"); } if (!User::authenticate($_POST['login'], $_POST['password'])) { Flash::warning(__("Incorrect username and/or password, please try again.")); } if (!Flash::exists("warning")) { $user = new User(array("login" => $_POST['login'])); $_SESSION['user_id'] = $user->id; if (!isset($redirect)) { $redirect = oneof(@$_SESSION['redirect_to'], "/"); unset($_SESSION['redirect_to']); } Flash::notice(__("Logged in."), $redirect); } } $this->display("forms/user/login", array(), __("Log In")); }
public function post_comment_count_attr($attr, $post) { if (isset($this->comment_counts)) { return oneof(@$this->comment_counts[$post->id], 0); } $counts = SQL::current()->select("comments", array("COUNT(post_id) AS total", "post_id as post_id"), array("status not" => "spam", "status != 'denied' OR (\n (\n user_id != 0 AND\n user_id = :visitor_id\n ) OR (\n id IN " . self::visitor_comments() . "\n )\n )"), null, array(":visitor_id" => Visitor::current()->id), null, null, "post_id"); foreach ($counts->fetchAll() as $count) { $this->comment_counts[$count["post_id"]] = (int) $count["total"]; } return oneof(@$this->comment_counts[$post->id], 0); }
$tagged = preg_replace("/(" . preg_quote(parse_url($post->url(), PHP_URL_HOST)) . ")/", "\\1," . when("Y-m-d", $updated) . ":", $tagged, 1); $original_url = $post->url(); $url = $post->url(); $title = $post->title(); $trigger->filter($url, "feed_url", $post); if (!$post->user->no_results) { $author = oneof($post->user->full_name, $post->user->login); } else { $author = __("Guest"); } ?> <entry> <title type="html"> <?php echo $post->feather == 'text' ? '☃ ' : ''; echo fix(oneof($title, ucfirst($post->feather))); ?> </title> <id>tag:<?php echo $tagged; ?> </id> <updated><?php echo when("c", $updated); ?> </updated> <published><?php echo when("c", $post->created_at); ?> </published> <link rel="alternate" type="<?php
/** * Function: general_settings * General Settings page. */ public function general_settings() { if (!Visitor::current()->group->can("change_settings")) { show_403(__("Access Denied"), __("You do not have sufficient privileges to change settings.")); } $locales = array(); if ($open = opendir(INCLUDES_DIR . "/locale/")) { while (($folder = readdir($open)) !== false) { $split = explode(".", $folder); if (end($split) == "mo") { $locales[] = array("code" => $split[0], "name" => lang_code($split[0])); } } closedir($open); } if (empty($_POST)) { return $this->display("general_settings", array("locales" => $locales, "timezones" => timezones())); } if (!isset($_POST['hash']) or $_POST['hash'] != Config::current()->secure_hashkey) { show_403(__("Access Denied"), __("Invalid security key.")); } $config = Config::current(); $set = array($config->set("name", $_POST['name']), $config->set("description", $_POST['description']), $config->set("chyrp_url", rtrim($_POST['chyrp_url'], "/")), $config->set("url", rtrim(oneof($_POST['url'], $_POST['chyrp_url']), "/")), $config->set("email", $_POST['email']), $config->set("timezone", $_POST['timezone']), $config->set("locale", $_POST['locale'])); if (!in_array(false, $set)) { Flash::notice(__("Settings updated."), "/admin/?action=general_settings"); } }
/** * Function: add * Adds a user to the database with the passed username, password, and e-mail. * * Calls the @add_user@ trigger with the inserted user. * * Parameters: * $login - The Login for the new user. * $password - The Password for the new user. Don't hash this, it's done in the function. * $email - The E-Mail for the new user. * $full_name - The full name of the user. * $website - The user's website. * $group - The user's group (defaults to the configured default group). * $joined_at - Join date (defaults to now). * $hash_password - Hash the password automatically? (defaults to true) * * Returns: * The newly created <User>. * * See Also: * <update> */ static function add($login, $password, $email, $full_name = "", $website = "", $group_ = null, $joined_at = null, $hash_password = true) { $config = Config::current(); $sql = SQL::current(); $trigger = Trigger::current(); if (empty($group)) { $group_id = $config->default_group; } else { $group_id = $group instanceof Group ? $group->id : $group; } $new_values = array("login" => strip_tags($login), "password" => $hash_password ? self::hashPassword($password) : $password, "email" => strip_tags($email), "full_name" => strip_tags($full_name), "website" => strip_tags($website), "group_id" => $group_id, "joined_at" => oneof($joined_at, datetime())); $trigger->filter($new_values, "before_add_user"); $sql->insert("users", $new_values); $user = new self($sql->latest("users")); $trigger->call("add_user", $user); return $user; }
/** * Function: feeds * Outputs the Feed references. */ public function feeds() { // Compute the URL of the per-page feed (if any): $config = Config::current(); $request = $config->clean_urls ? rtrim(Route::current()->request, "/") : fix($_SERVER['REQUEST_URI']); $append = $config->clean_urls ? "/feed" : ((count($_GET) == 1 and Route::current()->action == "index") ? "/?feed" : "&feed"); $append .= $config->clean_urls ? "/" . urlencode($this->title) : "&title=" . urlencode($this->title); # Create basic list of links (site and page Atom feeds): $feedurl = oneof(@$config->feed_url, url("feed")); $pagefeedurl = $config->url . $request . $append; $links = array(array("href" => $feedurl, "type" => "application/atom+xml", "title" => $config->name)); if ($pagefeedurl != $feedurl) { $links[] = array("href" => $pagefeedurl, "type" => "application/atom+xml", "title" => "Current Page (if applicable)"); } # Ask modules to pitch in by adding their own <link> tag items to $links. # Each item must be an array with "href" and "rel" properties (and optionally "title" and "type"): Trigger::current()->filter($links, "links"); # Generate <link> tags: $tags = array(); foreach ($links as $link) { $rel = oneof(@$link["rel"], "alternate"); $href = $link["href"]; $type = @$link["type"]; $title = @$link["title"]; $tag = '<link rel="' . $rel . '" href="' . $link["href"] . '"'; if ($type) { $tag .= ' type="' . $type . '"'; } if ($title) { $tag .= ' title="' . $title . '"'; } $tags[] = $tag . ' />'; } return implode("\n\t", $tags); }
/** * Function: __get * Automatically handle model relationships when grabbing attributes of an object. * * Returns: * @mixed@ */ public function __get($name) { $model_name = get_class($this); $placeholders = (isset($this->__placeholders) and $this->__placeholders); Trigger::current()->filter($filtered, $model_name . "_" . $name . "_attr", $this); if ($filtered !== false) { $this->{$name} = $filtered; } $this->belongs_to = (array) $this->belongs_to; $this->has_many = (array) $this->has_many; $this->has_one = (array) $this->has_one; if (in_array($name, $this->belongs_to) or isset($this->belongs_to[$name])) { $class = isset($this->belongs_to[$name]) ? $this->belongs_to[$name] : $name; if (isset($this->belongs_to[$name])) { $opts =& $this->belongs_to[$name]; $model = oneof(@$opts["model"], $name); if (preg_match("/^\\(([a-z0-9_]+)\\)\$/", $model, $match)) { $model = $this->{$match}[1]; } $match = oneof(@$opts["by"], strtolower($name)); fallback($opts["where"], array("id" => $this->{$match . "_id"})); $opts["where"] = (array) $opts["where"]; foreach ($opts["where"] as &$val) { if (preg_match("/^\\(([a-z0-9_]+)\\)\$/", $val, $match)) { $val = $this->{$match}[1]; } } fallback($opts["placeholders"], $placeholders); } else { $model = $name; $opts = array("where" => array("id" => $this->{$name . "_id"})); } return $this->{$name} = new $model(null, $opts); } elseif (in_array($name, $this->has_many) or isset($this->has_many[$name])) { if (isset($this->has_many[$name])) { $opts =& $this->has_many[$name]; $model = oneof(@$opts["model"], depluralize($name)); if (preg_match("/^\\(([a-z0-9_]+)\\)\$/", $model, $match)) { $model = $this->{$match}[1]; } $match = oneof(@$opts["by"], strtolower($name)); fallback($opts["where"], array($match . "_id" => $this->id)); $opts["where"] = (array) $opts["where"]; foreach ($opts["where"] as &$val) { if (preg_match("/^\\(([a-z0-9_]+)\\)\$/", $val, $match)) { $val = $this->{$match}[1]; } } fallback($opts["placeholders"], $placeholders); } else { $model = depluralize($name); $match = $model_name; $opts = array("where" => array(strtolower($match) . "_id" => $this->id), "placeholders" => $placeholders); } return $this->{$name} = call_user_func(array($model, "find"), $opts); } elseif (in_array($name, $this->has_one) or isset($this->has_one[$name])) { if (isset($this->has_one[$name])) { $opts =& $this->has_one[$name]; $model = oneof(@$opts["model"], depluralize($name)); if (preg_match("/^\\(([a-z0-9_]+)\\)\$/", $model, $match)) { $model = $this->{$match}[1]; } $match = oneof(@$opts["by"], strtolower($name)); fallback($opts["where"], array($match . "_id" => $this->id)); $opts["where"] = (array) $opts["where"]; foreach ($opts["where"] as &$val) { if (preg_match("/^\\(([a-z0-9_]+)\\)\$/", $val, $match)) { $val = $this->{$match}[1]; } } } else { $model = depluralize($name); $match = $model_name; $opts = array("where" => array(strtolower($match) . "_id" => $this->id)); } return $this->{$name} = new $model(null, $opts); } if (isset($this->{$name})) { return $this->{$name}; } }
public function post_receive() { if (empty($_POST['payload'])) { exit("Empty payload."); } $json = json_decode($_POST['payload']); # Handle special keywords that stand for models. $targets = array("milestone" => array("Milestone", "name"), "owner" => array("User", "login"), "user" => array("User", "login")); foreach ($json->commits as $commit) { if (!preg_match("/\\[#[0-9]+(\\s[^\\]]+)?\\]/", $commit->message)) { continue; } $user = new User(array("email" => $commit->author->email)); $message = "Updated in commit [" . substr($commit->id, 0, 8) . "](" . $commit->url . "):\n\n" . $commit->message; preg_match_all("/\\[#([0-9]+)\\s?([^\\]]*)\\]/", $commit->message, $updates, PREG_SET_ORDER); foreach ($updates as $update) { $ticket = new Ticket($update[1], array("filter" => false)); if ($ticket->no_results) { continue; } preg_match_all("/([a-zA-Z]+):(\"([^\"]+)\"|([^ ]+))/", $update[2], $changes, PREG_SET_ORDER); $revchanges = array(); foreach ($changes as $change) { $attribute = $change[1]; $value = oneof($change[3], $change[4]); if (!in_array($attribute, array("title", "description", "state", "milestone", "owner", "user"))) { continue; } foreach ($targets as $name => $target) { if ($attribute == $name) { $model = $target[0]; if (is_numeric($value)) { $value = new $model($value); } else { $value = new $model(array($target[1] => $value)); } } } $revchanges[$attribute] = $value; } $fromto = array(); foreach ($revchanges as $attr => $val) { $old = @$ticket->{$attr}; $new = $val; foreach ($targets as $name => $target) { if ($attr == $name) { $old = $ticket->{$name}->{$target}[1]; $new = $val->{$target}[1]; } } $fromto[$attr] = array("from" => $old, "to" => $new); } $ticket->update(@$revchanges["title"], @$revchanges["description"], @$revchanges["state"], @$revchanges["milestone"], @$revchanges["owner"], @$revchanges["user"]); Revision::add($message, $fromto, $ticket, $user); } } }
public function title($post) { return oneof($post->title, $post->title_from_excerpt()); }
$type = $_POST['action'] == "disable_module" ? "module" : "feather"; if (!$visitor->group->can("change_settings")) { if ($type == "module") { exit("{ notifications: ['" . __("You do not have sufficient privileges to enable/disable modules.") . "'] }"); } else { exit("{ notifications: ['" . __("You do not have sufficient privileges to enable/disable feathers.") . "'] }"); } } if ($type == "module" and !module_enabled($_POST['extension']) or $type == "feather" and !feather_enabled($_POST['extension'])) { exit("{ notifications: [] }"); } $class_name = camelize($_POST["extension"]); if (method_exists($class_name, "__uninstall")) { call_user_func(array($class_name, "__uninstall"), $_POST['confirm'] == "1"); } $enabled_array = $type == "module" ? "enabled_modules" : "enabled_feathers"; $config->set($enabled_array, array_diff($config->{$enabled_array}, array($_POST['extension']))); exit('{ notifications: [] }'); break; case "reorder_feathers": $reorder = oneof(@$_POST['list'], $config->enabled_feathers); foreach ($reorder as &$value) { $value = preg_replace("/feathers\\[([^\\]]+)\\]/", "\\1", $value); } $config->set("enabled_feathers", $reorder); break; } $trigger->call("ajax"); if (!empty($_POST['action'])) { $trigger->call("ajax_" . $_POST['action']); }
/** * Function: update * Updates a post with the given attributes. * * Most of the function arguments will fall back to various POST values. * * Parameters: * $values - An array of data to set for the post. * $user - <User> to set as the post's author. * $pinned - Pin the post? * $status - Post status * $clean - A new clean URL for the post. * $url - A new URL for the post. * $created_at - New @created_at@ timestamp for the post. * $updated_at - New @updated_at@ timestamp for the post, or @false@ to not updated it. * $options - Options for the post. * * See Also: * <add> */ public function update($values = null, $user = null, $pinned = null, $status = null, $clean = null, $url = null, $created_at = null, $updated_at = null, $options = null) { if ($this->no_results) { return false; } $trigger = Trigger::current(); $user_id = $user instanceof User ? $user->id : $user; fallback($values, array_combine($this->attribute_names, $this->attribute_values)); fallback($user_id, oneof(@$_POST['user_id'], $this->user_id)); fallback($pinned, (int) (!empty($_POST['pinned']))); fallback($status, isset($_POST['draft']) ? "draft" : oneof(@$_POST['status'], $this->status)); fallback($clean, $this->clean); fallback($url, oneof(@$_POST['slug'], $this->feather . "." . $this->id)); fallback($created_at, !empty($_POST['created_at']) ? datetime($_POST['created_at']) : $this->created_at); fallback($updated_at, $updated_at === false ? $this->updated_at : oneof($updated_at, @$_POST['updated_at'], datetime())); fallback($options, oneof(@$_POST['option'], array())); if ($url != $this->url) { # If they edited the slug, the clean URL should change too. $clean = $url; } $old = clone $this; # Update all values of this post. foreach (array("user_id", "pinned", "status", "url", "created_at", "updated_at") as $attr) { $this->{$attr} = ${$attr}; } $new_values = array("pinned" => $pinned, "status" => $status, "clean" => $clean, "url" => $url, "created_at" => $created_at, "updated_at" => $updated_at); $trigger->filter($new_values, "before_update_post"); $sql = SQL::current(); $sql->update("posts", array("id" => $this->id), $new_values); # Insert the post attributes. foreach (array_merge($values, $options) as $name => $value) { if ($sql->count("post_attributes", array("post_id" => $this->id, "name" => $name))) { $sql->update("post_attributes", array("post_id" => $this->id, "name" => $name), array("value" => $this->{$name} = $value)); } else { $sql->insert("post_attributes", array("post_id" => $this->id, "name" => $name, "value" => $this->{$name} = $value)); } } $trigger->call("update_post", $this, $old, $options); }
{ if (!self::check($setting)) { return; } unset(Config::$yaml["config"][$setting]); $protection = "<?php header(\"Status: 403\"); exit(\"Access denied.\"); ?>\n"; $dump = $protection . YAML::dump(Config::$yaml["config"]); echo _f("Removing %s setting...", array($setting)) . test(@file_put_contents(INCLUDES_DIR . "/config.yaml.php", $dump)); } } if (using_yaml()) { Config::$yaml["config"] = YAML::load(preg_replace("/<\\?php(.+)\\?>\n?/s", "", file_get_contents(config_file()))); if (database_file()) { Config::$yaml["database"] = YAML::load(preg_replace("/<\\?php(.+)\\?>\n?/s", "", file_get_contents(database_file()))); } else { Config::$yaml["database"] = oneof(@Config::$yaml["config"]["sql"], array()); } } else { # $config and $sql here are loaded from the eval()'s above. foreach ($config as $name => $val) { Config::$yaml["config"][$name] = $val; } foreach ($sql as $name => $val) { Config::$yaml["database"][$name] = $val; } } load_translator("chyrp", INCLUDES_DIR . "/locale/" . Config::get("locale") . ".mo"); /** * Function: test * Attempts to perform a task, and displays a "success" or "failed" message determined by the outcome. *
/** * Send an email notice about bug aditions and edits * * @param * * @return void */ function mail_bug_updates($bug, $in, $from, $ncomment, $edit = 1, $id = false) { global $tla, $bug_types, $siteBig, $site_method, $site_url, $basedir; $text = array(); $headers = array(); $changed = bug_diff($bug, $in); $from = str_replace(array("\n", "\r"), '', $from); /* Default addresses */ list($mailto, $mailfrom, $Bcc, $params) = get_package_mail(oneof(@$in['package_name'], $bug['package_name']), $id, oneof(@$in['bug_type'], $bug['bug_type'])); $headers[] = array(' ID', $bug['id']); switch ($edit) { case 4: $headers[] = array(' Patch added by', $from); $from = "\"{$from}\" <{$mailfrom}>"; break; case 3: $headers[] = array(' Comment by', $from); $from = "\"{$from}\" <{$mailfrom}>"; break; case 2: $from = spam_protect(txfield('email', $bug, $in), 'text'); $headers[] = array(' User updated by', $from); $from = "\"{$from}\" <{$mailfrom}>"; break; default: $headers[] = array(' Updated by', $from); } $fields = array('email' => 'Reported by', 'sdesc' => 'Summary', 'status' => 'Status', 'bug_type' => 'Type', 'package_name' => 'Package', 'php_os' => 'Operating System', 'php_version' => 'PHP Version', 'assign' => 'Assigned To', 'block_user_comment' => 'Block user comment', 'private' => 'Private report', 'cve_id' => 'CVE-ID'); foreach ($fields as $name => $desc) { $prefix = ' '; if (isset($changed[$name])) { $headers[] = array("-{$desc}", $changed[$name]['from']); $prefix = '+'; } /* only fields that are set get added. */ if ($f = txfield($name, $bug, $in)) { if ($name == 'email') { $f = spam_protect($f, 'text'); } $foo = isset($changed[$name]['to']) ? $changed[$name]['to'] : $f; $headers[] = array($prefix . $desc, $foo); } } /* Make header output aligned */ $maxlength = 0; $actlength = 0; foreach ($headers as $v) { $actlength = strlen($v[0]) + 1; $maxlength = $maxlength < $actlength ? $actlength : $maxlength; } /* Align header content with headers (if a header contains more than one line, wrap it intelligently) */ $header_text = ''; $spaces = str_repeat(' ', $maxlength + 1); foreach ($headers as $v) { $hcontent = wordwrap($v[1], 72 - $maxlength, "\n{$spaces}"); // wrap and indent $hcontent = rtrim($hcontent); // wordwrap may add spacer to last line $header_text .= str_pad($v[0] . ':', $maxlength) . " {$hcontent}\n"; } if ($ncomment) { $ncomment = preg_replace('#<div class="changeset">(.*)</div>#sUe', "ltrim(strip_tags('\\1'))", $ncomment); $text[] = " New Comment:\n\n{$ncomment}"; } $old_comments = get_old_comments($bug['id'], empty($ncomment)); $old_comments = preg_replace('#<div class="changeset">(.*)</div>#sUe', "ltrim(strip_tags('\\1'))", $old_comments); $text[] = $old_comments; #$wrapped_text = wordwrap(join("\n", $text), 72); $wrapped_text = join("\n", $text); /* user text with attention, headers and previous messages */ $user_text = <<<USER_TEXT ATTENTION! Do NOT reply to this email! To reply, use the web interface found at {$site_method}://{$site_url}{$basedir}/bug.php?id={$bug['id']}&edit=2 {$header_text} {$wrapped_text} USER_TEXT; /* developer text with headers, previous messages, and edit link */ $dev_text = <<<DEV_TEXT Edit report at {$site_method}://{$site_url}{$basedir}/bug.php?id={$bug['id']}&edit=1 {$header_text} {$wrapped_text} -- Edit this bug report at {$site_method}://{$site_url}{$basedir}/bug.php?id={$bug['id']}&edit=1 DEV_TEXT; if (preg_match('/.*@php\\.net\\z/', $bug['email'])) { $user_text = $dev_text; } // Defaults $subj = $bug_types[$bug['bug_type']]; $sdesc = txfield('sdesc', $bug, $in); /* send mail if status was changed, there is a comment, private turned on/off or the bug type was changed to/from Security */ if (empty($in['status']) || $in['status'] != $bug['status'] || $ncomment != '' || isset($in['private']) && $in['private'] != $bug['private'] || isset($in['bug_type']) && $in['bug_type'] != $bug['bug_type'] && ($in['bug_type'] == 'Security' || $bug['bug_type'] == 'Security')) { if (isset($in['bug_type']) && $in['bug_type'] != $bug['bug_type']) { $subj = $bug_types[$bug['bug_type']] . '->' . $bug_types[$in['bug_type']]; } $old_status = $bug['status']; $new_status = $bug['status']; if (isset($in['status']) && $in['status'] != $bug['status'] && $edit != 3) { /* status changed */ $new_status = $in['status']; $subj .= " #{$bug['id']} [{$tla[$old_status]}->{$tla[$new_status]}]"; } elseif ($edit == 4) { /* patch */ $subj .= " #{$bug['id']} [PATCH]"; } elseif ($edit == 3) { /* comment */ $subj .= " #{$bug['id']} [Com]"; } else { /* status did not change and not comment */ $subj .= " #{$bug['id']} [{$tla[$bug['status']]}]"; } // the user gets sent mail with an envelope sender that ignores bounces bugs_mail($bug['email'], "{$subj}: {$sdesc}", $user_text, "From: {$siteBig} Bug Database <{$mailfrom}>\n" . "Bcc: {$Bcc}\n" . "X-PHP-Bug: {$bug['id']}\n" . "X-PHP-Site: {$siteBig}\n" . "In-Reply-To: <bug-{$bug['id']}@{$site_url}>"); // Spam protection $tmp = $edit != 3 ? $in : $bug; $tmp['new_status'] = $new_status; $tmp['old_status'] = $old_status; foreach (array('bug_type', 'php_version', 'package_name', 'php_os') as $field) { $tmp[$field] = strtok($tmp[$field], "\r\n"); } // but we go ahead and let the default sender get used for the list bugs_mail($mailto, "{$subj}: {$sdesc}", $dev_text, "From: {$from}\n" . "X-PHP-Bug: {$bug['id']}\n" . "X-PHP-Site: {$siteBig}\n" . "X-PHP-Type: {$tmp['bug_type']}\n" . "X-PHP-Version: {$tmp['php_version']}\n" . "X-PHP-Category: {$tmp['package_name']}\n" . "X-PHP-OS: {$tmp['php_os']}\n" . "X-PHP-Status: {$tmp['new_status']}\n" . "X-PHP-Old-Status: {$tmp['old_status']}\n" . "In-Reply-To: <bug-{$bug['id']}@{$site_url}>", $params); } /* if a developer assigns someone else, let that other person know about it */ if ($edit == 1 && $in['assign'] && $in['assign'] != $bug['assign']) { $email = $in['assign'] . '@php.net'; // If the developer assigns him self then skip if ($email == $from) { return; } bugs_mail($email, $subj . txfield('sdesc', $bug, $in), "{$in['assign']} you have just been assigned to this bug by {$from}\n\n{$dev_text}", "From: {$from}\n" . "X-PHP-Bug: {$bug['id']}\n" . "In-Reply-To: <bug-{$bug['id']}@{$site_url}>"); } }
/** * Function: update * Updates the topic. * * Parameters: * $title - The new title. * $description - The new description. */ public function update($title = null, $description = null, $forum = null, $user = null, $created_at = null, $updated_at = null) { if ($this->no_results) { return false; } $sql = SQL::current(); $trigger = Trigger::current(); $old = clone $this; foreach (array("title", "description", "forum_id", "user_id", "created_at", "updated_at") as $attr) { if (substr($attr, -3) == "_id") { $arg = ${substr($attr, 0, -3)}; $this->{$attr} = ${$attr} = oneof($arg instanceof Model ? $arg->id : $arg, $this->{$attr}); } elseif ($attr == "updated_at") { $this->{$attr} = ${$attr} = datetime(); } else { $this->{$attr} = ${$attr} = ${$attr} === null ? $this->{$attr} : ${$attr}; } } $sql->update("topics", array("id" => $this->id), array("title" => $title, "description" => $description, "forum_id" => $forum_id, "user_id" => $user_id, "created_at" => $created_at, "updated_at" => $updated_at)); if (module_enabled("cacher")) { Modules::$instances["cacher"]->regenerate(); } $trigger->call("update_topic", $this, $old); }
</textarea> </p> <p id="timezone_field"> <label for="timezone"><?php echo __("What time is it?"); ?> </label> <select name="timezone" id="timezone"> <?php foreach (timezones() as $zone) { ?> <option value="<?php echo $zone["name"]; ?> "<?php selected($zone["name"], oneof(@$_POST['timezone'], $default_timezone)); ?> > <?php echo strftime("%I:%M %p on %B %d, %Y", $zone["now"]); ?> — <?php echo str_replace(array("_", "St "), array(" ", "St. "), $zone["name"]); ?> </option> <?php } ?> </select> </p>
public function add_option($options, $post = null) { if (isset($post) and $post->feather != "photo") { return; } if (!isset($_GET['feather']) and Config::current()->enabled_feathers[0] != "photo" or isset($_GET['feather']) and $_GET['feather'] != "photo") { return; } $options[] = array("attr" => "option[alt_text]", "label" => __("Alt-Text", "photo"), "type" => "text", "value" => oneof(@$post->alt_text, "")); $options[] = array("attr" => "option[source]", "label" => __("Source", "photo"), "type" => "text", "value" => oneof(@$post->source, "")); $options[] = array("attr" => "from_url", "label" => __("From URL?", "photo"), "type" => "text"); return $options; }