public function get($page_id) { $query = 'SELECT a.*' . ", b.id AS 'content.id'" . ", b.name AS 'content.name'" . ", b.content AS 'content.content'" . ' FROM page_content AS a' . ' LEFT JOIN content AS b ON a.content_id = b.id' . ' WHERE a.page_id = :page_id' . ' ORDER BY a.position ASC'; $data = $this->razor_db->query_all($query, array('page_id' => $page_id)); $content = array(); $locations = array(); foreach ($data as $row) { if (!empty($row["content.id"])) { $content[$row['content.id']] = array("content_id" => $row["content.id"], "name" => $row["content.name"], "content" => $row["content.content"]); } $location_data = array("id" => $row["id"], "content_id" => $row["content_id"], "extension" => $row["extension"], "settings" => json_decode($row["json_settings"])); if (!empty($row["extension"])) { $manifest = RazorFileTools::read_file_contents(RAZOR_BASE_PATH . "extension/{$row['extension']}", "json"); if (isset($manifest->content_settings) && !empty($manifest->content_settings)) { // create object if (!is_object($location_data["settings"])) { $location_data["settings"] = new stdClass(); } // copy settings $location_data["extension_content_settings"] = $manifest->content_settings; // if no settings present, add defaults from manifest foreach ($manifest->content_settings as $cs) { if (!isset($location_data["settings"]->{$cs->name})) { $location_data["settings"]->{$cs->name} = $cs->value; } } } } $locations[$row["location"]][$row["column"]][] = $location_data; } // return the basic user details $this->response(array("content" => $content, "locations" => $locations), "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"); // grab contact form settings $where = array("type" => $manifest->type, "handle" => $manifest->handle, "extension" => $manifest->extension); $extension = $this->razor_db->get_first('extension', array('json_settings'), $where); if (empty($extension)) { $this->response(null, null, 400); } $extension_settings = json_decode($extension['json_settings']); // fetch extension settings and look for email $where = array(array("type" => $manifest->type), array("handle" => $manifest->handle), array("extension" => $manifest->extension)); $site = $this->razor_db->get_first('setting', array('value'), array('name' => 'name')); $site_name = json_decode($site['value']); // clean email data $to = $extension_settings->email; $from = preg_replace('/[^A-Za-z0-9-_+@.]/', '', $data["email"]); $subject = "{$site_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($page_id) { // go through all changes and update all $db = new RazorDB(); $db->connect("page_content"); // set options $options = array("order" => array("column" => "position", "direction" => "asc")); $search = array("column" => "page_id", "value" => (int) $page_id); $page_contents = $db->get_rows($search, $options); $page_contents = $page_contents["result"]; $db->disconnect(); // split into content and locations $db->connect("content"); $content = array(); $locations = array(); foreach ($page_contents as $row) { if (!empty($row["content_id"])) { $options = array("limit" => 1); $search = array("column" => "id", "value" => (int) $row["content_id"]); $found_content = $db->get_rows($search, $options); $found_content = $found_content["result"][0]; $content[$found_content["id"]] = array("content_id" => $found_content["id"], "name" => $found_content["name"], "content" => $found_content["content"]); } $location_data = array("id" => $row["id"], "content_id" => $row["content_id"], "extension" => $row["extension"], "settings" => json_decode($row["json_settings"])); if (!empty($row["extension"])) { $manifest = RazorFileTools::read_file_contents(RAZOR_BASE_PATH . "extension/{$row['extension']}", "json"); if (isset($manifest->content_settings) && !empty($manifest->content_settings)) { // create object if (!is_object($location_data["settings"])) { $location_data["settings"] = new stdClass(); } // copy settings $location_data["extension_content_settings"] = $manifest->content_settings; // if no settings present, add defaults from manifest foreach ($manifest->content_settings as $cs) { if (!isset($location_data["settings"]->{$cs->name})) { $location_data["settings"]->{$cs->name} = $cs->value; } } } } $locations[$row["location"]][$row["column"]][] = $location_data; } $db->disconnect(); // return the basic user details $this->response(array("content" => $content, "locations" => $locations), "json"); }
/** * Look through json files for a matching keys value, only checks top level keys * * @param string $path The file to search * @param array $search The values to find [["key" => string, "search" => string],[]...] */ public static function select_from_json_php_file($path, $search_array) { if (isset($search_array["key"])) { $search_array = array($search_array); } $data = RazorFileTools::read_file_contents($path, "json.php"); if (empty($data)) { return; } $match = array(); foreach ($data as $row) { $match_count = 0; foreach ($search_array as $search) { if (!isset($row->{$search}["key"]) || $row->{$search}["key"] != $search["search"]) { continue; } $match_count++; } if ($match_count == count($search_array)) { $match[] = $row; } } return $match; }
public function content($loc, $col) { // create extension dependancy list $ext_dep_list = array(); // admin angluar loading for editor, return if (isset($_GET["edit"]) && ($this->logged_in > 6 || $this->logged_in > 5 && !$this->page["active"])) { //<div text-angular name="{$loc}{$col}{{block.content_id}}" ng-if="!block.extension" ta-disabled="!editingThis('{$loc}{$col}' + block.content_id)" class="content-edit" ng-model="content[block.content_id].content" ng-click="startBlockEdit('{$loc}{$col}', block.content_id)" ></div> echo <<<OUTPUT <div class="content-column" ng-if="changed" ng-class="{'edit': toggle}"> \t<div class="content-block" ng-class="{'active': editingThis('{$loc}{$col}' + block.content_id)}" ng-repeat="block in locations.{$loc}.{$col}"> \t\t<div class="input-group block-controls" ng-if="!block.extension"> \t\t\t<span class="input-group-btn"> \t\t\t\t<button class="btn btn-default" ng-click="locations.{$loc}.{$col}.splice(\$index - 1, 0, locations.{$loc}.{$col}.splice(\$index, 1)[0])" ng-show="toggle"><i class="fa fa-arrow-up"></i></button> \t\t\t\t<button class="btn btn-default" ng-click="locations.{$loc}.{$col}.splice(\$index + 1, 0, locations.{$loc}.{$col}.splice(\$index, 1)[0])" ng-show="toggle"><i class="fa fa-arrow-down"></i></button> \t\t\t</span> \t\t\t<input type="text" class="form-control" placeholder="Add Content Name" ng-show="toggle" ng-model="content[block.content_id].name"/> \t\t\t<span class="input-group-btn"> \t\t\t\t<button class="btn btn-warning" ng-show="toggle" ng-click="removeContent('{$loc}', '{$col}', \$index)"><i class="fa fa-times"></i></button> \t\t\t</span> \t\t</div> \t\t<div id="{$loc}{$col}{{block.content_id}}" ng-if="!block.extension" class="content-edit" ng-click="startBlockEdit('{$loc}{$col}', block.content_id)" ng-bind-html="content[block.content_id].content | html"></div> \t\t<div class="content-settings" ng-if="block.extension"> \t\t\t<div class="extension-controls"> \t\t\t\t<span class="btn-group pull-left"> \t\t\t\t\t<button class="btn btn-default" ng-click="locations.{$loc}.{$col}.splice(\$index - 1, 0, locations.{$loc}.{$col}.splice(\$index, 1)[0])" ng-show="toggle"><i class="fa fa-arrow-up"></i></button> \t\t\t\t\t<button class="btn btn-default" ng-click="locations.{$loc}.{$col}.splice(\$index + 1, 0, locations.{$loc}.{$col}.splice(\$index, 1)[0])" ng-show="toggle"><i class="fa fa-arrow-down"></i></button> \t\t\t\t</span> \t\t\t\t<h3 class="extension-title pull-left"><i class="fa fa-puzzle-piece"></i> Extension</h3> \t\t\t\t<button class="btn btn-warning pull-right" ng-show="toggle" ng-click="removeContent('{$loc}', '{$col}', \$index)"><i class="fa fa-times"></i></button> \t\t\t</div> \t\t\t<form class="form-horizontal" role="form" name="form" novalidate> \t\t\t\t<div class="form-group"> \t\t\t\t\t<label class="col-sm-3 control-label">Type</label> \t\t\t\t\t<div class="col-sm-7"> \t\t\t\t\t\t<input type="text" class="form-control" value="{{block.extension.split('/')[0]}}" disabled> \t\t\t\t\t</div> \t\t\t\t</div> \t\t\t\t<div class="form-group"> \t\t\t\t\t<label class="col-sm-3 control-label">Handle</label> \t\t\t\t\t<div class="col-sm-7"> \t\t\t\t\t\t<input type="text" class="form-control" value="{{block.extension.split('/')[1]}}" disabled> \t\t\t\t\t</div> \t\t\t\t</div> \t\t\t\t<div class="form-group"> \t\t\t\t\t<label class="col-sm-3 control-label">Extension</label> \t\t\t\t\t<div class="col-sm-7"> \t\t\t\t\t\t<input type="text" class="form-control" value="{{block.extension.split('/')[2]}}" disabled> \t\t\t\t\t</div> \t\t\t\t</div> \t\t\t\t<div class="form-group" ng-if="block.extension_content_settings[0]"> \t\t\t\t\t<label class="col-sm-3 control-label">{{block.extension_content_settings[0].label}}</label> \t\t\t\t\t<div class="col-sm-7"> \t\t\t\t\t\t<input type="text" class="form-control" placeholder="{{block.extension_content_settings[0].placeholder}}" name="input0" ng-model="block.settings[block.extension_content_settings[0].name]" ng-pattern="{{block.extension_content_settings[0].regex}}" > \t\t\t\t\t</div> \t\t\t\t\t<div class="col-sm-2 error-block" ng-show="form.input0.\$dirty && form.input0.\$invalid"> \t\t\t\t\t\t<span class="alert alert-danger alert-form" ng-show="form.input0.\$error.pattern">Invalid</span> \t\t\t\t\t</div> \t\t\t\t</div> \t\t\t\t<div class="form-group" ng-if="block.extension_content_settings[1]"> \t\t\t\t\t<label class="col-sm-3 control-label">{{block.extension_content_settings[1].label}}</label> \t\t\t\t\t<div class="col-sm-7"> \t\t\t\t\t\t<input type="text" class="form-control" placeholder="{{block.extension_content_settings[1].placeholder}}" name="input1" ng-model="block.settings[block.extension_content_settings[1].name]" ng-pattern="{{block.extension_content_settings[1].regex}}" > \t\t\t\t\t</div> \t\t\t\t\t<div class="col-sm-2 error-block" ng-show="form.input1.\$dirty && form.input1.\$invalid"> \t\t\t\t\t\t<span class="alert alert-danger alert-form" ng-show="form.input1.\$error.pattern">Invalid</span> \t\t\t\t\t</div> \t\t\t\t</div> \t\t\t\t<div class="form-group" ng-if="block.extension_content_settings[2]"> \t\t\t\t\t<label class="col-sm-3 control-label">{{block.extension_content_settings[2].label}}</label> \t\t\t\t\t<div class="col-sm-7"> \t\t\t\t\t\t<input type="text" class="form-control" placeholder="{{block.extension_content_settings[2].placeholder}}" name="input2" ng-model="block.settings[block.extension_content_settings[2].name]" ng-pattern="{{block.extension_content_settings[2].regex}}" > \t\t\t\t\t</div> \t\t\t\t\t<div class="col-sm-2 error-block" ng-show="form.input2.\$dirty && form.input2.\$invalid"> \t\t\t\t\t\t<span class="alert alert-danger alert-form" ng-show="form.input2.\$error.pattern">Invalid</span> \t\t\t\t\t</div> \t\t\t\t</div> \t\t\t\t<div class="form-group" ng-if="block.extension_content_settings[3]"> \t\t\t\t\t<label class="col-sm-3 control-label">{{block.extension_content_settings[3].label}}</label> \t\t\t\t\t<div class="col-sm-7"> \t\t\t\t\t\t<input type="text" class="form-control" placeholder="{{block.extension_content_settings[3].placeholder}}" name="input3" ng-model="block.settings[block.extension_content_settings[3].name]" ng-pattern="{{block.extension_content_settings[3].regex}}" > \t\t\t\t\t</div> \t\t\t\t\t<div class="col-sm-2 error-block" ng-show="form.input3.\$dirty && form.input3.\$invalid"> \t\t\t\t\t\t<span class="alert alert-danger alert-form" ng-show="form.input3.\$error.pattern">Invalid</span> \t\t\t\t\t</div> \t\t\t\t</div> \t\t\t\t<div class="form-group" ng-if="block.extension_content_settings[4]"> \t\t\t\t\t<label class="col-sm-3 control-label">{{block.extension_content_settings[4].label}}</label> \t\t\t\t\t<div class="col-sm-7"> \t\t\t\t\t\t<input type="text" class="form-control" placeholder="{{block.extension_content_settings[4].placeholder}}" name="input4" ng-model="block.settings[block.extension_content_settings[4].name]" ng-pattern="{{block.extension_content_settings[4].regex}}" > \t\t\t\t\t</div> \t\t\t\t\t<div class="col-sm-2 error-block" ng-show="form.input4.\$dirty && form.input4.\$invalid"> \t\t\t\t\t\t<span class="alert alert-danger alert-form" ng-show="form.input4.\$error.pattern">Invalid</span> \t\t\t\t\t</div> \t\t\t\t</div> \t\t\t\t<div class="form-group" ng-if="block.extension_content_settings[5]"> \t\t\t\t\t<label class="col-sm-3 control-label">{{block.extension_content_settings[5].label}}</label> \t\t\t\t\t<div class="col-sm-7"> \t\t\t\t\t\t<input type="text" class="form-control" placeholder="{{block.extension_content_settings[5].placeholder}}" name="input5" ng-model="block.settings[block.extension_content_settings[5].name]" ng-pattern="{{block.extension_content_settings[5].regex}}" > \t\t\t\t\t</div> \t\t\t\t\t<div class="col-sm-2 error-block" ng-show="form.input5.\$dirty && form.input5.\$invalid"> \t\t\t\t\t\t<span class="alert alert-danger alert-form" ng-show="form.input5.\$error.pattern">Invalid</span> \t\t\t\t\t</div> \t\t\t\t</div> \t\t\t\t<div class="form-group" ng-if="block.extension_content_settings[6]"> \t\t\t\t\t<label class="col-sm-3 control-label">{{block.extension_content_settings[6].label}}</label> \t\t\t\t\t<div class="col-sm-7"> \t\t\t\t\t\t<input type="text" class="form-control" placeholder="{{block.extension_content_settings[6].placeholder}}" name="input6" ng-model="block.settings[block.extension_content_settings[6].name]" ng-pattern="{{block.extension_content_settings[6].regex}}" > \t\t\t\t\t</div> \t\t\t\t\t<div class="col-sm-2 error-block" ng-show="form.input6.\$dirty && form.input6.\$invalid"> \t\t\t\t\t\t<span class="alert alert-danger alert-form" ng-show="form.input6.\$error.pattern">Invalid</span> \t\t\t\t\t</div> \t\t\t\t</div> \t\t\t\t<div class="form-group" ng-if="block.extension_content_settings[7]"> \t\t\t\t\t<label class="col-sm-3 control-label">{{block.extension_content_settings[7].label}}</label> \t\t\t\t\t<div class="col-sm-7"> \t\t\t\t\t\t<input type="text" class="form-control" placeholder="{{block.extension_content_settings[7].placeholder}}" name="input7" ng-model="block.settings[block.extension_content_settings[7].name]" ng-pattern="{{block.extension_content_settings[7].regex}}" > \t\t\t\t\t</div> \t\t\t\t\t<div class="col-sm-2 error-block" ng-show="form.input7.\$dirty && form.input7.\$invalid"> \t\t\t\t\t\t<span class="alert alert-danger alert-form" ng-show="form.input7.\$error.pattern">Invalid</span> \t\t\t\t\t</div> \t\t\t\t</div> \t\t\t</form>\t \t\t</div> \t</div> \t<button class="btn btn-default" ng-show="toggle" ng-click="addNewBlock('{$loc}', '{$col}')"><i class="fa fa-plus"></i></button> \t<button class="btn btn-default" ng-show="toggle" ng-click="findBlock('{$loc}', '{$col}')"><i class="fa fa-search"></i></button> \t<button class="btn btn-default" ng-show="toggle" ng-click="findExtension('{$loc}', '{$col}')"><i class="fa fa-puzzle-piece"></i></button> </div> OUTPUT; return; } $db = new RazorDB(); // if not editor and not empty, output content for public foreach ($this->content as $c_data) { if ($c_data["location"] == $loc && $c_data["column"] == $col) { if (!empty($c_data["content_id"])) { // load content echo '<div ng-if="!changed" content-id="' . $c_data["content_id"] . '">'; $db->connect("content"); $search = array("column" => "id", "value" => $c_data["content_id"]); $content = $db->get_rows($search); $content = $content["result"][0]; $db->disconnect(); echo str_replace("\\n", "", $content["content"]); echo '</div>'; } elseif (!empty($c_data["extension"])) { // load extension $manifest = RazorFileTools::read_file_contents(RAZOR_BASE_PATH . "extension/{$c_data['extension']}", "json"); $view_path = RAZOR_BASE_PATH . "extension/{$manifest->type}/{$manifest->handle}/{$manifest->extension}/view/{$manifest->view}.php"; echo '<div ng-if="!changed">'; include $view_path; echo '</div>'; } } } }
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"); }
/** * Log Error * Log the error to log file * * @param array $error Error data array * @param string $log_book The log book to write to * @return bool False on fail */ private function log_error($error, $log_book = 'razor-error-log') { if (empty($error)) { return false; } // get file contents $log = array(); if (is_file(RAZOR_BASE_PATH . "storage/log/{$log_book}.php")) { $log = RazorFileTools::read_file_contents(RAZOR_BASE_PATH . "storage/log/{$log_book}.php", 'array'); } // set date time $date_time = @date('d m Y - h:i:s', time()); $entry = "<?php /* [{$date_time}] [{$error['error']}]"; $entry .= isset($error['type']) ? " [type: {$error['type']}]" : ""; $entry .= isset($error['file']) ? " [file: {$error['file']}]" : ""; $entry .= isset($error['line']) ? " [line: {$error['line']}]" : ""; $entry .= " [message: {$error['string']}] */ ?>\n\r"; $log[] = $entry; if (count($log) > 100) { array_shift($log); } $log_string = implode('', $log); if (!is_dir(RAZOR_BASE_PATH . 'storage/log')) { mkdir(RAZOR_BASE_PATH . 'storage/log'); } RazorFileTools::write_file_contents(RAZOR_BASE_PATH . "storage/log/{$log_book}.php", $log_string); }