diff --git a/.htaccess b/.htaccess new file mode 100644 index 000000000..d7e98ac48 --- /dev/null +++ b/.htaccess @@ -0,0 +1,7 @@ + + RewriteEngine on + RewriteRule ^$ public/ [L] + + #RewriteCond %{REQUEST_URI} !^/cake$ + RewriteRule (.*) public/$1 [L] + diff --git a/app/app_controller.php b/app/app_controller.php new file mode 100644 index 000000000..ed671b394 --- /dev/null +++ b/app/app_controller.php @@ -0,0 +1,104 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: AppController + * Enter description here... + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.app + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.app + * @since Cake v 0.2.9 + * + */ +class AppController extends Controller { + +/** + * Enter description here... + * + * @param unknown_type $tags + * @param unknown_type $active + * @return unknown + */ + function tags_as_links ($tags, $active=array()) { + $tags = is_array($tags)? $tags: Tag::split_tags($tags); + + $links = array(); + foreach ($tags as $tag) { + + if (in_array($tag, $active)) + $url_tags = $this->array_except($active, $tag); + else + $url_tags = array_merge($active, array($tag)); + + $url = '/memes/with_tags/'.$this->tags_to_url($url_tags); + + $links[] = $this->link_to($tag, $url, in_array($tag, $active)? array('class'=>'active_tag'): null); + } + + return join(' ', $links); + } + +/** + * Enter description here... + * + * @param unknown_type $array + * @param unknown_type $except + * @return unknown + */ + function array_except ($array, $except) { + if (!is_array($except)) $except = array($except); + $out = array(); + + foreach ($array as $k=>$v) { + if (!in_array($v, $except)) + $out[$k] = $v; + } + + return $out; + } + +/** + * Enter description here... + * + * @param unknown_type $tags + * @return unknown + */ + function tags_to_url ($tags) { + $out = array(); + foreach ($tags as $tag) + $out[] = urlencode($tag); + + return join('+', $out); + } + +} + +?> \ No newline at end of file diff --git a/app/app_model.php b/app/app_model.php new file mode 100644 index 000000000..4cb24687f --- /dev/null +++ b/app/app_model.php @@ -0,0 +1,44 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: AppModel + * Enter description here... + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.app + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.app + * @since Cake v 0.2.9 + * + */ +class AppModel extends Model { +} + +?> \ No newline at end of file diff --git a/app/controllers/put_controllers_here b/app/controllers/put_controllers_here new file mode 100644 index 000000000..e69de29bb diff --git a/app/models/put_models_here b/app/models/put_models_here new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/layouts/default.thtml b/app/views/layouts/default.thtml new file mode 100644 index 000000000..148df5885 --- /dev/null +++ b/app/views/layouts/default.thtml @@ -0,0 +1,14 @@ + + + + <?=$title_for_layout?> + + + + + + + + + + diff --git a/app/views/layouts/error.thtml b/app/views/layouts/error.thtml new file mode 100644 index 000000000..f0c37b4ff --- /dev/null +++ b/app/views/layouts/error.thtml @@ -0,0 +1,11 @@ + + + +<?=$code?> <?=$name?> + + + +

+

+ + diff --git a/app/views/layouts/flash.thtml b/app/views/layouts/flash.thtml new file mode 100644 index 000000000..5d43c69b5 --- /dev/null +++ b/app/views/layouts/flash.thtml @@ -0,0 +1,19 @@ + + + +<?=$page_title?> + + + + + + + +

