diff --git a/README.md b/README.md
index abdde5d..edf833c 100644
--- a/README.md
+++ b/README.md
@@ -63,22 +63,36 @@ In this example, if the program is told to create a new python project (exact sy
**Special Keywords:**
-The content of files, defined in the JSON files, can have special keywords that will be replaced by dynamic or static data.
-All keywords are in the format `|!keyword!|`. The supported keywords are:
+The content of files, created by both the file and the project actions, can have special keywords that will be replaced by dynamic or static data.
+
+All keywords are in the format `|!keyword{multiplier}[case]!|`.
+- `keyword`: One of the supported keywords. See below for a list of global keywords, as well as, how to add your own.
+- `multiplier` (Optional): An integer (whole number) indicating how many times that keyword replacement should be inserted.
+- `case` (Optional): A tag indicating a specific case status for the keyword replacement. The supported tags are:
+ - `uc`: insert the keyword replacement in UPPERCASE.
+ - `lc`: insert the keyword replacement in lowercase.
+ - `t`: insert the keyword replacement Capitalized.
+
+The **global keywords** are:
Keyword | Replace Value | Supported Actions
--- | --- | ---
copyright | copyright text
see below for details on how to customize the text | project
file
project_name | the new project's name | project
file (1)
+file_name | the new file's name | project
file
+file_type | the new file's type | project
file
project_type | the new project's type | project
no_www_domain | the new project's name, striped of any starting "www." | project
-file_name | the new file's name | file
-file_type | the new file's type | file
(1) When creating a new file, the code will search the file's path for the first directory with a `.git` folder inside it. That directory will be treated as the file's project_name.
-All static keywords and their replacement strings are defined in the `keywords.json` file.
-Any keywords added to this file will become usable in file's content.
+Adding **custom keywords**:
+
+All custom keywords and their replacement strings are defined in the `keywords.json` file.
+Any keywords added to this file will become usable in all the actions.
+
+It is valid to use other keywords in the replacement string.
+
This is also where the copyright text is defined and can be customized.
NOTE: the code expects the keyword to have a string as a value in `keywords.json` and will replace it with an empty string if that is not the case.
diff --git a/classes/Application.py b/classes/Application.py
index 5445038..1adc93e 100644
--- a/classes/Application.py
+++ b/classes/Application.py
@@ -1,6 +1,6 @@
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
-# Python Project Manager v1.2.1 #
+# Python Project Manager v1.3.0 #
# #
# Copyright 2016, PedroHenriques #
# http://www.pedrojhenriques.com #
@@ -198,6 +198,21 @@ def executeHelp(self) :
help_string += "\n\t- " + key
else:
# a topic was provided
+ # split the topic into its parts
+ topic_parts = topic.split(":")
+
+ # check if a sub topic was provided
+ sub_topic = True
+ if (len(topic_parts) == 1) :
+ # it wasn't
+ sub_topic = False
+
+ # ask for the base information about this topic
+ topic += ":base"
+
+ # update the topic parts
+ topic_parts = topic.split(":")
+
# get the information relevant for the desired topic
if (not self.updateJsonData(topic)) :
# the file_type isn't defined, so bail out
@@ -213,12 +228,53 @@ def executeHelp(self) :
# store the help string
help_string = self.json_data
+ # if a subtopic was provided, add the extra information
+ if (sub_topic) :
+ if (topic_parts[1] == "type") :
+ # get the relevant JSON file's content
+ sub_topic_json_data = self.parseJSON(self.json_path + topic_parts[0] + ".json")
+
+ # check if the topic is "project"
+ if (topic_parts[0] == "project") :
+ # it is, so only loop through the 1st tier of the JSON file
+ # loop through the JSON's content
+ for key in sub_topic_json_data :
+ help_string += "\n\t- " + key
+ else :
+ # it isn't, so loop through all the tiers of the JSON file
+ # loop through the JSON's content
+ for key in sub_topic_json_data :
+ help_string += "\n\t- " + self.buildTypesString(key, sub_topic_json_data[key])
+
# print the help text
print(help_string)
# at this point everything went OK
return(True)
+ # builds and returns a string with all the type supported by the various actions
+ # NOTE: called recursively
+ def buildTypesString(self, parent_str, data) :
+ res = ""
+
+ # loop through the data
+ for key in data :
+ # check if key's value is a string
+ if (isinstance(data[key], str)) :
+ # it is, so this is an end tier which is to be ignored
+ continue
+
+ # this isn't an end tier
+ # update the type string with this tier's sub-tiers
+ res += self.buildTypesString(parent_str + ":" + key, data[key]) + " "
+
+ # check if this tier had any valid sub-tiers
+ if (len(res) == 0) :
+ # it didn't, so the type is the tier itself
+ res = parent_str
+
+ return(res.strip())
+
# searches the selected JSON file for the needed information
# the changes will be made to self.json_data
# return True if successful or False otherwise
@@ -283,16 +339,20 @@ def createStructure(self, structure, path) :
# build the dictionary with replacement keywords
replacements = self.keywords.copy()
+ # determine this file's extension
+ aux_pos = key.rfind(".")
+ if (aux_pos == -1) :
+ file_extension = ""
+ else :
+ file_extension = key[aux_pos + 1:]
+
+ # add this file's name and type to the replacements
+ replacements["file_name"] = key[:aux_pos]
+ replacements["file_type"] = file_extension
+
# check if this file requires the copyright text to be inserted
if ("|!copyright!|" in file_content) :
# it does
- # determine this file's extension
- aux_pos = key.rfind(".")
- if (aux_pos == -1) :
- file_extension = ""
- else :
- file_extension = key[aux_pos + 1:]
-
# add the copyright replacement information
replacements["copyright"] = self.buildCopyrightString(file_extension)
@@ -371,35 +431,53 @@ def deleteDir(self, path) :
# NOTE: any keywords found in string not present in replacements will be replaced by an empty string
def replaceKeyWords(self, replacements, string) :
# the pattern to identify the placeholders
- re_pattern = "\|!([^{!]+)\{?(\d+)*\}?!\|"
+ re_pattern = "\|!([^{!\[\]]+)(\{\d+\})?(\[[^{!\[\]]+\])?!\|"
+
+ # the map between case tag in the regex and the String class function to use
+ str_func = {"lc" : "lower", "uc" : "upper", "t" : "title"}
# loop while there are keywords in the string
re_matches = re.search(re_pattern, string)
while (re_matches != None) :
# grab the re_matches groups
- match_groups = re_matches.groups()
+ match_groups = re_matches.groups("")
+ match_count = len(match_groups)
# check if the keyword found is present in replacements and is a string
if (match_groups[0] in replacements and isinstance(replacements[match_groups[0]], str)) :
# it is
- # build the new_string
+ # build the replacement string
new_string = replacements[match_groups[0]]
else :
# it isn't
# replace the keyword with an empty string
new_string = ""
- # check if this match has a multiplier
- if (match_groups[1] == None) :
- # it doesn't
- keyword = match_groups[0]
- else :
- # it does
- keyword = match_groups[0] + "{" + match_groups[1] + "}"
- new_string *= int(match_groups[1])
+ # check if there is any other information provided
+ if (len(new_string) > 0 and match_count > 1) :
+ # there is
+ # loop through the remaining matches
+ i = 1
+ while (i < match_count):
+ # check if this match is a multiplier
+ if (match_groups[i].startswith("{") and match_groups[i].endswith("}")) :
+ # it is
+ # update the replacement string
+ new_string *= int(match_groups[i][1:-1])
+ # check if this match is a case enforcer
+ elif (match_groups[i].startswith("[") and match_groups[i].endswith("]")) :
+ # it is
+ # check if this case enforcer is valid
+ case_enforcer = match_groups[i][1:-1].lower()
+ if (case_enforcer in str_func) :
+ # it is
+ # update the replacement string
+ new_string = getattr(new_string, str_func[case_enforcer], new_string)()
+
+ i += 1
# replace the keyword with the new_string
- string = string.replace("|!" + keyword + "!|", new_string)
+ string = string.replace("|!" + "".join(match_groups) + "!|", new_string)
# check the pattern again
re_matches = re.search(re_pattern, string)
diff --git a/classes/CLI.py b/classes/CLI.py
index 75c8094..e428357 100644
--- a/classes/CLI.py
+++ b/classes/CLI.py
@@ -1,6 +1,6 @@
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
-# Python Project Manager v1.2.1 #
+# Python Project Manager v1.3.0 #
# #
# Copyright 2016, PedroHenriques #
# http://www.pedrojhenriques.com #
@@ -130,7 +130,10 @@ def processHelp(self) :
# store the necessary arguments
# desired topic, if 1 was given, or None otherwise
- self.args["topic"] = sys.argv[2] if (len(sys.argv) > 2) else None
+ if (len(sys.argv) > 2) :
+ self.args["topic"] = sys.argv[2]
+ else :
+ self.args["topic"] = None
# all OK
return(True)
diff --git a/classes/__init__.py b/classes/__init__.py
index 83c18f5..cf6189a 100644
--- a/classes/__init__.py
+++ b/classes/__init__.py
@@ -1,6 +1,6 @@
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# #
-# Python Project Manager v1.2.1 #
+# Python Project Manager v1.3.0 #
# #
# Copyright 2016, PedroHenriques #
# http://www.pedrojhenriques.com #
diff --git a/data/file.json b/data/file.json
index 56c8a7e..f3830a4 100644
--- a/data/file.json
+++ b/data/file.json
@@ -1,24 +1,50 @@
{
"php" : {
+ "blank" : {
+ "extension" : "php",
+ "content" : ""
+ },
"class" : {
"extension" : "php",
- "content" : ""
+ "content" : ""
},
"ajax" : {
"extension" : "php",
- "content" : ""
+ "content" : ""
}
},
"ruby" : {
+ "blank" : {
+ "extension" : "rb",
+ "content" : "|!copyright!|\n\n"
+ },
"class" : {
"extension" : "rb",
- "content" : "|!copyright!|\n\nclass |!file_name!|\n\tdef initialize()\n\tend"
+ "content" : "|!copyright!|\n\nclass |!file_name[t]!|\n\tdef initialize()\n\tend"
}
},
"python" : {
+ "blank" : {
+ "extension" : "py",
+ "content" : "|!copyright!|\n\n"
+ },
"class" : {
"extension" : "py",
- "content" : "|!copyright!|\n\nclass |!file_name!| :\n\t\"\"\"String with class information\"\"\"\n\n\tdef __init__(self) :\n\t\tpass"
+ "content" : "|!copyright!|\n\nclass |!file_name[t]!| :\n\t\"\"\"String with class information\"\"\"\n\n\tdef __init__(self) :\n\t\tpass"
+ }
+ },
+ "cpp" : {
+ "blank" : {
+ "extension" : "cpp",
+ "content" : "|!copyright!|\n\n"
+ },
+ "class" : {
+ "extension" : "cpp",
+ "content" : "|!copyright!|\n\n#include \"|!file_name[t]!|.h\"\n\n|!file_name[t]!|::|!file_name[t]!|() {}\n\n|!file_name[t]!|::~|!file_name[t]!|() {}"
+ },
+ "header" : {
+ "extension" : "h",
+ "content" : "|!copyright!|\n\n// include guard: |!file_name[uc]!|_H\n#ifndef |!file_name[uc]!|_H\n#define |!file_name[uc]!|_H\n\n// includes\n\n// class definition\nclass |!file_name[t]!| {\n\tpublic:\n\t\t|!file_name[t]!|();\n\t\t~|!file_name[t]!|();};\n\n// include guard: |!file_name[uc]!|_H\n#endif"
}
},
"css" : {
diff --git a/data/help.json b/data/help.json
index fd7cc9e..4915018 100644
--- a/data/help.json
+++ b/data/help.json
@@ -1,4 +1,10 @@
{
- "project" : "=> Creates a new project. The command syntax is:\n\tproject path name type\n- path is the path, relative to the current directory, where the project should be created. Use a fullstop if the current directory is the desired path.\n- name is the project's directory name\n- type is the type of the project, as defined in \"project.json\". Use : to separate JSON tiers.",
- "file" : "=> Creates a new file. The command syntax is:\n\tfile path name type [-flags]\n- path is the path, relative to the current directory, where the file should be created. Use a fullstop if the current directory is the desired path.\n- name is the file's name (without the extension).\n- type is the type of the file, as defined in \"file.json\". Use : to separate JSON tiers.\n- [-flags] is an optional argument where configuration flags can be provided. The supported flags are:\n\tf = force the creation of the file by creating any directories in the path that don't exist.\n\to = if a file with the same path already exists, it will be overwritten."
+ "project" : {
+ "base" : "=> Creates a new project. The command syntax is:\n\tproject path name type\n- path is the path, relative to the current directory, where the project should be created. Use a fullstop if the current directory is the desired path.\n- name is the project's directory name\n- type is the type of the project, as defined in \"project.json\". Type \"help project:type\" for a list of supported project types.",
+ "type" : "=> The project types supported by this program are:"
+ },
+ "file" : {
+ "base" : "=> Creates a new file. The command syntax is:\n\tfile path name type [-flags]\n- path is the path, relative to the current directory, where the file should be created. Use a fullstop if the current directory is the desired path.\n- name is the file's name (without the extension).\n- type is the type of the file, as defined in \"file.json\". Type \"help file:type\" for a list of supported file types.\n- [-flags] is an optional argument where configuration flags can be provided. The supported flags are:\n\tf = force the creation of the file by creating any directories in the path that don't exist.\n\to = if a file with the same path already exists, it will be overwritten.",
+ "type" : "=> The file types supported by this program are:"
+ }
}
diff --git a/data/keywords.json b/data/keywords.json
index 2b67738..c1aac86 100644
--- a/data/keywords.json
+++ b/data/keywords.json
@@ -8,7 +8,9 @@
"js" : {"start" : "/*!!", "end" : "*/", "char" : "*"},
"scss" : {"start" : "/*!!", "end" : "*/", "char" : "*"},
"rb" : {"start" : "#", "end" : "#", "char" : "#"},
- "py" : {"start" : "#", "end" : "#", "char" : "#"}
+ "py" : {"start" : "#", "end" : "#", "char" : "#"},
+ "cpp" : {"start" : "/*", "end" : "*/", "char" : "*"},
+ "h" : {"start" : "/*", "end" : "*/", "char" : "*"}
}
}
}
diff --git a/data/project.json b/data/project.json
index 9cf0b76..fb884e1 100644
--- a/data/project.json
+++ b/data/project.json
@@ -1,5 +1,5 @@
{
- "website" : {
+ "php" : {
"robots.txt" : "",
".gitignore" : "vendor/\n.sass-cache/\nmain.css.map\nimages/\n_extra/",
"assets" : {
@@ -20,13 +20,13 @@
"ajax_files" : {},
"aux_pages" : {},
"classes" : {
- "DB.php" : "pdo_obj = new PDO(\"mysql:host=localhost;dbname=\".self::$db_name, self::$db_user, self::$db_pw);\n\t\t}catch (PDOException $e) {\n\t\t\t// couldn't connect to DB\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// returns the DB connection\n\t// if one doesn't exist, then a connection will be created\n\tpublic static function getInstance() {\n\t\t// if a DB connection hasn't been created\n\t\tif (self::$instance == null) {\n\t\t\t// create a DB instance and store it\n\t\t\t$new_instance = new self;\n\n\t\t\t// if an instance was successfuly created, store it\n\t\t\tif ($new_instance->pdo_obj !== null) {\n\t\t\t\tself::$instance = $new_instance;\n\t\t\t}\n\t\t}\n\n\t\treturn(self::$instance);\n\t}\n\n\t// begins a transaction\n\t// returns True if successful or False otherwise\n\tpublic function beginTransaction() {\n\t\ttry {\n\t\t\treturn((bool)$this->pdo_obj->beginTransaction());\n\t\t}catch (PDOException $e) {\n\t\t\treturn(false);\n\t\t}\n\t}\n\n\t// commits a transaction\n\t// returns True if successful or False otherwise\n\tpublic function commit() {\n\t\ttry {\n\t\t\t// check if there is an open transaction\n\t\t\tif (!(bool)$this->pdo_obj->inTransaction()) {\n\t\t\t\t// there isn't an open transition\n\t\t\t\treturn(true);\n\t\t\t}\n\n\t\t\treturn((bool)$this->pdo_obj->commit());\n\t\t}catch (PDOException $e) {\n\t\t\treturn(false);\n\t\t}\n\t}\n\n\t// rollback a transaction\n\t// returns True if successful or False otherwise\n\tpublic function rollBack() {\n\t\ttry {\n\t\t\t// check if there is an open transaction\n\t\t\tif (!(bool)$this->pdo_obj->inTransaction()) {\n\t\t\t\t// there isn't an open transition\n\t\t\t\treturn(true);\n\t\t\t}\n\n\t\t\treturn((bool)$this->pdo_obj->rollBack());\n\t\t}catch (PDOException $e) {\n\t\t\treturn(false);\n\t\t}\n\t}\n\n\t// prepares and runs a SELECT query\n\t// returns all query's results, as an assoc array\n\tpublic function querySelect($query, array $input_params) {\n\t\ttry {\n\t\t\t// prepare the query\n\t\t\t$pdo_statement = $this->pdo_obj->prepare($query);\n\n\t\t\tif ($pdo_statement === false) {\n\t\t\t\t// the query couldn't be prepared\n\t\t\t\treturn([]);\n\t\t\t}\n\n\t\t\t// execute the query\n\t\t\tif (!$pdo_statement->execute($input_params)) {\n\t\t\t\t// the query couldn't be executed\n\t\t\t\treturn([]);\n\t\t\t}\n\n\t\t\t// check if a game was found\n\t\t\tif ($pdo_statement->rowCount() === 0) {\n\t\t\t\t// it wasn't\n\t\t\t\treturn([]);\n\t\t\t}\n\n\t\t\t// fetch the results\n\t\t\t$pdo_results = $pdo_statement->fetchAll(PDO::FETCH_ASSOC);\n\n\t\t\tif ($pdo_results === false) {\n\t\t\t\t// failed to fetch results\n\t\t\t\treturn([]);\n\t\t\t}\n\n\t\t\t// at this point everything should have gone OK\n\t\t\treturn($pdo_results);\n\t\t}catch (PDOException $e) {\n\t\t\treturn([]);\n\t\t}\n\t}\n\n\t// prepares and runs an INSERT query\n\t// returns the IDs of the inserted rows\n\tpublic function queryInsert($query, array $input_params) {\n\t\ttry {\n\t\t\t// prepare the query\n\t\t\t$pdo_statement = $this->pdo_obj->prepare($query);\n\n\t\t\tif ($pdo_statement === false) {\n\t\t\t\t// the query couldn't be prepared\n\t\t\t\treturn([]);\n\t\t\t}\n\n\t\t\t// stores the inserted IDs\n\t\t\t$inserted_ids = [];\n\n\t\t\t// loop through each $input_params element\n\t\t\tforeach ($input_params as $params) {\n\t\t\t\t// execute the query\n\t\t\t\tif (!$pdo_statement->execute($params)) {\n\t\t\t\t\t// the query couldn't be executed\n\t\t\t\t\t$inserted_ids[] = null;\n\t\t\t\t}\n\n\t\t\t\t// store the inserted ID\n\t\t\t\t$inserted_ids[] = $this->pdo_obj->lastInsertId();\n\t\t\t}\n\n\t\t\t// return the inserted IDs\n\t\t\treturn($inserted_ids);\n\t\t}catch (PDOException $e) {\n\t\t\treturn([]);\n\t\t}\n\t}\n\n\t// prepares and runs an UPDATE query\n\t// returns the number of updated rows\n\tpublic function queryUpdate($query, array $input_params) {\n\t\ttry {\n\t\t\t// prepare the query\n\t\t\t$pdo_statement = $this->pdo_obj->prepare($query);\n\n\t\t\tif ($pdo_statement === false) {\n\t\t\t\t// the query couldn't be prepared\n\t\t\t\treturn([]);\n\t\t\t}\n\n\t\t\t// stores the number of updated rows\n\t\t\t$num_updated_rows = 0;\n\n\t\t\t// loop through each $input_params element\n\t\t\tforeach ($input_params as $params) {\n\t\t\t\t// execute the query\n\t\t\t\tif ($pdo_statement->execute($params)) {\n\t\t\t\t\t// the query was executed\n\t\t\t\t\t$num_updated_rows++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// return the number of updated rows\n\t\t\treturn($num_updated_rows);\n\t\t}catch (PDOException $e) {\n\t\t\treturn([]);\n\t\t}\n\t}\n}\n\n?>",
- "General.php" : ""
+ "DB.php" : "pdo_obj = new PDO(\"mysql:host=localhost;dbname=\".self::$db_name, self::$db_user, self::$db_pw);\n\t\t}catch (PDOException $e) {\n\t\t\t// couldn't connect to DB\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// returns the DB connection\n\t// if one doesn't exist, then a connection will be created\n\tpublic static function getInstance() {\n\t\t// if a DB connection hasn't been created\n\t\tif (self::$instance == null) {\n\t\t\t// create a DB instance and store it\n\t\t\t$new_instance = new self;\n\n\t\t\t// if an instance was successfuly created, store it\n\t\t\tif ($new_instance->pdo_obj !== null) {\n\t\t\t\tself::$instance = $new_instance;\n\t\t\t}\n\t\t}\n\n\t\treturn(self::$instance);\n\t}\n\n\t// begins a transaction\n\t// returns True if successful or False otherwise\n\tpublic function beginTransaction() {\n\t\ttry {\n\t\t\treturn((bool)$this->pdo_obj->beginTransaction());\n\t\t}catch (PDOException $e) {\n\t\t\treturn(false);\n\t\t}\n\t}\n\n\t// commits a transaction\n\t// returns True if successful or False otherwise\n\tpublic function commit() {\n\t\ttry {\n\t\t\t// check if there is an open transaction\n\t\t\tif (!(bool)$this->pdo_obj->inTransaction()) {\n\t\t\t\t// there isn't an open transition\n\t\t\t\treturn(true);\n\t\t\t}\n\n\t\t\treturn((bool)$this->pdo_obj->commit());\n\t\t}catch (PDOException $e) {\n\t\t\treturn(false);\n\t\t}\n\t}\n\n\t// rollback a transaction\n\t// returns True if successful or False otherwise\n\tpublic function rollBack() {\n\t\ttry {\n\t\t\t// check if there is an open transaction\n\t\t\tif (!(bool)$this->pdo_obj->inTransaction()) {\n\t\t\t\t// there isn't an open transition\n\t\t\t\treturn(true);\n\t\t\t}\n\n\t\t\treturn((bool)$this->pdo_obj->rollBack());\n\t\t}catch (PDOException $e) {\n\t\t\treturn(false);\n\t\t}\n\t}\n\n\t// prepares and runs a SELECT query\n\t// returns all query's results, as an assoc array\n\t// NOTE: this is ONLY for SELECT queries\n\t// NOTE: only runs the query for 1 set of $input_params\n\tpublic function querySelect($query, array $input_params, array $param_types) {\n\t\t// make the query into a 1 line string\n\t\t$query = trim(preg_replace(\"/\\r|\\n|\\t/\", \" \", $query));\n\n\t\t// sanity check\n\t\tif ($query === \"\" || preg_match(\"/^SELECT[ ]+/i\", $query) !== 1 || (empty($input_params) && !empty($param_types)) || (!empty($input_params) && empty($param_types))) {\n\t\t\treturn([]);\n\t\t}\n\n\t\ttry {\n\t\t\t// prepare the query\n\t\t\t$pdo_statement = $this->pdo_obj->prepare($query);\n\n\t\t\tif ($pdo_statement === false) {\n\t\t\t\t// the query couldn't be prepared\n\t\t\t\treturn([]);\n\t\t\t}\n\n\t\t\t// check if the #values in $input_params matches the #values in $param_types\n\t\t\tif (count($input_params) !== count($param_types)) {\n\t\t\t\t// they don't\n\t\t\t\treturn([]);\n\t\t\t}\n\n\t\t\t// bind the params\n\t\t\t$params_bound = true;\n\t\t\tfor ($i = 0; $i < count($input_params); $i++) {\n\t\t\t\tif (!$pdo_statement->bindValue($i + 1, $input_params[$i], $param_types[$i])) {\n\t\t\t\t\t// the bind param failled\n\t\t\t\t\t$params_bound = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// execute the query\n\t\t\tif (!$params_bound || !$pdo_statement->execute()) {\n\t\t\t\t// the query couldn't be executed\n\t\t\t\treturn([]);\n\t\t\t}\n\n\t\t\t// check if data was found\n\t\t\tif ($pdo_statement->rowCount() === 0) {\n\t\t\t\t// it wasn't\n\t\t\t\treturn([]);\n\t\t\t}\n\n\t\t\t// fetch the results\n\t\t\t$pdo_results = $pdo_statement->fetchAll(PDO::FETCH_ASSOC);\n\n\t\t\tif ($pdo_results === false) {\n\t\t\t\t// failed to fetch results\n\t\t\t\treturn([]);\n\t\t\t}\n\n\t\t\t// at this point everything should have gone OK\n\t\t\treturn($pdo_results);\n\t\t}catch (PDOException $e) {\n\t\t\treturn([]);\n\t\t}\n\t}\n\n\t// prepares and runs a query\n\t// returns the IDs of the inserted rows, in order the queries where executed\n\t// with NULL in the indexes of the ones that failled\n\t// NOTE: this is NOT for SELECT queries\n\tpublic function queryDetailed($query, array $input_params, array $param_types) {\n\t\t// make the query into a 1 line string\n\t\t$query = trim(preg_replace(\"/\\r|\\n|\\t/\", \" \", $query));\n\n\t\t// sanity check\n\t\tif ($query === \"\" || preg_match(\"/^SELECT[ ]+/i\", $query) !== 0 || empty($input_params) || empty($param_types)) {\n\t\t\treturn([]);\n\t\t}\n\n\t\ttry {\n\t\t\t// prepare the query\n\t\t\t$pdo_statement = $this->pdo_obj->prepare($query);\n\n\t\t\tif ($pdo_statement === false) {\n\t\t\t\t// the query couldn't be prepared\n\t\t\t\treturn([]);\n\t\t\t}\n\n\t\t\t// stores the inserted IDs\n\t\t\t$inserted_ids = [];\n\n\t\t\t// loop through each $input_params element\n\t\t\tforeach ($input_params as $params_row) {\n\t\t\t\t// check if the #values in $input_params matches the #values in $param_types\n\t\t\t\t$params_bound = true;\n\t\t\t\tif (count($params_row) === count($param_types)) {\n\t\t\t\t\t// they do\n\t\t\t\t\t// bind the params\n\t\t\t\t\tfor ($i = 0; $i < count($params_row); $i++) {\n\t\t\t\t\t\t\tif (!$pdo_statement->bindValue($i + 1, $params_row[$i], $param_types[$i])) {\n\t\t\t\t\t\t\t// the bind param failled\n\t\t\t\t\t\t\t$params_bound = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}else{\n\t\t\t\t\t// they don't\n\t\t\t\t\t$params_bound = false;\n\t\t\t\t}\n\n\t\t\t\t// execute the query\n\t\t\t\tif ($params_bound && $pdo_statement->execute()) {\n\t\t\t\t\t// succcess, so store the inserted ID\n\t\t\t\t\t$inserted_ids[] = $this->pdo_obj->lastInsertId();\n\t\t\t\t}else{\n\t\t\t\t\t// the query couldn't be executed\n\t\t\t\t\t$inserted_ids[] = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// return the inserted IDs\n\t\t\treturn($inserted_ids);\n\t\t}catch (PDOException $e) {\n\t\t\treturn([]);\n\t\t}\n\t}\n\n\t// prepares and runs a query\n\t// returns the number of affected rows\n\t// NOTE: this is NOT for SELECT queries\n\tpublic function querySimple($query, array $input_params, array $param_types) {\n\t\t// make the query into a 1 line string\n\t\t$query = trim(preg_replace(\"/\\r|\\n|\\t/\", \" \", $query));\n\n\t\t// sanity check\n\t\tif ($query === \"\" || preg_match(\"/^SELECT[ ]+/i\", $query) !== 0 || empty($input_params) || empty($param_types)) {\n\t\t\treturn([]);\n\t\t}\n\n\t\t// used to control some querky behavior of the rowCount() function\n\t\t$max_row_count = null;\n\n\t\t// check if the query is \"SELECT INTO ... ON DUPLICATE KEY UPDATE ...\"\n\t\tif (preg_match(\"/^insert[ ]+into[ ]+.+[ ]+on[ ]+duplicate[ ]+key[ ]+update/i\", $query) === 1) {\n\t\t\t// this type of query will return 2 for each affected row, when in fact it's just 1 affected row\n\t\t\t$max_row_count = 1;\n\t\t}\n\n\t\ttry {\n\t\t\t// prepare the query\n\t\t\t$pdo_statement = $this->pdo_obj->prepare($query);\n\n\t\t\tif ($pdo_statement === false) {\n\t\t\t\t// the query couldn't be prepared\n\t\t\t\treturn(0);\n\t\t\t}\n\n\t\t\t// stores the number of updated rows\n\t\t\t$num_affected_rows = 0;\n\n\t\t\t// loop through each $input_params element\n\t\t\tforeach ($input_params as $params_row) {\n\t\t\t\t// check if the #values in $input_params matches the #values in $param_types\n\t\t\t\t$params_bound = true;\n\t\t\t\tif (count($params_row) === count($param_types)) {\n\t\t\t\t\t// they do\n\t\t\t\t\t// bind the params\n\t\t\t\t\tfor ($i = 0; $i < count($params_row); $i++) {\n\t\t\t\t\t\tif (!$pdo_statement->bindValue($i + 1, $params_row[$i], $param_types[$i])) {\n\t\t\t\t\t\t\t// the bind param failled\n\t\t\t\t\t\t\t$params_bound = false;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}else{\n\t\t\t\t\t// they don't\n\t\t\t\t\t$params_bound = false;\n\t\t\t\t}\n\n\t\t\t\t// execute the query\n\t\t\t\tif ($params_bound && $pdo_statement->execute()) {\n\t\t\t\t\t// the query was executed\n\t\t\t\t\t// check if there is any max to the rowCount() return value\n\t\t\t\t\tif ($max_row_count === null) {\n\t\t\t\t\t\t// there isn't\n\t\t\t\t\t\t$num_affected_rows += $pdo_statement->rowCount();\n\t\t\t\t\t}else{\n\t\t\t\t\t\t// there is\n\t\t\t\t\t\t$num_affected_rows += min($pdo_statement->rowCount(), $max_row_count);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// return the number of updated rows\n\t\t\treturn($num_affected_rows);\n\t\t}catch (PDOException $e) {\n\t\t\treturn(0);\n\t\t}\n\t}\n}\n\n?>",
+ "General.php" : ""
},
"interfaces" : {},
"languages" : {},
"templates" : {
- "init.php" : "",
- "header.php" : "\n\n\n\n\n\t