function updatePage($page, $data) { $page = sqlescape($page); // Save the existing copy as a draft, remove drafts for this page that are one month old or older. $current = sqlfetch(sqlquery("SELECT * FROM bigtree_pages WHERE id = '{$page}'")); foreach ($current as $key => $val) { ${$key} = sqlescape($val); } // Figure out if we currently have a template that the user isn't allowed to use. If they do, we're not letting them change it. $template_data = BigTreeCMS::getTemplate($template); if (is_array($template_data) && $template_data["level"] > $this->Level) { $data["template"] = $template; } // Copy it to the saved versions sqlquery("INSERT INTO bigtree_page_revisions (`page`,`title`,`meta_keywords`,`meta_description`,`template`,`external`,`new_window`,`resources`,`author`,`updated_at`) VALUES ('{$page}','{$title}','{$meta_keywords}','{$meta_description}','{$template}','{$external}','{$new_window}','{$resources}','{$last_edited_by}','{$updated_at}')"); // Count the page revisions $r = sqlrows(sqlquery("SELECT id FROM bigtree_page_revisions WHERE page = '{$page}' AND saved = ''")); // If we have more than 10, delete any that are more than a month old if ($r > 10) { sqlquery("DELETE FROM bigtree_page_revisions WHERE updated_at < '" . date("Y-m-d", strtotime("-1 month")) . "' AND saved = ''"); } // Remove this page from the cache static::unCache($page); // Set local variables in a clean fashion that prevents _SESSION exploitation. Also, don't let them somehow overwrite $page and $current. foreach ($data as $key => $val) { if (substr($key, 0, 1) != "_" && $key != "current" && $key != "page") { if (is_array($val)) { ${$key} = BigTree::json($val, true); } else { ${$key} = sqlescape($val); } } } // Set the trunk flag back to the current value if the user isn't a developer if ($this->Level < 2) { $trunk = $current["trunk"]; } else { $trunk = sqlescape($data["trunk"]); } // If this is top level nav and the user isn't a developer, use what the current state is. if (!$current["parent"] && $this->Level < 2) { $in_nav = sqlescape($current["in_nav"]); } else { $in_nav = sqlescape($data["in_nav"]); } // Make an ipl:// or {wwwroot}'d version of the URL if ($external) { $external = static::makeIPL($external); } // If somehow we didn't provide a parent page (like, say, the user didn't have the right to change it) then pull the one from before. Actually, this might be exploitable… look into it later. if (!isset($data["parent"])) { $parent = $current["parent"]; } if ($page == 0) { // Home page doesn't get a route - fixes sitemap bug $route = ""; } else { // Create a route if we don't have one, otherwise, make sure the one they provided doesn't suck. $route = $data["route"]; if (!$route) { $route = BigTreeCMS::urlify($data["nav_title"]); } else { $route = BigTreeCMS::urlify($route); } // Get a unique route $oroute = $route; $x = 2; // Reserved paths. if ($parent == 0) { while (file_exists(SERVER_ROOT . "site/" . $route . "/")) { $route = $oroute . "-" . $x; $x++; } while (in_array($route, static::$ReservedTLRoutes)) { $route = $oroute . "-" . $x; $x++; } } // Existing pages. $f = sqlfetch(sqlquery("SELECT id FROM bigtree_pages WHERE `route` = '{$route}' AND parent = '{$parent}' AND id != '{$page}'")); while ($f) { $route = $oroute . "-" . $x; $f = sqlfetch(sqlquery("SELECT id FROM bigtree_pages WHERE `route` = '{$route}' AND parent = '{$parent}' AND id != '{$page}'")); $x++; } // Make sure route isn't longer than 255 $route = substr($route, 0, 255); } // We have no idea how this affects the nav, just wipe it all. if ($current["nav_title"] != $nav_title || $current["route"] != $route || $current["in_nav"] != $in_nav || $current["parent"] != $parent) { static::clearCache(); } // Make sure we set the publish date to NULL if it wasn't provided or we'll have a page that got published at 0000-00-00 if ($publish_at && $publish_at != "NULL") { $publish_at = "'" . date("Y-m-d", strtotime($publish_at)) . "'"; } else { $publish_at = "NULL"; } // If we set an expiration date, make it the proper MySQL format. if ($expire_at && $expire_at != "NULL") { $expire_at = "'" . date("Y-m-d", strtotime($expire_at)) . "'"; } else { $expire_at = "NULL"; } // Set the full path, saves DB access time on the front end. if ($parent > 0) { $path = static::getFullNavigationPath($parent) . "/" . $route; } else { $path = $route; } // htmlspecialchars stuff so that it doesn't need to be re-encoded when echo'd on the front end. $title = htmlspecialchars($title); $nav_title = htmlspecialchars($nav_title); $meta_description = htmlspecialchars($meta_description); $meta_keywords = htmlspecialchars($meta_keywords); $seo_invisible = $data["seo_invisible"] ? "on" : ""; $external = htmlspecialchars($external); // Update the database sqlquery("UPDATE bigtree_pages SET `trunk` = '{$trunk}', `parent` = '{$parent}', `nav_title` = '{$nav_title}', `route` = '{$route}', `path` = '{$path}', `in_nav` = '{$in_nav}', `title` = '{$title}', `template` = '{$template}', `external` = '{$external}', `new_window` = '{$new_window}', `resources` = '{$resources}', `meta_keywords` = '{$meta_keywords}', `meta_description` = '{$meta_description}', `seo_invisible` = '{$seo_invisible}', `last_edited_by` = '" . $this->ID . "', updated_at = NOW(), publish_at = {$publish_at}, expire_at = {$expire_at}, max_age = '{$max_age}' WHERE id = '{$page}'"); // Remove any pending drafts sqlquery("DELETE FROM bigtree_pending_changes WHERE `table` = 'bigtree_pages' AND item_id = '{$page}'"); // Remove old paths from the redirect list sqlquery("DELETE FROM bigtree_route_history WHERE old_route = '{$path}' OR old_route = '" . $current["path"] . "'"); // Create an automatic redirect from the old path to the new one. if ($current["path"] != $path) { sqlquery("INSERT INTO bigtree_route_history (`old_route`,`new_route`) VALUES ('" . $current["path"] . "','{$path}')"); // Update all child page routes, ping those engines, clean those caches static::updateChildPagePaths($page); static::pingSearchEngines(); static::clearCache(); } // Handle tags sqlquery("DELETE FROM bigtree_tags_rel WHERE `table` = 'bigtree_pages' AND entry = '{$page}'"); if (is_array($data["_tags"])) { foreach ($data["_tags"] as $tag) { sqlquery("INSERT INTO bigtree_tags_rel (`table`,`entry`,`tag`) VALUES ('bigtree_pages','{$page}','{$tag}')"); } } // Audit trail. $this->track("bigtree_pages", $page, "updated"); return $page; }
static function getAvailableFileName($directory, $file, $prefixes = array()) { $parts = static::pathInfo($directory . $file); // Clean up the file name $clean_name = BigTreeCMS::urlify($parts["filename"]); if (strlen($clean_name) > 50) { $clean_name = substr($clean_name, 0, 50); } $file = $clean_name . "." . strtolower($parts["extension"]); // Just find a good filename that isn't used now. $x = 2; while (!$file || file_exists($directory . $file)) { $file = $clean_name . "-{$x}." . strtolower($parts["extension"]); // Check prefixes foreach ($prefixes as $prefix) { if (file_exists($directory . $prefix . $file)) { $file = false; } } $x++; } return $file; }