示例#1
0
 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");
 }
示例#2
0
 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");
 }
示例#3
0
 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");
 }
示例#4
0
 /**
  * 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;
 }
示例#5
0
    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>';
                }
            }
        }
    }
示例#6
0
 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);
 }