public function delete($id) { // login check - if fail, return no data to stop error flagging to user if ((int) $this->check_access() < 8) { $this->response(null, null, 401); } if (!is_numeric($id)) { $this->response(null, null, 400); } $db = new RazorDB(); // delete page $db->connect("page"); $db->delete_rows(array("column" => "id", "value" => (int) $id)); $db->disconnect(); // remove any page_content items $db->connect("page_content"); $db->delete_rows(array("column" => "page_id", "value" => (int) $id)); $db->disconnect(); // remove any menu_items $db->connect("menu_item"); $db->delete_rows(array("column" => "page_id", "value" => (int) $id)); $db->disconnect(); // return the basic user details $this->response("success", "json"); }
public function get($id) { $db = new RazorDB(); $db->connect("content"); // set options $options = array("order" => array("column" => "id", "direction" => "desc")); $search = array("column" => "id", "value" => null, "not" => true); $content = $db->get_rows($search, $options); $content = $content["result"]; $db->disconnect(); // now get all page content so we can show what pages are using this content $db->connect("page_content"); $options = array("join" => array("table" => "page", "join_to" => "page_id")); $search = array("column" => "id", "value" => null, "not" => true); $page_content = $db->get_rows($search, $options); $page_content = $page_content["result"]; $db->disconnect(); foreach ($content as $key => $row) { foreach ($page_content as $pc) { if ($row["id"] == $pc["content_id"]) { if (!isset($content[$key]["used_on_pages"])) { $content[$key]["used_on_pages"] = array(); } $content[$key]["used_on_pages"][$pc["page_id"]] = array("id" => $pc["page_id"], "name" => $pc["page_id.name"], "link" => $pc["page_id.link"]); } } } // return the basic user details $this->response(array("content" => $content), "json"); }
public function post($data) { // no email if (empty($data["email"])) { $this->response("User not found", "json", 404); } // try find user $db = new RazorDB(); $db->connect("user"); $options = array("amount" => 1); $search = array("column" => "email_address", "value" => $data["email"]); $user = $db->get_rows($search); $db->disconnect(); // check for match if ($user["count"] != 1) { $this->response("User not found", "json", 404); } // check attempts $user = $user["result"][0]; if ($user["reminder_time"] > time() - 600) { $this->response("Only one password request allowed per hour", "json", 401); } /* Match found, attempts good, carry on */ // now we will store token and send it via email $user_agent = $_SERVER["HTTP_USER_AGENT"]; $ip_address = $_SERVER["REMOTE_ADDR"]; $pass_hash = $user["password"]; $reminder_time = time(); $reminder_token = sha1($reminder_time . $user_agent . $ip_address . $pass_hash); // set new reminder $db->connect("user"); $search = array("column" => "id", "value" => $user["id"]); $row = array("reminder_token" => $reminder_token, "reminder_time" => $reminder_time); $db->edit_rows($search, $row); $db->disconnect(); // email user pasword reset email $server_email = str_replace("www.", "", $_SERVER["SERVER_NAME"]); $reminder_link = RAZOR_BASE_URL . "admin#/password-reset/{$reminder_token}_{$user["id"]}"; $message = <<<EOT <html> <head> <title>razorCMS - Password Reset</title> </head> <body> <h1>Reset your razorCMS Account Password</h1> <p>This email address has requested a password reset for the account on razorCMS ({$_SERVER["SERVER_NAME"]}). If this was not you that requested this, please ignore this email and the password reset will expire in 1 hour.</p> <p>If you did request this, then you can reset your password using the link below.</p> <a href="{$reminder_link}">{$reminder_link}</a> </body> </html> EOT; $this->email("no-reply@{$server_email}", $user["email_address"], "razorCMS Account Password Reset", $message); $this->response("success", "json"); }
public function post($data) { // login check - if fail, return no data to stop error flagging to user if ((int) $this->check_access() < 6) { $this->response(null, null, 401); } if (empty($data)) { $this->response(null, null, 400); } $db = new RazorDB(); $db->connect("page"); // check link unique $options = array("amount" => 1); $search = array("column" => "link", "value" => isset($data["link"]) ? $data["link"] : ""); $count = $db->get_rows($search, $options); if ($count["count"] > 0) { $this->response(array("error" => "duplicate link found", "code" => 101), 'json', 409); } // copy the page $row = array("name" => $data["name"], "title" => $data["title"], "link" => $data["link"], "keywords" => $data["keywords"], "description" => $data["description"], "access_level" => (int) $data["access_level"], "theme" => $data["theme"], "json_settings" => $data["json_settings"], "active" => false); $new_page = $db->add_rows($row); $db->disconnect(); if ($new_page["count"] != 1) { $this->response(null, null, 400); } // next lets get all the page content for page we are copying $db->connect("page_content"); $search = array("column" => "page_id", "value" => $data["id"]); $page_content = $db->get_rows($search); // now copy if any found if ($page_content["count"] > 0) { $new_rows = array(); foreach ($page_content["result"] as $row) { $new_row = array(); foreach ($row as $key => $col) { if ($key == "id") { continue; } else { if ($key == "page_id") { $new_row[$key] = $new_page["result"][0]["id"]; } else { $new_row[$key] = $col; } } } $new_rows[] = $new_row; } $db->add_rows($new_rows); } $db->disconnect(); // return the basic page details $this->response($new_page["result"][0], "json"); }
public function post($data) { // no email if (empty($data["email"])) { $this->response("User not found", "json", 404); } // try find user $db = new RazorDB(); $db->connect("user"); $options = array("amount" => 1); $search = array("column" => "email_address", "value" => $data["email"]); $user = $db->get_rows($search); $db->disconnect(); // check for match if ($user["count"] != 1) { $this->response("User not found", "json", 404); } // check attempts $user = $user["result"][0]; if ($user["reminder_time"] > time() - 600) { $this->response("Only one password request allowed per hour", "json", 401); } /* Match found, attempts good, carry on */ // now we will store token and send it via email $user_agent = $_SERVER["HTTP_USER_AGENT"]; $ip_address = $_SERVER["REMOTE_ADDR"]; $pass_hash = $user["password"]; $reminder_time = time(); $reminder_token = sha1($reminder_time . $user_agent . $ip_address . $pass_hash); // set new reminder $db->connect("user"); $search = array("column" => "id", "value" => $user["id"]); $row = array("reminder_token" => $reminder_token, "reminder_time" => $reminder_time); $db->edit_rows($search, $row); $db->disconnect(); // get setting $db->connect("setting"); $setting = $db->get_rows(array("column" => "name", "value" => "forgot_password_email")); $forgot_password_email = $setting["result"][0]["value"]; $db->disconnect(); // email user pasword reset email $server_email = str_replace("www.", "", $_SERVER["SERVER_NAME"]); $reminder_link = RAZOR_BASE_URL . "login#/password-reset/{$reminder_token}_{$user["id"]}"; // email text replacement $search = array("**server_name**", "**user_email**", "**forgot_password_link**"); $replace = array($_SERVER["SERVER_NAME"], $user["email_address"], $reminder_link); $message = str_replace($search, $replace, $forgot_password_email); $this->email("no-reply@{$server_email}", $user["email_address"], "{$_SERVER["SERVER_NAME"]} Account Password Reset", $message); $this->response("success", "json"); }
public function post($ext) { if ((int) $this->check_access() < 9) { $this->response(null, null, 401); } if (empty($ext)) { $this->response(null, null, 400); } $settings = array(); foreach ($ext["settings"] as $set) { $settings[$set["name"]] = $set["value"]; } $db = new RazorDB(); $db->connect("extension"); $options = array("amount" => 1); $search = array(array("column" => "extension", "value" => $ext["extension"]), array("column" => "type", "value" => $ext["type"]), array("column" => "handle", "value" => $ext["handle"])); $extension = $db->get_rows($search, $options); if ($extension["count"] == 1) { $db->edit_rows($search, array("json_settings" => json_encode($settings))); } else { // add new $row = array("extension" => $ext["extension"], "type" => $ext["type"], "handle" => $ext["handle"], "json_settings" => json_encode($settings), "user_id" => $this->user["id"], "access_level" => 0); $db->add_rows($row); } $db->disconnect(); $this->response("success", "json"); }
public function get($id) { if ((int) $this->check_access() < 6) { $this->response(null, null, 401); } $db = new RazorDB(); // get menu data too $db->connect("setting"); $res = $db->get_rows(array("column" => "id", "value" => null, "not" => true)); $db->disconnect(); $settings = array(); foreach ($res["result"] as $result) { switch ($result["type"]) { case "bool": $settings[$result["name"]] = (bool) $result["value"]; break; case "int": $settings[$result["name"]] = (int) $result["value"]; break; default: $settings[$result["name"]] = (string) $result["value"]; break; } } // return the basic user details $this->response(array("settings" => $settings), "json"); }
public function post($data) { // login check - if fail, return no data to stop error flagging to user if ((int) $this->check_access() < 10) { $this->response(null, null, 401); } if (empty($data)) { $this->response(null, null, 400); } $db = new RazorDB(); $db->connect("user"); // check link unique $search = array("column" => "id", "value" => $this->user["id"]); $row = array("name" => $data["name"], "email_address" => $data["email_address"]); if (isset($data["new_password"])) { $row["password"] = $this->create_hash($data["new_password"]); } $db->edit_rows($search, $row); $db->disconnect(); // return the basic user details if (isset($data["new_password"])) { $this->response(array("reload" => true), "json"); } $this->response("success", "json"); }
public function post($data) { // check present, token ok, password and password confirm ok if (!isset($data["token"], $data["passwords"]["password"], $data["passwords"]["repeat_password"])) { $this->response("Bad data", null, 400); } if (empty($data["token"]) || strlen($data["token"]) < 20) { $this->response("Bad data", null, 400); } if (empty($data["passwords"]["password"]) || empty($data["passwords"]["repeat_password"]) || $data["passwords"]["password"] !== $data["passwords"]["repeat_password"]) { $this->response("Bad data", null, 400); } $token_data = explode("_", $data["token"]); if (count($token_data) != 2 || empty($token_data[0]) || empty($token_data[1])) { $this->response("Bad data", null, 400); } /* data present and pre check good, lets do a user search and check */ // try find user $db = new RazorDB(); $db->connect("user"); $search = array("column" => "id", "value" => (int) $token_data[1]); $user = $db->get_rows($search); $db->disconnect(); // no valid user found if ($user["count"] != 1) { $this->response("Bad data", null, 400); } $user = $user["result"][0]; // check token if (empty($user["reminder_token"]) || $token_data[0] != $user["reminder_token"] || $user["reminder_time"] + 3600 < time()) { $this->response("Bad data", null, 400); } /* user ok, token ok, lets change password */ $password = RazorAPI::create_hash($data["passwords"]["password"]); // set new reminder $db->connect("user"); $search = array("column" => "id", "value" => $user["id"]); $row = array("password" => $password, "reminder_token" => ""); $db->edit_rows($search, $row); $db->disconnect(); $this->response("success", "json"); }
public function get($id) { $db = new RazorDB(); $db->connect("page"); $search = array("column" => "id", "value" => null, "not" => true); $pages = $db->get_rows($search); $pages = $pages["result"]; $db->disconnect(); // return the basic user details $this->response(array("pages" => $pages), "json"); }
public function get($page_id) { $db = new RazorDB(); // get menu data too $db->connect("site"); $search = array("column" => "id", "value" => 1); $site = $db->get_rows($search); $site = $site["result"][0]; $db->disconnect(); // return the basic user details $this->response(array("site" => $site), "json"); }
public function get($id) { if ((int) $this->check_access() < 10) { $this->response(null, null, 401); } $db = new RazorDB(); $db->connect("user"); // set options $options = array("filter" => array("id", "name", "email_address", "access_level", "active", "ip_address", "last_logged_in")); $search = array("column" => "id", "value" => null, "not" => true); $user = $db->get_rows($search, $options); $db->disconnect(); // return the basic user details $this->response(array("users" => $user["result"]), "json"); }
public function get($id) { if ((int) $this->check_access() < 6) { $this->response(null, null, 401); } if (empty($id)) { $this->response(null, null, 400); } // get menu data too $db = new RazorDB(); $db->connect("system"); $search = array("column" => "id", "value" => 1); $system = $db->get_rows($search); $system = $system["result"][0]; $db->disconnect(); $this->response(array("system" => $system), "json"); }
public function post($data) { // login check - if fail, return no data to stop error flagging to user if ((int) $this->check_access() < 10) { $this->response(null, null, 401); } if (empty($data)) { $this->response(null, null, 400); } // update content $db = new RazorDB(); $db->connect("page"); // set options $search = array("column" => "id", "value" => $data["id"]); // ensure we only have changes we want $changes = array("active" => $data["active"], "name" => $data["name"], "title" => $data["title"], "link" => $data["link"], "theme" => $data["theme"], "keywords" => $data["keywords"], "description" => $data["description"]); $db->edit_rows($search, $changes); $db->disconnect(); // return the basic user details $this->response($data, "json"); }
public function post($data) { // login check - if fail, return no data to stop error flagging to user if ((int) $this->check_access() < 10) { $this->response(null, null, 401); } if (empty($data)) { $this->response(null, null, 400); } $db = new RazorDB(); $db->connect("site"); $search = array("column" => "id", "value" => 1); $row = array(); if (isset($data["name"])) { $row["name"] = $data["name"]; } if (isset($data["google_analytics_code"])) { $row["google_analytics_code"] = $data["google_analytics_code"]; } $db->edit_rows($search, $row); $db->disconnect(); $this->response("success", "json"); }
public function get($id) { if (strlen($id) < 20) { $this->response("Activation key not set", 400); } $db = new RazorDB(); $db->connect("user"); $search = array("column" => "activate_token", "value" => $id); $user = $db->get_rows($search); if ($user["count"] != 1) { $this->response(null, null, 409); } // now we know token is ok, lets activate user // set new reminder $search = array("column" => "id", "value" => $user["result"][0]["id"]); $row = array("activate_token" => null, "active" => true); $db->edit_rows($search, $row); $db->disconnect(); // if all ok, redirect to login page and set activate message off $redirect = RAZOR_BASE_URL . "login#/user-activated"; header("Location: {$redirect}"); exit; }
public function check_access($access_timeout = RARS_ACCESS_TIMEOUT) { // retrieve token from incoming request $token = isset($_SERVER["HTTP_AUTHORIZATION"]) ? $_SERVER["HTTP_AUTHORIZATION"] : (isset($_SERVER["REDIRECT_HTTP_AUTHORIZATION"]) ? $_SERVER["REDIRECT_HTTP_AUTHORIZATION"] : (isset($_COOKIE["token"]) ? $_COOKIE["token"] : null)); if (empty($token)) { return false; } // extract token and id $token_data = explode("_", $token); if (count($token_data) != 2) { return false; } $token = preg_replace("/[^a-zA-Z0-9]/", '', $token_data[0]); $id = (int) $token_data[1]; // find user $db = new RazorDB(); $db->connect("user"); $search = array("column" => "id", "value" => $id); $options = array("amount" => 1); $res = $db->get_rows($search, $options); $db->disconnect(); // no user found or no access in XXX seconds if ($res["count"] != 1) { return false; } $user = $res["result"][0]; if ($user["last_accessed"] < time() - $access_timeout) { return false; } /* all ok, so go verify user */ // need to create a token and last logged stamp $last_logged = $user["last_logged_in"]; $user_agent = preg_replace("/[^0-9a-zA-Z.:;-_]/", '', substr($_SERVER["HTTP_USER_AGENT"], 0, 250)); $ip_address = preg_replace("/[^0-9.]/", '', substr($_SERVER["REMOTE_ADDR"], 0, 50)); $pass_hash = $user["password"]; $gen_token = sha1($last_logged . $user_agent . $ip_address . $pass_hash); if ($gen_token !== $token) { return false; } // set user and return $this->user = array("id" => $user["id"], "name" => $user["name"], "email_address" => $user["email_address"], "last_logged_in" => $user["last_logged_in"], "access_level" => $user["access_level"]); // update access time to keep connection alive, only do this once an hour to keep writes to db down for user table // connection will stay live for a day anyway so we do not need to be this heavy on the last access time writes if ($user["last_accessed"] > time() - 3600) { return $this->user["access_level"]; } $db = new RazorDB(); $db->connect("user"); $search = array("column" => "id", "value" => $this->user["id"]); $changes = array("last_accessed" => time()); $db->edit_rows($search, $changes); $db->disconnect(); return $this->user["access_level"]; }
public function post($data) { // login check - if fail, return no data to stop error flagging to user if ((int) $this->check_access() < 10) { $this->response(null, null, 401); } if (!isset($data["content"])) { $this->response(null, null, 400); } // update content $db = new RazorDB(); $db->connect("content"); // update or add content $new_content_map = array(); foreach ($data["content"] as $key => $content) { if (!isset($content["content_id"]) || !isset($content["content"]) || empty($content["content"])) { unset($data["content"][$key]); continue; } if (stripos($content["content_id"], "new-") === false) { // update $search = array("column" => "id", "value" => $content["content_id"]); $db->edit_rows($search, array("content" => $content["content"], "name" => $content["name"])); } else { // add new content and map the ID to the new id for locations table $row = array("content" => $content["content"], "name" => $content["name"]); $result = $db->add_rows($row); $new_content_map[$content["content_id"]] = $result["result"][0]["id"]; } } $db->disconnect(); // update or add locations $db = new RazorDB(); $db->connect("page_content"); // 1. first take snapshot of current $search = array("column" => "page_id", "value" => (int) $data["page_id"]); $current_page_content = $db->get_rows($search); $current_page_content = $current_page_content["result"]; // 2. iterate through updating or adding, make a note of all id's $page_content_map = array(); foreach ($data["locations"] as $location => $columns) { foreach ($columns as $column => $blocks) { foreach ($blocks as $pos => $block) { if ($block["id"] != "new") { // update $search = array("column" => "id", "value" => $block["id"]); $row = array("location" => $location, "column" => (int) $column, "position" => $pos + 1, "json_settings" => json_encode($block["settings"])); if (isset($block["extension"])) { $row["extension"] = $block["extension"]; } $db->edit_rows($search, $row); $page_content_map[] = $block["id"]; } else { // add new, if new, add, if new but already present add, else add as ext $new_content_id = isset($block["content_id"], $new_content_map[$block["content_id"]]) ? $new_content_map[$block["content_id"]] : (isset($block["content_id"]) && is_numeric($block["content_id"]) ? $block["content_id"] : null); if (!empty($new_content_id) || isset($block["extension"])) { $row = array("page_id" => (int) $data["page_id"], "content_id" => $new_content_id, "location" => $location, "column" => (int) $column, "position" => $pos + 1); if (isset($block["extension"])) { $row["extension"] = $block["extension"]; $row["json_settings"] = isset($block["settings"]) ? json_encode($block["settings"]) : null; } $result = $db->add_rows($row); $page_content_map[] = $result["result"][0]; } } } } } // 3. run through id's affected against snapshot, if any missing, remove them. foreach ($current_page_content as $row) { if (!in_array($row["id"], $page_content_map)) { $db->delete_rows(array("column" => "id", "value" => (int) $row["id"])); } } $db->disconnect(); // return the basic user details $this->response("success", "json"); }
public function get($type) { if ((int) $this->check_access() < 10) { $this->response(null, null, 401); } if (empty($type) || !in_array($type, $this->types)) { $this->response(null, null, 400); } // first scan the folders for manifests $manifests = RazorFileTools::find_file_contents(RAZOR_BASE_PATH . "extension", "manifest.json", "json", "end"); // split into types, so we can filter a little $extensions = array(); $db = new RazorDB(); $db->connect("extension"); foreach ($manifests as $mf) { $mf->created = date("D jS M Y", $mf->created); // grab settings if any if (isset($mf->settings)) { $options = array("amount" => 1); $search = array(array("column" => "extension", "value" => $mf->extension), array("column" => "type", "value" => $mf->type), array("column" => "handle", "value" => $mf->handle)); $extension = $db->get_rows($search, $options); if ($extension["count"] == 1) { $db_settings = json_decode($extension["result"][0]["json_settings"]); foreach ($mf->settings as $key => $setting) { if (isset($db_settings->{$setting->name})) { $mf->settings[$key]->value = $db_settings->{$setting->name}; } } } } // sort list if ($mf->type == $type) { if ($mf->type == "theme") { // group manifest layouts for themes if (!isset($extensions[$mf->type . $mf->handle . $mf->extension])) { $extensions[$mf->type . $mf->handle . $mf->extension] = array("layouts" => array(), "type" => $mf->type, "handle" => $mf->handle, "description" => $mf->description, "name" => $mf->name); } $extensions[$mf->type . $mf->handle . $mf->extension]["layouts"][] = $mf; } else { $extensions[] = $mf; } } else { if ($type == "system" && $mf->type != "theme") { $extensions[] = $mf; } else { if ($type == "all") { $mf->type = ucfirst($mf->type); if ($mf->type == "Theme") { // group manifest layouts for themes if (!isset($extensions[$mf->type . $mf->handle . $mf->extension])) { $extensions[$mf->type . $mf->handle . $mf->extension] = array("layouts" => array(), "type" => $mf->type, "handle" => $mf->handle, "extension" => $mf->extension, "description" => $mf->description, "name" => $mf->name); } $extensions[$mf->type . $mf->handle . $mf->extension]["layouts"][] = $mf; } else { $extensions[] = $mf; } } } } } // ensure we have array return and not object $extensions = array_values($extensions); $db->disconnect(); $this->response(array("extensions" => $extensions), "json"); }
public function post($data) { // login check - if fail, return no data to stop error flagging to user if ((int) $this->check_access() < 10) { $this->response(null, null, 401); } // menu item $db = new RazorDB(); $db->connect("menu_item"); // 1. grab all menus in position order $options = array("order" => array("column" => "position", "direction" => "asc")); $search = array("column" => "id", "not" => true, "value" => null); $all_menu_items = $db->get_rows($search, $options); $all_menu_items = $all_menu_items["result"]; // 2. make flat arrays $new_menus_flat = array(); foreach ($data as $menu) { // set up menu item arrays if (!isset($new_menus_flat[$menu["id"]])) { $new_menus_flat[$menu["id"]] = array(); } foreach ($menu["menu_items"] as $mi) { if (isset($mi["id"])) { $new_menus_flat[$menu["id"]][] = $mi["id"]; } if (isset($mi["sub_menu"]) & !empty($mi["sub_menu"])) { foreach ($mi["sub_menu"] as $sub_menu_item) { if (isset($sub_menu_item["id"])) { $new_menus_flat[$menu["id"]][] = $sub_menu_item["id"]; } } } } } $current_menus_flat = array(); foreach ($all_menu_items as $ami) { // set up menu item arrays if (!isset($current_menus_flat[$ami["menu_id"]])) { $current_menus_flat[$ami["menu_id"]] = array(); } $current_menus_flat[$ami["menu_id"]][] = $ami["id"]; // at same time remove any items missing if (!in_array($ami["id"], $new_menus_flat[$ami["menu_id"]])) { $db->delete_rows(array("column" => "id", "value" => (int) $ami["id"])); } } // 3. update all of sent menu data, by looping through the new $data foreach ($data as $new_menu) { $pos = 1; // each menu foreach ($new_menu["menu_items"] as $nmi) { if (isset($nmi["id"]) && in_array($nmi["id"], $current_menus_flat[$new_menu["id"]])) { // update menu item $search = array("column" => "id", "value" => $nmi["id"]); $db->edit_rows($search, array("position" => $pos)); } else { // add new item $row = array("menu_id" => (int) $new_menu["id"], "position" => $pos, "level" => 1, "page_id" => $nmi["page_id"], "link_id" => 0); $db->add_rows($row); } $pos++; // now check for sub menu if (isset($nmi["sub_menu"]) && !empty($nmi["sub_menu"])) { foreach ($nmi["sub_menu"] as $nsmi) { if (isset($nsmi["id"]) && in_array($nsmi["id"], $current_menus_flat[$new_menu["id"]])) { // update menu item $search = array("column" => "id", "value" => $nsmi["id"]); $db->edit_rows($search, array("position" => $pos)); } else { // add new item $row = array("menu_id" => (int) $new_menu["id"], "position" => $pos, "level" => 2, "page_id" => $nsmi["page_id"], "link_id" => 0); $db->add_rows($row); } $pos++; } } } } $db->disconnect(); $this->response("success", "json"); }
private function get_content_data() { // if no page found, end here if (empty($this->page)) { return; } // grab all content $db = new RazorDB(); $db->connect("page_content"); // set options $options = array("order" => array("column" => "position", "direction" => "asc")); $search = array("column" => "page_id", "value" => $this->page["id"]); $content = $db->get_rows($search, $options); $this->content = $content["result"]; $db->disconnect(); }
/** * Get rows from search * * Fetch all the rows found from a search on a columns * Using extra parameters you can specify, not, wildcard, case insensitive as well as specify how to use one search with another (default is or) * @param array $search Search [column => string, value => mixed[, not => bool, and => bool, case_insensitive => bool, wildcard => bool]] * @param array $options Any options to use ['filter': array['col1', 'col2'...], 'amount': int, 'join': array['table' => string, 'join_to' => string]] multiple joins can be added to array, all joins are inner * @return mixed The data in array format ('table' => 'name, 'count' => resultCount, 'result' => rows(('col' => 'val',...)) or false on fail */ public function get_rows($search, $options = null) { // check connected if (!$this->connected) { trigger_error("Not connected to table, cannot perform query"); return false; } // resolve table name and file $time = microtime(true); // options $amount = isset($options['amount']) ? $options['amount'] : null; $filter = isset($options['filter']) ? $options['filter'] : null; $joins = isset($options['join']) ? $options['join'] : null; $order = isset($options['order']) ? $options['order'] : null; // get table headers if (empty($this->columns)) { if (!$this->headers()) { return false; } } // check for single or multi array if (isset($search['column'])) { $search = array($search); } foreach ($search as $search_data) { if (!isset($search_data['column'])) { trigger_error("'column' not provided in search"); return false; } if (!isset($this->columns[$search_data['column']])) { trigger_error("Column '{$search_data['column']}' does not exist in table '{$this->table}'"); return false; } } // resolve join data if ($joins !== null) { if (isset($joins['table'])) { $joins = array($joins); } foreach ($joins as $join_data) { // check all join data present if (!isset($join_data['table']) || !isset($join_data['join_to'])) { trigger_error("Join needs 'table', 'join_to' in order to join a table"); return false; } // check join table exists if (!is_file(RAZOR_BASE_PATH . "storage/database/{$join_data['table']}.db.php")) { // return error on non bad con trigger_error("Cannot join table '{$join_data['table']}', table does not exist"); return false; } // check join_to column exists in parent table if (!isset($this->columns[$join_data['join_to']])) { trigger_error("Cannot join to column '{$join_data['join_to']}' in parent table '{$this->table}', column does not exist"); return false; } } } // open and move pointer to beginning $this->open(); // work out how many markers to use and size (16ms without prequery on test3) $markers_amount = (int) round($this->row_count / 150); if ($markers_amount < 1) { $markers_amount = 1; } fseek($this->handle, 0, SEEK_END); $size = ftell($this->handle); $marker_size = round($size / $markers_amount); fseek($this->handle, 0, SEEK_SET); // perform query $matches = array(); $cpq = 0; // skip headers stream_get_line($this->handle, 2048, "--- end headers ---\n"); while (!feof($this->handle)) { // read in block, if not first, clean up to first \n $pq_cache = stream_get_line($this->handle, $marker_size); if ($cpq > 0) { if (($find_me = strpos($pq_cache, "\n")) === false) { break; } // no more complete lines left $pq_cache = substr($pq_cache, $find_me + 1); // clean up to first \n } $cpq++; // cache file pointer $pre_query_position = ftell($this->handle); // read in to next \n to finish line off (at least a meg) $pq_cache .= stream_get_line($this->handle, 1049000, "\n"); // rewind file pointer fseek($this->handle, $pre_query_position, SEEK_SET); // send pq cache off for pre-query if ($this->pre_query($pq_cache, $search) !== false) { // if match, iterate over $pq_cache, maybe explode it by \n and query each value $rows = explode("\n", $pq_cache); foreach ($rows as $row_data) { // Check row data if (substr($row_data, 3, 4) !== 'row:') { trigger_error("Failed to read line in '{$this->table}' db file, db file corrupt"); return false; } // query further $match = $this->query($row_data, $search, true); // filter if (!empty($match)) { // collate join data for search later if ($joins !== null) { $j = 0; foreach ($joins as $join) { $joins[$j]['join_data'][$match[$join['join_to']]] = array('column' => 'id', 'value' => $match[$join['join_to']]); $j++; } } // filter out any cols do not want in results if (!empty($filter)) { foreach ($match as $match_col => $match_value) { if (is_string($filter) && $match_col !== $filter || is_array($filter) && !in_array($match_col, $filter)) { unset($match[$match_col]); } } } $matches[] = $match; } // collect correct amount of rows if ($amount !== null && count($matches) >= $amount) { $result = array('table' => $this->table, 'count' => count($matches), 'time' => microtime(true) - $time, 'result' => $matches); return $result; } } } } $this->close(); // perform any join searchs now if ($joins !== null) { foreach ($joins as $join) { $join_ob = new RazorDB('razor_db:join:' . $this->table . '>' . $join['table']); if (!$join_ob->connect($join['table'])) { trigger_error("Failed to join table '{$join['table']}' omitting this data from results"); continue; } // no join data found, skip this join if (!isset($join['join_data'])) { continue; } $found = $join_ob->get_rows($join['join_data']); // attach data to matches foreach ($matches as $key => $match) { if ($found['count'] > 0) { foreach ($found['result'] as $found_result) { if ($match[$join['join_to']] === $found_result['id']) { foreach ($found_result as $col => $val) { $matches[$key][$join['join_to'] . '.' . $col] = $val; } } } } else { // no results so no match unset($matches[$key]); } } $join_ob->disconnect(); } } // sort results if (!empty($order)) { $this->order = $order; usort($matches, array($this, 'sort')); } $result = array('table' => $this->table, 'count' => count($matches), 'time' => microtime(true) - $time, 'result' => $matches, 'order' => $order); return $result; }
public function post($data) { // are we accepting registrations $db = new RazorDB(); // get menu data too $db->connect("setting"); $allow = $db->get_rows(array("column" => "name", "value" => "allow_registration")); $manual = $db->get_rows(array("column" => "name", "value" => "manual_activation")); $registration_email = $db->get_rows(array("column" => "name", "value" => "registration_email")); $activation_email = $db->get_rows(array("column" => "name", "value" => "activation_email")); $activate_user_email = $db->get_rows(array("column" => "name", "value" => "activate_user_email")); $db->disconnect(); if (!isset($allow["result"][0]["value"]) || !$allow["result"][0]["value"]) { $this->response(null, null, 405); } // verify form is coming from site and that human has sent it // Check details if (!isset($_SERVER["REMOTE_ADDR"], $_SERVER["HTTP_USER_AGENT"], $_SERVER["HTTP_REFERER"], $_SESSION["signature"])) { $this->response(null, null, 400); } if (empty($_SERVER["REMOTE_ADDR"]) || empty($_SERVER["HTTP_USER_AGENT"]) || empty($_SERVER["HTTP_REFERER"]) || empty($_SESSION["signature"])) { $this->response(null, null, 400); } // check referer matches the site if (strpos($_SERVER["HTTP_REFERER"], RAZOR_BASE_URL) !== 0) { $this->response(null, null, 400); } // check data if (!isset($data["signature"], $data["name"], $data["email_address"], $data["new_password"])) { $this->response(null, null, 400); } if (empty($data["signature"]) || empty($data["name"]) || empty($data["email_address"]) || empty($data["new_password"])) { $this->response(null, null, 400); } if (!isset($data["human"]) || !empty($data["human"])) { $this->response("robot", "json", 406); } // get signature and compare to session if ($_SESSION["signature"] !== $data["signature"]) { $this->response(null, null, 400); } unset($_SESSION["signature"]); session_destroy(); // now we know registrations allowed, form came from website etc so lets check email unique and proceed with adding user $db->connect("user"); // check email is unique $search = array("column" => "email_address", "value" => $data["email_address"]); $user = $db->get_rows($search); if ($user["count"] > 0) { $this->response(null, null, 409); } // create new user $password = $this->create_hash($data["new_password"]); $row = array("name" => $data["name"], "email_address" => $data["email_address"], "access_level" => 1, "active" => false, "password" => $this->create_hash($data["new_password"])); $activate_link = ""; if (!$manual["result"][0]["value"]) { $activate_token = sha1($_SERVER["HTTP_USER_AGENT"] . $_SERVER["REMOTE_ADDR"] . $password); $row["activate_token"] = $activate_token; $activate_link = RAZOR_BASE_URL . "rars/user/activate/{$activate_token}"; } $db->add_rows($row); $db->disconnect(); $server_email = str_replace("www.", "", $_SERVER["SERVER_NAME"]); // email text replacement $search = array("**server_name**", "**user_email**", "**activation_link**"); $replace = array($_SERVER["SERVER_NAME"], $data["email_address"], $activate_link); if ($manual["result"][0]["value"]) { // send notifcation of registration and activation is manual to user $message1 = str_replace($search, $replace, $registration_email["result"][0]["value"]); $this->email("no-reply@{$server_email}", $data["email_address"], "{$_SERVER["SERVER_NAME"]} Account Registered", $message1); // send notifcation to super admin email that someone has registered and needs activation $db->connect("user"); $res = $db->get_rows(array("column" => "id", "value" => 1)); $super_email = $res["result"][0]["email_address"]; $db->disconnect(); $message2 = str_replace($search, $replace, $activate_user_email["result"][0]["value"]); $this->email("no-reply@{$server_email}", $super_email, "{$_SERVER["SERVER_NAME"]} Account Registered", $message2); } else { $message3 = str_replace($search, $replace, $activation_email["result"][0]["value"]); $this->email("no-reply@{$server_email}", $data["email_address"], "{$_SERVER["SERVER_NAME"]} Account Activation", $message3); } $this->response(array("manual_activation" => $manual["result"][0]["value"]), "json"); }
public function delete($id) { // check we have a logged in user if ((int) $this->check_access() < 1) { $this->response(null, null, 401); } if (empty($id)) { $this->response(null, null, 400); } if ($id == 1) { $this->response(null, null, 400); } $id = (int) $id; $db = new RazorDB(); $db->connect("user"); if ($this->user["id"] == $id) { // this is your account, allow removal of own account $search = array("column" => "id", "value" => $this->user["id"]); $db->delete_rows($search); $response = "reload"; } elseif ($this->check_access() == 10) { // if not account owner, but acces of 10, can remove account $search = array("column" => "id", "value" => $id); $db->delete_rows($search); $response = "success"; } else { $this->response(null, null, 401); } $db->disconnect(); $this->response($response, "json"); }
public function post($data) { // login check - if fail, return no data to stop error flagging to user if ((int) $this->check_access() < 9) { $this->response(null, null, 401); } if (empty($data)) { $this->response(null, null, 400); } $db = new RazorDB(); $db->connect("setting"); if (isset($data["name"])) { $search = array("column" => "name", "value" => "name"); $res = $db->edit_rows($search, array("value" => $data["name"])); if ($res["count"] == 0) { $db->add_rows(array("name" => "name", "value" => (string) $data["name"], "type" => "string")); } } if (isset($data["google_analytics_code"])) { $search = array("column" => "name", "value" => "google_analytics_code"); $res = $db->edit_rows($search, array("value" => $data["google_analytics_code"])); if ($res["count"] == 0) { $db->add_rows(array("name" => "google_analytics_code", "value" => (string) $data["google_analytics_code"], "type" => "string")); } } if (isset($data["forgot_password_email"])) { $search = array("column" => "name", "value" => "forgot_password_email"); $res = $db->edit_rows($search, array("value" => (string) $data["forgot_password_email"])); if ($res["count"] == 0) { $db->add_rows(array("name" => "forgot_password_email", "value" => (string) $data["forgot_password_email"], "type" => "string")); } } if (isset($data["allow_registration"])) { $search = array("column" => "name", "value" => "allow_registration"); $res = $db->edit_rows($search, array("value" => (string) $data["allow_registration"])); if ($res["count"] == 0) { $db->add_rows(array("name" => "allow_registration", "value" => (string) $data["allow_registration"], "type" => "bool")); } } if (isset($data["manual_activation"])) { $search = array("column" => "name", "value" => "manual_activation"); $res = $db->edit_rows($search, array("value" => (string) $data["manual_activation"])); if ($res["count"] == 0) { $db->add_rows(array("name" => "manual_activation", "value" => (string) $data["manual_activation"], "type" => "bool")); } } if (isset($data["registration_email"])) { $search = array("column" => "name", "value" => "registration_email"); $res = $db->edit_rows($search, array("value" => (string) $data["registration_email"])); if ($res["count"] == 0) { $db->add_rows(array("name" => "registration_email", "value" => (string) $data["registration_email"], "type" => "string")); } } if (isset($data["activation_email"])) { $search = array("column" => "name", "value" => "activation_email"); $res = $db->edit_rows($search, array("value" => (string) $data["activation_email"])); if ($res["count"] == 0) { $db->add_rows(array("name" => "activation_email", "value" => (string) $data["activation_email"], "type" => "string")); } } if (isset($data["activate_user_email"])) { $search = array("column" => "name", "value" => "activate_user_email"); $res = $db->edit_rows($search, array("value" => (string) $data["activate_user_email"])); if ($res["count"] == 0) { $db->add_rows(array("name" => "activate_user_email", "value" => (string) $data["activate_user_email"], "type" => "string")); } } if (isset($data["cookie_message"])) { $search = array("column" => "name", "value" => "cookie_message"); $res = $db->edit_rows($search, array("value" => (string) $data["cookie_message"])); if ($res["count"] == 0) { $db->add_rows(array("name" => "cookie_message", "value" => (string) $data["cookie_message"], "type" => "string")); } } if (isset($data["cookie_message_button"])) { $search = array("column" => "name", "value" => "cookie_message_button"); $res = $db->edit_rows($search, array("value" => (string) $data["cookie_message_button"])); if ($res["count"] == 0) { $db->add_rows(array("name" => "cookie_message_button", "value" => (string) $data["cookie_message_button"], "type" => "string")); } } $db->disconnect(); $this->response("success", "json"); }
public function post($data) { // Check details if (!isset($_SERVER["REMOTE_ADDR"], $_SERVER["HTTP_USER_AGENT"], $_SERVER["HTTP_REFERER"], $_SESSION["signature"])) { $this->response(null, null, 400); } if (empty($_SERVER["REMOTE_ADDR"]) || empty($_SERVER["HTTP_USER_AGENT"]) || empty($_SERVER["HTTP_REFERER"]) || empty($_SESSION["signature"])) { $this->response(null, null, 400); } // check referer matches the site if (strpos($_SERVER["HTTP_REFERER"], RAZOR_BASE_URL) !== 0) { $this->response(null, null, 400); } // check data if (!isset($data["signature"], $data["email"], $data["message"], $data["extension"]["type"], $data["extension"]["handle"], $data["extension"]["extension"])) { $this->response(null, null, 400); } if (empty($data["signature"]) || empty($data["email"]) || empty($data["message"]) || empty($data["extension"]["type"]) || empty($data["extension"]["handle"]) || empty($data["extension"]["extension"])) { $this->response(null, null, 400); } if (!isset($data["human"]) || !empty($data["human"])) { $this->response("robot", "json", 406); } // get signature and compare to session if ($_SESSION["signature"] !== $data["signature"]) { $this->response(null, null, 400); } unset($_SESSION["signature"]); session_destroy(); // create manifest path for extension that requested email $ext_type = preg_replace('/[^A-Za-z0-9-]/', '', $data["extension"]["type"]); $ext_handle = preg_replace('/[^A-Za-z0-9-]/', '', $data["extension"]["handle"]); $ext_extension = preg_replace('/[^A-Za-z0-9-]/', '', $data["extension"]["extension"]); $manifest_path = RAZOR_BASE_PATH . "extension/{$ext_type}/{$ext_handle}/{$ext_extension}/{$ext_extension}.manifest.json"; if (!is_file($manifest_path)) { $this->response(null, null, 400); } $manifest = RazorFileTools::read_file_contents($manifest_path, "json"); // fetch extension settings and look for email $db = new RazorDB(); $db->connect("extension"); $options = array("amount" => 1, "filter" => array("json_settings")); $search = array(array("column" => "type", "value" => $manifest->type), array("column" => "handle", "value" => $manifest->handle), array("column" => "extension", "value" => $manifest->extension)); $extension_settings = $db->get_rows($search, $options); $extension_settings = $extension_settings["result"][0]["json_settings"]; $db->disconnect(); if (empty($extension_settings)) { $this->response(null, null, 400); } $extension_settings = json_decode($extension_settings); // get site data $db->connect("setting"); $res = $db->get_rows(array("column" => "id", "value" => null, "not" => true)); $db->disconnect(); $settings = array(); foreach ($res["result"] as $result) { switch ($result["type"]) { case "bool": $settings[$result["name"]] = (bool) $result["value"]; break; case "int": $settings[$result["name"]] = (int) $result["value"]; break; default: $settings[$result["name"]] = (string) $result["value"]; break; } } // clean email data $to = $extension_settings->email; $from = preg_replace('/[^A-Za-z0-9-_+@.]/', '', $data["email"]); $subject = "{$settings["name"]} Contact Form"; $message = htmlspecialchars($data["message"], ENT_QUOTES); // send to email response $this->email($from, $to, $subject, $message); // return the basic user details $this->response("success", "json"); }
public function get($phrase) { if (empty($phrase)) { $this->response(null, null, 400); } // search database and use scoring system to order. need to do pagination somehow $db = new RazorDB(); // first break the search data down into searchable chunks $words = explode(' ', $phrase); // find page ids matching query results $db->connect('page'); $options = array('filter' => array('id')); $search = array(); foreach ($words as $word) { $search[] = array('column' => 'title', 'value' => $word, 'case_insensitive' => true, 'wildcard' => true); $search[] = array('column' => 'description', 'value' => $word, 'case_insensitive' => true, 'wildcard' => true); $search[] = array('column' => 'keywords', 'value' => $word, 'case_insensitive' => true, 'wildcard' => true); } $pages = $db->get_rows($search); $db->disconnect(); // find content ids matching query results $db->connect('content'); $options = array('filter' => array('id')); $search = array(); foreach ($words as $word) { $search[] = array('column' => 'content', 'value' => $word, 'case_insensitive' => true, 'wildcard' => true); } $content = $db->get_rows($search); $db->disconnect(); // find page and content from IDs if ($content['count'] > 0 || $pages['count'] > 0) { $db->connect('page_content'); $options = array('join' => array(array('table' => 'content', 'join_to' => 'content_id'), array('table' => 'page', 'join_to' => 'page_id')), 'filter' => array('id', 'page_id', 'content_id', 'page_id.title', 'page_id.description', 'page_id.keywords', 'content_id.content', 'page_id.link', 'page_id.name')); $search = array(); foreach ($content['result'] as $row) { $search[] = array('column' => 'content_id', 'value' => $row['id']); } foreach ($pages['result'] as $row) { $search[] = array('column' => 'page_id', 'value' => $row['id']); } $page_content = $db->get_rows($search, $options); $db->disconnect(); } if (!isset($page_content) || $page_content['count'] < 1) { $this->response(null, null, 404); } /* We now have a collection of all matches */ // loop through results working out scoring, removing duplicates $matches = array(); foreach ($page_content['result'] as $pc) { // capture page for results and set page score once if (!isset($matches[$pc['page_id']])) { $matches[$pc['page_id']] = $pc; $matches[$pc['page_id']]['score'] = $this->get_page_score($pc, $phrase); } // work out content score each content on page $matches[$pc['page_id']]['score'] += $this->get_content_score($pc, $phrase); } // present the results as an array sorted by score usort($matches, array('self', 'sort_score')); $this->response(array('results' => $matches), 'json'); }