+ + + diff --git a/app/views/put_views_folders_here b/app/views/put_views_folders_here new file mode 100644 index 000000000..e69de29bb diff --git a/config/database.php b/config/database.php new file mode 100644 index 000000000..366fa0de0 --- /dev/null +++ b/config/database.php @@ -0,0 +1,41 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: + * Enter description here... + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.config + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +$DATABASE_CONFIG = array( + 'devel' => array( + 'host' => 'localhost', + 'login' => 'www', + 'password' => 'www', + 'database' => 'ease' + ) +); + +?> \ No newline at end of file diff --git a/config/database.php.default b/config/database.php.default new file mode 100644 index 000000000..142496aa0 --- /dev/null +++ b/config/database.php.default @@ -0,0 +1,41 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: + * Enter description here... + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.config + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +$DATABASE_CONFIG = array( + 'devel' => array( + 'host' => 'localhost', + 'login' => 'cake', + 'password' => 'cake', + 'database' => 'cake' + ) +); + +?> \ No newline at end of file diff --git a/config/routes.php b/config/routes.php new file mode 100644 index 000000000..053b888e7 --- /dev/null +++ b/config/routes.php @@ -0,0 +1,42 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: + * Enter description here... + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.config + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +# Homepage +$Route->connect ('/', array('controller'=>'Memes', 'action'=>'add')); + +# Tags +$Route->connect ('/tags/popular', array('controller'=>'Tags', 'action'=>'popular')); +$Route->connect ('/tags/*', array('controller'=>'Memes', 'action'=>'with_tags')); + +# Default route +$Route->connect ('/:controller/:action/*'); + +?> \ No newline at end of file diff --git a/config/routes.php.default b/config/routes.php.default new file mode 100644 index 000000000..0c14b5d4a --- /dev/null +++ b/config/routes.php.default @@ -0,0 +1,44 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: + * Enter description here... + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.config + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +# Homepage +$Route->connect ('/', array('controller'=>'Pages', 'action'=>'view', 'home')); + +# Source browser +#$Route->connect ('/sources/*', array('controller'=>'Sources', 'action'=>'index')); + +# Content pages +#$Route->connect ('/*', array('controller'=>'Pages', 'action'=>'view')); + +# Default route +$Route->connect ('/:controller/:action/*'); + +?> \ No newline at end of file diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt new file mode 100644 index 000000000..6b9988c68 --- /dev/null +++ b/docs/CHANGELOG.txt @@ -0,0 +1,7 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +---------------------------------------------------------------------------------------------------+ // +// + $Id$ +// + Last Modified: $Date$ +// + Modified By: $LastChangedBy$ +// +---------------------------------------------------------------------------------------------------+ // +/////////////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/docs/CREDITS.txt b/docs/CREDITS.txt new file mode 100644 index 000000000..6b9988c68 --- /dev/null +++ b/docs/CREDITS.txt @@ -0,0 +1,7 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +---------------------------------------------------------------------------------------------------+ // +// + $Id$ +// + Last Modified: $Date$ +// + Modified By: $LastChangedBy$ +// +---------------------------------------------------------------------------------------------------+ // +/////////////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/docs/README.txt b/docs/README.txt new file mode 100644 index 000000000..7fcbab8f0 --- /dev/null +++ b/docs/README.txt @@ -0,0 +1,18 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +---------------------------------------------------------------------------------------------------+ // +// + $Id$ +// + Last Modified: $Date$ +// + Modified By: $LastChangedBy$ +// +---------------------------------------------------------------------------------------------------+ // +/////////////////////////////////////////////////////////////////////////////////////////////////////////// + +This README will be updated + +for now visit: + +https://developers.nextco.com/cake/ + +OR: + +http://sputnik.pl/cake/ + diff --git a/index.php b/index.php new file mode 100644 index 000000000..e8ae9387e --- /dev/null +++ b/index.php @@ -0,0 +1,40 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Enter description here... + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +define ('BASE_URL', $_SERVER['SCRIPT_NAME']); +define ('ROOT', dirname($_SERVER['SCRIPT_FILENAME']).'/'); + +$_GET['url'] = ltrim($_SERVER['PATH_INFO'],'/'); + +require ROOT.'public/dispatch.php'; +?> diff --git a/libs/adodb/put_adodb_files_here b/libs/adodb/put_adodb_files_here new file mode 100644 index 000000000..e69de29bb diff --git a/libs/bake.php b/libs/bake.php new file mode 100644 index 000000000..cf843b032 --- /dev/null +++ b/libs/bake.php @@ -0,0 +1,275 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Bake + * Creates controller, model, view files, and the required directories on demand. + * Used by scripts/add.php + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +uses('object', 'inflector'); + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class Bake extends Object { + +/** + * Enter description here... + * + * @var unknown_type + */ + var $stdin = null; + +/** + * Enter description here... + * + * @var unknown_type + */ + var $stdout = null; + +/** + * Enter description here... + * + * @var unknown_type + */ + var $stderr = null; + +/** + * Enter description here... + * + * @var unknown_type + */ + var $actions = null; + +/** + * Enter description here... + * + * @var unknown_type + */ + var $model_template = " +"; + +/** + * Enter description here... + * + * @var unknown_type + */ + var $action_template = " + function %s () { + } +"; + +/** + * Enter description here... + * + * @var unknown_type + */ + var $controller_template = " +"; + +/** + * Enter description here... + * + * @param unknown_type $type + * @param unknown_type $names + */ + function __construct ($type, $names) { + + $this->stdin = fopen('php://stdin', 'r'); + $this->stdout = fopen('php://stdout', 'w'); + $this->stderr = fopen('php://stderr', 'w'); + + switch ($type) { + + case 'model': + case 'models': + foreach ($names as $model_name) + $this->create_model($model_name); + break; + + case 'controller': + case 'ctrl': + $controller = array_shift($names); + + $add_actions = array(); + foreach ($names as $action) { + $add_actions[] = $action; + $this->create_view($controller, $action); + } + + $this->create_controller($controller, $add_actions); + break; + + case 'view': + case 'views': + $r = null; + foreach ($names as $model_name) { + if (preg_match('/^([a-z0-9_]+(?:\/[a-z0-9_]+)*)\/([a-z0-9_]+)$/i', $model_name, $r)) { + $this->create_view($r[1], $r[2]); + } + } + break; + } + + if (!$this->actions) + fwrite($this->stderr, "Nothing to do, quitting.\n"); + + } + +/** + * Enter description here... + * + * @param unknown_type $controller + * @param unknown_type $name + */ + function create_view ($controller, $name) { + $dir = Inflector::underscore($controller); + $this->create_dir(VIEWS.$dir); + $this->create_file(VIEWS.$dir.'/'.strtolower($name).'.thtml', ''); + $this->actions++; + } + +/** + * Enter description here... + * + * @param unknown_type $name + * @param unknown_type $actions + */ + function create_controller ($name, $actions=array()) { + $class_name = Inflector::camelize($name).'Controller'; + $content = array(); + foreach ($actions as $action) + $content[] = sprintf($this->action_template, ($action)); + + $this->create_file($this->controller_fn($name), sprintf($this->controller_template, $class_name, join('', $content))); + $this->actions++; + } + +/** + * Enter description here... + * + * @param unknown_type $name + */ + function create_model ($name) { + $class_name = Inflector::camelize($name); + $this->create_file($this->model_fn($name), sprintf($this->model_template, $class_name)); + $this->actions++; + } + +/** + * Enter description here... + * + * @param unknown_type $name + * @return unknown + */ + function model_fn ($name) { + return MODELS.Inflector::underscore($name).'.php'; + } + +/** + * Enter description here... + * + * @param unknown_type $name + * @return unknown + */ + function controller_fn ($name) { + return CONTROLLERS.Inflector::underscore($name).'_controller.php'; + } + +/** + * Enter description here... + * + * @param unknown_type $path + * @param unknown_type $contents + * @return unknown + */ + function create_file ($path, $contents) { + + if (is_file($path)) { + fwrite($this->stdout, "File {$path} exists, overwrite? (y/N) "); + $key = fgets($this->stdin); + + if (preg_match("/^q/", $key)) { + exit; + } + if (!preg_match("/^y/", $key)) { + fwrite($this->stdout, "Skip {$path}\n"); + return false; + } + } + + if ($f = fopen($path, 'w')) { + fwrite($f, $contents); + fclose($f); + fwrite($this->stdout, "Wrote {$path}\n"); + return true; + } + else { + fwrite($this->stderr, "Error! Couldn't open {$path} for writing.\n"); + return false; + } + } + +/** + * Enter description here... + * + * @param unknown_type $path + */ + function create_dir ($path) { + if (!is_dir($path)) { + if (mkdir($path)) { + fwrite($this->stdout, "Created {$path}\n"); + } + else { + fwrite($this->stderr, "Error! Couldn't create dir {$path}\n"); + } + } + } +} + +?> \ No newline at end of file diff --git a/libs/basics.php b/libs/basics.php new file mode 100644 index 000000000..7a27edf4e --- /dev/null +++ b/libs/basics.php @@ -0,0 +1,236 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Basics + * Basic Cake functionalities. + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +function load_libs () { + foreach (list_modules(LIBS) as $lib) { + if ($lib != 'basics') { + include_once (LIBS.$lib.'.php'); + } + } +} + +/** + * Enter description here... + * + */ +function load_models () { + require (APP.'app_model.php'); + foreach (list_modules(MODELS) as $model) { + require (MODELS.$model.'.php'); + } +} + +/** + * Enter description here... + * + */ +function load_controllers () { + require (APP.'app_controller.php'); + foreach (list_modules(CONTROLLERS) as $controller) { + require (CONTROLLERS.$controller.'.php'); + } +} + +/** + * Enter description here... + * + * @param unknown_type $path + * @param unknown_type $sort + * @return unknown + */ +function list_modules($path, $sort=true) { + if ($d = opendir($path)) { + $out = array(); + $r = null; + while (false !== ($fn = readdir($d))) { + if (preg_match('#^(.+)\.php$#', $fn, $r)) { + $out[] = $r[1]; + } + } + if ($sort || $this->sort) { + sort($out); + } + + return $out; + } + else { + return false; + } +} + +/** + * Enter description here... + * + */ +function uses_config () { + global $TIME_START; + + require (CONFIGS.'core.php'); +} + +/** + * Enter description here... + * + */ +function uses_database () { + global $DB; + + if (file_exists(CONFIGS.'database.php')) { + require (CONFIGS.'database.php'); + $DB = new DBO ($DATABASE_CONFIG['devel'], DEBUG > 1); + } +} + +/** + * Enter description here... + * + */ +function uses_tags () { + require (CONFIGS.'tags.php'); +} + +/** + * Enter description here... + * + */ +function uses () { + $args = func_get_args(); + foreach ($args as $arg) { + require_once (LIBS.$arg.'.php'); + } +} + +/** + * Enter description here... + * + * @param unknown_type $var + * @param unknown_type $show_html + */ +function debug($var = FALSE, $show_html = false) { + if (DEBUG) { + print "\n
\n";
+        if ($show_html) $var = str_replace('<', '<', str_replace('>', '>', $var));
+        print_r($var);
+        print "\n
\n"; + } +} + + +if (!function_exists('getMicrotime')) { + +/** + * Enter description here... + * + * @return unknown + */ + function getMicrotime() { + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); + } +} +if (!function_exists('sortByKey')) { +/** + * Enter description here... + * + * @param unknown_type $array + * @param unknown_type $sortby + * @param unknown_type $order + * @param unknown_type $type + * @return unknown + */ + function sortByKey(&$array, $sortby, $order='asc', $type=SORT_NUMERIC) { + + if( is_array($array) ) { + + foreach( $array AS $key => $val ) + $sa[$key] = $val[$sortby]; + + if( $order == 'asc' ) + asort($sa, $type); + else + arsort($sa, $type); + + foreach( $sa as $key=>$val ) + $out[] = $array[$key]; + + Return $out; + + } + else + Return null; + } +} + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class neatArray { + +/** + * Enter description here... + * + * @param unknown_type $value + * @return neatArray + */ + function neatArray ($value) { + $this->value = $value; + } + +/** + * Enter description here... + * + * @param unknown_type $field_name + * @param unknown_type $value + * @return unknown + */ + function find_in ($field_name, $value) { + $out = false; + foreach ($this->value as $k=>$v) { + if (isset($v[$field_name]) && ($v[$field_name] == $value)) { + $out[$k] = $v; + } + } + + return $out; + } +} + +?> \ No newline at end of file diff --git a/libs/cache.php b/libs/cache.php new file mode 100644 index 000000000..3f422e78d --- /dev/null +++ b/libs/cache.php @@ -0,0 +1,151 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Cache + * Description: + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +uses('model'); + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class Cache extends Model { + +/** + * Enter description here... + * + * @var unknown_type + */ + var $id = null; + +/** + * Enter description here... + * + * @var unknown_type + */ + var $data = null; + +/** + * Enter description here... + * + * @var unknown_type + */ + var $for_caching = null; + +/** + * Enter description here... + * + * @var unknown_type + */ + var $use_table = 'cache'; + +/** + * Enter description here... + * + * @param unknown_type $id + */ + function __construct ($id) { + $this->id = (md5($id)); + parent::__construct($this->id); + } + +/** + * Enter description here... + * + * @param unknown_type $id + * @return unknown + */ + function id ($id=null) { + if (!$id) return $this->id; + return ($this->id = $id); + } + +/** + * Enter description here... + * + * @param unknown_type $content + * @param unknown_type $keep_for + * @return unknown + */ + function remember ($content, $keep_for=CACHE_PAGES_FOR) { + $data = addslashes($this->for_caching.$content); + $expire = date("Y-m-d H:i:s",time()+($keep_for>0? $keep_for: 999999999)); + return $this->query("REPLACE {$this->use_table} (id,data,expire) VALUES ('{$this->id}', '{$data}', '{$expire}')"); + } + +/** + * Enter description here... + * + * @return unknown + */ + function restore () { + if (empty($this->data['data'])) + return $this->find("id='{$this->id}' AND expire>NOW()"); + + return $this->data['data']; + } + +/** + * Enter description here... + * + * @return unknown + */ + function has () { + return is_array($this->data = $this->find("id='{$this->id}' AND expire>NOW()")); + } + +/** + * Enter description here... + * + * @param unknown_type $string + */ + function append ($string) { + $this->for_caching .= $string; + } + +/** + * Enter description here... + * + * @return unknown + */ + function clear () { + return $this->query("DELETE FROM {$this->use_table}"); + } +} + +?> \ No newline at end of file diff --git a/libs/controller.php b/libs/controller.php new file mode 100644 index 000000000..31883ba34 --- /dev/null +++ b/libs/controller.php @@ -0,0 +1,545 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Controller + * Application controller (controllers are where you put all the actual code) based on RoR (www.rubyonrails.com) + * Provides basic functionality, such as rendering views (aka displaying templates). + * Automatically selects model name from on singularized object class name + * and creates the model object if proper class exists. + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +uses('model', 'template', 'inflector'); + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class Controller extends Template { + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $name = null; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $parent = null; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $action = null; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $use_model = null; + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $uses = false; + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_crumbs = array(); + +/** + * Enter description here... + * + */ + function __construct () { + global $DB; + + $r = null; + if (!preg_match('/(.*)Controller/i', get_class($this), $r)) + die("Controller::__construct() : Can't get or parse my own class name, exiting."); + + $this->name = strtolower($r[1]); + + if ($this->uses === false) { + if (!$DB) + die("Controller::__construct() : ".$this->name." controller needs database access, exiting."); + + $model_class = Inflector::singularize($this->name); + if (class_exists($model_class)) + $this->$model_class = new $model_class (); + } + elseif ($this->uses) { + if (!$DB) + die("Controller::__construct() : ".$this->name." controller needs database access, exiting."); + + $uses = is_array($this->uses)? $this->uses: array($this->uses); + + foreach ($uses as $model_name) { + $model_class = ucfirst(strtolower($model_name)); + if (class_exists($model_class)) + $this->$model_name = new $model_name (false); + else + die("Controller::__construct() : ".ucfirst($this->name)." requires missing model {$model_class}, exiting."); + } + } + + parent::__construct(); + } + +/** + * Enter description here... + * + * @param unknown_type $url + */ + function redirect ($url) { + $this->auto_render = false; + header ('Location: '.$this->base.$url); + } + +/** + * Enter description here... + * + * @param unknown_type $url + * @return unknown + */ + function url_for ($url=null) { + if (empty($url)) { + return $this->base.'/'.strtolower($this->params['controller']).'/'.strtolower($this->params['action']); + } + elseif ($url[0] == '/') { + return $this->base . $url; + } + else { + return $this->base . '/' . strtolower($this->params['controller']) . '/' . $url; + } + } + +/** + * Enter description here... + * + * @param unknown_type $options + * @param unknown_type $insert_before + * @param unknown_type $insert_after + * @return unknown + */ + function parse_html_options ($options, $insert_before=' ', $insert_after=null) { + if (is_array($options)) { + $out = array(); + foreach ($options as $k=>$v) { + $out[] = "{$k}=\"{$v}\""; + } + $out = join(' ', $out); + return $out? $insert_before.$out.$insert_after: null; + } + else { + return $options? $insert_before.$options.$insert_after: null; + } + } + +/** + * Enter description here... + * + * @param unknown_type $title + * @param unknown_type $url + * @param unknown_type $html_options + * @param unknown_type $confirm + * @return unknown + */ + function link_to ($title, $url, $html_options=null, $confirm=false) { + $confirm? $html_options['onClick'] = "return confirm('{$confirm}')": null; + return sprintf(TAG_LINK, $this->url_for($url), $this->parse_html_options($html_options), $title); + } + +/** + * Enter description here... + * + * @param unknown_type $title + * @param unknown_type $url + * @param unknown_type $html_options + * @return unknown + */ + function link_out ($title, $url=null, $html_options=null) { + $url = $url? $url: $title; + return sprintf(TAG_LINK, $url, $this->parse_html_options($html_options), $title); + } + +/** + * Enter description here... + * + * @param unknown_type $target + * @param unknown_type $type + * @param unknown_type $html_options + * @return unknown + */ + function form_tag ($target=null, $type='post', $html_options=null) { + $html_options['action'] = $this->url_for($target); + $html_options['method'] = $type=='get'? 'get': 'post'; + $type == 'file'? $html_options['enctype'] = 'multipart/form-data': null; + + return sprintf(TAG_FORM, $this->parse_html_options($html_options, '')); + } + +/** + * Enter description here... + * + * @param unknown_type $caption + * @param unknown_type $html_options + * @return unknown + */ + function submit_tag ($caption='Submit', $html_options=null) { + $html_options['value'] = $caption; + return sprintf(TAG_SUBMIT, $this->parse_html_options($html_options, '', ' ')); + } + +/** + * Enter description here... + * + * @param unknown_type $tag_name + * @param unknown_type $size + * @param unknown_type $html_options + * @return unknown + */ + function input_tag ($tag_name, $size=20, $html_options=null) { + $html_options['size'] = $size; + $html_options['value'] = isset($html_options['value'])? $html_options['value']: $this->tag_value($tag_name); + $this->tag_is_invalid($tag_name)? $html_options['class'] = 'form_error': null; + return sprintf(TAG_INPUT, $tag_name, $this->parse_html_options($html_options, '', ' ')); + } + +/** + * Enter description here... + * + * @param unknown_type $tag_name + * @param unknown_type $value + * @param unknown_type $html_options + * @return unknown + */ + function hidden_tag ($tag_name, $value=null, $html_options=null) { + $html_options['value'] = $value? $value: $this->tag_value($tag_name); + return sprintf(TAG_HIDDEN, $tag_name, $this->parse_html_options($html_options, '', ' ')); + } + +/** + * Enter description here... + * + * @param unknown_type $tag_name + * @param unknown_type $size + * @param unknown_type $html_options + * @return unknown + */ + function password_tag ($tag_name, $size=20, $html_options=null) { + $html_options['size'] = $size; + $html_options['value'] = $value? $value: $this->tag_value($tag_name); + return sprintf(TAG_PASSWORD, $tag_name, $this->parse_html_options($html_options, '', ' ')); + } + +/** + * Enter description here... + * + * @param unknown_type $tag_name + * @param unknown_type $html_options + * @return unknown + */ + function file_tag ($tag_name, $html_options=null) { + return sprintf(TAG_FILE, $tag_name, $this->parse_html_options($html_options, '', ' ')); + } + +/** + * Enter description here... + * + * @param unknown_type $tag_name + * @param unknown_type $cols + * @param unknown_type $rows + * @param unknown_type $html_options + * @return unknown + */ + function area_tag ($tag_name, $cols=60, $rows=10, $html_options=null) { + $value = $value? $value: $this->tag_value($tag_name); + $html_options['cols'] = $cols; + $html_options['rows'] = $rows; + return sprintf(TAG_AREA, $tag_name, $this->parse_html_options($html_options, ' '), $value); + } + +/** + * Enter description here... + * + * @param unknown_type $tag_name + * @param unknown_type $title + * @param unknown_type $html_options + * @return unknown + */ + function checkbox_tag ($tag_name, $title=null, $html_options=null) { + $this->tag_value($tag_name)? $html_options['checked'] = 'checked ': null; + $title = $title? $title: ucfirst($tag_name); + return sprintf(TAG_CHECKBOX, $tag_name, $tag_name, $tag_name, $this->parse_html_options($html_options, '', ' '), $title); + } + +/** + * Enter description here... + * + * @param unknown_type $tag_name + * @param unknown_type $options + * @param unknown_type $inbetween + * @param unknown_type $html_options + * @return unknown + */ + function radio_tags ($tag_name, $options, $inbetween=null, $html_options=null) { + $value = isset($html_options['value'])? $html_options['value']: $this->tag_value($tag_name); + $out = array(); + foreach ($options as $opt_value=>$opt_title) { + $options_here = array('value' => $opt_value); + $opt_value==$value? $options_here['checked'] = 'checked': null; + $parsed_options = $this->parse_html_options(array_merge($html_options, $options_here), '', ' '); + $individual_tag_name = "{$tag_name}_{$opt_value}"; + $out[] = sprintf(TAG_RADIOS, $individual_tag_name, $tag_name, $individual_tag_name, $parsed_options, $opt_title); + } + + return join($inbetween, $out); + } + +/** + * Enter description here... + * + * @param unknown_type $tag_name + * @param unknown_type $options + * @param unknown_type $outer_options + * @param unknown_type $inner_options + * @return unknown + */ + function select_tag ($tag_name, $options, $outer_options=null, $inner_options=null) { + $selected = isset($html_options['value'])? $html_options['value']: $this->tag_value($tag_name); + $select[] = sprintf(TAG_SELECT_START, $tag_name, $this->parse_html_options($outer_options)); + $select[] = sprintf(TAG_SELECT_EMPTY, $this->parse_html_options($inner_options)); + + foreach ($options as $name=>$title) { + $options_here = $selected==$name? array_merge($inner_options, array('selected'=>'selected')): $inner_options; + $select[] = sprintf(TAG_SELECT_OPTION, $name, $this->parse_html_options($options_here), $title); + } + + $select[] = sprintf(TAG_SELECT_END); + + return implode("\n", $select); + } + +/** + * Enter description here... + * + * @param unknown_type $names + * @param unknown_type $tr_options + * @param unknown_type $th_options + * @return unknown + */ + function table_headers ($names, $tr_options=null, $th_options=null) { + $args = func_get_args(); + + $out = array(); + foreach ($names as $arg) + $out[] = sprintf(TAG_TABLE_HEADER, $this->parse_html_options($th_options), $arg); + + return sprintf(TAG_TABLE_HEADERS, $this->parse_html_options($tr_options), join(' ', $out)); + } + +/** + * Enter description here... + * + * @param unknown_type $data + * @param unknown_type $tr_options + * @param unknown_type $td_options + * @return unknown + */ + function table_cells ($data, $tr_options=null, $td_options=null) { + if (empty($data[0]) || !is_array($data[0])) + $data = array($data); + + foreach ($data as $line) { + $cells_out = array(); + foreach ($line as $cell) $cells_out[] = sprintf(TAG_TABLE_CELL, $this->parse_html_options($td_options), $cell); + $out[] = join(' ', $cells_out); + } + + return sprintf(TAG_TABLE_ROW, $this->parse_html_options($tr_options), join("\n", $out)); + } + +/** + * Enter description here... + * + * @param unknown_type $name + * @param unknown_type $alt + * @param unknown_type $html_options + * @return unknown + */ + function image_tag ($name, $alt=null, $html_options=null) { + $url = "{$this->base}/images/{$name}"; + return sprintf(TAG_IMAGE, $url, $alt, $this->parse_html_options($html_options, '', ' ')); + } + + + +/** + * Enter description here... + * + * @param unknown_type $tag_name + * @return unknown + */ + function tag_value ($tag_name) { + return isset($this->params['data'][$tag_name])? $this->params['data'][$tag_name]: null; + } + +/** + * Enter description here... + * + * @param unknown_type $field + * @return unknown + */ + function tag_is_invalid ($field) { + return !empty($this->validation_errors[$field]); + } + +/** + * Enter description here... + * + * @param unknown_type $field + * @param unknown_type $text + * @return unknown + */ + function validation_error ($field, $text) { + return $this->tag_is_invalid($field)? sprintf(SHORT_ERROR_MESSAGE, $text): null; + } + + + +/** + * Enter description here... + * + * @param unknown_type $name + * @param unknown_type $link + */ + function add_crumb ($name, $link) { + $this->_crumbs[] = array ($name, $link); + } + +/** + * Enter description here... + * + * @return unknown + */ + function get_crumbs () { + + if (count($this->_crumbs)) { + + $out = array("base}\">START"); + foreach ($this->_crumbs as $crumb) { + $out[] = "base}{$crumb[1]}\">{$crumb[0]}"; + } + + return join(' » ', $out); + } + else + return null; + } + +/** + * Enter description here... + * + * @param unknown_type $action + */ + function set_action ($action) { + $this->action = $action; + + $args = func_get_args(); + call_user_func_array(array(&$this, $action), $args); + } + +/** + * Enter description here... + * + * @param unknown_type $code + * @param unknown_type $name + * @param unknown_type $message + */ + function error ($code, $name, $message) { + header ("HTTP/1.0 {$code} {$name}"); + print ($this->_do_render(VIEWS.'layouts/error.thtml', array('code'=>$code,'name'=>$name,'message'=>$message))); + } + +/** + * Enter description here... + * + * @return unknown + */ + function validates () { + $args = func_get_args(); + $errors = call_user_func_array(array(&$this, 'validation_errors'), $args); + + return count($errors); + } + +/** + * Enter description here... + * + * @return unknown + */ + function validation_errors () { + $objects = func_get_args(); + if (!count($objects)) return false; + + $errors = array(); + foreach ($objects as $object) { + $errors = array_merge($errors, $object->invalid_fields()); + } + + return $this->validation_errors = (count($errors)? $errors: false); + } +} + +?> \ No newline at end of file diff --git a/libs/dbo-ado.php b/libs/dbo-ado.php new file mode 100644 index 000000000..cd7247e43 --- /dev/null +++ b/libs/dbo-ado.php @@ -0,0 +1,511 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: DBO/ADO + * + * Description: + * A MySQL functions wrapper. Provides ability to get results as arrays + * and query logging (with execution time). + * + * Example usage: + * + * + * require('dbo.php'); + * + * // create and connect the object + * $db = new DBO(array( + * 'host'=>'localhost', + * 'login'=>'username', + * 'password'=>'password', + * 'database'=>'database' + * 'type'=>'mysql')); + * + * // read the whole query result array (of rows) + * $all_rows = $db->all("SELECT a,b,c FROM table"); + * + * // read the first row with debugging on + * $first_row_only = $db->one("SELECT a,b,c FROM table WHERE a=1", TRUE); + * + * // emulate the usual MySQL way of reading query results + * if ($db->q("SELECT a,b,c FROM table")) { + * while ( $row = $db->farr() ) { + * print $row['a'].$row['b'].$row['c']; + * } + * } + * + * // show a log of all queries, sorted by execution time + * $db->show_log(TRUE); + * + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +require_once('adodb/adodb.inc.php'); + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class DBO { + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $connected=FALSE; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $error=NULL; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $insert_id=NULL; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $affected=NULL; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $took=NULL; + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_conn=NULL; + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_result=NULL; + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_queries_cnt=0; + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_queries_time=NULL; + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_queries_log=array(); + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_adodb=NULL; + +/** + * Enter description here... + * + * @param unknown_type $config + * @param unknown_type $DEBUG + * @return DBO + */ + function DBO($config=NULL,$DEBUG=FALSE) { + $this->__constructor($config,$DEBUG); + } + +/** + * Enter description here... + * + * @param unknown_type $config + * @param unknown_type $DEBUG + */ + function __constructor($config=NULL,$DEBUG=FALSE) { + $this->debug = $DEBUG; + if ($DEBUG > 1) register_shutdown_function( array( &$this, "show_log" ) ); + $this->connect($config); + } + +/** + * Enter description here... + * + */ + function __destructor() { + $this->close(); + } + +/** + * Enter description here... + * + * @param unknown_type $config + */ + function connect($config) { + if($config) { + $this->config = $config; + if(isset($this->config['type'])) { + $this->_adodb = NewADOConnection($this->config['type']); + $adodb =& $this->_adodb; + $this->connected = $adodb->Connect($this->config['host'],$this->config['login'],$this->config['password'],$this->config['database']); + } + } + + if(!$this->connected) + die('Could not connect to DB.'); + } + +/** + * Enter description here... + * + */ + function close() { + $adodb =& $this->_adodb; + $adodb->close; + showLog(); + $this->_conn = NULL; + $this->connected = NULL; + } + +/** + * Enter description here... + * + * @param unknown_type $q + * @param unknown_type $DEBUG + * @param unknown_type $log + * @return unknown + */ + function q($q,$DEBUG=FALSE,$log=TRUE) { + Return $this->query($q,$DEBUG,$log); + } + +/** + * Enter description here... + * + * @param unknown_type $q + * @param unknown_type $DEBUG + * @param unknown_type $log + * @return unknown + */ + function query($q,$DEBUG=FALSE,$log=TRUE) { + $adodb =& $this->_adodb; + $t = getMicrotime(); + + if($log){ + $this->_result =& $adodb->Execute($q); + $result =& $this->_result; + $this->took = round((getmicrotime()-$t)*1000, 0); + if(!$this->_result && $adodb->ErrorMsg()) + $this->error = $adodb->ErrorMsg(); + else + $this->error = NULL; + + $this->insert_id = $adodb->Insert_ID(); + + $this->affected = $adodb->Affected_Rows(); + + $this->num_rows = $result->RecordCount(); + $this->_log_query($q); + + if($this->debug || $DEBUG) $this->_show_query($q); + + Return $this->error? FALSE: $this->_result; + } + else { + $this->_result = $adodb->Execute($q); + Return $this->_result; + } + } + +/** + * Enter description here... + * + * @return unknown + */ + function farr() { + $result =& $this->_result; + return $result->FetchRow(); + } + + //SAME AS ABOVE? +/** + * Enter description here... + * + * @param unknown_type $q + * @param unknown_type $DEBUG + * @return unknown + */ + function one($q,$DEBUG=FALSE) { + $result =& $this->_result; + Return $this->query($q,$DEBUG)? $result->FetchRow(): FALSE; + } + +/** + * Enter description here... + * + * @param unknown_type $q + * @param unknown_type $DEBUG + * @return unknown + */ + function all($q,$DEBUG=FALSE) { + if($this->query($q,$DEBUG)) { + $result = $this->_result; + return $result->GetRows(); + } else { + Return FALSE; + } + } + +/** + * Enter description here... + * + * @param unknown_type $name + * @param unknown_type $q + * @param unknown_type $DEBUG + * @return unknown + */ + function field($name, $q, $DEBUG=FALSE) { + $data = $this->one($q, $DEBUG); + return empty($data[$name])? false: $data[$name]; + } + +/** + * Enter description here... + * + * @return unknown + */ + function tables() { + $adodb =& $this->_adodb; + $tables = $adodb->MetaTables('TABLES'); + + if (!sizeof($tables)>0) { + trigger_error(ERROR_NO_TABLE_LIST, E_USER_NOTICE); + exit; + } + return $tables; + } + +/** + * Enter description here... + * + * @param unknown_type $table + * @param unknown_type $sql + * @return unknown + */ + function has_any($table, $sql) { + $out = $this->one("SELECT COUNT(*) AS count FROM {$table} WHERE {$sql}"); + return is_array($out)? $out['count']: FALSE; + } + +/** + * Enter description here... + * + * @return unknown + */ + function got_connected() { + Return $this->connected; + } + +/** + * Enter description here... + * + * @return unknown + */ + function got_insert_id() { + Return $this->insert_id; + } + +/** + * Enter description here... + * + * @return unknown + */ + function got_affected() { + Return $this->affected; + } + +/** + * Enter description here... + * + * @return unknown + */ + function got_num_rows() { + Return $this->num_rows; + } + +/** + * Enter description here... + * + * @return unknown + */ + function got_error() { + return $this->error; + } + +/** + * Enter description here... + * + * @param unknown_type $sorted + */ + function show_log($sorted=FALSE) { + $log = $sorted? + sortByKey($this->_queries_log, 'took', 'desc', SORT_NUMERIC): + $this->_queries_log; + + print("\n\n"); + print("\n"); + + foreach($log AS $k=>$i) { + print("\n"); + } + + print("
{$this->_queries_cnt} queries took {$this->_queries_time} ms
NrQueryErrorAffectedNum. rowsTook (ms)
".($k+1)."{$i['query']}{$i['error']}{$i['affected']}{$i['num_rows']}{$i['took']}
\n"); + } + +/** + * Enter description here... + * + * @param unknown_type $q + */ + function _log_query($q) { + $this->_queries_cnt++; + $this->_queries_time += $this->took; + $this->_queries_log[] = array( + 'query'=>$q, + 'error'=>$this->error, + 'affected'=>$this->affected, + 'num_rows'=>$this->num_rows, + 'took'=>$this->took + ); + + + if ($this->error && function_exists('logError')) + logError("Query: {$q} RETURNS ERROR {$this->error}"); + } + +/** + * Enter description here... + * + * @param unknown_type $q + */ + function _show_query($q) { + $error = $this->error; + + if ($this->debug || $error) { + print("

