Browse Source

Initial commit

master
Sven Slootweg 10 years ago
commit
ede5d9f3fe
  1. 14
      LICENSE
  2. 41
      base.php
  3. 154
      class.base.php
  4. 404
      class.databaserecord.php
  5. 79
      class.localizer.php
  6. 132
      class.templater.php
  7. 72
      components/component.errorhandler.php
  8. 319
      components/component.formbuilder.php
  9. 62
      components/component.router.php
  10. 19
      config.mysql.sample.php
  11. 42
      config.sample.php
  12. 24
      include.constants.php
  13. 180
      include.datetime.php
  14. 101
      include.dependencies.php
  15. 23
      include.exceptions.php
  16. 156
      include.memcache.php
  17. 120
      include.misc.php
  18. 27
      include.mysql.php
  19. 16
      include.session.php

14
LICENSE

@ -0,0 +1,14 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

41
base.php

@ -0,0 +1,41 @@
<?php
/*
* CPHP is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
require("include.constants.php");
require("cphp/config.php");
require("include.dependencies.php");
require("include.exceptions.php");
require("include.datetime.php");
require("include.misc.php");
require("include.memcache.php");
require("include.mysql.php");
require("include.session.php");
require("class.templater.php");
require("class.localizer.php");
$locale = new Localizer();
$locale->Load($cphp_locale_name);
setlocale(LC_ALL, $locale->locale);
require("class.base.php");
require("class.databaserecord.php");
foreach($cphp_components as $component)
{
require("components/component.{$component}.php");
}

154
class.base.php

@ -0,0 +1,154 @@
<?php
/*
* CPHP is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if($_CPHP !== true) { die(); }
class CPHPBaseClass
{
public $render_template = "";
public function RenderTimeAgo($template, $property)
{
global $locale;
$variable_name = "s{$property}";
if(isset($this->$variable_name) && is_numeric($this->$variable_name))
{
$timestamp = $this->$variable_name;
if($timestamp > time())
{
$sTimeAgo = $locale->strings['event-future'];
}
elseif($timestamp == time())
{
$sTimeAgo = $locale->strings['event-now'];
}
else
{
$date1 = new DateTime("@{$timestamp}", new DateTimeZone("GMT"));
$date2 = new DateTime("now", new DateTimeZone("GMT"));
$interval = $date1->diff($date2);
$years = (int)$interval->format("%G");
$months = (int)$interval->format("%m");
$weeks = (int)$interval->format("%U");
$days = (int)$interval->format("%d");
$hours = (int)$interval->format("%H");
$minutes = (int)$interval->format("%i");
$seconds = (int)$interval->format("%S");
if($years > 1)
{
$sTimeAgo = sprintf($locale->strings['event-years-ago'], $years);
}
elseif($years == 1)
{
$sTimeAgo = $locale->strings['event-1year-ago'];
}
elseif($months > 1)
{
$sTimeAgo = sprintf($locale->strings['event-months-ago'], $months);
}
elseif($months == 1)
{
$sTimeAgo = $locale->strings['event-1month-ago'];
}
elseif($weeks > 1)
{
$sTimeAgo = sprintf($locale->strings['event-weeks-ago'], $weeks);
}
elseif($weeks == 1)
{
$sTimeAgo = $locale->strings['event-1week-ago'];
}
elseif($days > 1)
{
$sTimeAgo = sprintf($locale->strings['event-days-ago'], $days);
}
elseif($days == 1)
{
$sTimeAgo = $locale->strings['event-1day-ago'];
}
elseif($hours > 1)
{
$sTimeAgo = sprintf($locale->strings['event-hours-ago'], $hours);
}
elseif($hours == 1)
{
$sTimeAgo = $locale->strings['event-1hour-ago'];
}
elseif($minutes > 1)
{
$sTimeAgo = sprintf($locale->strings['event-minutes-ago'], $minutes);
}
elseif($minutes == 1)
{
$sTimeAgo = $locale->strings['event-1minute-ago'];
}
elseif($seconds > 1)
{
$sTimeAgo = sprintf($locale->strings['event-seconds-ago'], $seconds);
}
elseif($seconds == 1)
{
$sTimeAgo = $locale->strings['event-1second-ago'];
}
else
{
// If you see this, there's probably something wrong.
$sTimeAgo = $locale->strings['event-past'];
}
}
$sDate = local_from_unix($timestamp, $locale->datetime_long);
return $this->RenderTemplateExternal($template, array(
'local-time' => $sDate,
'time-ago' => $sTimeAgo,
'timestamp' => $timestamp
));
}
else
{
$classname = get_class($this);
throw new Exception("Property {$classname}.{$property} does not exist or is not of a valid format.");
}
}
public function RenderTemplateExternal($template, $strings)
{
return $this->DoRenderTemplate($template, $strings);
}
public function DoRenderTemplate($template, $strings)
{
global $locale;
try
{
$tpl = new Templater();
$tpl->Load($template);
$tpl->Localize($locale->strings);
$tpl->Compile($strings);
return $tpl->Render();
}
catch(Exception $e)
{
$classname = get_class($this);
throw new Exception("Failed to render template {$classname}.{$template}.");
}
}
}

404
class.databaserecord.php

@ -0,0 +1,404 @@
<?php
/*
* CPHP is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if($_CPHP !== true) { die(); }
abstract class CPHPDatabaseRecordClass extends CPHPBaseClass
{
public $fill_query = "";
public $verify_query = "";
public $table_name = "";
public $query_cache = 60;
public $prototype = array();
public $prototype_render = array();
public $uData = array();
public $sId = 0;
public function __construct($uDataSource, $uCommunityId = 0)
{
$this->ConstructDataset($uDataSource, $uCommunityId);
$this->EventConstructed();
}
public function ConstructDataset($uDataSource, $uCommunityId = 0)
{
$bind_datasets = true;
if(is_numeric($uDataSource))
{
if($uDataSource != 0)
{
if(!empty($this->fill_query))
{
$this->sId = (is_numeric($uDataSource)) ? $uDataSource : 0;
$query = sprintf($this->fill_query, $uDataSource);
if($result = mysql_query_cached($query, $this->query_cache))
{
$uDataSource = $result->data[0];
}
else
{
$classname = get_class($this);
throw new NotFoundException("Could not locate {$classname} {$uDataSource} in database.");
}
}
else
{
$classname = get_class($this);
throw new PrototypeException("No fill query defined for {$classname} class.");
}
}
else
{
$bind_datasets = false;
}
}
elseif(is_object($uDataSource))
{
if(isset($uDataSource->data[0]))
{
$uDataSource = $uDataSource->data[0];
}
else
{
throw new NotFoundException("No result set present in object.");
}
}
elseif(is_array($uDataSource))
{
if(isset($uDataSource[0]))
{
$uDataSource = $uDataSource[0];
}
}
else
{
$classname = get_class($this);
throw new ConstructorException("Invalid type passed on to constructor for object of type {$classname}.");
}
if($bind_datasets === true)
{
$this->sId = (is_numeric($uDataSource['Id'])) ? $uDataSource['Id'] : 0;
$this->uData = $uDataSource;
foreach($this->prototype as $type => $dataset)
{
$this->BindDataset($type, $dataset);
}
$this->sFound = true;
}
else
{
$this->sFound = false;
}
if(!empty($uCommunityId) && !empty($this->sCommunityId))
{
$sCommunityId = (is_numeric($uCommunityId)) ? $uCommunityId : 0;
if($sCommunityId != $this->sCommunity->sId)
{
$classname = get_class($this);
throw new OwnershipException("{$classname} {$this->sId} does not belong to Community {$sCommunityId}.");
}
}
}
public function BindDataset($type, $dataset)
{
global $cphp_class_map;
if(is_array($dataset))
{
foreach($dataset as $variable_name => $column_name)
{
$original_value = $this->uData[$column_name];
switch($type)
{
case "string":
$value = htmlspecialchars(stripslashes($original_value));
$variable_type = CPHP_VARIABLE_SAFE;
break;
case "html":
$value = filter_html(stripslashes($original_value));
$variable_type = CPHP_VARIABLE_SAFE;
break;
case "simplehtml":
$value = filter_html_strict(stripslashes($original_value));
$variable_type = CPHP_VARIABLE_SAFE;
break;
case "nl2br":
$value = nl2br(htmlspecialchars(stripslashes($original_value)), false);
$variable_type = CPHP_VARIABLE_SAFE;
break;
case "numeric":
$value = (is_numeric($original_value)) ? $original_value : 0;
$variable_type = CPHP_VARIABLE_SAFE;
break;
case "timestamp":
$value = unix_from_mysql($original_value);
$variable_type = CPHP_VARIABLE_SAFE;
break;
case "boolean":
$value = (empty($original_value)) ? false : true;
$variable_type = CPHP_VARIABLE_SAFE;
break;
case "user":
$value = new User($original_value);
$variable_type = CPHP_VARIABLE_SAFE;
break;
case "none":
$value = $original_value;
$variable_type = CPHP_VARIABLE_UNSAFE;
break;
default:
$found = false;
foreach($cphp_class_map as $class_type => $class_name)
{
if($type == $class_type)
{
$value = new $class_name($original_value);
$variable_type = CPHP_VARIABLE_SAFE;
$found = true;
}
}
if($found == false)
{
$classname = get_class($this);
throw new Exception("Cannot determine type of dataset ({$type}) passed on to {$classname}.BindDataset.");
break;
}
}
if($variable_type == CPHP_VARIABLE_SAFE)
{
$variable_name_safe = "s" . $variable_name;
$this->$variable_name_safe = $value;
}
$variable_name_unsafe = "u" . $variable_name;
$this->$variable_name_unsafe = $original_value;
}
}
else
{
$classname = get_class($this);
throw new Exception("Invalid dataset passed on to {$classname}.BindDataset.");
}
}
public function DoRenderInternalTemplate()
{
if(!empty($this->render_template))
{
$strings = array();
foreach($this->prototype_render as $template_var => $object_var)
{
$variable_name = "s" . $object_var;
$strings[$template_var] = $this->$variable_name;
}
return $this->DoRenderTemplate($this->render_template, $strings);
}
else
{
$classname = get_class($this);
throw new Exception("Cannot render template: no template defined for {$classname} class.");
}
}
public function InsertIntoDatabase()
{
if(!empty($this->verify_query))
{
if($this->sId == 0)
{
$insert_mode = CPHP_INSERTMODE_INSERT;
}
else
{
$query = sprintf($this->verify_query, $this->sId);
if($result = mysql_query_cached($query))
{
$insert_mode = CPHP_INSERTMODE_UPDATE;
}
else
{
$insert_mode = CPHP_INSERTMODE_INSERT;
}
}
$element_list = array();
foreach($this->prototype as $type_key => $type_value)
{
foreach($type_value as $element_key => $element_value)
{
switch($type_key)
{
case "none":
case "numeric":
case "boolean":
case "timestamp":
case "string":
$element_list[$element_value] = array(
'key' => $element_key,
'type' => $type_key
);
break;
default:
break;
}
}
}
$sKeyList = array();
$sValueList = array();
foreach($element_list as $sKey => $value)
{
$variable_name_safe = "s" . $value['key'];
$variable_name_unsafe = "u" . $value['key'];
if(isset($this->$variable_name_safe) || isset($this->$variable_name_unsafe))
{
switch($value['type'])
{
case "none":
$sFinalValue = mysql_real_escape_string($this->$variable_name_unsafe);
break;
case "numeric":
$number = (isset($this->$variable_name_unsafe)) ? $this->$variable_name_unsafe : $this->$variable_name_safe;
$sFinalValue = (is_numeric($number)) ? $number : 0;
break;
case "boolean":
$bool = (isset($this->$variable_name_unsafe)) ? $this->$variable_name_unsafe : $this->$variable_name_safe;
$sFinalValue = ($bool) ? "1" : "0";
break;
case "timestamp":
$sFinalValue = (isset($this->$variable_name_safe)) ? mysql_from_unix($this->$variable_name_safe) : mysql_from_unix(unix_from_local($this->$variable_name_unsafe));
break;
case "string":
$sFinalValue = (isset($this->$variable_name_unsafe)) ? mysql_real_escape_string($this->$variable_name_unsafe) : mysql_real_escape_string($this->$variable_name_safe);
break;
case "default":
$sFinalValue = mysql_real_escape_string($this->$variable_name_unsafe);
break;
}
$sFinalValue = "'{$sFinalValue}'";
$sKey = "`{$sKey}`";
$sKeyList[] = $sKey;
$sValueList[] = $sFinalValue;
}
else
{
$classname = get_class($this);
throw new Exception("Database insertion failed: prototype property {$value['key']} not found in object of type {$classname}.");
}
}
if($insert_mode == CPHP_INSERTMODE_INSERT)
{
$sQueryKeys = implode(", ", $sKeyList);
$sQueryValues = implode(", ", $sValueList);
$query = "INSERT INTO {$this->table_name} ({$sQueryKeys}) VALUES ({$sQueryValues})";
}
elseif($insert_mode == CPHP_INSERTMODE_UPDATE)
{
$sKeyValueList = array();
for($i = 0; $i < count($sKeyList); $i++)
{
$sKey = $sKeyList[$i];
$sValue = $sValueList[$i];
$sKeyValueList[] = "{$sKey} = {$sValue}";
}
$sQueryKeysValues = implode(", ", $sKeyValueList);
$query = "UPDATE {$this->table_name} SET {$sQueryKeysValues} WHERE `Id` = '{$this->sId}'";
}
if($result = mysql_query($query))
{
if($insert_mode == CPHP_INSERTMODE_INSERT)
{
$this->sId = mysql_insert_id();
}
$this->PurgeCache();
return $result;
}
else
{
$classname = get_class($this);
throw new DatabaseException("Database insertion query failed in object of type {$classname}. Error message: " . mysql_error());
}
}
else
{
$classname = get_class($this);
throw new Exception("No verification query defined for {$classname} class.");
}
}
public function RetrieveChildren($type, $field)
{
if(!isset($cphp_class_map[$type]))
{
$classname = get_class($this);
throw new NotFoundException("Non-existent 'type' argument passed on to {$classname}.RetrieveChildren function.");
}
$parent_type = get_parent_class($cphp_class_map[$type]);
if($parent_type !== "CPHPDatabaseRecordClass")
{
$parent_type = ($parent_type === false) ? "NONE" : $parent_type;
$classname = get_class($this);
throw new TypeException("{$classname}.RetrieveChildren expected 'type' argument of parent-type CPHPDatabaseRecordClass, but got {$parent_type} instead.");
}
$query = "";
}
public function PurgeCache()
{
$query = sprintf($this->fill_query, $this->sId);
$key = md5($query) . md5($query . "x");
mc_delete($key);
}
public function RenderTemplate($template = "")
{
if(!empty($template))
{
$this->render_template = $template;
}
return $this->DoRenderInternalTemplate();
}
// Define events
protected function EventConstructed() { }
}

79
class.localizer.php

@ -0,0 +1,79 @@
<?php
/*
* CPHP is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if($_CPHP !== true) { die(); }
class Localizer
{
public $strings = array();
public $locale = "";
public $datetime_short = "";
public $datetime_long = "";
public $date_short = "";
public $date_long = "";
public $time = "";
public function Load($locale)
{
$this->strings = array();
$this->LoadInternal("english");
$this->LoadInternal($locale);
}
public function LoadInternal($locale)
{
global $cphp_locale_path, $cphp_locale_ext;
$lng_contents = file_get_contents("{$cphp_locale_path}/{$locale}.{$cphp_locale_ext}");
if($lng_contents !== false)
{
$lines = explode("\n", $lng_contents);
foreach($lines as $line)
{
$line = str_replace("\r", "", $line);
if(preg_match("/(.+?[^\\\]);(.+)/", $line, $matches))
{
$key = trim(str_replace("\;", ";", $matches[1]));
$value = trim(str_replace("\;", ";", $matches[2]));
switch($key)
{
case "_locale":
$this->locale = explode(",", $value);
break;
case "_datetime_short":
$this->datetime_short = $value;
break;
case "_datetime_long":
$this->datetime_long = $value;
break;
case "_date_short":
$this->date_short = $value;
break;
case "_date_long":
$this->date_long = $value;
break;
case "_time":
$this->time = $value;
break;
default:
$this->strings[$key] = $value;
break;
}
}
}
}
else
{
Throw new Exception("Failed to load locale {$locale}.");
}
}
}

132
class.templater.php

@ -0,0 +1,132 @@
<?php
/*
* CPHP is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if($_CPHP !== true) { die(); }
$template_cache = array();
class Templater
{
private $basedir = "templates/";
private $extension = ".tpl";
private $tpl = NULL;
private $tpl_rendered = NULL;
public function Load($template)
{
global $template_cache;
if(isset($template_cache[$template]))
{
$tpl_contents = $template_cache[$template];
}
else
{
$tpl_contents = file_get_contents($this->basedir . $template . $this->extension);
$template_cache[$template] = $tpl_contents;
}
if($tpl_contents !== false)
{
$this->tpl = $tpl_contents;
$this->tpl_rendered = $tpl_contents;
}
else
{
Throw new Exception("Failed to load template {$template}.");
}
}
public function Reset()
{
if(!is_null($this->tpl))
{
$this->tpl_rendered = $this->tpl;
}
else
{
Throw new Exception("No template loaded.");
}
}
public function Localize($strings)
{
if(!is_null($this->tpl))
{
preg_match_all("/<%!([a-zA-Z0-9_-]+)>/", $this->tpl_rendered, $strlist);
foreach($strlist[1] as $str)
{
if(isset($strings[$str]))
{
$this->tpl_rendered = str_replace("<%!{$str}>", $strings[$str], $this->tpl_rendered);
}
}
}
else
{
Throw new Exception("No template loaded.");
}
}
public function Compile($strings)
{
if(!is_null($this->tpl))
{
preg_match_all("/<%\?([a-zA-Z0-9_-]+)>/", $this->tpl_rendered, $strlist);
foreach($strlist[1] as $str)
{
if(isset($strings[$str]))
{
$this->tpl_rendered = str_replace("<%?{$str}>", $strings[$str], $this->tpl_rendered);
}
}
}
else
{
Throw new Exception("No template loaded.");
}
}
public function Render()
{
if(!is_null($this->tpl))
{
return $this->tpl_rendered;
}
else
{
Throw new Exception("No template loaded.");
}
}
public function Output()
{
if(!is_null($this->tpl))
{
echo($this->tpl_rendered);
}
else
{
Throw new Exception("No template loaded.");
}
}
public static function InlineRender($templatename, $localize = array(), $compile = array())
{
$template = new Templater();
$template->Load($templatename);
$template->Localize($localize);
$template->Compile($compile);
return $template->Render();
}
}

72
components/component.errorhandler.php

@ -0,0 +1,72 @@
<?php
/*
* CPHP is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
cphp_dependency_provides("cphp_errorhandler", "0.1");
define("CPHP_ERRORHANDLER_TYPE_ERROR", 90001 );
define("CPHP_ERRORHANDLER_TYPE_INFO", 90002 );
define("CPHP_ERRORHANDLER_TYPE_WARNING", 90003 );
define("CPHP_ERRORHANDLER_TYPE_SUCCESS", 90004 );
class CPHPErrorHandler
{
public $sErrorType = CPHP_ERRORHANDLER_TYPE_ERROR;
public $sLogError = true;
public $sTitle = "";
public $sMessage = "";
public function __construct($type, $title, $message, $log = true)
{
$this->sErrorType = $type;
$this->sLogError = $log;
$this->sTitle = $title;
$this->sMessage = $message;
}
public function LogError($context, $message)
{
// FIXME placeholder function, error logging has not been implemented yet
}
public function Render()
{
global $locale;
$template['error'] = new Templater();
switch($this->sErrorType)
{
case CPHP_ERRORHANDLER_TYPE_ERROR:
$template['error']->Load("errorhandler.error");
break;
case CPHP_ERRORHANDLER_TYPE_INFO:
$template['error']->Load("errorhandler.info");
break;
case CPHP_ERRORHANDLER_TYPE_WARNING:
$template['error']->Load("errorhandler.warning");
break;
case CPHP_ERRORHANDLER_TYPE_SUCCESS:
$template['error']->Load("errorhandler.success");
break;
}
$template['error']->Localize($locale->strings);
$template['error']->Compile(array(
'title' => $this->sTitle,
'message' => $this->sMessage
));
return $template['error']->Render();
}
}
?>

319
components/component.formbuilder.php

@ -0,0 +1,319 @@
<?php
/*
* CPHP is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
cphp_dependency_provides("cphp_formbuilder", "1.0");
$cphp_formbuilder_increment = 0;
abstract class CPHPFormBuilderBaseClass
{
public $parameters = array();
public function AddParameter($key, $value)
{
$this->parameters[$key] = $value;
}
public function RenderParameters($parameters)
{
if(empty($parameters))
{
return "";
}
$rendered = array();
foreach($parameters as $key => $value)
{
$value = utf8entities($value);
$rendered[] = "{$key}=\"{$value}\"";
}
return " " . implode(" ", $rendered);
}
public function RenderNote()
{
if(!empty($this->note))
{
return "<div class=\"cphp_fbd_note\">{$this->note}</div>";
}
else
{
return "";
}
}
}
abstract class CPHPFormBuilderContainer extends CPHPFormBuilderBaseClass
{
public $elements = array();
public function AddElement($element)
{
$this->elements[] = $element;
}
}
class CPHPFormBuilder extends CPHPFormBuilderContainer
{
public $method = "";
public $action = "";
public function __construct($method, $target)
{
$this->method = strtolower($method);
$this->action = $target;
}
public function Render()
{
$rendered_elements = "";
foreach($this->elements as $element)
{
$rendered_elements .= $element->Render();
}
$this->AddParameter("method", $this->method);
$this->AddParameter("action", $this->action);
$rendered_parameters = $this->RenderParameters($this->parameters);
return "<form{$rendered_parameters}>{$rendered_elements}</form>";
}
}
class CPHPFormSection extends CPHPFormBuilderContainer
{
public $label = "";
public $fieldset = true;
public $classname = "";
public function __construct($fieldset = true, $label = "")
{
if(!empty($label))
{
$this->label = $label;
}
$this->fieldset = $fieldset;
}
public function Render()
{
if(!empty($this->label))
{
$legend = "<legend>{$this->label}</legend>";
}
else
{
$legend = "";
}
if($this->fieldset === true)
{
$this->classname = trim("{$this->classname} cphp_fbd_fieldset");
}
$rendered_elements = "";
foreach($this->elements as $element)
{
$rendered_elements .= $element->Render();
}
if($this->fieldset === true)
{
$this->AddParameter("class", $this->classname);
$rendered_parameters = $this->RenderParameters($this->parameters);
return "<fieldset{$rendered_parameters}>{$legend}<div class=\"cphp_fbd_form\">{$rendered_elements}</div></fieldset>";
}
else
{
return "<div class=\"cphp_fbd_form\"{$rendered_parameters}>{$rendered_elements}</div>";
}
}
}
abstract class CPHPFormInputElement extends CPHPFormBuilderBaseClass
{
public $id = "";
public $name = "";
public $value = "";
public $label = "";
public function __construct($label, $name, $value = "", $note = "", $id = "")
{
global $cphp_formbuilder_increment;
$this->name = $name;
$this->value = $value;
$this->label = $label;
$this->note = $note;
if(empty($id))
{
$this->id = "cphp_fbd_{$cphp_formbuilder_increment}";
$cphp_formbuilder_increment += 1;
}
else
{
$this->id = $id;
}
}
}
abstract class CPHPFormInput extends CPHPFormInputElement
{
public function Render()
{
$this->AddParameter("id", $this->id);
$this->AddParameter("type", $this->type);
$this->AddParameter("name", $this->name);
$this->AddParameter("value", $this->value);
$rendered_parameters = $this->RenderParameters($this->parameters);
$rendered_note = $this->RenderNote();
return "<div class=\"cphp_fbd_row\"><div class=\"cphp_fbd_label\">{$this->label}{$rendered_note}</div><div class=\"cphp_fbd_field\"><input{$rendered_parameters}></div></div>";
}
}
class CPHPFormTextInput extends CPHPFormInput
{
public $type = "text";
}
class CPHPFormPasswordInput extends CPHPFormInput
{
public $type = "password";
}
class CPHPFormDateInput extends CPHPFormInput
{
public $type = "date";
}
class CPHPFormTimeInput extends CPHPFormInput
{
public $type = "time";
}
class CPHPFormEmailInput extends CPHPFormInput
{
public $type = "email";
}
class CPHPFormUrlInput extends CPHPFormInput
{
public $type = "url";
}
class CPHPFormRangeInput extends CPHPFormInput
{
public $type = "range";
}
class CPHPFormColorInput extends CPHPFormInput
{
public $type = "color";
}
class CPHPFormSearchInput extends CPHPFormInput
{
public $type = "search";
}
class CPHPFormCheckboxGroup extends CPHPFormBuilderContainer
{
public function __construct($label, $note = "")
{
global $cphp_formbuilder_increment;
$this->label = $label;
$this->note = $note;
}
public function Render()
{
$rendered_note = $this->RenderNote();
$rendered_elements = "";
foreach($this->elements as $element)
{
$rendered_elements .= $element->Render();
}
return "<div class=\"cphp_fbd_row\"><div class=\"cphp_fbd_label\">{$this->label}{$rendered_note}</div><div class=\"cphp_fbd_field\">{$rendered_elements}</div></div>";
}
}
class CPHPFormCheckbox extends CPHPFormInputElement
{
public function Render()
{
$this->AddParameter("id", $this->id);
$this->AddParameter("type", "checkbox");
$this->AddParameter("name", $this->name);
if($this->value === true)
{
$this->AddParameter("checked", "");
}
$rendered_parameters = $this->RenderParameters($this->parameters);
$rendered_note = $this->RenderNote();
return "<div class=\"cphp_fbd_cblabel\"><input{$rendered_parameters}><label for=\"{$this->id}\">{$this->label}{$rendered_note}</label></div>";
}
}
class CPHPFormRadioButton extends CPHPFormInput
{
public $type = "radio";
}
class CPHPFormButton extends CPHPFormInputElement
{
public $type = "button";
public function Render()
{
$this->AddParameter("type", $this->type);
$this->AddParameter("name", $this->name);
$this->AddParameter("value", $this->value);
$rendered_parameters = $this->RenderParameters($this->parameters);
return "<div class=\"cphp_fbd_row\"><div class=\"cphp_fbd_label\"></div><div class=\"cphp_fbd_field\"><button{$rendered_parameters}>{$this->label}</button></div></div>";
}
}
class CPHPFormSubmitButton extends CPHPFormButton
{
public $type = "submit";
}
class CPHPFormResetButton extends CPHPFormButton
{
public $type = "reset";
}
class CPHPFormSelect extends CPHPFormInputElement
{
public $options = array();
}
?>

62
components/component.router.php

@ -0,0 +1,62 @@
<?php
/*
* CPHP is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
cphp_dependency_provides("cphp_router", "1.0");
class CPHPRouter extends CPHPBaseClass
{
public $routes = array();
public $parameters = array();
public $custom_query = "";
public function RouteRequest()
{
eval(extract_globals()); // hack hackity hack hack
if(!empty($this->custom_query))
{
$requestpath = $this->custom_query;
}
else
{
if(!empty($_SERVER['REQUEST_URI']))
{
$requestpath = trim($_SERVER['REQUEST_URI']);
}
else
{
$requestpath = "/";
}
}
$found = false; // Workaround because a break after an include apparently doesn't work in PHP.
foreach($this->routes as $priority)
{
foreach($priority as $route_regex => $route_destination)
{
if($found === false)
{
$regex = str_replace("/", "\/", $route_regex);
if(preg_match("/{$regex}/i", $requestpath, $matches))
{
$this->uParameters = $matches;
include($route_destination);
$found = true;
}
}
}
}
}
}
?>

19
config.mysql.sample.php

@ -0,0 +1,19 @@
<?php
/*
* CPHP is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
$cphp_mysql_host = "localhost";
$cphp_mysql_user = "root";
$cphp_mysql_pass = "";
$cphp_mysql_db = "";
?>

42
config.sample.php

@ -0,0 +1,42 @@
<?php
/*
* CPHP is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if($_CPHP !== true) { die(); }
$cphp_class_map = array(
'classa' => "ClassA",
'classb' => "ClassB"
);
$cphp_locale_name = "english";
$cphp_locale_path = "locales";
$cphp_locale_ext = "lng";
$cphp_usersettings[CPHP_SETTING_TIMEZONE] = "Europe/Amsterdam";
/* These are the memcache settings. You will need to have memcache set
* up on your server to use these. Compression requires zlib. */
$cphp_memcache_enabled = true; // Whether to user memcache.
$cphp_memcache_server = "localhost"; // The hostname of the memcached
$cphp_memcache_port = 11211; // The port number of memcached
$cphp_memcache_compressed = true; // Whether to compress memcache objects
$cphp_mysql_enabled = true;
require("config.mysql.php");
$cphp_components = array(
"router",
"errorhandler",
"formbuilder"
);

