From 5bfe7ea5458e6c9243df914b0cf1b5c981aa9249 Mon Sep 17 00:00:00 2001 From: xevidos Date: Sun, 7 Apr 2019 20:58:53 -0400 Subject: [PATCH] Continued work on sql library, started refactor of install process to support new library. --- common.php | 26 ++- components/active/init.js | 5 + components/filemanager/init.js | 4 + components/install/install.php | 264 ++++++++++++++++++++++- components/install/view.php | 10 +- components/settings/class.settings.php | 5 - components/settings/init.js | 13 ++ components/sql/class.sql.conversions.php | 191 +++++++++++++--- components/sql/class.sql.php | 21 +- 9 files changed, 497 insertions(+), 42 deletions(-) diff --git a/common.php b/common.php index 8d3ba9e..404414e 100755 --- a/common.php +++ b/common.php @@ -559,12 +559,32 @@ class Common { public static function checkPath( $path ) { global $sql; - $query = "SELECT * FROM projects WHERE LOCATE( path, ? ) > 0 LIMIT 1;"; - $bind_variables = array( $path ); - $result = $sql->query( $query, $bind_variables, array() )[0]; + //$query = "SELECT * FROM projects WHERE LOCATE( path, ? ) > 0 LIMIT 1;"; + //$bind_variables = array( $path ); + //$result = $sql->query( $query, $bind_variables, array() )[0]; + $result = $sql->select( + "projects", + array(), + array( + array( + "find", + "[path]", + $path, + array( + "more than", + 0 + ) + ), + array( + "limit", + 1 + ) + ) + ); if( ! empty( $result ) ) { + $result = $result[0]; try { $users = json_decode( $result["access"] ); diff --git a/components/active/init.js b/components/active/init.js index 094cf53..b3b138b 100755 --- a/components/active/init.js +++ b/components/active/init.js @@ -54,6 +54,8 @@ //} + /* Notify listeners. */ + amplify.publish('active.onFileWillAppear', {path: path}); if (focus === undefined) { focus = true; @@ -376,6 +378,9 @@ moveToTabList = true; } + /* Notify listeners. */ + amplify.publish('active.onWillFocus', path); + this.highlightEntry(path, moveToTabList); if(path != this.getPath()) { diff --git a/components/filemanager/init.js b/components/filemanager/init.js index 773b8e9..651208b 100755 --- a/components/filemanager/init.js +++ b/components/filemanager/init.js @@ -440,6 +440,10 @@ ////////////////////////////////////////////////////////////////// openFile: function(path, focus) { + + /* Notify listeners. */ + amplify.publish('filemanager.onFileWillOpen', {path: path}); + if (focus === undefined) { focus = true; } diff --git a/components/install/install.php b/components/install/install.php index 4293e0c..7388155 100644 --- a/components/install/install.php +++ b/components/install/install.php @@ -5,7 +5,9 @@ class Install { public $active = ""; public $config = ""; public $db_types = array(); + public $path = ""; public $projects = ""; + public $rel = ""; public $sessions = ""; public $sql = null; public $users = ""; @@ -14,13 +16,15 @@ class Install { function __construct() { $path = $_POST['path']; - $rel = str_replace( '/components/install/process.php', '', $_SERVER['REQUEST_URI'] ); + $rel = str_replace( '/components/install/install.php', '', $_SERVER['REQUEST_URI'] ); $this->active = $path . "/data/active.php"; $this->config = $path . "/config.php"; $this->projects = $path . "/data/projects.php"; + $this->path = $path; $this->sessions = $path . "/data/sessions"; $this->users = $path . "/data/users.php"; + $this->rel = $rel; $this->workspace = $path . "/workspace"; $this->db_types = sql::db_types; @@ -28,6 +32,7 @@ class Install { require_once( "../sql/class.sql.php" ); $this->sql = new sql(); + $this->install(); } function check() { @@ -50,6 +55,263 @@ class Install { } } + function clean_path( $path ) { + + // prevent Poison Null Byte injections + $path = str_replace( chr( 0 ), '', $path ); + + // prevent go out of the workspace + while ( strpos( $path, '../' ) !== false ) { + + $path = str_replace( '../', '', $path ); + } + return $path; + } + + function clean_username( $username ) { + + return strtolower( preg_replace( '#[^A-Za-z0-9' . preg_quote( '-_@. ').']#', '', $username ) ); + } + + function create_config() { + + $config_data = 'path . '"); + +// BASE URL TO CODIAD (without trailing slash) +define("BASE_URL", "' . $_SERVER["HTTP_HOST"] . $this->rel . '"); + +// THEME : default, modern or clear (look at /themes) +define("THEME", "default"); + +// ABSOLUTE PATH +define("WHITEPATHS", BASE_PATH . ",/home"); + +// SESSIONS (e.g. 7200) +$cookie_lifetime = "0"; + +// TIMEZONE +date_default_timezone_set("' . $_POST['timezone'] . '"); + +// External Authentification +//define("AUTH_PATH", "/path/to/customauth.php"); + +// Site Name +define("SITE_NAME", "' . $_POST['site_name'] . '"); + +// Database Information +define( "DBHOST", "' . $_POST['dbhost'] . '" ); +define( "DBNAME", "' . $_POST['dbname'] . '" ); +define( "DBUSER", "' . $_POST['dbuser'] . '" ); +define( "DBPASS", "' . $_POST['dbpass'] . '" ); +define( "DBTYPE", "' . $_POST['dbtype'] . '" ); + +////////////////////////////////////////////////////////////////// +// ** DO NOT EDIT CONFIG BELOW ** +////////////////////////////////////////////////////////////////// + +// PATHS +define("COMPONENTS", BASE_PATH . "/components"); +define("PLUGINS", BASE_PATH . "/plugins"); +define("THEMES", BASE_PATH . "/themes"); +define("DATA", BASE_PATH . "/data"); +define("WORKSPACE", BASE_PATH . "/workspace"); + +// URLS +define("WSURL", BASE_URL . "/workspace"); + +// Marketplace +//define("MARKETURL", "http://market.codiad.com/json"); +'; + saveFile( $config, $config_data ); + echo( "success" ); + } + + function create_project() { + + $project_path = $this->clean_path( $project_path ); + + if ( ! $this->is_abs_path( $project_path ) ) { + + $project_path = str_replace( " ", "_", preg_replace( '/[^\w-\.]/', '', $project_path ) ); + if( ! is_dir( $workspace . "/" . $project_path ) ) { + + mkdir( $workspace . "/" . $project_path ); + } + } else { + + if ( substr( $project_path, -1 ) == '/' ) { + + $project_path = substr( $project_path, 0, strlen( $project_path ) - 1 ); + } + if ( ! file_exists( $project_path ) ) { + + if ( ! mkdir( $project_path . '/', 0755, true ) ) { + + die( '{"message": "Unable to create Absolute Path"}' ); + } + } else { + + if ( ! is_writable( $project_path ) || ! is_readable( $project_path ) ) { + + die( '{"message": "No Read/Write Permission"}' ); + } + } + } + + $bind_variables = array( + $project_name, + $project_path, + $username + ); + $query = "INSERT INTO projects(name, path, owner) VALUES (?,?,?);"; + $statement = $connection->prepare( $query ); + $statement->execute( $bind_variables ); + $error = $statement->errorInfo(); + + if( ! $error[0] == "00000" ) { + + die( '{"message":"Could not create project in database.","error":"' . addslashes(json_encode( $error )) .'"}' ); + } + } + + function create_tables() { + + $this->sql->create_tables( + array( + "options" => array( + "fields" => array( + "id" => "int", + "name" => "string", + "value" => "text", + ), + "attributes" => array( + "id" => array( "id" ), + "name" => array( "not null", "unique" ), + "value" => array( "not null" ), + ) + ), + "projects" => array( + "fields" => array( + "id" => "int", + "name" => "string", + "path" => "text", + "owner" => "string", + "access" => "string", + ), + "attributes" => array( + + "id" => array( "id" ), + "name" => array( "not null" ), + "path" => array( "not null", "unique" ), + "owner" => array( "not null", "unique" ), + "access" => array( "not null" ), + ) + ), + "users" => array( + "fields" => array( + "id" => "int", + "first_name" => "string", + "last_name" => "string", + "username" => "string", + "password" => "text", + "email" => "string", + "project" => "string", + "access" => "string", + "groups" => "string", + "token" => "string", + ), + "attributes" => array( + "id" => array( "id" ), + "username" => array( "not null", "unique" ), + "password" => array( "not null" ), + "access" => array( "not null" ), + ) + ), + "user_options" => array( + "fields" => array( + "id" => "int", + "name" => "string", + "username" => "string", + "value" => "text", + ), + "attributes" => array( + "id" => array( "id" ), + "name" => array( "not null", "unique" ), + "username" => array( "not null", "unique" ), + "value" => array( "not null" ), + ) + ), + ) + ); + } + + function create_user() { + + $bind_variables = array( + "", + "", + $username, + $password, + "", + $project_path, + "admin", + "", + "" + ); + $query = "INSERT INTO users(first_name, last_name, username, password, email, project, access, groups, token) VALUES (?,?,?,?,?,?,?,?,?)"; + $statement = $connection->prepare( $query ); + $statement->execute( $bind_variables ); + $error = $statement->errorInfo(); + + if( ! $error[0] == "00000" ) { + + die( '{"message":"Could not create user in database.","error":"' . addslashes(json_encode( $error )) .'"}' ); + } + } + + function is_abs_path( $path ) { + + return $path[0] === '/'; + } + + function install() { + + $project_name = $_POST['project_name']; + if ( isset( $_POST['project_path'] ) ) { + + $project_path = $_POST['project_path']; + } else { + + $project_path = $project_name; + } + $timezone = $_POST['timezone']; + + $dbtype = $_POST['dbtype']; + $dbhost = $_POST['dbhost']; + $dbname = $_POST['dbname']; + $dbuser = $_POST['dbuser']; + $dbpass = $_POST['dbpass']; + + $connection = $this->sql->connect(); + + $this->create_tables(); + $this->create_project(); + $this->create_user(); + $this->create_config(); + } + function JSEND( $message, $error=null ) { $message = array( diff --git a/components/install/view.php b/components/install/view.php index 80904ae..ea9e6fb 100755 --- a/components/install/view.php +++ b/components/install/view.php @@ -7,6 +7,8 @@ * [root]/license.txt for more. This information must remain intact. */ +require_once( "./install.php" ); + $path = rtrim(str_replace("index.php", "", $_SERVER['SCRIPT_FILENAME']), "/"); $workspace = is_writable($path . "/workspace"); @@ -49,14 +51,6 @@ $autocomplete = array( 'dbtype' => 'mysql', ); -//Valid databases Codiad is able to use -$aValidDBType = [ - 'MySQL'=>'mysql' - ,'PostgreSQL'=>'pgsql' - ,'SQLite'=>'sqlite' -]; - - if (!empty($query)) { $params = explode('&', $query); foreach ($params as $param) { diff --git a/components/settings/class.settings.php b/components/settings/class.settings.php index 1722d6a..6b9fd24 100755 --- a/components/settings/class.settings.php +++ b/components/settings/class.settings.php @@ -77,10 +77,6 @@ class Settings { "name" => "codiad.settings.autosave", "value" => "true", ), - array( - "name" => "codiad.settings.plugin.sync", - "value" => "true", - ), ); ////////////////////////////////////////////////////////////////// @@ -211,7 +207,6 @@ class Settings { public function update_option( $option, $value, $user_setting = true ) { global $sql; - if( $user_setting == null ) { $query = "INSERT INTO options ( name, username, value ) VALUES ( ?, ? );"; diff --git a/components/settings/init.js b/components/settings/init.js index 722fc9b..d4d82c1 100755 --- a/components/settings/init.js +++ b/components/settings/init.js @@ -140,6 +140,19 @@ option: option, value: value }, + success: function( data ) { + + console.log( "Data: " + data ) + }, + error: function(jqXHR, textStatus, errorThrown) { + + console.log('jqXHR:'); + console.log(jqXHR); + console.log('textStatus:'); + console.log(textStatus); + console.log('errorThrown:'); + console.log(errorThrown); + }, }); }, diff --git a/components/sql/class.sql.conversions.php b/components/sql/class.sql.conversions.php index 163f661..7a16dda 100644 --- a/components/sql/class.sql.conversions.php +++ b/components/sql/class.sql.conversions.php @@ -76,6 +76,13 @@ class sql_conversions { "pgsql" => "!=", "sqlite" => "!=", ), + + "where" => array( + + "mysql" => "WHERE", + "pgsql" => "WHERE", + "sqlite" => "WHERE", + ), ); public $data_types = array( @@ -109,6 +116,16 @@ class sql_conversions { ), ); + public $general = array( + + "from" => array( + + "mysql" => "FROM", + "pgsql" => "FROM", + "sqlite" => "FROM", + ), + ); + public $specials = array( "id" => array( @@ -148,9 +165,9 @@ class sql_conversions { "unique" => array( - "mysql" => "CONSTRAINT %constraint_name% UNIQUE ( %field_names% )", - "pgsql" => "UNIQUE", - "sqlite" => "UNIQUE", + "mysql" => "CONSTRAINT '%constraint_name%' UNIQUE ( %field_names% )", + "pgsql" => "CONSTRAINT '%constraint_name%' UNIQUE ( %field_names% )", + "sqlite" => "CONSTRAINT '%constraint_name%' UNIQUE ( %field_names% )", ), ); @@ -173,11 +190,33 @@ class sql_conversions { ), ); - public function find( $string, $substring ) { + public function check_field( $needle, $haystack ) { + + $field = preg_replace_callback( + // Matches parts to be replaced: '[field]' + '/(\[.*?\])/', + // Callback function. Use 'use()' or define arrays as 'global' + function( $matches ) use ( $haystack ) { + + // Remove square brackets from the match + // then use it as variable name + $match = trim( $matches[1], "[]" ); + return $match; + }, + // Input string to search in. + $needle + ); + + if( $field === $needle ) { + + $field = false; + } + return $field; + } + + public function find( $substring, $string ) { $dbtype = DBTYPE; - $id_close = $this->wraps["close"][$dbtype]; - $id_open = $this->wraps["open"][$dbtype]; $find_string = $this->actions["find"][$dbtype]; $find_string = str_replace( "%string%", $string, $find_string ); $find_string = str_replace( "%substring%", $substring, $find_string ); @@ -185,6 +224,108 @@ class sql_conversions { return $find_string; } + public function select( $table, $fields, $where ) { + + $dbtype = DBTYPE; + $id_close = $this->wraps["close"][$dbtype]; + $id_open = $this->wraps["open"][$dbtype]; + $query = $this->actions["select"][$dbtype] . " "; + $bind_vars = array(); + + if( empty( $fields ) ) { + + $query .= " * "; + } + + foreach( $fields as $field ) { + + $query .= $field . ","; + } + + $query = substr( $query, 0, -1 ); + $query .= " {$this->general["from"][$dbtype]} {$table} "; + + if( ! empty( $where ) ) { + + $query .= " {$this->comparisons["where"][$dbtype]} "; + } + + foreach( $where as $comparison ) { + + $comparison_string = ""; + + //Put a replace of %% symbols with fields and open / close + if( $comparison[0] == "find" ) { + + $c1 = $this->check_field( $comparison[1], $fields ); + $c2 = $this->check_field( $comparison[2], $fields ); + $c3 = $this->check_field( $comparison[3][1], $fields ); + + if( ! $c1 === FALSE ) { + + $c1 = $id_open . $c1 . $id_close; + } else { + + $c1 = "?"; + array_push( $bind_vars, $comparison[1] ); + } + + if( ! $c2 === FALSE ) { + + $c2 = $id_open . $c2 . $id_close; + } else { + + $c2 = "?"; + array_push( $bind_vars, $comparison[2] ); + } + + if( ! $c3 === FALSE ) { + + $c3 = $id_open . $c3 . $id_close; + } else { + + $c3 = "?"; + array_push( $bind_vars, $comparison[3][1] ); + } + + $c0 = $this->find( $c1, $c2 ); + $comparison_string .= "{$c0} {$this->comparisons[$comparison[3][0]][$dbtype]} {$c3}"; + } elseif( $comparison[0] == "in" ) { + + + } elseif( $comparison[0] == "limit" ) { + + + } else { + + if( in_array( $fields, $comparison[1] ) ) { + + $comparison[1] = $id_open . $comparison[1] . $id_close; + } + + if( in_array( $fields, $comparison[3] ) ) { + + $comparison[3] = $id_open . $comparison[3] . $id_close; + } + + $comparison_string .= "{$comparison[1]} {$this->$comparisons[$comparison[0]][$dbtype]} {$comparison[2]}"; + } + + $index = array_search( $comparison, $where ); + + if( $index ) { + + } else { + + $query .= "{$comparison_string} "; + } + } + + //$query = substr( $query, 0, -1 ); + $query .= ";"; + return array( $query, $bind_vars ); + } + public function table( $table_name, $fields, $attributes ) { $dbtype = DBTYPE; @@ -201,7 +342,7 @@ class sql_conversions { $attribute_string = $this->specials["$attribute"][$dbtype]; - if( $attribute == "unique" && $dbtype == "mysql" ) { + if( $attribute == "unique" ) { continue; } @@ -228,30 +369,27 @@ class sql_conversions { $query .= ","; } - if( $dbtype == "mysql" ) { + $id_close = $this->wraps["close"][$dbtype]; + $id_open = $this->wraps["open"][$dbtype]; + $fields_string = ""; + $unique_string = ""; + + foreach( $attributes as $id => $attributes ) { - $constraint_name = ""; - $id_close = $this->wraps["close"][$dbtype]; - $id_open = $this->wraps["open"][$dbtype]; - $fields_string = ""; - $unique_string = ""; - - foreach( $attributes as $id => $attributes ) { + if( in_array( "unique", $attributes ) ) { - if( in_array( "unique", $attributes ) ) { + if( $unique_string == "" ) { - if( $unique_string == "" ) { - - $unique_string = $this->specials["unique"] . ","; - } - $fields_string .= "{$id_open}{$id}{$id_close},"; + $unique_string = $this->specials["unique"] . ","; } + $fields_string .= "{$id_open}{$id}{$id_close},"; } - $unique_string = str_replace( "%constraint_name%", $constraint_name, $unique_string ); - $unique_string = str_replace( "%field_names%", $fields_string, $unique_string ); - $query .= $unique_string; } + $unique_string = str_replace( "%constraint_name%", $fields_string, $unique_string ); + $unique_string = str_replace( "%field_names%", $fields_string, $unique_string ); + $query .= $unique_string; + $query = substr( $query, 0, -1 ); $query .= ");"; return( $query ); @@ -267,6 +405,11 @@ class sql_conversions { } return( $query ); } + + public function update( $table, $fields, $where ) { + + + } } ?> diff --git a/components/sql/class.sql.php b/components/sql/class.sql.php index 2ff6654..35aed27 100755 --- a/components/sql/class.sql.php +++ b/components/sql/class.sql.php @@ -77,7 +77,8 @@ class sql { */ $query = $this->conversions->tables( $table ); - echo var_dump( $query ); + //echo var_dump( $query ) . "
"; + $result = $this->query( $query, array(), array() ); } public static function escape_identifier( $i ) { @@ -109,6 +110,22 @@ class sql { return self::$instance; } + public function select( $table, $fields=array(), $where=array() ) { + + $array = $this->conversions->select( $table, $fields, $where ); + $query = $array[0]; + $bind_vars = $array[1]; + $result = $this->query( $query, $bind_vars, array() ); + //echo var_dump( $query, $bind_vars ) . "
"; + return $result; + } + + public function update( $table, $fields=array(), $where=array() ) { + + $query = $this->conversions->update( $table, $fields, $where ); + //echo var_dump( $query ) . "
"; + } + public function query( $query, $bind_variables, $default, $action='fetchAll' ) { $connection = $this->connect(); @@ -146,6 +163,8 @@ class sql { $return = $default; } + //echo var_dump( $error, $return ); + $this->close(); return( $return ); }