This commit is contained in:
Ty Clifford
2026-07-03 07:31:09 -04:00
commit cebb0d3af1
800 changed files with 89782 additions and 0 deletions
+123
View File
@@ -0,0 +1,123 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class dbJSON {
public $db;
public $dbBackup;
public $file;
public $firstLine;
// $file, the JSON file.
// $firstLine, TRUE if you want to remove the first line, FALSE otherwise
function __construct($file, $firstLine=true)
{
$this->file = $file;
$this->db = array();
$this->dbBackup = array();
$this->firstLine = $firstLine;
if (file_exists($file)) {
// Read JSON file
$lines = file($file);
// Remove the first line, the first line is for security reasons
if ($firstLine) {
unset($lines[0]);
}
// Regenerate the JSON file
$implode = implode('', $lines);
// Unserialize, JSON to Array
$array = $this->unserialize($implode);
if (empty($array)) {
$this->db = array();
$this->dbBackup = array();
} else {
$this->db = $array;
$this->dbBackup = $array;
}
}
}
public function restoreDB()
{
$this->db = $this->dbBackup;
return true;
}
// Returns the number of rows in the database
public function count()
{
return count($this->db);
}
// Returns the value from the field
public function getField($field)
{
if (isset($this->db[$field])) {
return $this->db[$field];
}
if (isset($this->dbFields[$field])) {
return $this->dbFields[$field];
}
return null;
}
// Save the JSON file
public function save()
{
$data = '';
if ($this->firstLine) {
$data = "<?php defined('BLUDIT') or die('Bludit CMS.'); ?>".PHP_EOL;
}
// Serialize database
$data .= $this->serialize($this->db);
// Backup the new database.
$this->dbBackup = $this->db;
// LOCK_EX flag to prevent anyone else writing to the file at the same time.
if (file_put_contents($this->file, $data, LOCK_EX)) {
return true;
} else {
Log::set(__METHOD__.LOG_SEP.'Error occurred when trying to save the database file.', LOG_TYPE_ERROR);
return false;
}
}
// Returns a JSON encoded string on success or FALSE on failure
private function serialize($data)
{
if (DEBUG_MODE) {
return json_encode($data, JSON_PRETTY_PRINT);
}
return json_encode($data);
}
// Returns the value encoded in json in appropriate PHP type
private function unserialize($data)
{
// NULL is returned if the json cannot be decoded
$decode = json_decode($data, true);
if ($decode===NULL) {
Log::set(__METHOD__.LOG_SEP.'Error trying to read the JSON file: '.$this->file, LOG_TYPE_ERROR);
return false;
}
return $decode;
}
public function getDB()
{
return $this->db;
}
// Truncate all the rows
public function truncate()
{
$this->db = array();
return $this->save();
}
}
+191
View File
@@ -0,0 +1,191 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
/*
Database structure
{
"videos": {
"name": "Videos",
"template: "",
"description: "",
"list": [ "my-page", "second-page" ]
},
"pets": {
"name": "Pets",
"template: "",
"description: "",
"list": [ "cats-and-dogs" ]
}
}
*/
class dbList extends dbJSON
{
public $db = array();
function __construct($file)
{
parent::__construct($file);
}
public function keys()
{
return array_keys($this->db);
}
// Returns the list of keys filter by pageNumber
// $pageNumber start in 1
public function getList($key, $pageNumber, $numberOfItems)
{
if (!isset($this->db[$key])) {
Log::set(__METHOD__.LOG_SEP.'Error key does not exist '.$key);
return false;
}
// List of keys
$list = $this->db[$key]['list'];
// Returns all the items from the list
if ($numberOfItems==-1) {
return $list;
}
// The first page number is 1, so the real is 0
$realPageNumber = $pageNumber - 1;
$chunks = array_chunk($list, $numberOfItems);
if (isset($chunks[$realPageNumber])) {
return $chunks[$realPageNumber];
}
// Out of index,returns FALSE
return false;
}
public function generateKey($name)
{
global $L;
$key = Text::cleanUrl($name);
if (Text::isEmpty($key)) {
$key = $L->g('empty');
}
while (isset($this->db[$key])) {
$key++;
}
return $key;
}
// Add a new item to the dblist
// $args => 'name', 'template', 'description', 'list'
public function add($args)
{
$key = $this->generateKey($args['name']);
$this->db[$key]['name'] = Sanitize::removeTags($args['name']);
$this->db[$key]['template'] = isset($args['template'])?Sanitize::removeTags($args['template']):'';
$this->db[$key]['description'] = isset($args['description'])?Sanitize::removeTags($args['description']):'';
$this->db[$key]['list'] = isset($args['list'])?$args['list']:array();
$this->sortAlphanumeric();
$this->save();
return $key;
}
public function remove($key)
{
if (!isset($this->db[$key])) {
Log::set(__METHOD__.LOG_SEP.'The key does not exist, key: '.$key);
return false;
}
unset($this->db[$key]);
return $this->save();
}
// Edit an item to the dblist
// $args => 'name', 'oldkey', 'newKey', 'template', 'description'
public function edit($args)
{
if ( isset($this->db[$args['newKey']]) && ($args['newKey']!==$args['oldKey']) ) {
Log::set(__METHOD__.LOG_SEP.'The new key already exists. Key: '.$args['newKey'], LOG_TYPE_WARN);
return false;
}
$this->db[$args['newKey']]['name'] = Sanitize::removeTags($args['name']);
$this->db[$args['newKey']]['template'] = isset($args['template'])?Sanitize::removeTags($args['template']):'';
$this->db[$args['newKey']]['description'] = isset($args['description'])?Sanitize::removeTags($args['description']):'';
$this->db[$args['newKey']]['list'] = $this->db[$args['oldKey']]['list'];
// Remove the old category
if ($args['oldKey'] !== $args['newKey']) {
unset( $this->db[$args['oldKey']] );
}
$this->sortAlphanumeric();
$this->save();
return $args['newKey'];
}
// Sort the categories by "Natural order"
public function sortAlphanumeric()
{
// Sort key alphanumeric strings, a01, a10, b10, c02
return ksort($this->db);
}
// Returns the name associated to the key, FALSE if the key doesn't exist
public function getName($key)
{
if (isset($this->db[$key])) {
return $this->db[$key]['name'];
}
return false;
}
// Returns an array with key=>name of the list
public function getKeyNameArray()
{
$tmp = array();
foreach($this->db as $key=>$fields) {
$tmp[$key] = $fields['name'];
}
return $tmp;
}
// Returns the number of items in the list
public function countItems($key)
{
if (isset($this->db[$key])) {
return count($this->db[$key]['list']);
}
return 0;
}
public function exists($key)
{
return isset( $this->db[$key] );
}
public function existsName($name)
{
foreach ($this->db as $key=>$fields) {
if ($name==$fields['name']) {
return true;
}
}
return false;
}
// Returns an array with a portion of the database filtered by key
// Returns array( 'key'=>'', 'name'=>'', 'template'=>'', 'description'=>'', list'=>array() )
public function getMap($key)
{
if (isset($this->db[$key])) {
$tmp = $this->db[$key];
$tmp['key'] = $key;
return $tmp;
}
return false;
}
}
+354
View File
@@ -0,0 +1,354 @@
<?php defined('BLUDIT') or die('Bludit CMS.');
class Plugin
{
// (string) directory name, just the name
// Ex: sitemap
public $directoryName;
// (string) Absolute database filename and path
// Ex: /www/bludit/bl-content/plugins/sitemap/db.php
public $filenameDb;
// (string) Absolute metadata filename and path
// Ex: /www/bludit/bl-plugins/sitemap/metadata.json
public $filenameMetadata;
// (array) Plugin metadata
// Ex: array('author'=>'',...., 'notes'=>'')
public $metadata;
// (string) Class name
// Ex: pluginSitemap
public $className;
// (array) Database unserialized
public $db;
// (array) Database fields, only for initialize
public $dbFields;
// (boolean) Enable or disable default Save and Cancel button on plugin settings
public $formButtons;
// (array) List of custom hooks
public $customHooks;
function __construct()
{
$this->dbFields = array();
$this->customHooks = array();
$reflector = new ReflectionClass(get_class($this));
// Directory name
$this->directoryName = basename(dirname($reflector->getFileName()));
// Class Name
$this->className = $reflector->getName();
$this->formButtons = true;
// Call the method init() from the children
$this->init();
// Init empty database with default values
$this->db = $this->dbFields;
$this->filenameDb = PATH_PLUGINS_DATABASES . $this->directoryName . DS . 'db.php';
// --- Metadata ---
$this->filenameMetadata = PATH_PLUGINS . $this->directoryName() . DS . 'metadata.json';
$metadataString = file_get_contents($this->filenameMetadata);
$this->metadata = json_decode($metadataString, true);
// If the plugin is installed then get the database
if ($this->installed()) {
$Tmp = new dbJSON($this->filenameDb);
$this->db = $Tmp->db;
$this->prepare();
}
}
public function save()
{
$tmp = new dbJSON($this->filenameDb);
$tmp->db = $this->db;
return $tmp->save();
}
public function includeCSS($filename)
{
return '<link rel="stylesheet" type="text/css" href="' . $this->domainPath() . 'css/' . $filename . '?version=' . BLUDIT_VERSION . '">' . PHP_EOL;
}
public function includeJS($filename)
{
return '<script charset="utf-8" src="' . $this->domainPath() . 'js/' . $filename . '?version=' . BLUDIT_VERSION . '"></script>' . PHP_EOL;
}
// Returns absolute URL and path of the plugin directory
// This function helps to include CSS or Javascript files with absolute URL
public function domainPath()
{
return DOMAIN_PLUGINS . $this->directoryName . '/';
}
// Returns relative path of the plugin directory
// This function helps to include CSS or Javascript files with relative URL
public function htmlPath()
{
return HTML_PATH_PLUGINS . $this->directoryName . '/';
}
// Returns absolute path of the plugin directory
// This function helps to include PHP libraries or some file at server level
public function phpPath()
{
return PATH_PLUGINS . $this->directoryName . DS;
}
public function phpPathDB()
{
return PATH_PLUGINS_DATABASES . $this->directoryName . DS;
}
// Returns the value of the key from the metadata of the plugin, FALSE if the key doesn't exist
public function getMetadata($key)
{
if (isset($this->metadata[$key])) {
return $this->metadata[$key];
}
return false;
}
// Set a key / value on the metadata of the plugin
public function setMetadata($key, $value)
{
$this->metadata[$key] = $value;
return true;
}
// Returns the value of the field from the database
// (string) $field
// (boolean) $html, TRUE returns the value sanitized, FALSE unsanitized
public function getValue($field, $html = true)
{
if (isset($this->db[$field])) {
if ($html) {
return $this->db[$field];
} else {
return Sanitize::htmlDecode($this->db[$field]);
}
}
return $this->dbFields[$field];
}
public function label()
{
return $this->getMetadata('label');
}
public function name()
{
return $this->getMetadata('name');
}
public function description()
{
return $this->getMetadata('description');
}
public function author()
{
return $this->getMetadata('author');
}
public function email()
{
return $this->getMetadata('email');
}
public function website()
{
return $this->getMetadata('website');
}
public function position()
{
return $this->getValue('position');
}
public function version()
{
return $this->getMetadata('version');
}
public function releaseDate()
{
return $this->getMetadata('releaseDate');
}
public function className()
{
return $this->className;
}
public function formButtons()
{
return $this->formButtons;
}
public function isCompatible()
{
$bluditRoot = explode('.', BLUDIT_VERSION);
$compatible = explode(',', $this->getMetadata('compatible'));
foreach ($compatible as $version) {
$root = explode('.', $version);
if ($root[0] == $bluditRoot[0] && $root[1] == $bluditRoot[1]) {
return true;
}
}
return false;
}
public function directoryName()
{
return $this->directoryName;
}
// Return TRUE if the installation success, otherwise FALSE.
public function install($position = 1)
{
if ($this->installed()) {
return false;
}
// Create workspace
$workspace = $this->workspace();
mkdir($workspace, DIR_PERMISSIONS, true);
// Create plugin directory for the database
mkdir(PATH_PLUGINS_DATABASES . $this->directoryName, DIR_PERMISSIONS, true);
$this->dbFields['position'] = $position;
// Sanitize default values to store in the file
foreach ($this->dbFields as $key => $value) {
$value = Sanitize::html($value);
settype($value, gettype($this->dbFields[$key]));
$this->db[$key] = $value;
}
// Create the database
return $this->save();
}
public function uninstall()
{
// Delete database
$path = PATH_PLUGINS_DATABASES . $this->directoryName;
Filesystem::deleteRecursive($path);
// Delete workspace
$workspace = $this->workspace();
Filesystem::deleteRecursive($workspace);
return true;
}
// Returns TRUE if the plugin is installed
// This function just check if the database of the plugin is created
public function installed()
{
return file_exists($this->filenameDb);
}
public function workspace()
{
return PATH_WORKSPACES . $this->directoryName . DS;
}
public function init()
{
// This method is used on children classes
// The user can define his own field of the database
}
public function prepare()
{
// This method is used on children classes
// The user can prepare the plugin, when it is installed
}
public function post()
{
$args = $_POST;
foreach ($this->dbFields as $field => $value) {
if (isset($args[$field])) {
$finalValue = Sanitize::html($args[$field]);
if ($finalValue === 'false') {
$finalValue = false;
} elseif ($finalValue === 'true') {
$finalValue = true;
}
settype($finalValue, gettype($value));
$this->db[$field] = $finalValue;
}
}
return $this->save();
}
public function type()
{
return $this->getMetadata('type');
}
public function setField($field, $value)
{
$this->db[$field] = Sanitize::html($value);
return $this->save();
}
public function setPosition($position)
{
return $this->setField('position', $position);
}
// Returns the parameters after the URI, FALSE if the URI doesn't match with the webhook
// Example: https://www.mybludit.com/api/foo/bar
public function webhook($URI = false, $returnsAfterURI = false, $fixed = true)
{
global $url;
if (empty($URI)) {
return false;
}
// Check URI start with the webhook
$startString = HTML_PATH_ROOT . $URI;
$URI = $url->uri();
$length = mb_strlen($startString, CHARSET);
if (mb_substr($URI, 0, $length) != $startString) {
return false;
}
$afterURI = mb_substr($URI, $length);
if (!empty($afterURI)) {
if ($fixed) {
return false;
}
if ($afterURI[0] != '/') {
return false;
}
}
if ($returnsAfterURI) {
return $afterURI;
}
Log::set(__METHOD__ . LOG_SEP . 'Webhook requested.');
return true;
}
}