24
include.constants.php

@ -0,0 +1,24 @@
<?php
/*
* CPHP is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if($_CPHP !== true) { die(); }
define("CPHP_SETTING_TIMEZONE", 1100 );
define("CPHP_VARIABLE_SAFE", 1260 );
define("CPHP_VARIABLE_UNSAFE", 1261 );
define("CPHP_INSERTMODE_INSERT", 1270 );
define("CPHP_INSERTMODE_UPDATE", 1271 );
define("CPHP_REGEX_EMAIL", "/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i");

180
include.datetime.php

@ -0,0 +1,180 @@
<?php
/*
* CPHP is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if($_CPHP !== true) { die(); }
$timezones = array(
'Pacific/Kwajalein' => '(GMT-12:00) International Date Line West',
'Pacific/Midway' => '(GMT-11:00) Midway Island',
'Pacific/Samoa' => '(GMT-11:00) Samoa',
'Pacific/Honolulu' => '(GMT-10:00) Hawaii',
'America/Anchorage' => '(GMT-09:00) Alaska',
'America/Los_Angeles' => '(GMT-08:00) Pacific Time (US &amp; Canada)',
'America/Tijuana' => '(GMT-08:00) Tijuana, Baja California',
'America/Denver' => '(GMT-07:00) Mountain Time (US &amp; Canada)',
'America/Chihuahua' => '(GMT-07:00) Chihuahua',
'America/Mazatlan' => '(GMT-07:00) Mazatlan',
'America/Phoenix' => '(GMT-07:00) Arizona',
'America/Regina' => '(GMT-06:00) Saskatchewan',
'America/Tegucigalpa' => '(GMT-06:00) Central America',
'America/Chicago' => '(GMT-06:00) Central Time (US &amp; Canada)',
'America/Mexico_City' => '(GMT-06:00) Mexico City',
'America/Monterrey' => '(GMT-06:00) Monterrey',
'America/New_York' => '(GMT-05:00) Eastern Time (US &amp; Canada)',
'America/Bogota' => '(GMT-05:00) Bogota',
'America/Lima' => '(GMT-05:00) Lima',
'America/Rio_Branco' => '(GMT-05:00) Rio Branco',
'America/Indiana/Indianapolis' => '(GMT-05:00) Indiana (East)',
'America/Caracas' => '(GMT-04:30) Caracas',
'America/Halifax' => '(GMT-04:00) Atlantic Time (Canada)',
'America/Manaus' => '(GMT-04:00) Manaus',
'America/Santiago' => '(GMT-04:00) Santiago',
'America/La_Paz' => '(GMT-04:00) La Paz',
'America/St_Johns' => '(GMT-03:30) Newfoundland',
'America/Argentina/Buenos_Aires' => '(GMT-03:00) Georgetown',
'America/Sao_Paulo' => '(GMT-03:00) Brasilia',
'America/Godthab' => '(GMT-03:00) Greenland',
'America/Montevideo' => '(GMT-03:00) Montevideo',
'Atlantic/South_Georgia' => '(GMT-02:00) Mid-Atlantic',
'Atlantic/Azores' => '(GMT-01:00) Azores',
'Atlantic/Cape_Verde' => '(GMT-01:00) Cape Verde Is.',
'Europe/Dublin' => '(GMT) Dublin',
'Europe/Lisbon' => '(GMT) Lisbon',
'Europe/London' => '(GMT) London',
'Africa/Monrovia' => '(GMT) Monrovia',
'Atlantic/Reykjavik' => '(GMT) Reykjavik',
'Africa/Casablanca' => '(GMT) Casablanca',
'Europe/Belgrade' => '(GMT+01:00) Belgrade',
'Europe/Bratislava' => '(GMT+01:00) Bratislava',
'Europe/Budapest' => '(GMT+01:00) Budapest',
'Europe/Ljubljana' => '(GMT+01:00) Ljubljana',
'Europe/Prague' => '(GMT+01:00) Prague',
'Europe/Sarajevo' => '(GMT+01:00) Sarajevo',
'Europe/Skopje' => '(GMT+01:00) Skopje',
'Europe/Warsaw' => '(GMT+01:00) Warsaw',
'Europe/Zagreb' => '(GMT+01:00) Zagreb',
'Europe/Brussels' => '(GMT+01:00) Brussels',
'Europe/Copenhagen' => '(GMT+01:00) Copenhagen',
'Europe/Madrid' => '(GMT+01:00) Madrid',
'Europe/Paris' => '(GMT+01:00) Paris',
'Africa/Algiers' => '(GMT+01:00) West Central Africa',
'Europe/Amsterdam' => '(GMT+01:00) Amsterdam',
'Europe/Berlin' => '(GMT+01:00) Berlin',
'Europe/Rome' => '(GMT+01:00) Rome',
'Europe/Stockholm' => '(GMT+01:00) Stockholm',
'Europe/Vienna' => '(GMT+01:00) Vienna',
'Europe/Minsk' => '(GMT+02:00) Minsk',
'Africa/Cairo' => '(GMT+02:00) Cairo',
'Europe/Helsinki' => '(GMT+02:00) Helsinki',
'Europe/Riga' => '(GMT+02:00) Riga',
'Europe/Sofia' => '(GMT+02:00) Sofia',
'Europe/Tallinn' => '(GMT+02:00) Tallinn',
'Europe/Vilnius' => '(GMT+02:00) Vilnius',
'Europe/Athens' => '(GMT+02:00) Athens',
'Europe/Bucharest' => '(GMT+02:00) Bucharest',
'Europe/Istanbul' => '(GMT+02:00) Istanbul',
'Asia/Jerusalem' => '(GMT+02:00) Jerusalem',
'Asia/Amman' => '(GMT+02:00) Amman',
'Asia/Beirut' => '(GMT+02:00) Beirut',
'Africa/Windhoek' => '(GMT+02:00) Windhoek',
'Africa/Harare' => '(GMT+02:00) Harare',
'Asia/Kuwait' => '(GMT+03:00) Kuwait',
'Asia/Riyadh' => '(GMT+03:00) Riyadh',
'Asia/Baghdad' => '(GMT+03:00) Baghdad',
'Africa/Nairobi' => '(GMT+03:00) Nairobi',
'Asia/Tbilisi' => '(GMT+03:00) Tbilisi',
'Europe/Moscow' => '(GMT+03:00) Moscow',
'Europe/Volgograd' => '(GMT+03:00) Volgograd',
'Asia/Tehran' => '(GMT+03:30) Tehran',
'Asia/Muscat' => '(GMT+04:00) Muscat',
'Asia/Baku' => '(GMT+04:00) Baku',
'Asia/Yerevan' => '(GMT+04:00) Yerevan',
'Asia/Yekaterinburg' => '(GMT+05:00) Ekaterinburg',
'Asia/Karachi' => '(GMT+05:00) Karachi',
'Asia/Tashkent' => '(GMT+05:00) Tashkent',
'Asia/Kolkata' => '(GMT+05:30) Calcutta',
'Asia/Colombo' => '(GMT+05:30) Sri Jayawardenepura',
'Asia/Katmandu' => '(GMT+05:45) Kathmandu',
'Asia/Dhaka' => '(GMT+06:00) Dhaka',
'Asia/Almaty' => '(GMT+06:00) Almaty',
'Asia/Novosibirsk' => '(GMT+06:00) Novosibirsk',
'Asia/Rangoon' => '(GMT+06:30) Yangon (Rangoon)',
'Asia/Krasnoyarsk' => '(GMT+07:00) Krasnoyarsk',
'Asia/Bangkok' => '(GMT+07:00) Bangkok',
'Asia/Jakarta' => '(GMT+07:00) Jakarta',
'Asia/Brunei' => '(GMT+08:00) Beijing',
'Asia/Chongqing' => '(GMT+08:00) Chongqing',
'Asia/Hong_Kong' => '(GMT+08:00) Hong Kong',
'Asia/Urumqi' => '(GMT+08:00) Urumqi',
'Asia/Irkutsk' => '(GMT+08:00) Irkutsk',
'Asia/Ulaanbaatar' => '(GMT+08:00) Ulaan Bataar',
'Asia/Kuala_Lumpur' => '(GMT+08:00) Kuala Lumpur',
'Asia/Singapore' => '(GMT+08:00) Singapore',
'Asia/Taipei' => '(GMT+08:00) Taipei',
'Australia/Perth' => '(GMT+08:00) Perth',
'Asia/Seoul' => '(GMT+09:00) Seoul',
'Asia/Tokyo' => '(GMT+09:00) Tokyo',
'Asia/Yakutsk' => '(GMT+09:00) Yakutsk',
'Australia/Darwin' => '(GMT+09:30) Darwin',
'Australia/Adelaide' => '(GMT+09:30) Adelaide',
'Australia/Canberra' => '(GMT+10:00) Canberra',
'Australia/Melbourne' => '(GMT+10:00) Melbourne',
'Australia/Sydney' => '(GMT+10:00) Sydney',
'Australia/Brisbane' => '(GMT+10:00) Brisbane',
'Australia/Hobart' => '(GMT+10:00) Hobart',
'Asia/Vladivostok' => '(GMT+10:00) Vladivostok',
'Pacific/Guam' => '(GMT+10:00) Guam',
'Pacific/Port_Moresby' => '(GMT+10:00) Port Moresby',
'Asia/Magadan' => '(GMT+11:00) Magadan',
'Pacific/Fiji' => '(GMT+12:00) Fiji',
'Asia/Kamchatka' => '(GMT+12:00) Kamchatka',
'Pacific/Auckland' => '(GMT+12:00) Auckland',
'Pacific/Tongatapu' => '(GMT+13:00) Nukualofa'
);
function unix_from_local($timestamp)
{
global $user_preferences;
date_default_timezone_set($user_preferences[CPHP_SETTING_TIMEZONE]);
return strtotime($timestamp);
}
function unix_from_mysql($timestamp)
{
date_default_timezone_set("GMT");
return strtotime($timestamp);
}
function local_from_unix($timestamp, $format)
{
global $user_preferences;
date_default_timezone_set($user_preferences[CPHP_SETTING_TIMEZONE]);
return strftime($format, $timestamp);
}
function gmt_from_unix($timestamp, $format)
{
date_default_timezone_set("GMT");
return strftime($format, $timestamp);
}
function mysql_from_unix($timestamp)
{
date_default_timezone_set("GMT");
return date("Y-m-d H:i:s", $timestamp);
}
function floor_to_day($timestamp)
{
return floor($timestamp / (60 * 60 * 24)) * (60 * 60 * 24);
}

101
include.dependencies.php

@ -0,0 +1,101 @@
<?php
/*
* CPHP is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
$cphp_dependencies = array();
$cphp_last_dependency = "";
function cphp_dependency_provides($component, $version)
{
global $cphp_dependencies, $cphp_last_dependency;
$cphp_dependencies[$component] = $version;
$cphp_last_dependency = $component;
}
function cphp_dependency_requires($component, $version)
{
global $cphp_dependencies, $cphp_last_dependency;
if(!isset($cphp_dependencies[$component]))
{
die("The {$cphp_last_dependency} component requires the {$component} component to be loaded, but this is not the case.");
}
$current_version = $cphp_dependencies[$component];
if(!cphp_dependency_match($current_version, $version))
{
die("The {$cphp_last_dependency} component requires the {$component} component with version {$version} to be loaded, but an incompatible version ({$current_version}) was found.");
}
}
function cphp_dependency_match($available, $required)
{
if(strpos($required, ",") !== false)
{
$ranges = explode(",", $required);
}
else
{
$ranges[] = $version;
}
foreach($ranges as $range)
{
if(strpos($required, "|") !== false)
{
list($min, $max) = explode("|", $range);
$f_min = (float) $min;
$f_max = (float) $max;
$f_cur = (float) $available;
if(empty($min) && empty($max))
{
return true;
}
elseif(empty($min))
{
if($f_cur < $f_max)
{
return true;
}