summaryrefslogtreecommitdiff
path: root/modules/gallery/libraries
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gallery/libraries')
-rw-r--r--modules/gallery/libraries/Admin_View.php126
-rw-r--r--modules/gallery/libraries/Block.php30
-rw-r--r--modules/gallery/libraries/I18n.php410
-rw-r--r--modules/gallery/libraries/MY_Database.php92
-rw-r--r--modules/gallery/libraries/MY_Forge.php59
-rw-r--r--modules/gallery/libraries/MY_ORM.php46
-rw-r--r--modules/gallery/libraries/MY_Pagination.php35
-rw-r--r--modules/gallery/libraries/MY_View.php46
-rw-r--r--modules/gallery/libraries/Menu.php187
-rw-r--r--modules/gallery/libraries/ORM_MPTT.php307
-rw-r--r--modules/gallery/libraries/Sendmail.php97
-rw-r--r--modules/gallery/libraries/Task_Definition.php50
-rw-r--r--modules/gallery/libraries/Theme_View.php221
13 files changed, 1706 insertions, 0 deletions
diff --git a/modules/gallery/libraries/Admin_View.php b/modules/gallery/libraries/Admin_View.php
new file mode 100644
index 00000000..acc3f8ec
--- /dev/null
+++ b/modules/gallery/libraries/Admin_View.php
@@ -0,0 +1,126 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Admin_View_Core extends View {
+ private $theme_name = null;
+
+ /**
+ * Attempts to load a view and pre-load view data.
+ *
+ * @throws Kohana_Exception if the requested view cannot be found
+ * @param string $name view name
+ * @param string $theme_name view name
+ * @return void
+ */
+ public function __construct($name) {
+ $theme_name = module::get_var("core", "active_site_theme");
+ if (!file_exists("themes/$theme_name")) {
+ module::set_var("core", "active_site_theme", "admin_default");
+ theme::load_themes();
+ Kohana::log("error", "Unable to locate theme '$theme_name', switching to default theme.");
+ }
+ parent::__construct($name);
+
+ $this->theme_name = module::get_var("core", "active_admin_theme");
+ if (user::active()->admin) {
+ $this->theme_name = Input::instance()->get("theme", $this->theme_name);
+ }
+ $this->sidebar = "";
+ $this->set_global("theme", $this);
+ $this->set_global("user", user::active());
+ }
+
+ public function url($path, $absolute_url=false) {
+ $arg = "themes/{$this->theme_name}/$path";
+ return $absolute_url ? url::abs_file($arg) : url::file($arg);
+ }
+
+ public function display($page_name, $view_class="View") {
+ return new $view_class($page_name);
+ }
+
+ public function admin_menu() {
+ $menu = Menu::factory("root");
+ core_menu::admin($menu, $this);
+
+ foreach (module::active() as $module) {
+ if ($module->name == "core") {
+ continue;
+ }
+ $class = "{$module->name}_menu";
+ if (method_exists($class, "admin")) {
+ call_user_func_array(array($class, "admin"), array(&$menu, $this));
+ }
+ }
+
+ print $menu;
+ }
+
+ /**
+ * Print out any site wide status information.
+ */
+ public function site_status() {
+ return site_status::get();
+ }
+
+ /**
+ * Print out any messages waiting for this user.
+ */
+ public function messages() {
+ return message::get();
+ }
+
+ /**
+ * Handle all theme functions that insert module content.
+ */
+ public function __call($function, $args) {
+ switch ($function) {
+ case "admin_credits";
+ case "admin_footer":
+ case "admin_header_top":
+ case "admin_header_bottom":
+ case "admin_page_bottom":
+ case "admin_page_top":
+ case "admin_head":
+ $blocks = array();
+ foreach (module::active() as $module) {
+ $helper_class = "{$module->name}_theme";
+ if (method_exists($helper_class, $function)) {
+ $blocks[] = call_user_func_array(
+ array($helper_class, $function),
+ array_merge(array($this), $args));
+ }
+ }
+
+ if (Session::instance()->get("debug")) {
+ if ($function != "admin_head") {
+ array_unshift(
+ $blocks, "<div class=\"gAnnotatedThemeBlock gAnnotatedThemeBlock_$function\">" .
+ "<div class=\"title\">$function</div>");
+ $blocks[] = "</div>";
+ }
+ }
+
+ return implode("\n", $blocks);
+
+ default:
+ throw new Exception("@todo UNKNOWN_THEME_FUNCTION: $function");
+ }
+ }
+} \ No newline at end of file
diff --git a/modules/gallery/libraries/Block.php b/modules/gallery/libraries/Block.php
new file mode 100644
index 00000000..6fe679f1
--- /dev/null
+++ b/modules/gallery/libraries/Block.php
@@ -0,0 +1,30 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Block_Core {
+ public $content = null;
+ public $css_id = null;
+ public $id = null;
+ public $title = null;
+ public $anchor = null;
+
+ public function __toString() {
+ return View::factory("block.html", get_object_vars($this))->__toString();
+ }
+}
diff --git a/modules/gallery/libraries/I18n.php b/modules/gallery/libraries/I18n.php
new file mode 100644
index 00000000..c936be88
--- /dev/null
+++ b/modules/gallery/libraries/I18n.php
@@ -0,0 +1,410 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * Translates a localizable message.
+ * @param $message String The message to be translated. E.g. "Hello world"
+ * @param $options array (optional) Options array for key value pairs which are used
+ * for pluralization and interpolation. Special key: "locale" to override the
+ * currently configured locale.
+ * @return String The translated message string.
+ */
+function t($message, $options=array()) {
+ return I18n::instance()->translate($message, $options);
+}
+
+/**
+ * Translates a localizable message with plural forms.
+ * @param $singular String The message to be translated. E.g. "There is one album."
+ * @param $plural String The plural message to be translated. E.g.
+ * "There are %count albums."
+ * @param $count Number The number which is inserted for the %count placeholder and
+ * which is used to select the proper plural form ($singular or $plural).
+ * @param $options array (optional) Options array for key value pairs which are used
+ * for pluralization and interpolation. Special key: "locale" to override the
+ * currently configured locale.
+ * @return String The translated message string.
+ */
+function t2($singular, $plural, $count, $options=array()) {
+ return I18n::instance()->translate(array("one" => $singular, "other" => $plural),
+ array_merge($options, array("count" => $count)));
+}
+
+class I18n_Core {
+ private static $_instance;
+ private $_config = array();
+ private $_call_log = array();
+ private $_cache = array();
+
+ private function __construct($config) {
+ $this->_config = $config;
+ $this->locale($config['default_locale']);
+ }
+
+ public static function instance($config=null) {
+ if (self::$_instance == NULL || isset($config)) {
+ $config = isset($config) ? $config : Kohana::config('locale');
+ if (empty($config['default_locale'])) {
+ $config['default_locale'] = module::get_var('core', 'default_locale');
+ }
+ self::$_instance = new I18n_Core($config);
+ }
+
+ return self::$_instance;
+ }
+
+ public function locale($locale=null) {
+ if ($locale) {
+ $this->_config['default_locale'] = $locale;
+ // Attempt to set PHP's locale as well (for number formatting, collation, etc.)
+ // TODO: See G2 for better fallack code.
+ $locale_prefs = array($locale);
+ $locale_prefs[] = 'en_US';
+ setlocale(LC_ALL, $locale_prefs);
+ }
+ return $this->_config['default_locale'];
+ }
+
+ /**
+ * Translates a localizable message.
+ * @param $message String|array The message to be translated. E.g. "Hello world"
+ * or array("one" => "One album", "other" => "%count albums")
+ * @param $options array (optional) Options array for key value pairs which are used
+ * for pluralization and interpolation. Special keys are "count" and "locale",
+ * the latter to override the currently configured locale.
+ * @return String The translated message string.
+ */
+ public function translate($message, $options=array()) {
+ $locale = empty($options['locale']) ? $this->_config['default_locale'] : $options['locale'];
+ $count = isset($options['count']) ? $options['count'] : null;
+ $values = $options;
+ unset($values['locale']);
+ $this->log($message, $options);
+
+ $entry = $this->lookup($locale, $message);
+
+ if (null === $entry) {
+ // Default to the root locale.
+ $entry = $message;
+ $locale = $this->_config['root_locale'];
+ }
+
+ $entry = $this->pluralize($locale, $entry, $count);
+
+ $entry = $this->interpolate($locale, $entry, $values);
+
+ return $entry;
+ }
+
+ private function lookup($locale, $message) {
+ if (!isset($this->_cache[$locale])) {
+ $this->_cache[$locale] = array();
+ // TODO: Load data from locale file instead of the DB.
+ foreach (Database::instance()
+ ->select("key", "translation")
+ ->from("incoming_translations")
+ ->where(array("locale" => $locale))
+ ->get()
+ ->as_array() as $row) {
+ $this->_cache[$locale][$row->key] = unserialize($row->translation);
+ }
+
+ // Override incoming with outgoing...
+ foreach (Database::instance()
+ ->select("key", "translation")
+ ->from("outgoing_translations")
+ ->where(array("locale" => $locale))
+ ->get()
+ ->as_array() as $row) {
+ $this->_cache[$locale][$row->key] = unserialize($row->translation);
+ }
+ }
+
+ $key = self::get_message_key($message);
+
+ if (isset($this->_cache[$locale][$key])) {
+ return $this->_cache[$locale][$key];
+ } else {
+ return null;
+ }
+ }
+
+ public function has_translation($message, $options=null) {
+ $locale = empty($options['locale']) ? $this->_config['default_locale'] : $options['locale'];
+ $count = empty($options['count']) ? null : $options['count'];
+ $values = $options;
+ unset($values['locale']);
+ $this->log($message, $options);
+
+ $entry = $this->lookup($locale, $message);
+
+ if (null === $entry) {
+ return false;
+ } else if (!is_array($entry)) {
+ return $entry !== '';
+ } else {
+ $plural_key = self::get_plural_key($locale, $count);
+ return isset($entry[$plural_key])
+ && $entry[$plural_key] !== null
+ && $entry[$plural_key] !== '';
+ }
+ }
+
+ public static function get_message_key($message) {
+ $as_string = is_array($message) ? implode('|', $message) : $message;
+ return md5($as_string);
+ }
+
+ private function interpolate($locale, $string, $values) {
+ // TODO: Handle locale specific number formatting.
+
+ // Replace x_y before replacing x.
+ krsort($values, SORT_STRING);
+
+ $keys = array();
+ foreach (array_keys($values) as $key) {
+ $keys[] = "%$key";
+ }
+ return str_replace($keys, array_values($values), $string);
+ }
+
+ private function pluralize($locale, $entry, $count) {
+ if (!is_array($entry)) {
+ return $entry;
+ }
+
+ $plural_key = self::get_plural_key($locale, $count);
+ if (!isset($entry[$plural_key])) {
+ // Fallback to the default plural form.
+ $plural_key = 'other';
+ }
+
+ if (isset($entry[$plural_key])) {
+ return $entry[$plural_key];
+ } else {
+ // Fallback to just any plural form.
+ list ($plural_key, $string) = each($entry);
+ return $string;
+ }
+ }
+
+ private function log($message, $options) {
+ $key = self::get_message_key($message);
+ isset($this->_call_log[$key]) or $this->_call_log[$key] = array($message, $options);
+ }
+
+ public function call_log() {
+ return $this->_call_log;
+ }
+
+ private static function get_plural_key($locale, $count) {
+ $parts = explode('_', $locale);
+ $language = $parts[0];
+
+ // Data from CLDR 1.6 (http://unicode.org/cldr/data/common/supplemental/plurals.xml).
+ // Docs: http://www.unicode.org/cldr/data/charts/supplemental/language_plural_rules.html
+ switch ($language) {
+ case 'az':
+ case 'fa':
+ case 'hu':
+ case 'ja':
+ case 'ko':
+ case 'my':
+ case 'to':
+ case 'tr':
+ case 'vi':
+ case 'yo':
+ case 'zh':
+ case 'bo':
+ case 'dz':
+ case 'id':
+ case 'jv':
+ case 'ka':
+ case 'km':
+ case 'kn':
+ case 'ms':
+ case 'th':
+ return 'other';
+
+ case 'ar':
+ if ($count == 0) {
+ return 'zero';
+ } else if ($count == 1) {
+ return 'one';
+ } else if ($count == 2) {
+ return 'two';
+ } else if (is_int($count) && ($i = $count % 100) >= 3 && $i <= 10) {
+ return 'few';
+ } else if (is_int($count) && ($i = $count % 100) >= 11 && $i <= 99) {
+ return 'many';
+ } else {
+ return 'other';
+ }
+
+ case 'pt':
+ case 'am':
+ case 'bh':
+ case 'fil':
+ case 'tl':
+ case 'guw':
+ case 'hi':
+ case 'ln':
+ case 'mg':
+ case 'nso':
+ case 'ti':
+ case 'wa':
+ if ($count == 0 || $count == 1) {
+ return 'one';
+ } else {
+ return 'other';
+ }
+
+ case 'fr':
+ if ($count >= 0 and $count < 2) {
+ return 'one';
+ } else {
+ return 'other';
+ }
+
+ case 'lv':
+ if ($count == 0) {
+ return 'zero';
+ } else if ($count % 10 == 1 && $count % 100 != 11) {
+ return 'one';
+ } else {
+ return 'other';
+ }
+
+ case 'ga':
+ case 'se':
+ case 'sma':
+ case 'smi':
+ case 'smj':
+ case 'smn':
+ case 'sms':
+ if ($count == 1) {
+ return 'one';
+ } else if ($count == 2) {
+ return 'two';
+ } else {
+ return 'other';
+ }
+
+ case 'ro':
+ case 'mo':
+ if ($count == 1) {
+ return 'one';
+ } else if (is_int($count) && $count == 0 && ($i = $count % 100) >= 1 && $i <= 19) {
+ return 'few';
+ } else {
+ return 'other';
+ }
+
+ case 'lt':
+ if (is_int($count) && $count % 10 == 1 && $count % 100 != 11) {
+ return 'one';
+ } else if (is_int($count) && ($i = $count % 10) >= 2 && $i <= 9 && ($i = $count % 100) < 11 && $i > 19) {
+ return 'few';
+ } else {
+ return 'other';
+ }
+
+ case 'hr':
+ case 'ru':
+ case 'sr':
+ case 'uk':
+ case 'be':
+ case 'bs':
+ case 'sh':
+ if (is_int($count) && $count % 10 == 1 && $count % 100 != 11) {
+ return 'one';
+ } else if (is_int($count) && ($i = $count % 10) >= 2 && $i <= 4 && ($i = $count % 100) < 12 && $i > 14) {
+ return 'few';
+ } else if (is_int($count) && ($count % 10 == 0 || (($i = $count % 10) >= 5 && $i <= 9) || (($i = $count % 100) >= 11 && $i <= 14))) {
+ return 'many';
+ } else {
+ return 'other';
+ }
+
+ case 'cs':
+ case 'sk':
+ if ($count == 1) {
+ return 'one';
+ } else if (is_int($count) && $count >= 2 && $count <= 4) {
+ return 'few';
+ } else {
+ return 'other';
+ }
+
+ case 'pl':
+ if ($count == 1) {
+ return 'one';
+ } else if (is_int($count) && ($i = $count % 10) >= 2 && $i <= 4 &&
+ ($i = $count % 100) < 12 && $i > 14 && ($i = $count % 100) < 22 && $i > 24) {
+ return 'few';
+ } else {
+ return 'other';
+ }
+
+ case 'sl':
+ if ($count % 100 == 1) {
+ return 'one';
+ } else if ($count % 100 == 2) {
+ return 'two';
+ } else if (is_int($count) && ($i = $count % 100) >= 3 && $i <= 4) {
+ return 'few';
+ } else {
+ return 'other';
+ }
+
+ case 'mt':
+ if ($count == 1) {
+ return 'one';
+ } else if ($count == 0 || is_int($count) && ($i = $count % 100) >= 2 && $i <= 10) {
+ return 'few';
+ } else if (is_int($count) && ($i = $count % 100) >= 11 && $i <= 19) {
+ return 'many';
+ } else {
+ return 'other';
+ }
+
+ case 'mk':
+ if ($count % 10 == 1) {
+ return 'one';
+ } else {
+ return 'other';
+ }
+
+ case 'cy':
+ if ($count == 1) {
+ return 'one';
+ } else if ($count == 2) {
+ return 'two';
+ } else if ($count == 8 || $count == 11) {
+ return 'many';
+ } else {
+ return 'other';
+ }
+
+ default: // en, de, etc.
+ return $count == 1 ? 'one' : 'other';
+ }
+ }
+} \ No newline at end of file
diff --git a/modules/gallery/libraries/MY_Database.php b/modules/gallery/libraries/MY_Database.php
new file mode 100644
index 00000000..c56f16e8
--- /dev/null
+++ b/modules/gallery/libraries/MY_Database.php
@@ -0,0 +1,92 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Database extends Database_Core {
+ protected $_table_names;
+
+ public function open_paren() {
+ $this->where[] = "(";
+ return $this;
+ }
+
+ public function close_paren() {
+ // Search backwards for the last opening paren and resolve it
+ $i = count($this->where) - 1;
+ $this->where[$i] .= ")";
+ while (--$i >= 0) {
+ if ($this->where[$i] == "(") {
+ // Remove the paren from the where clauses, and add it to the right of the operator of the
+ // next where clause. If removing the paren makes the next where clause the first element
+ // in the where list, then the operator shouldn't be there. It's there because we
+ // calculate whether or not we need an operator based on the number of where clauses, and
+ // the open paren seems like a where clause even though it isn't.
+ array_splice($this->where, $i, 1);
+ $this->where[$i] = preg_replace("/^(AND|OR) /", $i ? "\\1 (" : "(", $this->where[$i]);
+ return $this;
+ }
+ }
+
+ throw new Kohana_Database_Exception('database.missing_open_paren');
+ }
+
+ /**
+ * Parse the query string and convert any strings of the form `\([a-zA-Z0-9_]*?)\]
+ * table prefix . $1
+ */
+ public function query($sql = '') {
+ if (!empty($sql)) {
+ $sql = $this->add_table_prefixes($sql);
+ }
+ return parent::query($sql);
+ }
+
+ public function add_table_prefixes($sql) {
+ $prefix = $this->config["table_prefix"];
+ if (strpos($sql, "SHOW TABLES") === 0) {
+ /*
+ * Don't ignore "show tables", otherwise we could have a infinite
+ * @todo this may have to be changed if we support more than mysql
+ */
+ return $sql;
+ } else if (strpos($sql, "CREATE TABLE") === 0) {
+ // Creating a new table add it to the table cache.
+ $open_brace = strpos($sql, "{") + 1;
+ $close_brace = strpos($sql, "}", $open_brace);
+ $name = substr($sql, $open_brace, $close_brace - $open_brace);
+ $this->_table_names["{{$name}}"] = "{$prefix}$name";
+ }
+
+ if (!isset($this->_table_names)) {
+ // This should only run once on the first query
+ $this->_table_names =array();
+ $len = strlen($prefix);
+ foreach($this->list_tables() as $table_name) {
+ if ($len > 0) {
+ $naked_name = strpos($table_name, $prefix) !== 0 ?
+ $table_name : substr($table_name, $len);
+ } else {
+ $naked_name = $table_name;
+ }
+ $this->_table_names["{{$naked_name}}"] = $table_name;
+ }
+ }
+
+ return empty($this->_table_names) ? $sql : strtr($sql, $this->_table_names);
+ }
+} \ No newline at end of file
diff --git a/modules/gallery/libraries/MY_Forge.php b/modules/gallery/libraries/MY_Forge.php
new file mode 100644
index 00000000..17d0465b
--- /dev/null
+++ b/modules/gallery/libraries/MY_Forge.php
@@ -0,0 +1,59 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+class Forge extends Forge_Core {
+ /**
+ * Force a CSRF element into every form.
+ */
+ public function __construct($action=null, $title='', $method=null, $attr=array()) {
+ parent::__construct($action, $title, $method, $attr);
+ $this->hidden("csrf")->value("");
+ }
+ /**
+ * Use our own template
+ */
+ public function render($template="form.html", $custom=false) {
+ $this->hidden["csrf"]->value(access::csrf_token());
+ return parent::render($template, $custom);
+ }
+
+ /**
+ * Associate validation rules defined in the model with this form.
+ */
+ public function add_rules_from($model) {
+ foreach ($this->inputs as $name => $input) {
+ if (isset($input->inputs)) {
+ $input->add_rules_from($model);
+ }
+ if (isset($model->rules[$name])) {
+ $input->rules($model->rules[$name]);
+ }
+ }
+ }
+
+ /**
+ * Validate our CSRF value as a mandatory part of all form validation.
+ */
+ public function validate() {
+ $status = parent::validate();
+ access::verify_csrf();
+ return $status;
+ }
+} \ No newline at end of file
diff --git a/modules/gallery/libraries/MY_ORM.php b/modules/gallery/libraries/MY_ORM.php
new file mode 100644
index 00000000..fb2f80a7
--- /dev/null
+++ b/modules/gallery/libraries/MY_ORM.php
@@ -0,0 +1,46 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class ORM extends ORM_Core {
+ public function open_paren() {
+ $this->db->open_paren();
+ return $this;
+ }
+
+ public function close_paren() {
+ $this->db->close_paren();
+ return $this;
+ }
+}
+
+/**
+ * Slide this in here for convenience. We won't ever be overloading ORM_Iterator without ORM.
+ */
+class ORM_Iterator extends ORM_Iterator_Core {
+ /**
+ * Cache the result row
+ */
+ public function current() {
+ $row = parent::current();
+ if (is_object($row)) {
+ model_cache::set($row);
+ }
+ return $row;
+ }
+} \ No newline at end of file
diff --git a/modules/gallery/libraries/MY_Pagination.php b/modules/gallery/libraries/MY_Pagination.php
new file mode 100644
index 00000000..d06a974f
--- /dev/null
+++ b/modules/gallery/libraries/MY_Pagination.php
@@ -0,0 +1,35 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Pagination extends Pagination_Core {
+ public function render($style=NULL) {
+ // Hide single page pagination
+ if ($this->auto_hide === TRUE AND $this->total_pages <= 1) {
+ return "";
+ }
+
+ if ($style === NULL) {
+ // Use default style
+ $style = $this->style;
+ }
+
+ // Return rendered pagination view
+ return View::factory("pager.html", get_object_vars($this))->render();
+ }
+}
diff --git a/modules/gallery/libraries/MY_View.php b/modules/gallery/libraries/MY_View.php
new file mode 100644
index 00000000..836d1087
--- /dev/null
+++ b/modules/gallery/libraries/MY_View.php
@@ -0,0 +1,46 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class View extends View_Core {
+ /**
+ * Override View_Core::__construct so that we can set the csrf value into all views.
+ *
+ * @see View_Core::__construct
+ */
+ public function __construct($name = NULL, $data = NULL, $type = NULL) {
+ parent::__construct($name, $data, $type);
+ $this->set_global("csrf", access::csrf_token());
+ }
+
+ /**
+ * Override View_Core::render so that we trap errors stemming from bad PHP includes and show a
+ * visible stack trace to help developers.
+ *
+ * @see View_Core::render
+ */
+ public function render($print=false, $renderer=false) {
+ try {
+ return parent::render($print, $renderer);
+ } catch (Exception $e) {
+ Kohana::Log('error', $e->getTraceAsString());
+ Kohana::Log('debug', $e->getMessage());
+ return "";
+ }
+ }
+}
diff --git a/modules/gallery/libraries/Menu.php b/modules/gallery/libraries/Menu.php
new file mode 100644
index 00000000..d19d8b1e
--- /dev/null
+++ b/modules/gallery/libraries/Menu.php
@@ -0,0 +1,187 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Menu_Element {
+ public $label;
+ public $url;
+ public $css_id;
+ public $css_class;
+ public $id;
+
+ /**
+ * Set the id
+ * @chainable
+ */
+ public function id($id) {
+ $this->id = $id;
+ return $this;
+ }
+
+ /**
+ * Set the label
+ * @chainable
+ */
+ public function label($label) {
+ $this->label = $label;
+ return $this;
+ }
+
+ /**
+ * Set the url
+ * @chainable
+ */
+ public function url($url) {
+ $this->url = $url;
+ return $this;
+ }
+
+ /**
+ * Set the css id
+ * @chainable
+ */
+ public function css_id($css_id) {
+ $this->css_id = $css_id;
+ return $this;
+ }
+
+ /**
+ * Set the css class
+ * @chainable
+ */
+ public function css_class($css_class) {
+ $this->css_class = $css_class;
+ return $this;
+ }
+
+}
+
+/**
+ * Menu element that provides a link to a new page.
+ */
+class Menu_Element_Link extends Menu_Element {
+ public function __toString() {
+ if (isset($this->css_id) && !empty($this->css_id)) {
+ $css_id = " id=\"$this->css_id\"";
+ } else {
+ $css_id = "";
+ }
+ if (isset($this->css_class) && !empty($this->css_class)) {
+ $css_class = " $this->css_class";
+ } else {
+ $css_class = "";
+ }
+ return "<li><a$css_id class=\"gMenuElement$css_class\" href=\"$this->url\" " .
+ "title=\"$this->label\">$this->label</a></li>";
+ }
+}
+
+/**
+ * Menu element that provides a pop-up dialog
+ */
+class Menu_Element_Dialog extends Menu_Element {
+ public function __toString() {
+ if (isset($this->css_id) && !empty($this->css_id)) {
+ $css_id = " id=\"$this->css_id\"";
+ } else {
+ $css_id = "";
+ }
+ if (isset($this->css_class) && !empty($this->css_class)) {
+ $css_class = " $this->css_class";
+ } else {
+ $css_class = "";
+ }
+ return "<li><a$css_id class=\"gMenuLink$css_class\" href=\"$this->url\" " .
+ "title=\"$this->label\">$this->label</a></li>";
+ }
+}
+
+/**
+ * Root menu or submenu
+ */
+class Menu_Core extends Menu_Element {
+ public $elements;
+ public $is_root = false;
+
+ /**
+ * Return an instance of a Menu_Element
+ * @chainable
+ */
+ public static function factory($type) {
+ switch($type) {
+ case "link":
+ return new Menu_Element_Link();
+
+ case "dialog":
+ return new Menu_Element_Dialog();
+
+ case "root":
+ $menu = new Menu();
+ $menu->is_root = true;
+ return $menu;
+
+ case "submenu":
+ return new Menu();
+
+ default:
+ throw Exception("@todo UNKNOWN_MENU_TYPE");
+ }
+ }
+
+ public function __construct() {
+ $this->elements = array();
+ }
+
+ /**
+ * Add a new element to this menu
+ */
+ public function append($menu_element) {
+ $this->elements[$menu_element->id] = $menu_element;
+ return $this;
+ }
+
+ /**
+ * Add a new element to this menu
+ */
+ public function add_after($target_id, $new_menu_element) {
+ $copy = array();
+ foreach ($this->elements as $id => $menu_element) {
+ $copy[$id] = $menu_element;
+ if ($id == $target_id) {
+ $copy[$new_menu_element->id] = $new_menu_element;
+ }
+ }
+ $this->elements = $copy;
+ return $this;
+ }
+
+ /**
+ * Retrieve a Menu_Element by id
+ */
+ public function get($id) {
+ return $this->elements[$id];
+ }
+
+ public function __toString() {
+ $html = $this->is_root ? "<ul class=\"gMenu\">" :
+ "<li><a href=#>$this->label</a><ul class=\"gMenu\">";
+ $html .= implode("\n", $this->elements);
+ $html .= $this->is_root ? "</ul>" : "</ul></li>";
+ return $html;
+ }
+}
diff --git a/modules/gallery/libraries/ORM_MPTT.php b/modules/gallery/libraries/ORM_MPTT.php
new file mode 100644
index 00000000..46280d95
--- /dev/null
+++ b/modules/gallery/libraries/ORM_MPTT.php
@@ -0,0 +1,307 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+/**
+ * Implement Modified Preorder Tree Traversal on top of ORM.
+ *
+ * MPTT is an efficient way to store and retrieve hierarchical data in a single database table.
+ * For a good description, read http://www.sitepoint.com/article/hierarchical-data-database/3/
+ *
+ * This code was heavily influenced by code from:
+ * - http://code.google.com/p/kohana-mptt/
+ * - http://code.google.com/p/kohana-mptt/wiki/Documentation
+ * - http://code.google.com/p/s7ncms/source/browse/trunk/modules/s7ncms/libraries/ORM_MPTT.php
+ *
+ * Unfortunately that code was not ready for production and I did not want to absorb their code
+ * and licensing issues so I've reimplemented just the features that we need.
+ */
+class ORM_MPTT_Core extends ORM {
+ private $model_name = null;
+
+ function __construct($id=null) {
+ parent::__construct($id);
+ $this->model_name = inflector::singular($this->table_name);
+ }
+
+ /**
+ * Add this node as a child of the parent provided.
+ *
+ * @chainable
+ * @param integer $parent_id the id of the parent node
+ * @return ORM
+ */
+ function add_to_parent($parent) {
+ $this->lock();
+
+ try {
+ // Make a hole in the parent for this new item
+ $this->db->query(
+ "UPDATE {{$this->table_name}} SET `left` = `left` + 2 WHERE `left` >= {$parent->right}");
+ $this->db->query(
+ "UPDATE {{$this->table_name}} SET `right` = `right` + 2 WHERE `right` >= {$parent->right}");
+ $parent->right += 2;
+
+ // Insert this item into the hole
+ $this->left = $parent->right - 2;
+ $this->right = $parent->right - 1;
+ $this->parent_id = $parent->id;
+ $this->level = $parent->level + 1;
+ $this->save();
+ $parent->reload();
+ } catch (Exception $e) {
+ $this->unlock();
+ throw $e;
+ }
+
+ $this->unlock();
+ return $this;
+ }
+
+ /**
+ * Delete this node and all of its children.
+ */
+ public function delete() {
+ $children = $this->children();
+ if ($children) {
+ foreach ($this->children() as $item) {
+ // Deleting children affects the MPTT tree, so we have to reload each child before we
+ // delete it so that we have current left/right pointers. This is inefficient.
+ // @todo load each child once, not twice.
+ $item->reload()->delete();
+ }
+
+ // Deleting children has affected this item
+ $this->reload();
+ }
+
+ $this->lock();
+ try {
+ $this->db->query(
+ "UPDATE {{$this->table_name}} SET `left` = `left` - 2 WHERE `left` > {$this->right}");
+ $this->db->query(
+ "UPDATE {{$this->table_name}} SET `right` = `right` - 2 WHERE `right` > {$this->right}");
+ } catch (Exception $e) {
+ $this->unlock();
+ throw $e;
+ }
+
+ $this->unlock();
+ parent::delete();
+ }
+
+ /**
+ * Return true if the target is descendant of this item.
+ * @param ORM $target
+ * @return boolean
+ */
+ function is_descendant($target) {
+ return ($this->left <= $target->left && $this->right >= $target->right);
+ }
+
+ /**
+ * Return the parent of this node
+ *
+ * @return ORM
+ */
+ function parent() {
+ if (!$this->parent_id) {
+ return null;
+ }
+ return model_cache::get($this->model_name, $this->parent_id);
+ }
+
+ /**
+ * Return all the parents of this node, in order from root to this node's immediate parent.
+ *
+ * @return array ORM
+ */
+ function parents() {
+ return $this
+ ->where("`left` <= {$this->left}")
+ ->where("`right` >= {$this->right}")
+ ->where("id <> {$this->id}")
+ ->orderby("left", "ASC")
+ ->find_all();
+ }
+
+ /**
+ * Return all of the children of this node, ordered by id.
+ *
+ * @chainable
+ * @param integer SQL limit
+ * @param integer SQL offset
+ * @param array orderby
+ * @return array ORM
+ */
+ function children($limit=null, $offset=0, $orderby=null) {
+ $this->where("parent_id", $this->id);
+ if (empty($orderby)) {
+ $this->orderby("id", "ASC");
+ } else {
+ $this->orderby($orderby);
+ }
+ return $this->find_all($limit, $offset);
+ }
+
+ /**
+ * Return all of the children of this node, ordered by id.
+ *
+ * @chainable
+ * @param integer SQL limit
+ * @param integer SQL offset
+ * @return array ORM
+ */
+ function children_count() {
+ return $this->where("parent_id", $this->id)->count_all();
+ }
+
+ /**
+ * Return all of the children of the specified type, ordered by id.
+ *
+ * @param integer SQL limit
+ * @param integer SQL offset
+ * @param string type to return
+ * @param array orderby
+ * @return object ORM_Iterator
+ */
+ function descendants($limit=null, $offset=0, $type=null, $orderby=null) {
+ $this->where("left >", $this->left)
+ ->where("right <=", $this->right);
+ if ($type) {
+ $this->where("type", $type);
+ }
+
+ if (empty($orderby)) {
+ $this->orderby("id", "ASC");
+ } else {
+ $this->orderby($orderby);
+ }
+
+ return $this->find_all($limit, $offset);
+ }
+
+ /**
+ * Return the count of all the children of the specified type.
+ *
+ * @param string type to count
+ * @return integer child count
+ */
+ function descendants_count($type=null) {
+ $this->where("left >", $this->left)
+ ->where("right <=", $this->right);
+ if ($type) {
+ $this->where("type", $type);
+ }
+ return $this->count_all();
+ }
+
+ /**
+ * Move this item to the specified target.
+ *
+ * @chainable
+ * @param Item_Model $target Target node
+ * @return ORM_MTPP
+ */
+ function move_to($target) {
+ if ($this->left <= $target->left &&
+ $this->right >= $target->right) {
+ throw new Exception("@todo INVALID_TARGET can't move item inside itself");
+ }
+
+ $number_to_move = (int)(($this->right - $this->left) / 2 + 1);
+ $size_of_hole = $number_to_move * 2;
+ $original_left = $this->left;
+ $original_right = $this->right;
+ $target_right = $target->right;
+ $level_delta = ($target->level + 1) - $this->level;
+
+ $this->lock();
+ try {
+ if ($level_delta) {
+ // Update the levels for the to-be-moved items
+ $this->db->query(
+ "UPDATE {{$this->table_name}} SET `level` = `level` + $level_delta" .
+ " WHERE `left` >= $original_left AND `right` <= $original_right");
+ }
+
+ // Make a hole in the target for the move
+ $target->db->query(
+ "UPDATE {{$this->table_name}} SET `left` = `left` + $size_of_hole" .
+ " WHERE `left` >= $target_right");
+ $target->db->query(
+ "UPDATE {{$this->table_name}} SET `right` = `right` + $size_of_hole" .
+ " WHERE `right` >= $target_right");
+
+ // Change the parent.
+ $this->db->query(
+ "UPDATE {{$this->table_name}} SET `parent_id` = {$target->id}" .
+ " WHERE `id` = {$this->id}");
+
+ // If the source is to the right of the target then we just adjusted its left and right above.
+ $left = $original_left;
+ $right = $original_right;
+ if ($original_left > $target_right) {
+ $left += $size_of_hole;
+ $right += $size_of_hole;
+ }
+
+ $new_offset = $target->right - $left;
+ $this->db->query(
+ "UPDATE {{$this->table_name}}" .
+ " SET `left` = `left` + $new_offset," .
+ " `right` = `right` + $new_offset" .
+ " WHERE `left` >= $left" .
+ " AND `right` <= $right");
+
+ // Close the hole in the source's parent after the move
+ $this->db->query(
+ "UPDATE {{$this->table_name}} SET `left` = `left` - $size_of_hole" .
+ " WHERE `left` > $right");
+ $this->db->query(
+ "UPDATE {{$this->table_name}} SET `right` = `right` - $size_of_hole" .
+ " WHERE `right` > $right");
+ } catch (Exception $e) {
+ $this->unlock();
+ throw $e;
+ }
+
+ $this->unlock();
+
+ // Lets reload to get the changes.
+ $this->reload();
+ return $this;
+ }
+
+ /**
+ * Lock the tree to prevent concurrent modification.
+ */
+ protected function lock() {
+ $result = $this->db->query("SELECT GET_LOCK('{$this->table_name}', 1) AS l")->current();
+ if (empty($result->l)) {
+ throw new Exception("@todo UNABLE_TO_LOCK_EXCEPTION");
+ }
+ }
+
+ /**
+ * Unlock the tree.
+ */
+ protected function unlock() {
+ $this->db->query("SELECT RELEASE_LOCK('{$this->table_name}')");
+ }
+}
diff --git a/modules/gallery/libraries/Sendmail.php b/modules/gallery/libraries/Sendmail.php
new file mode 100644
index 00000000..90998457
--- /dev/null
+++ b/modules/gallery/libraries/Sendmail.php
@@ -0,0 +1,97 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Sendmail_Core {
+ protected $to;
+ protected $subject;
+ protected $message;
+ protected $headers;
+ protected $line_length = 70;
+ protected $header_separator = "\r\n";
+
+ /**
+ * Return an instance of Sendmail
+ * @chainable
+ */
+ static function factory() {
+ return new Sendmail();
+ }
+
+ public function __construct() {
+ $this->headers = array();
+ $config = Kohana::config("sendmail");
+ foreach ($config as $key => $value) {
+ $this->$key($value);
+ }
+ }
+
+ public function __get($key) {
+ return null;
+ }
+
+ public function __call($key, $value) {
+ switch ($key) {
+ case "to":
+ $this->to = is_array($value[0]) ? $value[0] : array($value[0]);
+ break;
+ case "header":
+ if (count($value) != 2) {
+ throw new Exception("@todo INVALID_HEADER_PARAMETERS");
+ }
+ $this->headers[$value[0]] = $value[1];
+ break;
+ case "from":
+ $this->headers["From"] = $value[0];
+ break;
+ case "reply_to":
+ $this->headers["Reply-To"] = $value[0];
+ break;
+ default:
+ $this->$key = $value[0];
+ }
+ return $this;
+ }
+
+ public function send() {
+ if (empty($this->to)) {
+ throw new Exception("@todo TO_IS_REQUIRED_FOR_MAIL");
+ }
+ $to = implode(", ", $this->to);
+ $headers = array();
+ foreach ($this->headers as $key => $value) {
+ $key = ucfirst($key);
+ $headers[] = "$key: $value";
+ }
+
+ // The docs say headers should be separated by \r\n, but occasionaly that doesn't work and you
+ // need to use a single \n. This can be set in config/sendmail.php
+ $headers = implode($this->header_separator, $headers);
+ $message = wordwrap($this->message, $this->line_length, "\n");
+ if (!$this->mail($to, $this->subject, $message, $headers)) {
+ Kohana::log("error", wordwrap("Sending mail failed:\nTo: $to\n $this->subject\n" .
+ "Headers: $headers\n $this->message"));
+ throw new Exception("@todo SEND_MAIL_FAILED");
+ }
+ return $this;
+ }
+
+ public function mail($to, $subject, $message, $headers) {
+ return mail($to, $subject, $message, $headers);
+ }
+}
diff --git a/modules/gallery/libraries/Task_Definition.php b/modules/gallery/libraries/Task_Definition.php
new file mode 100644
index 00000000..8d9c5922
--- /dev/null
+++ b/modules/gallery/libraries/Task_Definition.php
@@ -0,0 +1,50 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+class Task_Definition_Core {
+ public $callback;
+ public $description;
+ public $name;
+ public $severity;
+
+ static function factory() {
+ return new Task_Definition();
+ }
+
+ function callback($callback) {
+ $this->callback = $callback;
+ return $this;
+ }
+
+ function description($description) {
+ $this->description = $description;
+ return $this;
+ }
+
+ function name($name) {
+ $this->name = $name;
+ return $this;
+ }
+
+ function severity($severity) {
+ $this->severity = $severity;
+ return $this;
+ }
+}
diff --git a/modules/gallery/libraries/Theme_View.php b/modules/gallery/libraries/Theme_View.php
new file mode 100644
index 00000000..b5b97666
--- /dev/null
+++ b/modules/gallery/libraries/Theme_View.php
@@ -0,0 +1,221 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2009 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Theme_View_Core extends View {
+ private $theme_name = null;
+
+ /**
+ * Attempts to load a view and pre-load view data.
+ *
+ * @throws Kohana_Exception if the requested view cannot be found
+ * @param string $name view name
+ * @param string $page_type page type: album, photo, tags, etc
+ * @param string $theme_name view name
+ * @return void
+ */
+ public function __construct($name, $page_type) {
+ $theme_name = module::get_var("core", "active_site_theme");
+ if (!file_exists("themes/$theme_name")) {
+ module::set_var("core", "active_site_theme", "default");
+ theme::load_themes();
+ Kohana::log("error", "Unable to locate theme '$theme_name', switching to default theme.");
+ }
+ parent::__construct($name);
+
+ $this->theme_name = module::get_var("core", "active_site_theme");
+ if (user::active()->admin) {
+ $this->theme_name = Input::instance()->get("theme", $this->theme_name);
+ }
+ $this->item = null;
+ $this->tag = null;
+ $this->set_global("theme", $this);
+ $this->set_global("user", user::active());
+ $this->set_global("page_type", $page_type);
+ if ($page_type == "album") {
+ $this->set_global("thumb_proportion", $this->thumb_proportion());
+ }
+
+ $maintenance_mode = Kohana::config("core.maintenance_mode", false, false);
+ if ($maintenance_mode) {
+ message::warning(t("This site is currently in maintenance mode"));
+ }
+ }
+
+ /**
+ * Proportion of the current thumb_size's to default
+ * @return int
+ */
+ public function thumb_proportion() {
+ // @TODO change the 200 to a theme supplied value when and if we come up with an
+ // API to allow the theme to set defaults.
+ return module::get_var("core", "thumb_size", 200) / 200;
+ }
+
+ public function url($path, $absolute_url=false) {
+ $arg = "themes/{$this->theme_name}/$path";
+ return $absolute_url ? url::abs_file($arg) : url::file($arg);
+ }
+
+ public function item() {
+ return $this->item;
+ }
+
+ public function tag() {
+ return $this->tag;
+ }
+
+ public function page_type() {
+ return $this->page_type;
+ }
+
+ public function display($page_name, $view_class="View") {
+ return new $view_class($page_name);
+ }
+
+ public function site_menu() {
+ $menu = Menu::factory("root");
+ if ($this->page_type != "login") {
+ core_menu::site($menu, $this);
+
+ foreach (module::active() as $module) {
+ if ($module->name == "core") {
+ continue;
+ }
+ $class = "{$module->name}_menu";
+ if (method_exists($class, "site")) {
+ call_user_func_array(array($class, "site"), array(&$menu, $this));
+ }
+ }
+ }
+
+ print $menu;
+ }
+
+ public function album_menu() {
+ $menu = Menu::factory("root");
+ core_menu::album($menu, $this);
+
+ foreach (module::active() as $module) {
+ if ($module->name == "core") {
+ continue;
+ }
+ $class = "{$module->name}_menu";
+ if (method_exists($class, "album")) {
+ call_user_func_array(array($class, "album"), array(&$menu, $this));
+ }
+ }
+
+ print $menu;
+ }
+
+ public function photo_menu() {
+ $menu = Menu::factory("root");
+ core_menu::photo($menu, $this);
+
+ foreach (module::active() as $module) {
+ if ($module->name == "core") {
+ continue;
+ }
+ $class = "{$module->name}_menu";
+ if (method_exists($class, "photo")) {
+ call_user_func_array(array($class, "photo"), array(&$menu, $this));
+ }
+ }
+
+ print $menu;
+ }
+
+ public function pager() {
+ if ($this->children_count) {
+ $this->pagination = new Pagination();
+ $this->pagination->initialize(
+ array('query_string' => 'page',
+ 'total_items' => $this->children_count,
+ 'items_per_page' => $this->page_size,
+ 'style' => 'classic'));
+ return $this->pagination->render();
+ }
+ }
+
+ /**
+ * Print out any site wide status information.
+ */
+ public function site_status() {
+ return site_status::get();
+ }
+
+ /**
+ * Print out any messages waiting for this user.
+ */
+ public function messages() {
+ return message::get();
+ }
+
+ /**
+ * Handle all theme functions that insert module content.
+ */
+ public function __call($function, $args) {
+ switch ($function) {
+ case "album_blocks":
+ case "album_bottom":
+ case "album_top":
+ case "credits";
+ case "dynamic_bottom":
+ case "dynamic_top":
+ case "footer":
+ case "head":
+ case "header_bottom":
+ case "header_top":
+ case "page_bottom":
+ case "page_top":
+ case "photo_blocks":
+ case "photo_bottom":
+ case "photo_top":
+ case "resize_bottom":
+ case "resize_top":
+ case "sidebar_blocks":
+ case "sidebar_bottom":
+ case "sidebar_top":
+ case "thumb_bottom":
+ case "thumb_info":
+ case "thumb_top":
+ $blocks = array();
+ foreach (module::active() as $module) {
+ $helper_class = "{$module->name}_theme";
+ if (method_exists($helper_class, $function)) {
+ $blocks[] = call_user_func_array(
+ array($helper_class, $function),
+ array_merge(array($this), $args));
+ }
+ }
+ if (Session::instance()->get("debug")) {
+ if ($function != "head") {
+ array_unshift(
+ $blocks, "<div class=\"gAnnotatedThemeBlock gAnnotatedThemeBlock_$function gClearFix\">" .
+ "<div class=\"title\">$function</div>");
+ $blocks[] = "</div>";
+ }
+ }
+ return implode("\n", $blocks);
+
+ default:
+ throw new Exception("@todo UNKNOWN_THEME_FUNCTION: $function");
+ }
+ }
+} \ No newline at end of file