diff --git a/modules/cron/README.markdown b/modules/cron/README.markdown deleted file mode 100644 index b08b42f..0000000 --- a/modules/cron/README.markdown +++ /dev/null @@ -1,86 +0,0 @@ -# Kohana-Cron - -This module provides a way to schedule tasks (jobs) within your Kohana application. - - -## Installation - -Step 1: Download the module into your modules subdirectory. - -Step 2: Enable the module in your bootstrap file: - - /** - * Enable modules. Modules are referenced by a relative or absolute path. - */ - Kohana::modules(array( - 'cron' => MODPATH.'cron', - // 'auth' => MODPATH.'auth', // Basic authentication - // 'codebench' => MODPATH.'codebench', // Benchmarking tool - // 'database' => MODPATH.'database', // Database access - // 'image' => MODPATH.'image', // Image manipulation - // 'orm' => MODPATH.'orm', // Object Relationship Mapping - // 'pagination' => MODPATH.'pagination', // Paging of results - // 'userguide' => MODPATH.'userguide', // User guide and API documentation - )); - - -Step 3: Make sure the settings in `config/cron.php` are correct for your environment. -If not, copy the file to `application/config/cron.php` and change the values accordingly. - - -## Usage - -In its simplest form, a task is a [PHP callback][1] and times at which it should run. -To configure a task call `Cron::set($name, array($frequency, $callback))` where -`$frequency` is a string of date and time fields identical to those found in [crontab][2]. -For example, - - Cron::set('reindex_catalog', array('@daily', 'Catalog::regenerate_index')); - Cron::set('calendar_notifications', array('*/5 * * * *', 'Calendar::send_emails')); - -Configured tasks are run with their appropriate frequency by calling `Cron::run()`. Call -this method in your bootstrap file, and you're done! - - -## Advanced Usage - -A task can also be an instance of `Cron` that extends `next()` and/or `execute()` as -needed. Such a task is configured by calling `Cron::set($name, $instance)`. - -If you have access to the system crontab, you can run Cron less (or more) than once -every request. You will need to modify the lines where the request is handled in your -bootstrap file to prevent extraneous output. The default is: - - /** - * Execute the main request. A source of the URI can be passed, eg: $_SERVER['PATH_INFO']. - * If no source is specified, the URI will be automatically detected. - */ - echo Request::instance() - ->execute() - ->send_headers() - ->response; - -Change it to: - - if ( ! defined('SUPPRESS_REQUEST')) - { - /** - * Execute the main request. A source of the URI can be passed, eg: $_SERVER['PATH_INFO']. - * If no source is specified, the URI will be automatically detected. - */ - echo Request::instance() - ->execute() - ->send_headers() - ->response; - } - -Then set up a system cron job to run your application's Cron once a minute: - - * * * * * /usr/bin/php -f /path/to/kohana/modules/cron/run.php - -The included `run.php` should work for most cases, but you are free to call `Cron::run()` -in any way you see fit. - - - [1]: http://php.net/manual/language.pseudo-types.php#language.types.callback - [2]: http://linux.die.net/man/5/crontab diff --git a/modules/cron/classes/Cron.php b/modules/cron/classes/Cron.php deleted file mode 100644 index 7f3d275..0000000 --- a/modules/cron/classes/Cron.php +++ /dev/null @@ -1,10 +0,0 @@ -load('cron'); - $result = FALSE; - - if (file_exists($config->lock) AND ($stat = @stat($config->lock)) AND time() - $config->window < $stat['mtime']) - { - // Lock exists and has not expired - return $result; - } - - $fh = fopen($config->lock, 'a'); - - if (flock($fh, LOCK_EX)) - { - fseek($fh, 0, SEEK_END); - - if (ftell($fh) === (empty($stat) ? 0 : $stat['size'])) - { - // Current size matches expected size - // Claim the file by changing the size - fwrite($fh, '.'); - - $result = TRUE; - } - - // else, Another process acquired during flock() - } - - fclose($fh); - - return $result; - } - - /** - * Store the timestamps of when jobs should run next - */ - protected static function _save() - { - Kohana::cache("Cron::run()", Cron::$_times, Kohana::$config->load('cron')->window * 2); - } - - /** - * Release the Cron mutex - */ - protected static function _unlock() - { - return @unlink(Kohana::$config->load('cron')->lock); - } - - /** - * @return boolean FALSE when another instance is running - */ - public static function run() - { - if (empty(Cron::$_jobs)) - return TRUE; - - if ( ! Cron::_lock()) - return FALSE; - - try - { - Cron::_load(); - - $now = time(); - $threshold = $now - Kohana::$config->load('cron')->window; - - foreach (Cron::$_jobs as $name => $job) - { - if (empty(Cron::$_times[$name]) OR Cron::$_times[$name] < $threshold) - { - // Expired - - Cron::$_times[$name] = $job->next($now); - - if ($job->next($threshold) < $now) - { - // Within the window - - $job->execute(); - } - } - elseif (Cron::$_times[$name] < $now) - { - // Within the window - - Cron::$_times[$name] = $job->next($now); - - $job->execute(); - } - } - } - catch (Exception $e) {} - - Cron::_save(); - Cron::_unlock(); - - if (isset($e)) - throw $e; - - return TRUE; - } - - protected $_callback; - protected $_period; - - public function __construct($period, $callback) - { - $this->_period = $period; - $this->_callback = $callback; - } - - /** - * Execute this job - */ - public function execute() - { - call_user_func($this->_callback); - } - - /** - * Calculates the next timestamp in this period - * - * @param integer Timestamp from which to calculate - * @return integer Next timestamp in this period - */ - public function next($from) - { - // PHP >= 5.3.0 - //if ($this->_period instanceof DatePeriod) { return; } - //if (is_string($this->_period) AND preg_match('/^P[\dDHMSTWY]+$/', $period)) { $this->_period = new DateInterval($this->_period); } - //if ($this->_period instanceof DateInterval) { return; } - - return $this->_next_crontab($from); - } - - /** - * Calculates the next timestamp of this crontab period - * - * @param integer Timestamp from which to calculate - * @return integer Next timestamp in this period - */ - protected function _next_crontab($from) - { - if (is_string($this->_period)) - { - // Convert string to lists of valid values - - if ($this->_period[0] === '@') - { - switch (substr($this->_period, 1)) - { - case 'annually': - case 'yearly': - // '0 0 1 1 *' - $this->_period = array('minutes' => array(0), 'hours' => array(0), 'monthdays' => array(1), 'months' => array(1), 'weekdays' => range(0,6)); - break; - - case 'daily': - case 'midnight': - // '0 0 * * *' - $this->_period = array('minutes' => array(0), 'hours' => array(0), 'monthdays' => range(1,31), 'months' => range(1,12), 'weekdays' => range(0,6)); - break; - - case 'hourly': - // '0 * * * *' - $this->_period = array('minutes' => array(0), 'hours' => range(0,23), 'monthdays' => range(1,31), 'months' => range(1,12), 'weekdays' => range(0,6)); - break; - - case 'monthly': - // '0 0 1 * *' - $this->_period = array('minutes' => array(0), 'hours' => array(0), 'monthdays' => array(1), 'months' => range(1,12), 'weekdays' => range(0,6)); - break; - - case 'weekly': - // '0 0 * * 0' - $this->_period = array('minutes' => array(0), 'hours' => array(0), 'monthdays' => range(1,31), 'months' => range(1,12), 'weekdays' => array(0)); - break; - } - } - else - { - list($minutes, $hours, $monthdays, $months, $weekdays) = explode(' ', $this->_period); - - $months = strtr(strtolower($months), array( - 'jan' => 1, - 'feb' => 2, - 'mar' => 3, - 'apr' => 4, - 'may' => 5, - 'jun' => 6, - 'jul' => 7, - 'aug' => 8, - 'sep' => 9, - 'oct' => 10, - 'nov' => 11, - 'dec' => 12, - )); - - $weekdays = strtr(strtolower($weekdays), array( - 'sun' => 0, - 'mon' => 1, - 'tue' => 2, - 'wed' => 3, - 'thu' => 4, - 'fri' => 5, - 'sat' => 6, - )); - - $this->_period = array( - 'minutes' => $this->_parse_crontab_field($minutes, 0, 59), - 'hours' => $this->_parse_crontab_field($hours, 0, 23), - 'monthdays' => $this->_parse_crontab_field($monthdays, 1, 31), - 'months' => $this->_parse_crontab_field($months, 1, 12), - 'weekdays' => $this->_parse_crontab_field($weekdays, 0, 7) - ); - - // Ensure Sunday is zero - if (end($this->_period['weekdays']) === 7) - { - array_pop($this->_period['weekdays']); - - if (reset($this->_period['weekdays']) !== 0) - { - array_unshift($this->_period['weekdays'], 0); - } - } - } - } - - $from = getdate($from); - - if ( ! in_array($from['mon'], $this->_period['months'])) - return $this->_next_crontab_month($from); - - if (count($this->_period['weekdays']) === 7) - { - // Day of Week is unrestricted, defer to Day of Month - if ( ! in_array($from['mday'], $this->_period['monthdays'])) - return $this->_next_crontab_monthday($from); - } - elseif (count($this->_period['monthdays']) === 31) - { - // Day of Month is unrestricted, use Day of Week - if ( ! in_array($from['wday'], $this->_period['weekdays'])) - return $this->_next_crontab_weekday($from); - } - else - { - // Both Day of Week and Day of Month are restricted - if ( ! in_array($from['mday'], $this->_period['monthdays']) AND ! in_array($from['wday'], $this->_period['weekdays'])) - return $this->_next_crontab_day($from); - } - - if ( ! in_array($from['hours'], $this->_period['hours'])) - return $this->_next_crontab_hour($from); - - return $this->_next_crontab_minute($from); - } - - /** - * Calculates the first timestamp in the next day of this period when both - * Day of Week and Day of Month are restricted - * - * @uses _next_crontab_month() - * - * @param array Date array from getdate() - * @return integer Timestamp of next restricted Day - */ - protected function _next_crontab_day(array $from) - { - // Calculate effective Day of Month for next Day of Week - - if ($from['wday'] >= end($this->_period['weekdays'])) - { - $next = reset($this->_period['weekdays']) + 7; - } - else - { - foreach ($this->_period['weekdays'] as $next) - { - if ($from['wday'] < $next) - break; - } - } - - $monthday = $from['mday'] + $next - $from['wday']; - - if ($monthday <= (int) date('t', mktime(0, 0, 0, $from['mon'], 1, $from['year']))) - { - // Next Day of Week is in this Month - - if ($from['mday'] >= end($this->_period['monthdays'])) - { - // No next Day of Month, use next Day of Week - $from['mday'] = $monthday; - } - else - { - // Calculate next Day of Month - foreach ($this->_period['monthdays'] as $next) - { - if ($from['mday'] < $next) - break; - } - - // Use earliest day - $from['mday'] = min($monthday, $next); - } - } - else - { - if ($from['mday'] >= end($this->_period['monthdays'])) - { - // No next Day of Month, use next Month - return $this->_next_crontab_month($from); - } - - // Calculate next Day of Month - foreach ($this->_period['monthdays'] as $next) - { - if ($from['mday'] < $next) - break; - } - - // Use next Day of Month - $from['mday'] = $next; - } - - // Use first Hour and first Minute - return mktime(reset($this->_period['hours']), reset($this->_period['minutes']), 0, $from['mon'], $from['mday'], $from['year']); - } - - /** - * Calculates the first timestamp in the next hour of this period - * - * @uses _next_crontab_day() - * @uses _next_crontab_monthday() - * @uses _next_crontab_weekday() - * - * @param array Date array from getdate() - * @return integer Timestamp of next Hour - */ - protected function _next_crontab_hour(array $from) - { - if ($from['hours'] >= end($this->_period['hours'])) - { - // No next Hour - - if (count($this->_period['weekdays']) === 7) - { - // Day of Week is unrestricted, defer to Day of Month - return $this->_next_crontab_monthday($from); - } - - if (count($this->_period['monthdays']) === 31) - { - // Day of Month is unrestricted, use Day of Week - return $this->_next_crontab_weekday($from); - } - - // Both Day of Week and Day of Month are restricted - return $this->_next_crontab_day($from); - } - - // Calculate next Hour - foreach ($this->_period['hours'] as $next) - { - if ($from['hours'] < $next) - break; - } - - // Use next Hour and first Minute - return mktime($next, reset($this->_period['minutes']), 0, $from['mon'], $from['mday'], $from['year']); - } - - /** - * Calculates the timestamp of the next minute in this period - * - * @uses _next_crontab_hour() - * - * @param array Date array from getdate() - * @return integer Timestamp of next Minute - */ - protected function _next_crontab_minute(array $from) - { - if ($from['minutes'] >= end($this->_period['minutes'])) - { - // No next Minute, use next Hour - return $this->_next_crontab_hour($from); - } - - // Calculate next Minute - foreach ($this->_period['minutes'] as $next) - { - if ($from['minutes'] < $next) - break; - } - - // Use next Minute - return mktime($from['hours'], $next, 0, $from['mon'], $from['mday'], $from['year']); - } - - /** - * Calculates the first timestamp in the next month of this period - * - * @param array Date array from getdate() - * @return integer Timestamp of next Month - */ - protected function _next_crontab_month(array $from) - { - if ($from['mon'] >= end($this->_period['months'])) - { - // No next Month, increment Year and use first Month - ++$from['year']; - $from['mon'] = reset($this->_period['months']); - } - else - { - // Calculate next Month - foreach ($this->_period['months'] as $next) - { - if ($from['mon'] < $next) - break; - } - - // Use next Month - $from['mon'] = $next; - } - - if (count($this->_period['weekdays']) === 7) - { - // Day of Week is unrestricted, use first Day of Month - $from['mday'] = reset($this->_period['monthdays']); - } - else - { - // Calculate Day of Month for the first Day of Week - $indices = array_flip($this->_period['weekdays']); - - $monthday = 1; - $weekday = (int) date('w', mktime(0, 0, 0, $from['mon'], 1, $from['year'])); - - while ( ! isset($indices[$weekday % 7]) AND $monthday < 7) - { - ++$monthday; - ++$weekday; - } - - if (count($this->_period['monthdays']) === 31) - { - // Day of Month is unrestricted, use first Day of Week - $from['mday'] = $monthday; - } - else - { - // Both Day of Month and Day of Week are restricted, use earliest one - $from['mday'] = min($monthday, reset($this->_period['monthdays'])); - } - } - - // Use first Hour and first Minute - return mktime(reset($this->_period['hours']), reset($this->_period['minutes']), 0, $from['mon'], $from['mday'], $from['year']); - } - - /** - * Calculates the first timestamp in the next day of this period when only - * Day of Month is restricted - * - * @uses _next_crontab_month() - * - * @param array Date array from getdate() - * @return integer Timestamp of next Day of Month - */ - protected function _next_crontab_monthday(array $from) - { - if ($from['mday'] >= end($this->_period['monthdays'])) - { - // No next Day of Month, use next Month - return $this->_next_crontab_month($from); - } - - // Calculate next Day of Month - foreach ($this->_period['monthdays'] as $next) - { - if ($from['mday'] < $next) - break; - } - - // Use next Day of Month, first Hour, and first Minute - return mktime(reset($this->_period['hours']), reset($this->_period['minutes']), 0, $from['mon'], $next, $from['year']); - } - - /** - * Calculates the first timestamp in the next day of this period when only - * Day of Week is restricted - * - * @uses _next_crontab_month() - * - * @param array Date array from getdate() - * @return integer Timestamp of next Day of Week - */ - protected function _next_crontab_weekday(array $from) - { - // Calculate effective Day of Month for next Day of Week - - if ($from['wday'] >= end($this->_period['weekdays'])) - { - $next = reset($this->_period['weekdays']) + 7; - } - else - { - foreach ($this->_period['weekdays'] as $next) - { - if ($from['wday'] < $next) - break; - } - } - - $monthday = $from['mday'] + $next - $from['wday']; - - if ($monthday > (int) date('t', mktime(0, 0, 0, $from['mon'], 1, $from['year']))) - { - // Next Day of Week is not in this Month, use next Month - return $this->_next_crontab_month($from); - } - - // Use next Day of Week, first Hour, and first Minute - return mktime(reset($this->_period['hours']), reset($this->_period['minutes']), 0, $from['mon'], $monthday, $from['year']); - } - - /** - * Returns a sorted array of all the values indicated in a Crontab field - * @link http://linux.die.net/man/5/crontab - * - * @param string Crontab field - * @param integer Minimum value for this field - * @param integer Maximum value for this field - * @return array - */ - protected function _parse_crontab_field($value, $min, $max) - { - $result = array(); - - foreach (explode(',', $value) as $value) - { - if ($slash = strrpos($value, '/')) - { - $step = (int) substr($value, $slash + 1); - $value = substr($value, 0, $slash); - } - - if ($value === '*') - { - $result = array_merge($result, range($min, $max, $slash ? $step : 1)); - } - elseif ($dash = strpos($value, '-')) - { - $result = array_merge($result, range(max($min, (int) substr($value, 0, $dash)), min($max, (int) substr($value, $dash + 1)), $slash ? $step : 1)); - } - else - { - $value = (int) $value; - - if ($min <= $value AND $value <= $max) - { - $result[] = $value; - } - } - } - - sort($result); - - return array_unique($result); - } - -} diff --git a/modules/cron/config/cron.php b/modules/cron/config/cron.php deleted file mode 100644 index 80cd3d3..0000000 --- a/modules/cron/config/cron.php +++ /dev/null @@ -1,28 +0,0 @@ - Kohana::$cache_dir.DIRECTORY_SEPARATOR.'cron.lck', - - /** - * Cron does not run EXACTLY when tasks are scheduled. - * A task can be executed up to this many seconds AFTER its scheduled time. - * - * For example, Cron is run at 10:48 and a task was scheduled to execute at - * 10:45, 180 seconds ago. If window is greater than 180, the task will be - * executed. - * - * This value should always be larger than the time it takes to run all - * your tasks. - */ - 'window' => 300, -); diff --git a/modules/cron/run.php b/modules/cron/run.php deleted file mode 100644 index 6cafdbf..0000000 --- a/modules/cron/run.php +++ /dev/null @@ -1,22 +0,0 @@ -next($from); - - $this->assertSame($expected_result, $result); - } - - public function provider_next() - { - return array - ( - array('@annually', mktime(8, 45, 0, 11, 19, 2009), mktime(0, 0, 0, 1, 1, 2010)), - array('@monthly', mktime(8, 45, 0, 11, 19, 2009), mktime(0, 0, 0, 12, 1, 2009)), - array('@weekly', mktime(8, 45, 0, 11, 19, 2009), mktime(0, 0, 0, 11, 22, 2009)), - array('@daily', mktime(8, 45, 0, 11, 19, 2009), mktime(0, 0, 0, 11, 20, 2009)), - array('@hourly', mktime(8, 45, 0, 11, 19, 2009), mktime(9, 0, 0, 11, 19, 2009)), - - array('* * * * *', mktime(8, 45, 0, 11, 19, 2009), mktime(8, 46, 0, 11, 19, 2009)), - - array( - '* * * * 0', // Sundays - mktime(0, 0, 0, 11, 30, 2009), // Monday, Nov 30, 2009 - mktime(0, 0, 0, 12, 6, 2009) // Sunday, Dec 6, 2009 - ), - - array( - '* * 15 * 6', // 15th and Saturdays - mktime(0, 0, 0, 11, 29, 2009), // Sunday, Nov 29, 2009 - mktime(0, 0, 0, 12, 5, 2009) // Saturday, Dec 5, 2009 - ), - - array( - '* * * * 1,5', // Mondays and Fridays - mktime(0, 0, 0, 11, 24, 2009), // Tuesday, Nov 24, 2009 - mktime(0, 0, 0, 11, 27, 2009) // Friday, Nov 27, 2009 - ), - - array( - '* * 15 * 6-7', // 15th, Saturdays, and Sundays - mktime(0, 0, 0, 11, 23, 2009), // Monday, Nov 23, 2009 - mktime(0, 0, 0, 11, 28, 2009) // Saturday, Nov 28, 2009 - ), - - array( - '* * 15,30 * 2', // 15th, 30th, and Tuesdays - mktime(0, 0, 0, 11, 29, 2009), // Sunday, Nov 29, 2009 - mktime(0, 0, 0, 11, 30, 2009) // Monday, Nov 30, 2009 - ), - - array( - '0 0 * * 4', // Midnight on Thursdays - mktime(1, 0, 0, 11, 19, 2009), // 01:00 Thursday, Nov 19, 2009 - mktime(0, 0, 0, 11, 26, 2009) // 00:00 Thursday, Nov 26, 2009 - ), - - array( - '0 0 */2 * 4', // Midnight on odd days and Thursdays - mktime(1, 0, 0, 11, 19, 2009), // 01:00 Thursday, Nov 19, 2009 - mktime(0, 0, 0, 11, 21, 2009) // 00:00 Saturday, Nov 21, 2009 - ), - ); - } -} diff --git a/modules/minion/classes/Kohana/Minion/CLI.php b/modules/minion/classes/Kohana/Minion/CLI.php index 4a1196b..13c1de6 100644 --- a/modules/minion/classes/Kohana/Minion/CLI.php +++ b/modules/minion/classes/Kohana/Minion/CLI.php @@ -92,7 +92,7 @@ class Kohana_Minion_CLI { { foreach ($values as $opt => $value) { - if ( ! in_array($opt, $options, TRUE)) + if ( ! in_array($opt, $options)) { // Set the given value unset($values[$opt]); diff --git a/modules/orm/classes/Kohana/ORM.php b/modules/orm/classes/Kohana/ORM.php index 6da6763..716e51d 100644 --- a/modules/orm/classes/Kohana/ORM.php +++ b/modules/orm/classes/Kohana/ORM.php @@ -183,15 +183,6 @@ class Kohana_ORM extends Model implements serializable { */ protected $_table_names_plural = TRUE; - // Suppress ORMs inclusion of .* - protected $_disable_wild_select = FALSE; - - // Suppress ORMs inclusion of . to column joins - protected $_disable_join_table_name = FALSE; - - // Suppress ORMs use of limit - protected $_disable_limit = FALSE; - /** * Model configuration, reload on wakeup? * @var bool @@ -277,7 +268,7 @@ class Kohana_ORM extends Model implements serializable { else { // Passing the primary key - $this->where(($this->_disable_join_table_name ? '' : $this->_object_name.'.').$this->_primary_key, '=', $id)->find(); + $this->where($this->_object_name.'.'.$this->_primary_key, '=', $id)->find(); } } elseif ( ! empty($this->_cast_data)) @@ -360,7 +351,6 @@ class Kohana_ORM extends Model implements serializable { } $defaults['foreign_key'] = $this->_object_name.$this->_foreign_key_suffix; - $defaults['far_key'] = Inflector::singular($alias).$this->_foreign_key_suffix; $init['_has_one'][$alias] = array_merge($defaults, $details); } @@ -369,7 +359,7 @@ class Kohana_ORM extends Model implements serializable { { if ( ! isset($details['model'])) { - $defaults['model'] = str_replace(' ', '_', ucwords(str_replace('_', ' ', ($this->_model_names_plural ? Inflector::singular($alias) : $alias)))); + $defaults['model'] = str_replace(' ', '_', ucwords(str_replace('_', ' ', Inflector::singular($alias)))); } $defaults['foreign_key'] = $this->_object_name.$this->_foreign_key_suffix; @@ -636,7 +626,7 @@ class Kohana_ORM extends Model implements serializable { $model = $this->_related($column); // Use this model's column and foreign model's primary key - $col = ($this->_disable_join_table_name ? '' : $model->_object_name.'.').$model->_primary_key; + $col = $model->_object_name.'.'.$model->_primary_key; $val = $this->_object[$this->_belongs_to[$column]['foreign_key']]; // Make sure we don't run WHERE "AUTO_INCREMENT column" = NULL queries. This would @@ -653,23 +643,9 @@ class Kohana_ORM extends Model implements serializable { { $model = $this->_related($column); - if (! is_array($this->_has_one[$column]['foreign_key'])) - { - // Use this model's primary key value and foreign model's column - $col = ($this->_disable_join_table_name ? '' : $model->_object_name.'.').$this->_has_one[$column]['foreign_key']; - $val = $this->_object[$this->_has_one[$column]['far_key']]; - } - else - { - foreach ($this->_has_one[$column]['foreign_key'] as $fk) - { - // Simple has_many relationship, search where target model's foreign key is this model's primary key - $col = ($this->_disable_join_table_name ? '' : $model->_object_name.'.').$fk; - $val = $this->_object[$fk]; - - $model = $model->where($col, '=', $val); - } - } + // Use this model's primary key value and foreign model's column + $col = $model->_object_name.'.'.$this->_has_one[$column]['foreign_key']; + $val = $this->pk(); $model->where($col, '=', $val)->find(); @@ -679,52 +655,29 @@ class Kohana_ORM extends Model implements serializable { { $model = ORM::factory($this->_has_many[$column]['model']); - if (! is_array($this->_has_many[$column]['foreign_key'])) + if (isset($this->_has_many[$column]['through'])) { - if (isset($this->_has_many[$column]['through'])) - { - // Grab has_many "through" relationship table - $through = $this->_has_many[$column]['through']; + // Grab has_many "through" relationship table + $through = $this->_has_many[$column]['through']; - // Join on through model's target foreign key (far_key) and target model's primary key - $join_col1 = ($this->_disable_join_table_name ? '' : $through.'.').$this->_has_many[$column]['far_key']; - $join_col2 = ($this->_disable_join_table_name ? '' : $model->_object_name.'.').$model->_primary_key; + // Join on through model's target foreign key (far_key) and target model's primary key + $join_col1 = $through.'.'.$this->_has_many[$column]['far_key']; + $join_col2 = $model->_object_name.'.'.$model->_primary_key; - $model->join($through)->on($join_col1, '=', $join_col2); + $model->join($through)->on($join_col1, '=', $join_col2); - // Through table's source foreign key (foreign_key) should be this model's primary key - $col = ($this->_disable_join_table_name ? '' : $through.'.').$this->_has_many[$column]['foreign_key']; - $val = $this->pk(); - } - else - { - // Simple has_many relationship, search where target model's foreign key is this model's primary key - $col = ($this->_disable_join_table_name ? '' : $model->_object_name.'.').$this->_has_many[$column]['foreign_key']; - $val = $this->_object[$this->_has_many[$column]['far_key']]; - } - - return $model->where($col, '=', $val); + // Through table's source foreign key (foreign_key) should be this model's primary key + $col = $through.'.'.$this->_has_many[$column]['foreign_key']; + $val = $this->pk(); } else { - foreach ($this->_has_many[$column]['foreign_key'] as $mk => $fk) - { - if (isset($this->_has_many[$column]['through'])) - { - throw new Kohana_Exception('This code hasnt been written yet!'); - } - else - { - // Simple has_many relationship, search where target model's foreign key is this model's primary key - $col = ($this->_disable_join_table_name ? '' : $model->_object_name.'.').$fk; - $val = $this->_object[$mk]; - } - - $model = $model->where($col, '=', $val); - } - - return $model; + // Simple has_many relationship, search where target model's foreign key is this model's primary key + $col = $model->_object_name.'.'.$this->_has_many[$column]['foreign_key']; + $val = $this->pk(); } + + return $model->where($col, '=', $val); } else { @@ -1078,15 +1031,14 @@ class Kohana_ORM extends Model implements serializable { { $this->_db_builder->from(array($this->_table_name, $this->_object_name)); - if ($multiple === FALSE AND ! $this->_disable_limit) + if ($multiple === FALSE) { // Only fetch 1 record $this->_db_builder->limit(1); } // Select all columns by default - if (! $this->_disable_wild_select) - $this->_db_builder->select_array($this->_build_select()); + $this->_db_builder->select_array($this->_build_select()); if ( ! isset($this->_db_applied['order_by']) AND ! empty($this->_sorting)) { @@ -1095,7 +1047,7 @@ class Kohana_ORM extends Model implements serializable { if (strpos($column, '.') === FALSE) { // Sorting column for use in JOINs - $column = ($this->_disable_join_table_name ? '' : $this->_object_name.'.').$column; + $column = $this->_object_name.'.'.$column; } $this->_db_builder->order_by($column, $direction); @@ -1213,10 +1165,9 @@ class Kohana_ORM extends Model implements serializable { * @param string $value The value to filter * @return string */ - protected function run_filter($field, $value, $filters=NULL) + protected function run_filter($field, $value) { - if (is_null($filters)) - $filters = $this->filters(); + $filters = $this->filters(); // Get the filters for this column $wildcards = empty($filters[TRUE]) ? array() : $filters[TRUE]; diff --git a/modules/unittest/bootstrap.php b/modules/unittest/bootstrap.php index 2abe238..177dae1 100644 --- a/modules/unittest/bootstrap.php +++ b/modules/unittest/bootstrap.php @@ -15,15 +15,13 @@ $application = 'application'; */ $modules = 'modules'; -$sysmodules = 'includes/kohana/modules'; - /** * The directory in which the Kohana resources are located. The system * directory must contain the classes/kohana.php file. * * @link http://kohanaframework.org/guide/about.install#system */ -$system = 'includes/kohana/system'; +$system = 'system'; /** * The default extension of resource files. If you change this, all resources @@ -76,12 +74,6 @@ if ( ! is_dir($modules) AND is_dir(DOCROOT.$modules)) $modules = DOCROOT.$modules; } -// Make the system relative to the docroot, for symlink'd index.php -if ( ! is_dir($sysmodules) AND is_dir(DOCROOT.$sysmodules)) -{ - $sysmodules = DOCROOT.$sysmodules; -} - // Make the system relative to the docroot if ( ! is_dir($system) AND is_dir(DOCROOT.$system)) { @@ -91,11 +83,10 @@ if ( ! is_dir($system) AND is_dir(DOCROOT.$system)) // Define the absolute paths for configured directories define('APPPATH', realpath($application).DIRECTORY_SEPARATOR); define('MODPATH', realpath($modules).DIRECTORY_SEPARATOR); -define('SMDPATH', realpath($sysmodules).DIRECTORY_SEPARATOR); define('SYSPATH', realpath($system).DIRECTORY_SEPARATOR); // Clean up the configuration vars -unset($application, $modules, $sysmodules, $system); +unset($application, $modules, $system); /** * Define the start time of the application, used for profiling. @@ -113,8 +104,6 @@ if ( ! defined('KOHANA_START_MEMORY')) define('KOHANA_START_MEMORY', memory_get_usage()); } -define('PHPUNITTEST','192.168.242.3'); - // Bootstrap the application require APPPATH.'bootstrap'.EXT; @@ -133,4 +122,4 @@ if (($ob_len = ob_get_length()) !== FALSE) } // Enable the unittest module -Kohana::modules(Kohana::modules() + array('unittest' => SMDPATH.'unittest')); +Kohana::modules(Kohana::modules() + array('unittest' => MODPATH.'unittest')); \ No newline at end of file diff --git a/modules/xml/LICENSE b/modules/xml/LICENSE deleted file mode 100644 index 82b7457..0000000 --- a/modules/xml/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2010 Cédric de Saint Léger - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/modules/xml/README.md b/modules/xml/README.md deleted file mode 100644 index c4b5dcb..0000000 --- a/modules/xml/README.md +++ /dev/null @@ -1,31 +0,0 @@ -Kohana_XML is a XML modules to generate and read XML documents in Kohana. -It is build for KO3, but there are barely one or two lines that makes it KO3 specific, -so I guess it should work for KO2.x without much trouble. - -## Notable Features - -* **Extendible, configurable drivers** — You can use the XML class to write simple XML, -or use the Atom driver to generate Atom compliant XML, or write your own driver (extending XML -or another driver) to generate XML compliant to any specs you want. Driver support initial -configuration, which will be used when using native functions, and your own function. -Namespaces and prefix, value filters, default attributes, node name abstraction are all part -of driver configuration and are then used as such by native functions, so they are dealt with -on the fly. But you can also write your own function very easily in your drivers, and writing -an add_author($user_model) function in the Atom driver would take a second. - -* **Dealing with objects of the same class whatever function you use** – $xml→add_node(“test”); -generates another XML instance of the same driver you can add nodes to, import array or XML files -to, search in, modify, export, combine… The whole XML document becomes modular, easy to read and -to modify, and to run through with method chaining. Just play Lego with your XML. - -* **Magic get and get()** — allows to easily run through the document. For instance -$atom→author→name will return an atom document author’s name, this regardless of your driver -configuration. As another example of node name abstraction, if you’ve decided to abstract “pubDate” -with “updated” in your RSS2 driver configuration and “published” with “updated” in you Atom driver, -then $atom→updated will give you the same result as $rss→updated. - -* **Jelly-style driver configuration** — I liked the way Jelly initializes its models, so you can -configure yours just the same way. Driver configuration then goes into a static meta class, which -improves performance. - -* You can still use **DOM functions** if you wish and reintegrate in Kohana_XML \ No newline at end of file diff --git a/modules/xml/classes/XML.php b/modules/xml/classes/XML.php deleted file mode 100644 index c4c3cd1..0000000 --- a/modules/xml/classes/XML.php +++ /dev/null @@ -1,13 +0,0 @@ - - * - * Description: - * XML class. Use this class to override XML_Core. - * Extend this class to make your own XML based driver (Atom, XRDS, GData, RSS, PodCast RSS, or your own brewed XML format) - */ - - class XML extends XML_Core - {} \ No newline at end of file diff --git a/modules/xml/classes/XML/Core.php b/modules/xml/classes/XML/Core.php deleted file mode 100644 index 1432e05..0000000 --- a/modules/xml/classes/XML/Core.php +++ /dev/null @@ -1,732 +0,0 @@ - - * - * Description: - * XML_Core class. - */ - - class XML_Core - { - /** - * @var string XML document version - */ - public static $xml_version = "1.0"; - - /** - * @var string Root Node name - */ - public $root_node; - - /** - * The DOM_Element corresponding to this XML instance - * This is made public to use DOM functions directly if desired. - * @var DOM_Element XML instance DOM node. - */ - public $dom_node; - - /** - * Basically a handy shortcut of $this->dom_node->ownerDocument - * All XML instance belonging to the same document will have this attribute in common - * @var DOM_Document XML instance DOM document, owner of dom_node - */ - public $dom_doc; - - /** - * @var array Array of XML_Meta, containing metadata about XML drivers config - */ - protected static $_metas = array(); - - - /** - * This creates an XML object from the specified driver. - * Specify the driver name, or if there is no specific driver, the root node name - * @param string $driver [optional] Driver Name - * @param string $root_node [optional] Root Node name. Force the root node name. Must be used if no driver nor element is specified. - * @param string $element [optional] XML string or file to generate XML from. Must be used if no driver nor root_node is specified. - * @return XML XML object - */ - public static function factory($driver = NULL, $root_node = NULL, $element = NULL) - { - if ($driver) - { - // Let's attempt to generate a new instance of the subclass corresponding to the driver provided - $class = 'XML_Driver_'.ucfirst($driver); - - // Register a new meta object - XML::$_metas[strtolower($class)] = $meta = new XML_Meta; - - // Override the meta with driver-specific attributes - call_user_func(array($class, "initialize"), $meta); - - // Set content type to default if it is not already set, and report it as initialized - $meta->content_type("text/xml")->set_initialized(); - - return new $class($element, $root_node); - } - else - { - // Register a new meta object in the root node - XML::$_metas["xml"] = $meta = new XML_Meta; - - // Set content type to default if it is not already set, and report it as initialized - $meta->content_type("text/xml")->set_initialized(); - - return new XML($element, $root_node); - } - } - - - /** - * Class constructor. You should use the factory instead. - * @param string $element [optional] What to construct from. Could be some xml string, a file name, or a DOMNode - * @param string $root_node [optional] The root node name. To be specified if no driver are used. - * @return XML XML object instance - */ - public function __construct($element = NULL, $root_node = NULL) - { - // Create the initial DOMDocument - $this->dom_doc = new DOMDocument(XML::$xml_version, Kohana::$charset); - - if ($root_node) - { - // If a root node is specified, overwrite the current_one - $this->root_node = $root_node; - } - - // Initialize the document with the given element - if (is_string($element)) - { - if (is_file($element) OR Valid::url($element)) - { - // Generate XML from a file - $this->dom_doc->load($element); - } - else - { - // Generate XML from a string - $this->dom_doc->loadXML($element); - } - // Node is the root node of the document, containing the whole tree - $this->dom_node = $this->dom_doc->documentElement; - } - elseif ($element instanceof DOMNode) - { - // This is called from another XML instance ( through add_node, or else...) - // Let's add that node to the new object node - $this->dom_node = $element; - - // And overwrite the document with that node's owner document - $this->dom_doc = $this->dom_node->ownerDocument; - } - elseif ( ! is_null($this->root_node)) - { - // Create the Root Element from the driver attributes - if ($this->meta()->get("namespace", $this->root_node)) - { - $root_node_name = $this->meta()->get("prefix", $this->root_node) ? $this->meta()->get("prefix", $this->root_node).":$this->root_node" : $this->root_node; - - // Create the root node in its prefixed namespace - $root_node = $this->dom_doc->createElementNS($this->meta()->get("namespace", $this->root_node), $root_node_name); - } - else - { - // Create the root node - $root_node = $this->dom_doc->createElement($this->root_node); - } - - // Append the root node to the object DOMDocument, and set the resulting DOMNode as it's node - $this->dom_node = $this->dom_doc->appendChild($root_node); - - // Add other attributes - $this->add_attributes($this->dom_node); - } - else - { - throw new Kohana_Exception("You have to specify a root_node, either in your driver or in the constructor if you're not using any."); - } - } - - - /** - * Adds a node to the document - * @param string $name Name of the node. Prefixed namespaces are handled automatically. - * @param value $value [optional] value of the node (will be filtered). If value is not valid CDATA, - * it will be wrapped into a CDATA section - * @param array $attributes [optional] array of attributes. Prefixed namespaces are handled automatically. - * @return XML instance for the node that's been added. - */ - public function add_node($name, $value = NULL, $attributes = array()) - { - // Trim the name - $name = trim($name); - - // Create the element - $node = $this->create_element($name); - - // Add the attributes - $this->add_attributes($node, $attributes); - - // Add the value if provided - if ($value !== NULL) - { - $value = strval($this->filter($name, $value, $node)); - - if (str_replace(array('<', '>', '&'), "", $value) === $value) - { - // Value is valid CDATA, let's add it as a new text node - $value = $this->dom_doc->createTextNode($value); - } - else - { - // We shall create a CDATA section to wrap the text provided - $value = $this->dom_doc->createCDATASection($value); - } - $node->appendChild($value); - } - - // return a new XML instance of the same class from the child node - $class = get_class($this); - return new $class($this->dom_node->appendChild($node)); - } - - - - /** - * Magic get returns the first child node matching the value - * @param string $node_name - * @return mixed If trying to get a node: - * NULL will be return if nothing is matched, - * A string value is returned if it a text/cdata node is matched - * An XML instance is returned otherwise, allowing chaining. - */ - public function __get($value) - { - if ( ! isset($this->$value)) - { - $node = current($this->get($value)); - - if ($node instanceof XML) - { - // Return the whole XML document - return $node; - } - // We did not match any child nodes - return NULL; - } - parent::__get($value); - } - - - - /** - * Gets all nodes matching a name and returns them as an array. - * Can also be used to get a pointer to a particular node and then deal with that node as an XML instance. - * @param string $value name of the nodes desired - * @param bool $as_array [optional] whether or not the nodes should be returned as an array - * @return array Multi-dimensional array or array of XML instances - */ - public function get($value, $as_array = FALSE) - { - $return = array(); - - $value = $this->meta()->alias($value); - - foreach ($this->dom_node->getElementsByTagName($value) as $item) - { - if ($as_array) - { - // Return as array but ignore root node - $array = $this->_as_array($item); - foreach ($array as $val) - { - $return[] = $val; - } - } - else - { - $class = get_class($this); - $return[] = new $class($item); - } - } - return $return; - } - - - /** - * Queries the document with an XPath query - * @param string $query XPath query - * @param bool $as_array [optional] whether or not the nodes should be returned as an array - * @return array Multi-dimensional array or array of XML instances - */ - public function xpath($query, $as_array = TRUE) - { - $return = array(); - - $xpath = new DOMXPath($this->dom_doc); - - foreach ($xpath->query($query) as $item) - { - if ($as_array) - { - $array = $this->_as_array($item); - foreach ($array as $val) - { - $return[] = $val; - } - } - else - { - $class = get_class($this); - $return[] = new $class($item); - } - } - return $return; - } - - - - /** - * Exports the document as a multi-dimensional array. - * Handles element with the same name. - * - * Root node is ignored, as it is known and available in the driver. - * Example : - * - * - * value1 - * - * - * value2 - * - * - * - * Here's the resulting array structure : - * array ("node_name" => array( - * // array of nodes called "node_name" - * 0 => array( - * // Attributes of that node - * "xml_attributes" => array( - * "attr_name" => "val", - * ) - * // node contents - * "child_node_name" => array( - * // array of nodes called "child_node_name" - * 0 => value1, - * 1 => value2, - * ) - * The output is retro-actively convertible to XML using from_array(). - * @return array - */ - public function as_array() - { - $dom_element = $this->dom_node; - - $return = array(); - - // This function is run on a whole XML document and this is the root node. - // That root node shall be ignored in the array as it driven by the driver and handles document namespaces. - foreach($dom_element->childNodes as $dom_child) - { - if ($dom_child->nodeType == XML_ELEMENT_NODE) - { - // Let's run through the child nodes - $child = $this->_as_array($dom_child); - - foreach ($child as $key => $val) - { - $return[$key][]=$val; - } - } - } - - return $return; - } - - - - /** - * Recursive as_array for child nodes - * @param DOMNode $dom_node - * @return Array - */ - private function _as_array(DOMNode $dom_node) - { - // All other nodes shall be parsed normally : attributes then text value and child nodes, running through the XML tree - $object_element = array(); - - // Get the desired node name for this node - $node_name = $this->meta()->key($dom_node->tagName); - - // Get children, run through XML tree - if ($dom_node->hasChildNodes()) - { - if (!$dom_node->firstChild->hasChildNodes()) - { - // Get text value - $object_element[$node_name] = trim($dom_node->firstChild->nodeValue); - } - - foreach($dom_node->childNodes as $dom_child) - { - if ($dom_child->nodeType === XML_ELEMENT_NODE) - { - $child = $this->_as_array($dom_child); - - foreach ($child as $key=>$val) - { - $object_element[$node_name][$key][]=$val; - } - } - } - } - - // Get attributes - if ($dom_node->hasAttributes()) - { - $object_element[$dom_node->nodeName]['xml_attributes'] = array(); - foreach($dom_node->attributes as $att_name => $dom_attribute) - { - // Get the desired name for this attribute - $att_name = $this->meta()->key($att_name); - $object_element[$node_name]['xml_attributes'][$att_name] = $dom_attribute->value; - } - } - return $object_element; - } - - - /** - * Converts an array to XML. Expected structure is given in as_array(). - * However, from_array() is essentially more flexible regarding to the input array structure, - * as we don't have to bother about nodes having the same name. - * Try something logical, that should work as expected. - * @param object $mixed - * @return XML - */ - public function from_array($array) - { - $this->_from_array($array, $this->dom_node); - - return $this; - } - - - /** - * Array shall be like : array('element_name' => array( 0 => text, 'xml_attributes' => array())); - * @param object $mixed - * @param DOMElement $dom_element - * @return - */ - protected function _from_array($mixed, DOMElement $dom_element) - { - if (is_array($mixed)) - { - foreach( $mixed as $index => $mixed_element ) - { - if ( is_numeric($index) ) - { - // If we have numeric keys, we're having multiple children of the same node. - // Append the new node to the current node's parent - // If this is the first node to add, $node = $dom_element - $node = $dom_element; - if ( $index != 0 ) - { - // If not, lets create a copy of the node with the same name - $node = $this->create_element($dom_element->tagName); - // And append it to the parent node - $node = $dom_element->parentNode->appendChild($node); - } - $this->_from_array($mixed_element, $node); - } - elseif ($index == "xml_attributes") - { - // Add attributes to the node - $this->add_attributes($dom_element, $mixed_element); - } - else - { - // Create a new element with the key as the element name. - // Create the element corresponding to the key - $node = $this->create_element($index); - - // Add the driver attributes - $this->add_attributes($node); - - // Append it - $dom_element->appendChild($node); - - // Treat the array by recursion - $this->_from_array($mixed_element, $node); - } - } - } - elseif ($mixed) - { - // This is a string value that shall be appended as such - $mixed = $this->filter($dom_element->tagName, $mixed, $dom_element); - $dom_element->appendChild($this->dom_doc->createTextNode($mixed)); - } - } - - - /** - * This function is used to import another XML instance, or whatever we can construct XML from (string, filename, DOMNode...) - * - * $xml1 = XML::factory("atom", "bla"); - * $xml2 = XML::factory("rss", ""); - * $node_xml2 = $xml2->add_node("key"); - * - * // outputs "bla" - * $node_xml2->import($xml1)->render(); - * - * // outputs "blabla" - * $xml1->import($xml2->get("key"))->render(); - * - * @param object $xml XML instance or DOMNode - * @return object $this Chainable function - */ - public function import($xml) - { - if (! $xml instanceof XML) - { - // Attempt to construct XML from the input - $class = get_class($this); - $xml = new $class($xml); - } - // Import the node, and all its children, to the document - $node = $this->dom_doc->importNode($xml->dom_node, TRUE); - $this->dom_node->appendChild($node); - - return $this; - } - - - /** - * Creates an element, sorts out namespaces (default / prefixed) - * @param string $name element name - * @return DOMElement - */ - private function create_element($name) - { - $name = $this->meta()->alias($name); - - // Let's check if the element name has a namespace, and if this prefix is defined in our driver - if ($namespace_uri = $this->meta()->get("namespace", $name)) - { - if (stristr($name, ":")) - { - // Separate the namespace prefix and the name - list($prefix, $name) = explode(":", $name); - - // Register the prefixed namespace in the document root - $this->dom_doc->documentElement->setAttributeNS("http://www.w3.org/2000/xmlns/" ,"xmlns:".$prefix, $namespace_uri); - - // Create the prefixed element within that namespace - $node = $this->dom_doc->createElementNS($namespace_uri, $prefix.":".$name); - } - else - { - // Create the element normally - $node = $this->dom_doc->createElement($name); - - // Add the new default namespace as an attribute. - $node->setAttribute("xmlns", $namespace_uri); - } - } - else - { - // Simply create the element - $node = $this->dom_doc->createElement($name); - } - return $node; - } - - - /** - * Applies attributes to a node - * @param DOMNode $node - * @param array $attributes as key => value - * @return DOMNode - */ - private function add_attributes(DOMNode $node, $attributes = array()) - { - $node_name = $this->meta()->alias($node->tagName); - - if ($this->meta()->get("attributes", $node_name)) - { - $attributes = array_merge($this->meta()->get("attributes", $node_name), $attributes); - } - - foreach ($attributes as $key => $val) - { - // Trim elements - $key = $this->meta()->alias(trim($key)); - $val = $this->filter($key, trim($val), $node); - - // Set the attribute - // Let's check if the attribute name has a namespace prefix, and if this prefix is defined in our driver - if ($namespace_uri = $this->meta()->get("namespace", $key) - AND stristr($name, ":")) - { - // Separate the namespace prefix and the name - list($prefix, $name) = explode(":", $name); - - // Register the prefixed namespace - $this->dom_node->setAttributeNS("http://www.w3.org/2000/xmlns/" ,"xmlns:".$prefix, $namespace_uri); - - // Add the prefixed attribute within that namespace - $node->setAttributeNS($namespace_uri, $key, $val); - } - else - { - // Simply add the attribute - $node->setAttribute($key, $val); - } - } - return $node; - } - - - /** - * Applies filter on a value. - * These filters are callbacks usually defined in the driver. - * They allow to format dates, links, standard stuff, and play - * as you wish with the value before it is added to the document. - * - * You could even extend it and modify the node name. - * - * @param string $name - * @param string $value - * @return string $value formatted value - */ - protected function filter($name, $value, &$node) - { - $name = $this->meta()->alias($name); - - if ($this->meta()->get("filter", $name)) - { - return call_user_func(array($this, $this->meta()->get("filter", $name)), $value, $node); - } - return $value; - } - - - /** - * This is a classic filter that takes a uri and makes a proper link - * @param object $value - * @return $value - */ - public function normalize_uri($value, $node) - { - if (strpos($value, '://') === FALSE) - { - if (strlen(URL::base()) > 1 AND stristr($value, URL::base())) - { - // Make sure the path is not base related - $value = str_replace(URL::base(), '', $value); - } - // Convert URIs to URLs - $value = URL::site($value, TRUE); - } - return $value; - } - - - /** - * Another classic filter to deal with boolean - * @param boolean $value - * @return string $value, true or false - */ - public function normalize_bool($value) - { - return $value ? "true" : "false"; - } - - - /** - * Returns this drivers XML metadata - * @return XML_Meta - */ - public function meta() - { - return XML::$_metas[strtolower(get_class($this))]; - } - - - /** - * Outputs nicely formatted XML when converting as string - * @return string - */ - public function __toString() - { - return $this->render(TRUE); - } - - - /** - * Render the XML. - * @param boolean $formatted [optional] Should the output be formatted and indented ? - * @return string - */ - public function render($formatted = FALSE) - { - $this->dom_doc->formatOutput = $formatted; - return $this->dom_doc->saveXML(); - } - - - /** - * Outputs the XML in a file - * @param string filename - * @return - */ - public function export($file) - { - return $this->dom_doc->save($file); - } - - - /** - * Returns this instance node value, if the dom_node is a text node - * - * @return string - */ - public function value() - { - if ($this->dom_node->hasChildNodes() AND $this->dom_node->firstChild->nodeType === XML_TEXT_NODE) - { - return $this->dom_node->nodeValue; - } - return NULL; - } - - - /** - * Returns this instance node value - * - * @return string|array attributes as array of attribute value if a name is specified - */ - public function attributes($attribute_name = NULL) - { - if ($attribute_name === NULL) - { - // Return an array of attributes - $attributes = array(); - - if ($this->dom_node->hasAttributes()) - { - foreach ($this->dom_node->attributes as $attribute) - { - $attributes[$attribute->name] = $attribute->value; - } - } - return $attributes; - } - - // Simply return the attribute value - return $this->dom_node->getAttribute($attribute_name); - } -} // End XML_Core diff --git a/modules/xml/classes/XML/Driver/Atom.php b/modules/xml/classes/XML/Driver/Atom.php deleted file mode 100644 index 4098964..0000000 --- a/modules/xml/classes/XML/Driver/Atom.php +++ /dev/null @@ -1,101 +0,0 @@ - - * - * Description: - * Atom driver - */ - -class XML_Driver_Atom extends XML -{ - public $root_node = 'feed'; - - - protected static function initialize(XML_Meta $meta) - { - $meta ->content_type("application/atom+xml") - ->nodes ( - array( - "feed" => array("namespace" => "http://www.w3.org/2005/Atom"), - // "entry" => array("namespace" => "http://www.w3.org/2005/Atom"), - "href" => array("filter" => "normalize_uri"), - "link" => array("filter" => "normalize_uri"), - "logo" => array("filter" => "normalize_uri"), - "icon" => array("filter" => "normalize_uri"), - "id" => array("filter" => "normalize_uri"), - "updated" => array("filter" => "normalize_datetime"), - "published" => array("filter" => "normalize_datetime"), - "startDate" => array("filter" => "normalize_date"), - 'endDate' => array("filter" => "normalize_date"), - "summary" => array("filter" => "normalize_text"), - "subtitle" => array("filter" => "normalize_text"), - "title" => array("filter" => "normalize_text"), - "content" => array("filter" => "normalize_text") - ) - ); - } - - - public function add_person($type, $name, $email = NULL, $uri = NULL) - { - $author = $this->add_node($type); - $author->add_node("name", $name); - if ($email) - { - $author->add_node("email", $email); - } - if ($uri) - { - $author->add_node("uri", $uri); - } - return $this; - } - - - public function add_content(XML $xml_document) - { - $this->add_node("content", NULL, array("type" => $xml_document->meta()->content_type()))->import($xml_document); - return $this; - } - - - public function normalize_text($value, $node) - { - if (strpos($value, "<") >= 0 AND strpos($value, ">") > 0) - { - // Assume type = html - $node->setAttribute("type", "html"); - } - else - { - $node->setAttribute("type", "text"); - } - return $value; - } - - - public function normalize_datetime($value) - { - if ( ! is_numeric($value)) - { - $value = strtotime($value); - } - - // Convert timestamps to RFC 3339 formatted datetime - return date(DATE_RFC3339, $value); - } - - - public function normalize_date($value) - { - if ( ! is_numeric($value)) - { - $value = strtotime($value); - } - - // Convert timestamps to RFC 3339 formatted dates - return date("Y-m-d", $value); - } -} \ No newline at end of file diff --git a/modules/xml/classes/XML/Driver/Rss2.php b/modules/xml/classes/XML/Driver/Rss2.php deleted file mode 100644 index b521763..0000000 --- a/modules/xml/classes/XML/Driver/Rss2.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * Description: - * RSS2 driver - */ - -class XML_Driver_Rss2 extends XML -{ - public $root_node = 'rss'; - - protected static function initialize(XML_Meta $meta) - { - $meta ->content_type("application/rss+xml") - ->nodes ( - array( - "rss" => array("attributes" => array("version" => "2.0")), - "title" => array("filter" => "normalize_text"), - "description" => array("filter" => "normalize_text"), - "link" => array("filter" => "normalize_uri"), - "atom:link" => array("attributes" => array( - "rel" => "self", - "type" => "application/rss+xml", - // "href" => URL::site(Request::initial()->uri(), TRUE) - ), - "namespace" => "http://www.w3.org/2005/Atom"), - "href" => array("filter" => "normalize_uri"), - "docs" => array("filter" => "normalize_uri"), - "guid" => array("filter" => "normalize_uri"), - "pubDate" => array("filter" => "normalize_date"), - "lastBuildDate" => array("filter" => "normalize_date") - ) - ); - } - - - public function normalize_date($value) - { - if ( ! is_numeric($value)) - { - $value = strtotime($value); - } - - // Convert timestamps to RFC 822 formatted dates, with 4 digits year - return date(DATE_RSS, $value); - } - - - public function normalize_text($value) - { - // Strip HTML tags - return strip_tags($value); - } -} \ No newline at end of file diff --git a/modules/xml/classes/XML/Driver/Xrds.php b/modules/xml/classes/XML/Driver/Xrds.php deleted file mode 100644 index 2f536d2..0000000 --- a/modules/xml/classes/XML/Driver/Xrds.php +++ /dev/null @@ -1,55 +0,0 @@ - - * - * Description: - * XRDS driver. For Service Discovery. - */ - -class XML_Driver_XRDS extends XML -{ - public $root_node = 'xrds:XRDS'; - - protected static function initialize(XML_Meta $meta) - { - $meta ->content_type("application/xrds+xml") - ->nodes ( - array( - "xrds:XRDS" => array("namespace" => 'xri://$xrds', "attributes" => array("xmlns" => 'xri://$xrd*($v*2.0)')), - "LocalID" => array("filter" => "normalize_uri"), - "openid:Delegate" => array("filter" => "normalize_uri", "namespace" => "http://openid.net/xmlns/1.0"), - "URI" => array("filter" => "normalize_uri"), - ) - ); - } - - - public function add_service($type, $uri, $priority = NULL) - { - if (! is_null($priority)) - { - $priority = array("priority" => $priority); - } - else - { - $priority = array(); - } - - $service_node = $this->add_node("Service", NULL, $priority); - - if (! is_array($type)) - { - $type = array($type); - } - - foreach ($type as $t) - { - $service_node->add_node("Type", $t); - } - $service_node->add_node("URI", $uri); - - return $service_node; - } -} \ No newline at end of file diff --git a/modules/xml/classes/XML/Meta.php b/modules/xml/classes/XML/Meta.php deleted file mode 100644 index 35df69d..0000000 --- a/modules/xml/classes/XML/Meta.php +++ /dev/null @@ -1,12 +0,0 @@ - - * - * Description: - * XML_Meta class. Use this to override XML_Meta_Core - */ - - class XML_Meta extends XML_Meta_Core - {} diff --git a/modules/xml/classes/XML/Meta/Core.php b/modules/xml/classes/XML/Meta/Core.php deleted file mode 100644 index 93f699a..0000000 --- a/modules/xml/classes/XML/Meta/Core.php +++ /dev/null @@ -1,187 +0,0 @@ - - * - * Description: - * XML_Meta_Core class. This class contains XML drivers metadata - */ - - class XML_Meta_Core - { - /** - * @var array assoc array alias => $node_name - * This is used to abstract the node names - */ - protected $nodes = array(); - - /** - * @var array whole node configuration array - * array("node_name" => array( - * // Effective node name in the XML document. - * // This name is abstracted and "node_name" is always used when dealing with the object. - * "node" => "effective_node_name", - * // Defines a namespace URI for this node - * "namespace" => "http://www.namespace.uri", - * // Defines a prefix for the namespace above. If not defined, namespace is interpreted as a default namespace - * "prefix" => "ns", - * // Defines a callback function to filter/normalize the value - * "filter" => "filter_function_name", - * // Array of attributes - * "attributes" => array("default_attribute1" => "value") - * ), - * "alias" => "node_name", - * ) - */ - protected $nodes_config = array(); - - /** - * @var string content type for HTML headers - */ - protected $content_type; - - /** - * @var boolean whether the object is initialized - */ - protected $_initialized = FALSE; - - - /** - * Returns the name of a node, sort out aliases - * @param string $name - * @return string $node_name - */ - public function alias($name) - { - if (isset($this->nodes_config[$name])) - { - if ( ! is_array($this->nodes_config[$name])) - { - $name = $this->nodes_config[$name]; - } - } - - return Arr::get($this->nodes, $name, $name); - } - - /** - * Returns the value of a meta key for a given node name - * exemple $this->get('attributes', 'feed') will return all the attributes set up in the meta - * for the node feed. - * @param object $key meta key - * @param object $name node name - * @return meta value or NULL if not set - */ - public function get($key, $name) - { - $name = $this->alias($name); - - if (isset($this->nodes_config[$name]) AND is_array($this->nodes_config[$name]) AND array_key_exists($key, $this->nodes_config[$name])) - { - return $this->nodes_config[$name][$key]; - } - return NULL; - } - - - /** - * Set nodes config attribute - * Use it this way : - * nodes(array("node_name" => array("namespace" => "http://www.namespace.uri", "prefix" => "ns", "filter" => "filter_function_name", "attributes" => array("default_attribute1" => "value")))), - * OR to set up node alias names : - * nodes(array("alias" => "node_name")); - * - * @param array $nodes array formatted as mentionned above - * @param bool $overwrite [optional] Overwrite current values if they are set ? - * @return object $this - */ - public function nodes(Array $nodes) - { - $this->nodes_config = $this->_initialized ? - array_merge($nodes, $this->nodes_config) : - array_merge($this->nodes_config, $nodes); - - $this->generate_nodes_map(); - - return $this; - } - - - /** - * Sets the content type for headers - * @param string $type - * @return object $this - */ - public function content_type($type = NULL) - { - if ($type) - { - $this->content_type = $this->_initialized ? - $type : - $this->content_type ? - $this->content_type : - $type; - } - else - { - return $this->content_type; - } - - return $this; - } - - - /** - * Returns the key name corresponding to a node name - * This is used when using as_array(), to return array keys corresponding to the node names - * @param object $node_name - * @return - */ - public function key($node_name) - { - // Extract the name if it is prefixed - $expl = explode(":", $node_name); - $node_name = count($expl) > 1 ? end($expl) : current($expl); - - if (in_array($node_name, $this->nodes)) - { - return current(array_keys($this->nodes, $node_name)); - } - return $node_name; - } - - - /** - * Generates - or re-generates the node map - * @return object $this - */ - public function generate_nodes_map() - { - $map = array(); - foreach ($this->nodes_config as $key => $config) - { - if (is_array($config)) - { - if (isset ($config["node"])) - { - $map[$key] = $config["node"]; - } - } - } - $this->nodes = $map; - return $this; - } - - /** - * Reports the Meta as initialized. - * This basically allows Meta methods to overwrite existing value, if they are called explicitely - * @return object $this - */ - public function set_initialized() - { - $this->_initialized = TRUE; - return $this; - } - -} \ No newline at end of file diff --git a/system/classes/Kohana/Debug.php b/system/classes/Kohana/Debug.php index ccc141d..9d1efdf 100644 --- a/system/classes/Kohana/Debug.php +++ b/system/classes/Kohana/Debug.php @@ -252,17 +252,13 @@ class Kohana_Debug { { $file = 'APPPATH'.DIRECTORY_SEPARATOR.substr($file, strlen(APPPATH)); } - elseif (strpos($file, MODPATH) === 0) - { - $file = 'MODPATH'.DIRECTORY_SEPARATOR.substr($file, strlen(MODPATH)); - } elseif (strpos($file, SYSPATH) === 0) { $file = 'SYSPATH'.DIRECTORY_SEPARATOR.substr($file, strlen(SYSPATH)); } - elseif (strpos($file, SMDPATH) === 0) + elseif (strpos($file, MODPATH) === 0) { - $file = 'SMDPATH'.DIRECTORY_SEPARATOR.substr($file, strlen(SMDPATH)); + $file = 'MODPATH'.DIRECTORY_SEPARATOR.substr($file, strlen(MODPATH)); } elseif (strpos($file, DOCROOT) === 0) { diff --git a/system/classes/Kohana/Request/Client/Curl.php b/system/classes/Kohana/Request/Client/Curl.php index 8415729..c5c85d3 100644 --- a/system/classes/Kohana/Request/Client/Curl.php +++ b/system/classes/Kohana/Request/Client/Curl.php @@ -64,7 +64,7 @@ class Kohana_Request_Client_Curl extends Request_Client_External { $this->_options[CURLOPT_HEADER] = FALSE; // Apply any additional options set to - $options = Arr::merge($options, $this->_options); + $options += $this->_options; $uri = $request->uri(); @@ -132,4 +132,4 @@ class Kohana_Request_Client_Curl extends Request_Client_External { return $options; } -} // End Kohana_Request_Client_Curl +} // End Kohana_Request_Client_Curl \ No newline at end of file diff --git a/system/tests/kohana/CoreTest.php b/system/tests/kohana/CoreTest.php index 17d6a7a..beb508b 100644 --- a/system/tests/kohana/CoreTest.php +++ b/system/tests/kohana/CoreTest.php @@ -250,7 +250,7 @@ class Kohana_CoreTest extends Unittest_TestCase { return array( array(array('unittest' => MODPATH.'fo0bar')), - array(array('unittest' => SMDPATH.'unittest', 'fo0bar' => MODPATH.'fo0bar')), + array(array('unittest' => MODPATH.'unittest', 'fo0bar' => MODPATH.'fo0bar')), ); } @@ -292,7 +292,7 @@ class Kohana_CoreTest extends Unittest_TestCase { return array( array(array(), array()), - array(array('unittest' => SMDPATH.'unittest'), array('unittest' => $this->dirSeparator(SMDPATH.'unittest/'))), + array(array('unittest' => MODPATH.'unittest'), array('unittest' => $this->dirSeparator(MODPATH.'unittest/'))), ); } diff --git a/system/tests/kohana/DebugTest.php b/system/tests/kohana/DebugTest.php index 5bc7149..39176ec 100644 --- a/system/tests/kohana/DebugTest.php +++ b/system/tests/kohana/DebugTest.php @@ -59,8 +59,8 @@ class Kohana_DebugTest extends Unittest_TestCase 'SYSPATH'.DIRECTORY_SEPARATOR.'classes'.DIRECTORY_SEPARATOR.'kohana.php' ), array( - SMDPATH.$this->dirSeparator('unittest/classes/kohana/unittest/runner').EXT, - $this->dirSeparator('SMDPATH/unittest/classes/kohana/unittest/runner').EXT + MODPATH.$this->dirSeparator('unittest/classes/kohana/unittest/runner').EXT, + $this->dirSeparator('MODPATH/unittest/classes/kohana/unittest/runner').EXT ), ); }