Query: {$q} [Aff:{$this->affected} Num:{$this->num_rows} Took:{$this->took}ms]"); + if($error) { + print("
ERROR: {$this->error}"); + } + print('

'); + } + } + +} + +if (!function_exists('getMicrotime')) { +/** + * Enter description here... + * + * @return unknown + */ + function getMicrotime() { + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); + } +} +if (!function_exists('sortByKey')) { +/** + * Enter description here... + * + * @param unknown_type $array + * @param unknown_type $sortby + * @param unknown_type $order + * @param unknown_type $type + * @return unknown + */ + function sortByKey(&$array, $sortby, $order='asc', $type=SORT_NUMERIC) { + + if( is_array($array) ) { + + foreach( $array AS $key => $val ) + $sa[$key] = $val[$sortby]; + + if( $order == 'asc' ) + asort($sa, $type); + else + arsort($sa, $type); + + foreach( $sa as $key=>$val ) + $out[] = $array[$key]; + + Return $out; + + } + else + Return null; + } +} + +?> \ No newline at end of file diff --git a/libs/dbo.php b/libs/dbo.php new file mode 100644 index 000000000..3490167d7 --- /dev/null +++ b/libs/dbo.php @@ -0,0 +1,478 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: DBO/ADO + * + * Description: + * A MySQL functions wrapper. Provides ability to get results as arrays + * and query logging (with execution time). + * + * Example usage: + * + * + * require('dbo.php'); + * + * // create and connect the object + * $db = new DBO(array( + * 'host'=>'localhost', + * 'login'=>'username', + * 'password'=>'password', + * 'database'=>'database')); + * + * // read the whole query result array (of rows) + * $all_rows = $db->all("SELECT a,b,c FROM table"); + * + * // read the first row with debugging on + * $first_row_only = $db->one("SELECT a,b,c FROM table WHERE a=1", TRUE); + * + * // emulate the usual MySQL way of reading query results + * if ($db->q("SELECT a,b,c FROM table")) { + * while ( $row = $db->farr() ) { + * print $row['a'].$row['b'].$row['c']; + * } + * } + * + * // show a log of all queries, sorted by execution time + * $db->show_log(TRUE); + * + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +uses('object'); + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class DBO extends Object { + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $connected=FALSE; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $debug=FALSE; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $error=NULL; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $insert_id=NULL; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $affected=NULL; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $took=NULL; + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_conn=NULL; + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_result=NULL; + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_queries_cnt=0; + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_queries_time=NULL; + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_queries_log=array(); + +/** + * Enter description here... + * + * @param unknown_type $config + * @param unknown_type $DEBUG + * @return unknown + */ + function __construct($config=NULL,$DEBUG=FALSE) { + $this->debug = $DEBUG; + if ($DEBUG > 1) register_shutdown_function( array( &$this, "show_log" ) ); + parent::__construct(); + Return $this->connect($config); + } + +/** + * Enter description here... + * + */ + function __destructor() { + $this->close(); + } + +/** + * Enter description here... + * + * @param unknown_type $config + * @return unknown + */ + function connect($config) { + if($config) { + $this->config = $config; + + $this->_conn = @mysql_pconnect($config['host'],$config['login'],$config['password']); + # $this->_conn = @mysql_connect($config['host'],$config['login'],$config['password']); + } + $this->connected = $this->_conn? TRUE: FALSE; + + if($this->connected) + Return @mysql_select_db($config['database'], $this->_conn); + else + die('Could not connect to DB.'); + } + +/** + * Enter description here... + * + * @param unknown_type $db_name + * @return unknown + */ + function use_db ($db_name) { + return $this->q("USE {$db_name}"); + } + +/** + * Enter description here... + * + */ + function close() { + @mysql_close(); + showLog(); + $this->_conn = NULL; + $this->connected = NULL; + } + +/** + * Enter description here... + * + * @param unknown_type $q + * @param unknown_type $DEBUG + * @param unknown_type $log + * @return unknown + */ + function q($q,$DEBUG=FALSE,$log=TRUE) { + Return $this->query($q,$DEBUG,$log); + } + +/** + * Enter description here... + * + * @param unknown_type $q + * @param unknown_type $DEBUG + * @param unknown_type $log + * @return unknown + */ + function query($q,$DEBUG=FALSE,$log=TRUE) { + $t = getMicrotime(); + + if($log){ + $this->_result = @mysql_query($q); + $this->took = round((getmicrotime()-$t)*1000, 0); + $this->error = mysql_errno()? mysql_errno().': '.mysql_error(): NULL; + $this->insert_id = @mysql_insert_id(); + $this->affected = @mysql_affected_rows(); + $this->num_rows = @mysql_num_rows($this->_result); + $this->_log_query($q); + + if($this->debug || $DEBUG) $this->_show_query($q); + + Return $this->error? FALSE: $this->_result; + } + else + Return @mysql_query($q); + } + +/** + * Enter description here... + * + * @param unknown_type $results + * @param unknown_type $type + * @return unknown + */ + function farr($results,$type=MYSQL_BOTH) { + return mysql_fetch_array($results,$type); + } + +/** + * Enter description here... + * + * @param unknown_type $q + * @param unknown_type $DEBUG + * @param unknown_type $type + * @return unknown + */ + function one($q,$DEBUG=FALSE,$type=MYSQL_BOTH) { + Return $this->query($q,$DEBUG)? mysql_fetch_array($this->_result, $type): FALSE; + } + +/** + * Enter description here... + * + * @param unknown_type $q + * @param unknown_type $DEBUG + * @return unknown + */ + function all($q,$DEBUG=FALSE) { + if($this->query($q,$DEBUG)) { + $out=NULL; + while($item = mysql_fetch_assoc($this->_result)) + $out[] = $item; + + Return $out; + } + else { + Return FALSE; + } + } + +/** + * Enter description here... + * + * @param unknown_type $name + * @param unknown_type $q + * @param unknown_type $DEBUG + * @param unknown_type $type + * @return unknown + */ + function field($name, $q, $DEBUG=FALSE, $type=MYSQL_BOTH) { + $data = $this->one($q, $DEBUG, $type); + return empty($data[$name])? false: $data[$name]; + } + +/** + * Enter description here... + * + * @return unknown + */ + function tables() { + $result = mysql_list_tables($this->config['database']); + + if (!$result) { + trigger_error(ERROR_NO_TABLE_LIST, E_USER_NOTICE); + exit; + } + else { + $tables = array(); + while ($line = mysql_fetch_array($result)) { + $tables[] = $line[0]; + } + return $tables; + } + } + +/** + * Enter description here... + * + * @param unknown_type $table_name + * @return unknown + */ + function fields ($table_name) { + return $this->all("DESC {$table_name}"); + } + +/** + * Enter description here... + * + * @param unknown_type $table + * @param unknown_type $sql + * @return unknown + */ + function has_any($table, $sql='1=1') { + $out = $this->one("SELECT COUNT(*) AS count FROM {$table} WHERE {$sql}"); + return is_array($out)? $out['count']: FALSE; + } + +/** + * Enter description here... + * + * @return unknown + */ + function is_connected() { + Return $this->connected; + } + +/** + * Enter description here... + * + * @return unknown + */ + function last_insert_id() { + Return $this->insert_id; + } + +/** + * Enter description here... + * + * @return unknown + */ + function last_affected() { + Return $this->affected; + } + +/** + * Enter description here... + * + * @return unknown + */ + function last_num_rows() { + Return $this->num_rows; + } + +/** + * Enter description here... + * + * @return unknown + */ + function last_error() { + return $this->error; + } + +/** + * Enter description here... + * + * @param unknown_type $sorted + */ + function show_log($sorted=FALSE) { + $log = $sorted? + sortByKey($this->_queries_log, 'took', 'desc', SORT_NUMERIC): + $this->_queries_log; + + print("\n\n"); + print("\n"); + + foreach($log AS $k=>$i) { + print("\n"); + } + + print("
{$this->_queries_cnt} queries took {$this->_queries_time} ms
NrQueryErrorAffectedNum. rowsTook (ms)
".($k+1)."{$i['query']}{$i['error']}{$i['affected']}{$i['num_rows']}{$i['took']}
\n"); + } + +/** + * Enter description here... + * + * @param unknown_type $q + */ + function _log_query($q) { + $this->_queries_cnt++; + $this->_queries_time += $this->took; + $this->_queries_log[] = array( + 'query'=>$q, + 'error'=>$this->error, + 'affected'=>$this->affected, + 'num_rows'=>$this->num_rows, + 'took'=>$this->took + ); + + + if ($this->error && function_exists('logError')) + logError("Query: {$q} RETURNS ERROR {$this->error}"); + } + +/** + * Enter description here... + * + * @param unknown_type $q + */ + function _show_query($q) { + $error = $this->error; + + if ($this->debug || $error) { + print("

Query: {$q} [Aff:{$this->affected} Num:{$this->num_rows} Took:{$this->took}ms]"); + if($error) { + print("
ERROR: {$this->error}"); + } + print('

'); + } + } + +} + +?> \ No newline at end of file diff --git a/libs/dispatcher.php b/libs/dispatcher.php new file mode 100644 index 000000000..492cc11c8 --- /dev/null +++ b/libs/dispatcher.php @@ -0,0 +1,203 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Dispatcher + * Dispatches the request, creating aproppriate models and controllers. + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +uses('error_messages', 'object', 'router', 'cache', 'controller'); + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class Dispatcher extends Object { +/** + * Enter description here... + * + * @var unknown_type + */ + var $base = false; +/** + * Enter description here... + * + * @var unknown_type + */ + var $passed_args = array(); + +/** + * Enter description here... + * + */ + function __construct () { + parent::__construct(); + } + +/** + * Enter description here... + * + * @param unknown_type $url + * @return unknown + */ + function dispatch ($url) { + global $_POST, $_GET, $_FILES, $_SESSION; + + if (CACHE_PAGES) { + $Cache = new Cache($url); + if ($Cache->has()) return print $Cache->restore(); + } + + $this->base = $this->parse_base_url(); + + $params = $this->parse_params($url); + + if (empty($params['controller'])) { + DEBUG? + trigger_error (ERROR_NO_CONTROLLER_SET, E_USER_ERROR): + $this->error('404', 'Not found', "The requested URL /{$url} was not found on this server (no controller set)."); + exit; + } + + $controller_class = ucfirst($params['controller']).'Controller'; + + if (!class_exists($controller_class)) { + DEBUG? + trigger_error (sprintf(ERROR_UNKNOWN_CONTROLLER, $controller_class), E_USER_ERROR): + $this->error('404', 'Not found', sprintf(ERROR_404, $url, "missing controller \"{$params['controller']}\"")); + exit; + } + + $controller = new $controller_class ($this); + $controller->cache = &$Cache; + $controller->base = $this->base; + + // if action is not set, and the default Controller::index() method doesn't exist + if (!$params['action'] && !method_exists($controller, 'index')) { + DEBUG? + trigger_error (ERROR_NO_ACTION_SET, E_USER_ERROR): + $this->error('404', 'Not found', "The requested URL /{$url} was not found on this server (no action set)."); + exit; + } + elseif (empty($params['action'])) { + $params['action'] = 'index'; + } + + // if the requested action doesn't exist + if (!method_exists($controller, $params['action'])) { + DEBUG? + trigger_error (sprintf(ERROR_NO_ACTION, $params['action'], $controller_class), E_USER_ERROR): + $this->error('404', 'Not found', sprintf(ERROR_404, $url, "missing controller \"{$params['controller']}\"")); + exit; + } + + $controller->params = $params; + empty($params['data'])? null: $controller->data = $params['data']; + $controller->action = $params['action']; + $controller->passed_args = empty($params['pass'])? null: $params['pass']; + + // EXECUTE THE REQUESTED ACTION + call_user_func_array(array(&$controller, $params['action']), empty($params['pass'])? null: $params['pass']); + + if ($controller->auto_render) + $controller->render(); + + if (CACHE_PAGES) $Cache->remember(null); + + return $params; + } + +/** + * Enter description here... + * + * @param unknown_type $from_url + * @return unknown + */ + function parse_params ($from_url) { + global $_POST, $_FILES; + + // load routes config + $Route = new Router(); + require CONFIGS.'routes.php'; + $params = $Route->parse ('/'.$from_url); + + // add submitted form data + $params['form'] = $_POST; + if (isset($_POST['data'])) + $params['data'] = $_POST['data']; + foreach ($_FILES as $name => $data) + $params['form'][$name] = $data; + + return $params; + } + +/** + * Enter description here... + * + * @return unknown + */ + function parse_base_url () { + global $_SERVER; + //non mod_rewrite use: + if (defined('BASE_URL')) return BASE_URL; + + + $doc_root = $_SERVER['DOCUMENT_ROOT']; + $script_name = $_SERVER['SCRIPT_NAME']; + + // if document root ends with 'public', it's probably correctly set + $r = null; + if (!ereg('/^.*/public(\/)?$/', $doc_root)) + return preg_match('/^(.*)\/public\/dispatch\.php$/', $script_name, $r)? $r[1]: false; + // document root is probably not set to Cake 'public' dir + else + return preg_match('/^(.*)\/dispatch\.php$/', $script_name, $r)? $r[1]: false; + } + +/** + * Enter description here... + * + * @param unknown_type $code + * @param unknown_type $name + * @param unknown_type $message + */ + function error ($code, $name, $message) { + $controller = new Controller ($this); + $controller->base = $this->base; + $controller->error($code, $name, $message); + } +} + +?> diff --git a/libs/error_messages.php b/libs/error_messages.php new file mode 100644 index 000000000..f33a8a702 --- /dev/null +++ b/libs/error_messages.php @@ -0,0 +1,115 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Error Messages Defines + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +define ('ERROR_NO_CONTROLLER_SET', '[Dispatcher] No default controller, can\'t continue, check routes config'); + +/** + * Enter description here... + * + */ +define ('ERROR_UNKNOWN_CONTROLLER', '[Dispatcher] Specified controller "%s" doesn\'t exist, create it first'); + +/** + * Enter description here... + * + */ +define ('ERROR_NO_ACTION', '[Dispatcher] Action "%s" is not defined in the "%s" controller, create it first'); + +/** + * Enter description here... + * + */ +define ('ERROR_IN_VIEW', '[Controller] Error in view "%s", got:
%s
'); + +/** + * Enter description here... + * + */ +define ('ERROR_NO_VIEW', '[Controller] No template file for view "%s" (expected "%s"), create it first'); + +/** + * Enter description here... + * + */ +define ('ERROR_IN_LAYOUT', '[Controller] Error in layout "%s", got:
"%s"
'); + +/** + * Enter description here... + * + */ +define ('ERROR_NO_LAYOUT', '[Controller] Couln\'t find layout "%s" (expected "%s"), create it first'); + +/** + * Enter description here... + * + */ +define ('ERROR_NO_TABLE_LIST', '[Database] Couldn\'t get table list, check database config'); + +/** + * Enter description here... + * + */ +define ('ERROR_NO_MODEL_TABLE', '[Model] No DB table for model "%s" (expected "%s"), create it first'); + +/** + * Enter description here... + * + */ +define ('ERROR_NO_FIELD_IN_MODEL_DB', '[Model::set()] Field "%s" is not present in table "%s", check database schema'); + +/** + * Enter description here... + * + */ +define ('SHORT_ERROR_MESSAGE', '
%s
'); + +/** + * Enter description here... + * + */ +define ('ERROR_CANT_GET_ORIGINAL_IMAGE', '[Image] Couln\'t load original image %s (tried from "%s")'); + +/** + * Enter description here... + * + */ +define ('ERROR_404', "The requested URL /%s was not found on this server (%s)."); + +/** + * Enter description here... + * + */ +define ('ERROR_500', "Application error, sorry."); + +?> \ No newline at end of file diff --git a/libs/flay.php b/libs/flay.php new file mode 100644 index 000000000..60fec2987 --- /dev/null +++ b/libs/flay.php @@ -0,0 +1,258 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Flay + * Text-to-html parser, similar to Textile or RedCloth, only with somehow different syntax. + * See Flay::test() for examples. + * Test with $flay = new Flay(); $flay->test(); + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +uses('object'); + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class Flay extends Object { +/** + * Enter description here... + * + * @var unknown_type + */ + var $text = null; + +/** + * Enter description here... + * + * @var unknown_type + */ + var $allow_html = false; + +/** + * Enter description here... + * + * @param unknown_type $text + */ + function __construct ($text=null) { + $this->text = $text; + parent::__construct(); + } + +/** + * Enter description here... + * + * @param unknown_type $text + * @return unknown + */ + function to_html ($text=null) { + // trim whitespace and disable all HTML + $text = str_replace('<', '<', str_replace('>', '>', trim($text? $text: $this->text))); + + // multi-paragraph functions + $text = preg_replace('#(?:[\n]{0,2})"""(.*)"""(?:[\n]{0,2})#s', "\n\n%BLOCKQUOTE%\n\n\\1\n\n%ENDBLOCKQUOTE%\n\n", $text); + $text = preg_replace('#(?:[\n]{0,2})===(.*)===(?:[\n]{0,2})#s', "\n\n%CENTER%\n\n\\1\n\n%ENDCENTER%\n\n", $text); + + // pre-parse newlines + $text = preg_replace("#\r\n#", "\n", $text); + $text = preg_replace("#[\n]{2,}#", "%PARAGRAPH%", $text); + $text = preg_replace('#[\n]{1}#', "%LINEBREAK%", $text); + + // split into paragraphs and parse + $out = ''; + foreach (split('%PARAGRAPH%', $text) as $line) { + + if ($line) { + + // pre-parse links + $links = array(); + $regs = null; + if (preg_match_all('#\[([^\[]{4,})\]#', $line, $regs)) { + foreach ($regs[1] as $reg) { + $links[] = $reg; + $line = str_replace("[{$reg}]",'%LINK'.(count($links)-1).'%', $line); + } + } + + // MAIN TEXT FUNCTIONS + // bold + $line = ereg_replace("\*([^\*]*)\*", "\\1", $line); + // italic + $line = ereg_replace("_([^_]*)_", "\\1", $line); + // entities + $line = str_replace(' - ', ' – ', $line); + $line = str_replace(' -- ', ' — ', $line); + $line = str_replace('(C)', '©', $line); + $line = str_replace('(R)', '®', $line); + $line = str_replace('(TM)', '™', $line); + + // guess e-mails + $emails = null; + if (preg_match_all("#([_A-Za-z0-9+-+]+(?:\.[_A-Za-z0-9+-]+)*@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*)#", $line, $emails)) { + foreach ($emails[1] as $email) { + $line = str_replace($email, "{$email}", $line); + } + } + // guess links + $urls = null; + if (preg_match_all("#((?:http|https|ftp|nntp)://[^ ]+)#", $line, $urls)) { + foreach ($urls[1] as $url) { + $line = str_replace($url, "{$url}", $line); + } + } + if (preg_match_all("#(www\.[^ ]+)#", $line, $urls)) { + foreach ($urls[1] as $url) { + $line = str_replace($url, "{$url}", $line); + } + } + + + // re-parse links + if (count($links)) { + for ($ii=0; $ii"; + elseif (preg_match('#^([^\]\ ]+)(?: ([^\]]+))?$#', $links[$ii], $regs)) + $with = "".(isset($regs[2])? $regs[2]: $regs[1]).""; + else + $with = $links[$ii]; + + $line = str_replace("%LINK{$ii}%", $with, $line); + } + } + + // re-parse newlines + $out .= str_replace('%LINEBREAK%', "
\n", "

{$line}

\n"); + } + } + + // re-parse multilines + $out = str_replace('

%BLOCKQUOTE%

', "
", $out); + $out = str_replace('

%ENDBLOCKQUOTE%

', "
", $out); + $out = str_replace('

%CENTER%

', "
", $out); + $out = str_replace('

%ENDCENTER%

', "
", $out); + + return $out; + } + +/** + * Enter description here... + * + * @param unknown_type $verbose + * @return unknown + */ + function test ($verbose=false) { + $errors = $tests = 0; + + $tests_to_html = array( + array( + 'text'=>"", + 'html'=>"" + ), + array( + 'text'=>"This is a text.", + 'html'=>"

This is a text.

\n" + ), + array( + 'text'=>"This is a line.\n\n\nThis is\n another one.\n\n", + 'html'=>"

This is a line.

\n

This is
\n another one.

\n" + ), + array( + 'text'=>"This line has *bold*, _italic_, and a _combo *bold* and italic_ texts.", + 'html'=>"

This line has bold, italic, and a combo bold and italic texts.

\n" + ), + array( + 'text'=>"This line has tags which are
not allowed.", + 'html'=>"

This line has <b>tags</b> which are <br />not allowed.

\n", + ), + array( + 'text'=>"[http://sputnik.pl] is a link, but so is [http://sputnik.pl/bla/ this one], and [this is not.", + 'html'=>"

http://sputnik.pl is a link, but so is this one, and [this is not.

\n" + ), + array( + 'text'=>"Why don't we try to insert an image.\n\n[http://sputnik.pl/test.jpg]", + 'html'=>"

Why don't we try to insert an image.

\n

\"\"

\n" + ), + array( + 'text'=>"Auto-link my.name+real@my-server.com and example@example.com, should work.", + 'html'=>"

Auto-link my.name+real@my-server.com and example@example.com, should work.

\n" + ), + array( + 'text'=>"\"\"\"This is a blockquote\"\"\"", + 'html'=>"
\n

This is a blockquote

\n
\n" + ), + array( + 'text'=>"How about a blockquote?\"\"\"This is a multiline blockquote.\n\nThis is the second line.\"\"\"\nAnd this is not.", + 'html'=>"

How about a blockquote?

\n
\n

This is a multiline blockquote.

\n

This is the second line.

\n
\n

And this is not.

\n" + ), + array( + 'text'=>"Now auto-link an url such as http://sputnik.pl or www.robocik-malowany.com/dupa[4] - or any other.", + 'html'=>"

Now auto-link an url such as http://sputnik.pl or www.robocik-malowany.com/dupa[4] – or any other.

\n" + ), + array( + 'text'=>"===This be centered===", + 'html'=>"
\n

This be centered

\n
\n" + ), + array( + 'text'=>"===This be centered.\n\nAnd this be centered too,\nalong with this.===\nThis, alas, be not.", + 'html'=>"
\n

This be centered.

\n

And this be centered too,
\nalong with this.

\n
\n

This, alas, be not.

\n" + ), + array( + 'text'=>"This tests (C)2004 Someone Else, \"Layer Your Apps(R)\" and Cake(TM).", + 'html'=>"

This tests ©2004 Someone Else, \"Layer Your Apps®\" and Cake™.

\n" + ), + ); + + foreach ($tests_to_html as $test) { + $this->text = $test['text']; + if ($test['html'] != ($o = $this->to_html())) { + debug ("Flay test error:\n Provided: {$test['text']}\n Expected: {$test['html']}\n Received: {$o}", 1); + $errors++; + } + elseif ($verbose) { + debug ("Flay test ok:\n Provided: {$test['text']}\n Received: {$o}", 1); + } + + $tests++; + } + + debug ("Flay: {$tests} tests, {$errors} errors (".($errors?'FAILED':'PASSED').')'); + + return !$errors; + } +} + +?> \ No newline at end of file diff --git a/libs/folder.php b/libs/folder.php new file mode 100644 index 000000000..a87182967 --- /dev/null +++ b/libs/folder.php @@ -0,0 +1,116 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Folder + * Folder structure browser, lists folders and files. + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +uses('object'); + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class Folder extends Object { + +/** + * Enter description here... + * + * @var unknown_type + */ + var $path = null; + +/** + * Enter description here... + * + * @var unknown_type + */ + var $sort = false; + +/** + * Enter description here... + * + * @param unknown_type $path + */ + function __construct ($path) { + $this->path = $path . (preg_match('#\/$#', $path)? '': '/'); + parent::__construct(); + } + +/** + * Enter description here... + * + * @param unknown_type $sort + * @return unknown + */ + function ls($sort=true) { + if ($dir = opendir($this->path)) { + $dirs = $files = array(); + while (false !== ($n = readdir($dir))) { + if (!preg_match('#^\.+$#', $n)) { + if (is_dir($this->path.$n)) + $dirs[] = $n; + else + $files[] = $n; + } + } + + if ($sort || $this->sort) { + sort($dirs); + sort($files); + } + + return array($dirs,$files); + } + else { + return false; + } + } + +/** + * Enter description here... + * + * @param unknown_type $path + * @return unknown + */ + function cd ($path) { + $new_path = preg('#^/#', $path)? $path: $this->path.$path; + return is_dir($new_path)? $this->path = $new_path: false; + } + +} + +?> \ No newline at end of file diff --git a/libs/inflector.php b/libs/inflector.php new file mode 100644 index 000000000..d5d3ca3c7 --- /dev/null +++ b/libs/inflector.php @@ -0,0 +1,253 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Inflector + * I'm trying to port RoR Inflector class here. + * Inflector pluralizes and singularizes english nouns. + * Test with $i = new Inflector(); $i->test(); + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +uses('object'); + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class Inflector extends Object { + // private + +/** + * Enter description here... + * + */ + function __construct () { + parent::__construct(); + } + +/** + * Enter description here... + * + * @param unknown_type $word + * @return unknown + */ + function pluralize ($word) { + $plural_rules = array( + '/(x|ch|ss|sh)$/' => '\1es', # search, switch, fix, box, process, address + '/series$/' => '\1series', + '/([^aeiouy]|qu)ies$/' => '\1y', + '/([^aeiouy]|qu)y$/' => '\1ies', # query, ability, agency + '/(?:([^f])fe|([lr])f)$/' => '\1\2ves', # half, safe, wife + '/sis$/' => 'ses', # basis, diagnosis + '/([ti])um$/' => '\1a', # datum, medium + '/person$/' => 'people', # person, salesperson + '/man$/' => 'men', # man, woman, spokesman + '/child$/' => 'children', # child + '/s$/' => 's', # no change (compatibility) + '/$/' => 's' + ); + foreach ($plural_rules as $rule => $replacement) { + if (preg_match($rule, $word)) { + return preg_replace($rule, $replacement, $word); + } + } + + return false; + } + +/** + * Enter description here... + * + * @param unknown_type $word + * @return unknown + */ + function singularize ($word) { + $singular_rules = array( + '/(x|ch|ss)es$/' => '\1', + '/movies$/' => 'movie', + '/series$/' => 'series', + '/([^aeiouy]|qu)ies$/' => '\1y', + '/([lr])ves$/' => '\1f', + '/([^f])ves$/' => '\1fe', + '/(analy|ba|diagno|parenthe|progno|synop|the)ses$/' => '\1sis', + '/([ti])a$/' => '\1um', + '/people$/' => 'person', + '/men$/' => 'man', + '/status$/' => 'status', + '/children$/' => 'child', + '/news$/' => 'news', + '/s$/' => '' + ); + + foreach ($singular_rules as $rule => $replacement) { + if (preg_match($rule, $word)) { + return preg_replace($rule, $replacement, $word); + } + } + + return false; + } + +/** + * Enter description here... + * + * @param unknown_type $lower_case_and_underscored_word + * @return unknown + */ + function camelize($lower_case_and_underscored_word) { + return str_replace(" ","",ucwords(str_replace("_"," ",$lower_case_and_underscored_word))); + } + +/** + * Enter description here... + * + * @param unknown_type $camel_cased_word + * @return unknown + */ + function underscore($camel_cased_word) { + $camel_cased_word = preg_replace('/([A-Z]+)([A-Z])/','\1_\2',$camel_cased_word); + return strtolower(preg_replace('/([a-z])([A-Z])/','\1_\2',$camel_cased_word)); + } + +/** + * Enter description here... + * + * @param unknown_type $lower_case_and_underscored_word + * @return unknown + */ + function humanize($lower_case_and_underscored_word) { + return ucwords(str_replace("_"," ",$lower_case_and_underscored_word)); + } + +/** + * Enter description here... + * + * @param unknown_type $class_name + * @return unknown + */ + function tableize($class_name) { + return Inflector::pluralize(Inflector::underscore($class_name)); + } + +/** + * Enter description here... + * + * @param unknown_type $table_name + * @return unknown + */ + function classify($table_name) { + return $this->camelize($this->singularize($table_name)); + } + +/** + * Enter description here... + * + * @param unknown_type $class_name + * @return unknown + */ + function foreign_key($class_name) { + return $this->underscore($class_name) . "_id"; + } + +/** + * Enter description here... + * + * @param unknown_type $verbose + */ + function test ($verbose=false) { + $singulars = array( + 'search', 'switch', 'fix', 'box', 'process', 'address', 'query', 'ability', + 'agency', 'half', 'safe', 'wife', 'basis', 'diagnosis', 'datum', 'medium', + 'person', 'salesperson', 'man', 'woman', 'spokesman', 'child', 'page', 'robot'); + $plurals = array( + 'searches', 'switches', 'fixes', 'boxes', 'processes', 'addresses', 'queries', 'abilities', + 'agencies', 'halves', 'saves', 'wives', 'bases', 'diagnoses', 'data', 'media', + 'people', 'salespeople', 'men', 'women', 'spokesmen', 'children', 'pages', 'robots'); + + $pluralize_errors = 0; + $singularize_errors = 0; + $tests = 0; + foreach (array_combine($singulars, $plurals) as $singular => $plural) { + if ($this->pluralize($singular) != $plural) { + debug ("Inflector test {$singular} yelded ".$this->pluralize($singular)." (expected {$plural})"); + $pluralize_errors++; + } + elseif ($verbose) { + debug ("Inflector test ok: {$singular} => {$plural}",1); + } + + if ($this->singularize($plural) != $singular) { + debug ("Inflector test {$plural} yelded ".$this->singularize($plural)." (expected {$singular})"); + $singularize_errors++; + } + elseif ($verbose) { + debug ("Inflector test ok: {$plural} => {$singular}",1); + } + $tests++; + } + + $errors = $pluralize_errors + $singularize_errors; + debug ("Inflector: {$tests} tests, {$errors} errors (".($errors?'FAILED':'PASSED').')'); + } +} + + + +if (!function_exists('array_combine')) { +/** + * Enter description here... + * + * @param unknown_type $a1 + * @param unknown_type $a2 + * @return unknown + */ + function array_combine($a1, $a2) { + $a1 = array_values($a1); + $a2 = array_values($a2); + + if (count($a1) != count($a2)) return false; // different lenghts + if (count($a1) <= 0) return false; // arrays are the same and both are empty + + $output = array(); + + for ($i = 0; $i < count($a1); $i++) { + $output[$a1[$i]] = $a2[$i]; + } + + return $output; + } +} + +?> diff --git a/libs/legacy.php b/libs/legacy.php new file mode 100644 index 000000000..2d1618d5c --- /dev/null +++ b/libs/legacy.php @@ -0,0 +1,41 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * with this hack you can use clone() in PHP4 code + * use "clone($object)" not "clone $object"! the former works in both PHP4 and PHP5 + * + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +if (version_compare(phpversion(), '5.0') < 0) { + eval(' + function clone($object) { + return $object; + } + '); +} + +?> \ No newline at end of file diff --git a/libs/model.php b/libs/model.php new file mode 100644 index 000000000..adb441713 --- /dev/null +++ b/libs/model.php @@ -0,0 +1,585 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Model + * DBO-backed object data model, loosly based on RoR (www.rubyonrails.com). + * Automatically selects db table name based on pluralized lowercase object class name + * (i.e. class 'User' => table 'users'; class 'Man' => table 'men') + * The table is required to have at least 'id auto_increment', 'created datetime', + * and 'modified datetime' fields + * + * To do: + * - schema-related cross-table ($has_one, $has_many, $belongs_to) + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +uses('object', 'validators', 'inflector'); + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class Model extends Object { + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $parent = false; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $use_table = false; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $id = false; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $data = array(); + // protected +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $table = false; + // private +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_table_info = null; + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_one_to_many = array(); + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_one_to_one = array(); + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_has_multiple = array(); + +/** + * Enter description here... + * + * append entries for validation as ('field_name' => '/^perl_compat_regexp$/') that has to match with preg_match() + * validate with Model::validate() + * @var unknown_type + */ + var $validate = array(); + +/** + * Enter description here... + * + * @param unknown_type $id + */ + function __construct ($id=false) { + global $DB; + + $this->db = &$DB; + + if ($id) + $this->id = $id; + + $table_name = $this->use_table? $this->use_table: Inflector::tableize(get_class($this)); + $this->use_table ($table_name); + parent::__construct(); + + $this->create_links(); + } + +/** + * Enter description here... + * + */ + function create_links () { + if (!empty($this->has_many)) + $this->_has_multiple = explode(',', $this->has_many); + + foreach ($this->_has_multiple as $model_name) { + // todo fix strip the model name + $model_name = Inflector::singularize($model_name); + $this->$model_name = new $model_name(); + } + + $this->relink(); + } + +/** + * Enter description here... + * + */ + function relink () { + foreach ($this->_has_multiple as $model) { + $name = Inflector::singularize($model); + $this->$name->clear_links(); + $this->$name->link_many_to_one(get_class($this), $this->id); + } + } + +/** + * Enter description here... + * + * @param unknown_type $model_name + * @param unknown_type $value + */ + function link_many_to_one ($model_name, $value=null) { + $table_name = Inflector::tableize($model_name); + $field_name = Inflector::singularize($table_name).'_id'; + $this->_one_to_many[] = array($table_name, $field_name, $value); + } + +/** + * Enter description here... + * + */ + function clear_links () { + $this->_one_to_many = array(); + } + +/** + * Enter description here... + * + * @param unknown_type $table_name + */ + function use_table ($table_name) { + if (!in_array($table_name, $this->db->tables())) + trigger_error (sprintf(ERROR_NO_MODEL_TABLE, get_class($this), $table_name), E_USER_ERROR); + else { + $this->table = $table_name; + $this->load_info(); + } + } + +/** + * Enter description here... + * + * @param unknown_type $one + * @param unknown_type $two + * @return unknown + */ + function set ($one, $two=null) { + $data = is_array($one)? $one: array($one=>$two); + + foreach ($data as $n => $v) { + if (!$this->has_field($n)) { + DEBUG? + trigger_error(sprintf(ERROR_NO_FIELD_IN_MODEL_DB, $n, $this->table), E_USER_ERROR): + trigger_error('Application error occured, trying to set a field name that doesn\'t exist.', E_USER_WARNING); + } + + $n == 'id'? $this->id = $v: $this->data[$n] = $v; + } + + return $data; + } + +/** + * Enter description here... + * + * @param unknown_type $id + */ + function set_id ($id) { + $this->id = $id; + $this->relink(); + } + +/** + * Enter description here... + * + */ + function load_info () { + if (empty($this->_table_info)) + $this->_table_info = new neatArray($this->db->fields($this->table)); + } + +/** + * Enter description here... + * + * @param unknown_type $name + * @return unknown + */ + function has_field ($name) { + return $this->_table_info->find_in('Field', $name); + } + + + // returns data from db + // requires $this->id + // expects coma-separated field list, array of field names, or empty for all fields +/** + * Enter description here... + * + * @param unknown_type $fields + * @return unknown + */ + function read ($fields=null) { + return $this->id? $this->find("id = '{$this->id}'", $fields): false; + } + + // returns a field value from db + // requires $this->id + // requires a field name +/** + * Enter description here... + * + * @param unknown_type $name + * @return unknown + */ + function field ($name) { + if (isset($this->data[$name])) + return $this->data[$name]; + else { + if ($this->id && $data = $this->read($name)) { + return isset($data[$name])? $data[$name]: false; + } + else { + return false; + } + } + } + + // saves $this->data to db + // if $this->id is set, updates a record, else inserts a records +/** + * Enter description here... + * + * @param unknown_type $data + * @return unknown + */ + function save ($data=null) { + if ($data) $this->set($data); + + if (!$this->validates()) + return false; + + $lines = array(); + foreach ($this->data as $n => $v) + $lines[] = "{$n} = '{$v}'"; + + // finds if 'created' and 'updated' fields exists and generates sql to handle them + $update_sql = array(); + if ($this->has_field('created') && !$this->id) $update_sql[] = 'created = NOW()'; + if ($this->has_field('modified')) $update_sql[] = 'modified = NOW()'; + $update_sql = count($update_sql)? ', '.join(', ', $update_sql): null; + + if (count($lines)) { + + if ($this->id) { + if ($this->db->q("UPDATE {$this->table} SET ".join(', ', $lines)."{$update_sql} WHERE id = '{$this->id}'") + && $this->db->last_affected()) { + $this->data = false; + return true; + } + else + return $this->db->has_any($this->table, "id = '{$this->id}'"); + } + else { + if ($this->db->q("INSERT INTO {$this->table} SET ".join(', ', $lines).$update_sql)) { + $this->id = $this->db->last_insert_id(); + return true; + } + else { + return false; + } + } + } + else { + return false; + } + } + + // deletes a record from db + // requires $this->id +/** + * Enter description here... + * + * @param unknown_type $id + * @return unknown + */ + function remove ($id=null) { + return $this->del($id); + } + +/** + * Enter description here... + * + * @param unknown_type $id + * @return unknown + */ + function del ($id=null) { + if ($id) $this->id = $id; + if ($this->id && $this->db->q("DELETE FROM {$this->table} WHERE id = '{$this->id}'")) { + $this->id = false; + return true; + } + else + return false; + } + + // returns true if record exists in db + // requires $this->id +/** + * Enter description here... + * + * @return unknown + */ + function exists () { + return $this->id? $this->db->has_any($this->table, "id = '{$this->id}'"): false; + } + + // returns a row if found, or otherwise null + // expects sql conditions, or empty for no conditions + // expects coma-separated fields list, array of field names, or empty for all fields +/** + * Enter description here... + * + * @param unknown_type $conditions + * @param unknown_type $fields + * @return unknown + */ + function find ($conditions = null, $fields = null) { + $data = $this->find_all($conditions, $fields, null, 1); + return empty($data[0])? false: $data[0]; + } + + // returns specified fields from db records matching conditions + // expects sql conditions, or empty for no conditions + // expects coma-separated fields list, array of field names, or empty for all fields + // expects sql order, or empty for default order + // expects limit, or empty for no limit + // expects page number for offset, or empty for no offset +/** + * Enter description here... + * + * @param unknown_type $conditions + * @param unknown_type $fields + * @param unknown_type $order + * @param unknown_type $limit + * @param unknown_type $page + * @return unknown + */ + function find_all ($conditions = null, $fields = null, $order = null, $limit = null, $page = null) { + if (is_array($fields)) + $f = $fields; + elseif ($fields) + $f = array($fields); + else + $f = array('*'); + + $joins = $whers = array(); + + foreach ($this->_one_to_many as $rule) { + list($table, $field, $value) = $rule; + $joins[] = "LEFT JOIN {$table} ON {$this->table}.{$field} = {$table}.id"; + $whers[] = "{$this->table}.{$field} = '{$value}'"; + } + + $joins = count($joins)? join(' ', $joins): null; + $whers = count($whers)? '('.join(' AND ', $whers).')': null; + $conditions .= ($conditions && $whers? ' AND ': null).$whers; + + $data = $this->db->all( + "SELECT " + .join(', ', $f) + ." FROM {$this->table} {$joins}" + .($conditions? " WHERE {$conditions}":null) + .($order? " ORDER BY {$order}": null) + .($limit? " LIMIT ".($page>0? $limit*($page-1): '0').",{$limit}": null), false, MYSQL_ASSOC); + + return $data; + } + +/** + * Enter description here... + * + * @param unknown_type $sql + * @param unknown_type $debug + * @return unknown + */ + function find_by_sql ($sql, $debug=0) { + return $this->db->all($sql, $debug); + } + +/** + * Enter description here... + * + * @param unknown_type $conditions + * @param unknown_type $fields + * @return unknown + */ + function find_all_threaded ($conditions=null, $fields=null) { + return $this->_do_thread($this->find_all($conditions, $fields), null); + } + +/** + * Enter description here... + * + * @param unknown_type $conditions + * @return unknown + */ + function find_count ($conditions) { + list($data) = $this->find_all($conditions, 'COUNT(id) AS count'); + return $data['count']; + } + +/** + * Enter description here... + * + * @param unknown_type $data + * @param unknown_type $root + * @return unknown + */ + function _do_thread ($data, $root) { + $out = array(); + + for ($ii=0; $ii_do_thread($data, $data[$ii]['id']): null; + $out[] = $tmp; + } + } + + return $out; + } + +/** + * Enter description here... + * + * @param unknown_type $conditions + * @param unknown_type $field + * @param unknown_type $value + * @return unknown + */ + function find_neighbours ($conditions, $field, $value) { + list($prev) = $this->find_all($conditions." AND {$field} < '{$value}'", $field, "{$field} DESC", 1); + list($next) = $this->find_all($conditions." AND {$field} > '{$value}'", $field, "{$field} ASC", 1); + + return array('prev'=>$prev['id'], 'next'=>$next['id']); + } + +/** + * Enter description here... + * + * @param unknown_type $sql + * @return unknown + */ + function query ($sql) { + return $this->db->q($sql); + } + +/** + * Enter description here... + * + * @param unknown_type $data + * @return unknown + */ + function validates ($data=null) { + $errors = count($this->invalid_fields($data)); + + return $errors == 0; + } + +/** + * Enter description here... + * + * @param unknown_type $data + * @return unknown + */ + function invalid_fields ($data=null) { + return $this->_invalid_fields($data); + } + +/** + * Enter description here... + * + * @param unknown_type $data + * @return unknown + */ + function _invalid_fields ($data=null) { + if (!isset($this->validate)) + return true; + + $data = ($data? $data: (isset($this->data)? $this->data: array())); + $errors = array(); + + foreach ($this->validate as $field_name=>$validator) { + if (isset($data[$field_name])) { + if (!preg_match($validator, $data[$field_name])) + $errors[$field_name] = 1; + } + } + + return $errors; + } + +} + +?> \ No newline at end of file diff --git a/libs/object.php b/libs/object.php new file mode 100644 index 000000000..50e9ab0a9 --- /dev/null +++ b/libs/object.php @@ -0,0 +1,61 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Object + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class Object { +/** + * Enter description here... + * + * @return Object + */ + function Object() { + $args= func_get_args(); + call_user_func_array(array(&$this, '__construct'), $args); + } + +/** + * Enter description here... + * + * @param unknown_type $args + */ + function __construct($args=NULL) { + } + +} + +?> \ No newline at end of file diff --git a/libs/router.php b/libs/router.php new file mode 100644 index 000000000..230015e40 --- /dev/null +++ b/libs/router.php @@ -0,0 +1,142 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Router + * Parses the request URL into controller, action, and params + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +uses('object'); + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class Router extends Object { + +/** + * Enter description here... + * + * @var unknown_type + */ + var $routes = array(); + +/** + * Enter description here... + * + */ + function __construct () { + parent::__construct(); + } + +/** + * Enter description here... + * + * @param unknown_type $route + * @param unknown_type $default + */ + function connect ($route, $default=null) { + $parsed = $names = array (); + + $r = null; + if ($route == '' || $route == '/') { + $this->routes[] = array('/^[\/]*$/', array(), $default); + } + else { + if (@preg_match_all('|(?:/([^/]+))|', $route, $r)) { + + foreach ($r[1] as $element) { + if (preg_match('/^:(.+)$/', $element, $r)) { + $parsed[] = '(?:\/([^\/]+))?'; + $names[] = $r[1]; + } + elseif (preg_match('/^\*$/', $element, $r)) { + $parsed[] = '(.*)'; + } + else { + $parsed[] = '/'.$element; + } + } + $regexp = '#^'.join('', $parsed).'$#'; + + $this->routes[] = array($regexp,$names,$default); + } + } + + } + +/** + * Enter description here... + * + * @param unknown_type $url + * @return unknown + */ + function parse ($url) { + $out = array(); + $r = null; + + foreach ($this->routes as $route) { + list($regexp,$names,$defaults) = $route; + + if (@preg_match($regexp, $url, $r)) { + + array_shift($r); + $ii = 0; + foreach ($r as $found) { + if (isset($names[$ii])) + $out[$names[$ii]] = $found; + elseif (preg_match_all('/(?:\/([^\/]+))/', $found, $r)) { + $out['pass'] = $r[1]; + } + $ii++; + } + + if (is_array($defaults)) { + foreach ($defaults as $name => $value) { + if (preg_match('/[a-zA-Z_\-]/', $name)) + $out[$name] = $value; + else + $out['pass'][] = $value; + } + } + break; + } + } + + return $out; + } +} + +?> \ No newline at end of file diff --git a/libs/template.php b/libs/template.php new file mode 100644 index 000000000..82394a947 --- /dev/null +++ b/libs/template.php @@ -0,0 +1,289 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Renderer + * Templating for Controller class. + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +uses('object'); + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class Template extends Object { + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $base = null; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $layout = 'default'; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $auto_render = true; + +/** + * Enter description here... + * + * @var unknown_type + * @access public + */ + var $auto_layout = true; + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_view_vars = array(); + +/** + * Enter description here... + * + * @var unknown_type + * @access private + */ + var $_page_title = false; + +/** + * Enter description here... + * + */ + function __construct () { + parent::__construct(); + } + +/** + * Enter description here... + * + * @param unknown_type $layout + */ + function set_layout ($layout) { + $this->layout = $layout; + } + +/** + * Enter description here... + * + * @param unknown_type $one + * @param unknown_type $two + * @return unknown + */ + function set($one, $two=null) { + return $this->_set_array(is_array($one)? $one: array($one=>$two)); + } + +/** + * Enter description here... + * + * @param unknown_type $value + */ + function set_title ($value) { + $this->_page_title = $value; + } + +/** + * Enter description here... + * + * @param unknown_type $data + */ + function _set_array($data) { + foreach ($data as $name => $value) { + if ($name == 'title') + $this->set_title ($value); + else + $this->_view_vars[$name] = $value; + } + } + +/** + * Enter description here... + * + * @param unknown_type $message + * @param unknown_type $url + * @param unknown_type $time + */ + function flash ($message, $url, $time=1) { + $this->auto_render = false; + $this->auto_layout = false; + + $this->set('url', $this->base.$url); + $this->set('message', $message); + $this->set('time', $time); + + $this->render(null,false,VIEWS.'layouts/flash.thtml'); + } + +/** + * Enter description here... + * + * @param unknown_type $action + * @param unknown_type $layout + * @param unknown_type $file + */ + function render ($action=null, $layout=null, $file=null) { + $this->auto_render = false; + + if (!$action) $action = $this->action; + if ($layout) $this->set_layout($layout); + + $view_fn = $file? $file: $this->_get_view_fn($action); + + if (!is_file($view_fn)) { + DEBUG? trigger_error (sprintf(ERROR_NO_VIEW, $action, $view_fn), E_USER_ERROR) + : $this->error('404', 'Not found', sprintf(ERROR_404, '', "missing view \"{$action}\"")); + die(); + } + + $out = $this->_do_render($view_fn, $this->_view_vars, 0); + + if ($out !== false) { + if ($this->layout && $this->auto_layout) $out = $this->render_layout($out); + if (CACHE_PAGES) $this->cache->append($out); + print $out; + } + else { + $out = $this->_do_render($view_fn, $this->_view_vars, false); + trigger_error (sprintf(ERROR_IN_VIEW, $view_fn, $out), E_USER_ERROR); + } + + } + +/** + * Enter description here... + * + * @param unknown_type $content_for_layout + * @return unknown + */ + function render_layout ($content_for_layout) { + $layout_fn = $this->_get_layout_fn(); + + $data_for_layout = array_merge($this->_view_vars, array( + 'title_for_layout'=>$this->_page_title !== false? $this->_page_title: ucfirst($this->name), + 'content_for_layout'=>$content_for_layout)); + + if (is_file($layout_fn)) { + $out = $this->_do_render($layout_fn, $data_for_layout); + + if ($out === false) { + $out = $this->_do_render($layout_fn, $data_for_layout, false); + trigger_error (sprintf(ERROR_IN_LAYOUT, $layout_fn, $out), E_USER_ERROR); + return false; + } + else { + return $out; + } + } + else { + trigger_error (sprintf(ERROR_NO_LAYOUT, $this->layout, $layout_fn), E_USER_ERROR); + return false; + } + } + +/** + * Enter description here... + * + * @return unknown + */ + function _get_layout_fn() { + return VIEWS."layouts/{$this->layout}.thtml"; + } + +/** + * Enter description here... + * + * @param unknown_type $action + * @return unknown + */ + function _get_view_fn($action) { + return VIEWS.$this->name."/{$action}.thtml"; + } + +/** + * Enter description here... + * + * @param unknown_type $___view_fn + * @param unknown_type $___data_for_view + * @param unknown_type $___play_safe + * @return unknown + */ + function _do_render($___view_fn, $___data_for_view, $___play_safe = true) { + extract($___data_for_view, EXTR_SKIP); # load all view variables + $BASE = $this->base; + $params = &$this->params; + $page_title = $this->_page_title; + ob_start(); # start caching output (eval outputs directly so we need to cache) + + # include the template + $___play_safe? @include($___view_fn): include($___view_fn); + + $out = ob_get_contents(); # retrieve cached output + ob_end_clean(); # end caching output + + return $out; + } + +/** + * Enter description here... + * + * trims a string to a specified length adding elipsis '..' if necessary + * + * @param unknown_type $string + * @param unknown_type $length + * @return unknown + */ + function trim_to ($string, $length) { + return substr($string, 0, $length).(strlen($string)>$length? '..': null); + } +} + +?> \ No newline at end of file diff --git a/libs/time.php b/libs/time.php new file mode 100644 index 000000000..b4b1d0b98 --- /dev/null +++ b/libs/time.php @@ -0,0 +1,121 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Time + * Time related functions, formatting for dates etc. + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +uses ('object'); + +/** + * Enter description here... + * + * + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * + */ +class Time extends Object { + +/** + * Enter description here... + * + * @param unknown_type $date_string + * @return unknown + */ + function nice ($date_string=null) { + $date = $date_string? strtotime($date_string): time(); + return date("D, M jS Y, H:i", $date); + } + +/** + * Enter description here... + * + * @param unknown_type $date_string + * @return unknown + */ + function nice_short ($date_string=null) { + $date = $date_string? Time::fromString($date_string): time(); + + $y = Time::isThisYear($date)? '': ' Y'; + + if (Time::isToday($date)) + return "Today, ".date("H:i", $date); + elseif (Time::wasYesterday($date)) + return "Yesterday, ".date("H:i", $date); + else + return date("M jS{$y}, H:i", $date); + } + +/** + * Enter description here... + * + * @param unknown_type $date + * @return unknown + */ + function isToday ($date) { + return date('Y-m-d', $date) == date('Y-m-d', time()); + } + +/** + * Enter description here... + * + * @param unknown_type $date + * @return unknown + */ + function isThisYear ($date) { + return date('Y', $date) == date('Y', time()); + } + +/** + * Enter description here... + * + * @param unknown_type $date + * @return unknown + */ + function wasYesterday ($date) { + return date('Y-m-d', $date) == date('Y-m-d', strtotime('yesterday')); + } + +/** + * Enter description here... + * + * @param unknown_type $date_string + * @return unknown + */ + function fromString ($date_string) { + return strtotime($date_string); + } + +} + +?> \ No newline at end of file diff --git a/libs/validators.php b/libs/validators.php new file mode 100644 index 000000000..1b92a9842 --- /dev/null +++ b/libs/validators.php @@ -0,0 +1,62 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Tort Validators + * Used to validate data in Models. + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.libs + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +define('VALID_NOT_EMPTY', '/.+/'); + +/** + * Enter description here... + * + */ +define('VALID_NUMBER', '/^[0-9]+$/'); + +/** + * Enter description here... + * + */ +define('VALID_EMAIL', '/^([a-z0-9][a-z0-9_\-\.\+]*)@([a-z0-9][a-z0-9\.\-]{0,63}\.[a-z]{2,3})$/i'); + +/** + * Enter description here... + * + */ +define('VALID_TAG', '/[a-z_]+/i'); + +/** + * Enter description here... + * + */ +define('VALID_TAGS', '/[a-z_ ]+/i'); + +?> \ No newline at end of file diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 000000000..bee15b3c9 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,9 @@ +# Based on Rails 0.10.0 .htaccess (www.rubyonrails.com) + +# Redirect all requests not available on the filesystem to Cake +RewriteEngine On +RewriteCond %{REQUEST_FILENAME} !-f +RewriteRule ^(.*)$ dispatch.php?url=$1 [QSA,L] + +# In case Cake experiences terminal errors +ErrorDocument 500 500.html diff --git a/public/500.html b/public/500.html new file mode 100644 index 000000000..1eddd44c1 --- /dev/null +++ b/public/500.html @@ -0,0 +1,11 @@ + + + +500 Server error + + + +

Server error

+

Cake has experienced a terminal error and it cannot continue. Please check your web server configuration.

+ + diff --git a/public/css/default.css b/public/css/default.css new file mode 100644 index 000000000..e69de29bb diff --git a/public/dispatch.php b/public/dispatch.php new file mode 100644 index 000000000..6f0afaff6 --- /dev/null +++ b/public/dispatch.php @@ -0,0 +1,110 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Purpose: Dispatch + * The main "loop" + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.public + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + + +## DIRECTORY LAYOUT +/** + * Enter description here... + * + */ +define ('ROOT', '../'); +/** + * Enter description here... + * + */ +define ('APP', ROOT.'app/'); +/** + * Enter description here... + * + */ +define ('MODELS', APP.'models/'); +/** + * Enter description here... + * + */ +define ('CONTROLLERS', APP.'controllers/'); +/** + * Enter description here... + * + */ +define ('VIEWS', APP.'views/'); +/** + * Enter description here... + * + */ +define ('CONFIGS', ROOT.'config/'); +/** + * Enter description here... + * + */ +define ('LIBS', ROOT.'libs/'); +/** + * Enter description here... + * + */ +define ('PUBLIC', ROOT.'public/'); + +## STARTUP +/** + * Enter description here... + * + */ +require (LIBS.'basics.php'); +uses ('dispatcher', 'dbo'); +uses_config(); +uses_database(); +uses_tags(); + +## LOAD MODELS & CONTROLLERS +## +load_models (); +load_controllers (); + +## START SESSION +## +session_start(); + +## RUN THE SCRIPT +## +$url = empty($_GET['url'])? null: $_GET['url']; +$DISPATCHER = new Dispatcher (); +$DISPATCHER->dispatch($url); + +## PRINT TIMING +## + +/** + * Enter description here... + * + */ +if (DEBUG) echo ""; + +?> diff --git a/public/files/put_downloadable_files_here b/public/files/put_downloadable_files_here new file mode 100644 index 000000000..e69de29bb diff --git a/public/img/put_images_here b/public/img/put_images_here new file mode 100644 index 000000000..e69de29bb diff --git a/public/index.php b/public/index.php new file mode 100644 index 000000000..f20982f0c --- /dev/null +++ b/public/index.php @@ -0,0 +1,36 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Enter description here... + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.public + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ + +/** + * Enter description here... + * + */ +header ('dispatch.php?url='.ltrim($_SERVER['PATH_INFO'],'/')); +?> diff --git a/scripts/add.bat b/scripts/add.bat new file mode 100644 index 000000000..2eb456cfc --- /dev/null +++ b/scripts/add.bat @@ -0,0 +1 @@ +@php -q scripts/add.php %1 %2 %3 %4 %5 %6 %7 %8 %9 \ No newline at end of file diff --git a/scripts/add.php b/scripts/add.php new file mode 100644 index 000000000..c2d4a2289 --- /dev/null +++ b/scripts/add.php @@ -0,0 +1,91 @@ + + // +// + Copyright: (c) 2005 Michal Tatarynowicz + // +// + + // +// + Author(s): (c) 2005 Michal Tatarynowicz + // +// + + // +// +------------------------------------------------------------------+ // +// + Licensed under the Public Domain Licence + // +// +------------------------------------------------------------------+ // +////////////////////////////////////////////////////////////////////////// + +/** + * Enter description here... + * + * @filesource + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @author Michal Tatarynowicz + * @copyright Copyright (c) 2005, Michal Tatarynowicz + * @package cake + * @subpackage cake.scripts + * @since Cake v 0.2.9 + * @version $Revision$ + * @license Public_Domain + * + */ +## DIRECTORIES +## +/** + * Enter description here... + * + */ +define ('ROOT', '../'); + +/** + * Enter description here... + * + */ +define ('APP', ROOT.'app/'); + +/** + * Enter description here... + * + */ +define ('MODELS', APP.'models/'); + +/** + * Enter description here... + * + */ +define ('CONTROLLERS', APP.'controllers/'); + +/** + * Enter description here... + * + */ +define ('VIEWS', APP.'views/'); + +/** + * Enter description here... + * + */ +define ('CONFIGS', ROOT.'config/'); + +/** + * Enter description here... + * + */ +define ('LIBS', ROOT.'libs/'); + +/** + * Enter description here... + * + */ +define ('PUBLIC', ROOT.'public/'); + +## LOAD LIBRARIES +## +require (LIBS.'basics.php'); +uses ('bake'); +#load_libs (); + +$script_name = array_shift($argv); +$action = array_shift($argv); + +$bake = new Bake ($action, $argv); + +?> \ No newline at end of file