summaryrefslogtreecommitdiff
path: root/modules/gallery
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gallery')
-rw-r--r--modules/gallery/controllers/admin.php3
-rw-r--r--modules/gallery/controllers/admin_dashboard.php4
-rw-r--r--modules/gallery/controllers/admin_graphics.php1
-rw-r--r--modules/gallery/controllers/admin_languages.php4
-rw-r--r--modules/gallery/controllers/admin_theme_details.php2
-rw-r--r--modules/gallery/controllers/albums.php14
-rw-r--r--modules/gallery/controllers/file_proxy.php5
-rw-r--r--modules/gallery/controllers/l10n_client.php105
-rw-r--r--modules/gallery/controllers/move.php9
-rw-r--r--modules/gallery/controllers/movies.php3
-rw-r--r--modules/gallery/controllers/package.php169
-rw-r--r--modules/gallery/controllers/permissions.php4
-rw-r--r--modules/gallery/controllers/photos.php5
-rw-r--r--modules/gallery/controllers/quick.php26
-rw-r--r--modules/gallery/controllers/rest.php10
-rw-r--r--modules/gallery/controllers/simple_uploader.php18
-rw-r--r--modules/gallery/css/l10n_client.css14
-rw-r--r--modules/gallery/helpers/gallery.php2
-rw-r--r--modules/gallery/helpers/gallery_menu.php13
-rw-r--r--modules/gallery/helpers/item.php17
-rw-r--r--modules/gallery/helpers/l10n_client.php76
-rw-r--r--modules/gallery/helpers/p.php2
-rw-r--r--modules/gallery/js/l10n_client.js100
-rw-r--r--modules/gallery/libraries/I18n.php27
-rw-r--r--modules/gallery/libraries/MY_Forge.php1
-rw-r--r--modules/gallery/libraries/Menu.php13
-rw-r--r--modules/gallery/models/item.php10
-rw-r--r--modules/gallery/tests/Access_Helper_Test.php4
-rw-r--r--modules/gallery/tests/Albums_Controller_Test.php20
-rw-r--r--modules/gallery/tests/Photos_Controller_Test.php21
-rw-r--r--modules/gallery/tests/xss_data.txt12
-rw-r--r--modules/gallery/views/l10n_client.html.php41
-rw-r--r--modules/gallery/views/move_tree.html.php4
-rw-r--r--modules/gallery/views/permissions_browse.html.php2
-rw-r--r--modules/gallery/views/simple_uploader.html.php2
35 files changed, 611 insertions, 152 deletions
diff --git a/modules/gallery/controllers/admin.php b/modules/gallery/controllers/admin.php
index af0f387a..b92a32cd 100644
--- a/modules/gallery/controllers/admin.php
+++ b/modules/gallery/controllers/admin.php
@@ -22,8 +22,9 @@ class Admin_Controller extends Controller {
public function __construct($theme=null) {
if (!(user::active()->admin)) {
- throw new Exception("@todo UNAUTHORIZED", 401);
+ access::forbidden();
}
+
parent::__construct();
}
diff --git a/modules/gallery/controllers/admin_dashboard.php b/modules/gallery/controllers/admin_dashboard.php
index a1090a6d..3cb97b14 100644
--- a/modules/gallery/controllers/admin_dashboard.php
+++ b/modules/gallery/controllers/admin_dashboard.php
@@ -29,6 +29,8 @@ class Admin_Dashboard_Controller extends Admin_Controller {
}
public function add_block() {
+ access::verify_csrf();
+
$form = gallery_block::get_add_block_form();
if ($form->validate()) {
list ($module_name, $id) = explode(":", $form->add_block->id->value);
@@ -51,6 +53,7 @@ class Admin_Dashboard_Controller extends Admin_Controller {
public function remove_block($id) {
access::verify_csrf();
+
$blocks_center = block_manager::get_active("dashboard_center");
$blocks_sidebar = block_manager::get_active("dashboard_sidebar");
@@ -73,6 +76,7 @@ class Admin_Dashboard_Controller extends Admin_Controller {
public function reorder() {
access::verify_csrf();
+
$active_set = array();
foreach (array("dashboard_sidebar", "dashboard_center") as $location) {
foreach (block_manager::get_active($location) as $id => $info) {
diff --git a/modules/gallery/controllers/admin_graphics.php b/modules/gallery/controllers/admin_graphics.php
index 7e8ef47c..72f8d8e1 100644
--- a/modules/gallery/controllers/admin_graphics.php
+++ b/modules/gallery/controllers/admin_graphics.php
@@ -43,6 +43,7 @@ class Admin_Graphics_Controller extends Admin_Controller {
public function choose($toolkit) {
access::verify_csrf();
+
if ($toolkit != module::get_var("gallery", "graphics_toolkit")) {
module::set_var("gallery", "graphics_toolkit", $toolkit);
diff --git a/modules/gallery/controllers/admin_languages.php b/modules/gallery/controllers/admin_languages.php
index 1dea733c..4639de89 100644
--- a/modules/gallery/controllers/admin_languages.php
+++ b/modules/gallery/controllers/admin_languages.php
@@ -31,6 +31,8 @@ class Admin_Languages_Controller extends Admin_Controller {
}
public function save() {
+ access::verify_csrf();
+
$form = $this->_languages_form();
if ($form->validate()) {
module::set_var("gallery", "default_locale", $form->choose_language->locale->value);
@@ -41,6 +43,8 @@ class Admin_Languages_Controller extends Admin_Controller {
}
public function share() {
+ access::verify_csrf();
+
$form = $this->_share_translations_form();
if (!$form->validate()) {
// Show the page with form errors
diff --git a/modules/gallery/controllers/admin_theme_details.php b/modules/gallery/controllers/admin_theme_details.php
index fec1311b..97696df5 100644
--- a/modules/gallery/controllers/admin_theme_details.php
+++ b/modules/gallery/controllers/admin_theme_details.php
@@ -26,6 +26,8 @@ class Admin_Theme_Details_Controller extends Admin_Controller {
}
public function save() {
+ access::verify_csrf();
+
$form = theme::get_edit_form_admin();
if ($form->validate()) {
module::set_var("gallery", "page_size", $form->edit_theme->page_size->value);
diff --git a/modules/gallery/controllers/albums.php b/modules/gallery/controllers/albums.php
index 5ccadb37..efde4f09 100644
--- a/modules/gallery/controllers/albums.php
+++ b/modules/gallery/controllers/albums.php
@@ -24,11 +24,11 @@ class Albums_Controller extends Items_Controller {
*/
public function _show($album) {
if (!access::can("view", $album)) {
- if ($album->id != 1) {
- access::forbidden();
- } else {
+ if ($album->id == 1) {
print new Theme_View("login_page.html", "album");
return;
+ } else {
+ access::forbidden();
}
}
@@ -77,6 +77,8 @@ class Albums_Controller extends Items_Controller {
* @see REST_Controller::_create($resource)
*/
public function _create($album) {
+ access::verify_csrf();
+ access::required("view", $album);
access::required("add", $album);
switch ($this->input->post("type")) {
@@ -92,6 +94,7 @@ class Albums_Controller extends Items_Controller {
}
private function _create_album($album) {
+ access::required("view", $album);
access::required("add", $album);
$form = album::get_add_form($album);
@@ -120,6 +123,7 @@ class Albums_Controller extends Items_Controller {
}
private function _create_photo($album) {
+ access::required("view", $album);
access::required("add", $album);
// If we set the content type as JSON, it triggers saving the result as
@@ -153,6 +157,8 @@ class Albums_Controller extends Items_Controller {
* @see REST_Controller::_update($resource)
*/
public function _update($album) {
+ access::verify_csrf();
+ access::required("view", $album);
access::required("edit", $album);
$form = album::get_edit_form($album);
@@ -202,6 +208,7 @@ class Albums_Controller extends Items_Controller {
*/
public function _form_add($album_id) {
$album = ORM::factory("item", $album_id);
+ access::required("view", $album);
access::required("add", $album);
switch ($this->input->get("type")) {
@@ -223,6 +230,7 @@ class Albums_Controller extends Items_Controller {
* @see REST_Controller::_form_add($parameters)
*/
public function _form_edit($album) {
+ access::required("view", $album);
access::required("edit", $album);
print album::get_edit_form($album);
diff --git a/modules/gallery/controllers/file_proxy.php b/modules/gallery/controllers/file_proxy.php
index 1901bd9f..1f885e53 100644
--- a/modules/gallery/controllers/file_proxy.php
+++ b/modules/gallery/controllers/file_proxy.php
@@ -32,13 +32,12 @@ class File_Proxy_Controller extends Controller {
$request_uri = $this->input->server("REQUEST_URI");
$request_uri = preg_replace("/\?.*/", "", $request_uri);
- // Firefox converts ~ to %7E breaking our url comparison, below. Convert that back here.
- $request_uri = str_replace("%7E", "~", $request_uri);
+ // Unescape %7E ("~") and %20 (" ")
+ $request_uri = str_replace(array("%7E", "%20"), array("~", " "), $request_uri);
// var_uri: http://example.com/gallery3/var/
$var_uri = url::file("var/");
-
// Make sure that the request is for a file inside var
$offset = strpos($request_uri, $var_uri);
if ($offset === false) {
diff --git a/modules/gallery/controllers/l10n_client.php b/modules/gallery/controllers/l10n_client.php
index 17520051..aa93a758 100644
--- a/modules/gallery/controllers/l10n_client.php
+++ b/modules/gallery/controllers/l10n_client.php
@@ -20,13 +20,40 @@
class L10n_Client_Controller extends Controller {
public function save() {
access::verify_csrf();
- user::active()->admin or access::forbidden();
+ if (!user::active()->admin) {
+ access::forbidden();
+ }
- $input = Input::instance();
- $message = $input->post("l10n-message-source");
- $translation = $input->post("l10n-edit-target");
- $key = I18n::get_message_key($message);
$locale = I18n::instance()->locale();
+ $input = Input::instance();
+ $key = $input->post("l10n-message-key");
+
+ $root_message = ORM::factory("incoming_translation")
+ ->where(array("key" => $key,
+ "locale" => "root"))
+ ->find();
+
+ if (!$root_message->loaded) {
+ throw new Exception("@todo bad request data / illegal state");
+ }
+ $is_plural = I18n::is_plural_message(unserialize($root_message->message));
+
+ if ($is_plural) {
+ $plural_forms = l10n_client::plural_forms($locale);
+ $translation = array();
+ foreach($plural_forms as $plural_form) {
+ $value = $input->post("l10n-edit-plural-translation-$plural_form");
+ if (null === $value || !is_string($value)) {
+ throw new Exception("@todo bad request data");
+ }
+ $translation[$plural_form] = $value;
+ }
+ } else {
+ $translation = $input->post("l10n-edit-translation");
+ if (null === $translation || !is_string($translation)) {
+ throw new Exception("@todo bad request data");
+ }
+ }
$entry = ORM::factory("outgoing_translation")
->where(array("key" => $key,
@@ -36,7 +63,7 @@ class L10n_Client_Controller extends Controller {
if (!$entry->loaded) {
$entry->key = $key;
$entry->locale = $locale;
- $entry->message = serialize($message);
+ $entry->message = $root_message->message;
$entry->base_revision = null;
}
@@ -58,6 +85,9 @@ class L10n_Client_Controller extends Controller {
public function toggle_l10n_mode() {
access::verify_csrf();
+ if (!user::active()->admin) {
+ access::forbidden();
+ }
$session = Session::instance();
$session->set("l10n_mode",
@@ -66,19 +96,6 @@ class L10n_Client_Controller extends Controller {
url::redirect("albums/1");
}
- private static function _l10n_client_form() {
- $form = new Forge("l10n_client/save", "", "post", array("id" => "gL10nClientSaveForm"));
- $group = $form->group("l10n_message");
- $group->hidden("l10n-message-source")->value("");
- $group->textarea("l10n-edit-target");
- $group->submit("l10n-edit-save")->value(t("Save translation"));
- // TODO(andy_st): Avoiding multiple submit buttons for now (hassle with jQuery form plugin).
- // $group->submit("l10n-edit-copy")->value(t("Copy source"));
- // $group->submit("l10n-edit-clear")->value(t("Clear"));
-
- return $form;
- }
-
private static function _l10n_client_search_form() {
$form = new Forge("l10n_client/search", "", "post", array("id" => "gL10nSearchForm"));
$group = $form->group("l10n_search");
@@ -90,36 +107,46 @@ class L10n_Client_Controller extends Controller {
public static function l10n_form() {
$calls = I18n::instance()->call_log();
+ $locale = I18n::instance()->locale();
if ($calls) {
+ $translations = array();
+ foreach (Database::instance()
+ ->select("key", "translation")
+ ->from("incoming_translations")
+ ->where(array("locale" => $locale))
+ ->get()
+ ->as_array() as $row) {
+ $translations[$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) {
+ $translations[$row->key] = unserialize($row->translation);
+ }
+
$string_list = array();
- foreach ($calls as $call) {
+ $cache = array();
+ foreach ($calls as $key => $call) {
list ($message, $options) = $call;
- // Note: Don't interpolate placeholders for the actual translation input field.
- // TODO: Use $options to generate a preview.
- if (is_array($message)) {
- // TODO: Handle plural forms.
- // Translate each message. If it has a plural form, get
- // the current locale's plural rules and all plural translations.
- continue;
- }
- $source = $message;
- $translation = '';
- $options_for_raw_translation = array();
- if (isset($options['count'])) {
- $options_for_raw_translation['count'] = $options['count'];
- }
- if (I18n::instance()->has_translation($message, $options_for_raw_translation)) {
- $translation = I18n::instance()->translate($message, $options_for_raw_translation);
- }
- $string_list[] = array('source' => $source,
+ // Ensure that the message is in the DB
+ l10n_scanner::process_message($message, $cache);
+ // Note: Not interpolating placeholders for the actual translation input field.
+ // TODO: Might show a preview w/ interpolations (using $options)
+ $translation = isset($translations[$key]) ? $translations[$key] : '';
+ $string_list[] = array('source' => $message,
+ 'key' => $key,
'translation' => $translation);
}
$v = new View('l10n_client.html');
$v->string_list = $string_list;
- $v->l10n_form = self::_l10n_client_form();
$v->l10n_search_form = self::_l10n_client_search_form();
+ $v->plural_forms = l10n_client::plural_forms($locale);
return $v;
}
diff --git a/modules/gallery/controllers/move.php b/modules/gallery/controllers/move.php
index 130c247f..93ef05a6 100644
--- a/modules/gallery/controllers/move.php
+++ b/modules/gallery/controllers/move.php
@@ -20,6 +20,7 @@
class Move_Controller extends Controller {
public function browse($source_id) {
$source = ORM::factory("item", $source_id);
+ access::required("view", $source);
access::required("edit", $source);
$view = new View("move_browse.html");
@@ -33,6 +34,11 @@ class Move_Controller extends Controller {
$source = ORM::factory("item", $source_id);
$target = ORM::factory("item", $this->input->post("target_id"));
+ access::required("view", $source);
+ access::required("edit", $source);
+ access::required("view", $target);
+ access::required("edit", $target);
+
item::move($source, $target);
print json_encode(
@@ -43,8 +49,11 @@ class Move_Controller extends Controller {
public function show_sub_tree($source_id, $target_id) {
$source = ORM::factory("item", $source_id);
$target = ORM::factory("item", $target_id);
+ access::required("view", $source);
access::required("edit", $source);
access::required("view", $target);
+ // show targets even if they're not editable because they may contain children which *are*
+ // editable
print $this->_get_tree_html($source, $target);
}
diff --git a/modules/gallery/controllers/movies.php b/modules/gallery/controllers/movies.php
index 55bbb0e5..86b0f177 100644
--- a/modules/gallery/controllers/movies.php
+++ b/modules/gallery/controllers/movies.php
@@ -66,6 +66,8 @@ class Movies_Controller extends Items_Controller {
* @see REST_Controller::_update($resource)
*/
public function _update($photo) {
+ access::verify_csrf();
+ access::required("view", $photo);
access::required("edit", $photo);
$form = photo::get_edit_form($photo);
@@ -108,6 +110,7 @@ class Movies_Controller extends Items_Controller {
* @see REST_Controller::_form_edit($resource)
*/
public function _form_edit($photo) {
+ access::required("view", $photo);
access::required("edit", $photo);
print photo::get_edit_form($photo);
}
diff --git a/modules/gallery/controllers/package.php b/modules/gallery/controllers/package.php
new file mode 100644
index 00000000..f5146fc8
--- /dev/null
+++ b/modules/gallery/controllers/package.php
@@ -0,0 +1,169 @@
+<?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 Package_Controller extends Controller {
+ function index() {
+ if (PHP_SAPI != 'cli') {
+ Kohana::show_404();
+ }
+
+ try {
+ $this->_reset(); // empty and reinstall the standard modules
+ $this->_dump_database(); // Dump the database
+ $this->_dump_var(); // Dump the var directory
+ } catch (Exception $e) {
+ print $e->getTraceAsString();
+ return;
+ }
+
+ print "Successfully wrote install.sql and init_var.php\n";
+ }
+
+ private function _reset() {
+ $db = Database::instance();
+
+ // Drop all tables
+ foreach ($db->list_tables() as $table) {
+ $db->query("DROP TABLE IF EXISTS `$table`");
+ }
+
+ // Clean out data
+ dir::unlink(VARPATH . "uploads");
+ dir::unlink(VARPATH . "albums");
+ dir::unlink(VARPATH . "resizes");
+ dir::unlink(VARPATH . "thumbs");
+ dir::unlink(VARPATH . "modules");
+ dir::unlink(VARPATH . "tmp");
+
+ $db->clear_cache();
+ module::$modules = array();
+ module::$active = array();
+
+ // Use a known random seed so that subsequent packaging runs will reuse the same random
+ // numbers, keeping our install.sql file more stable.
+ srand(0);
+
+ gallery_installer::install(true);
+ module::load_modules();
+
+ foreach (array("user", "comment", "organize", "info", "rss",
+ "search", "slideshow", "tag") as $module_name) {
+ module::install($module_name);
+ module::activate($module_name);
+ }
+ }
+
+ private function _dump_database() {
+ // We now have a clean install with just the packages that we want. Make sure that the
+ // database is clean too.
+ $i = 1;
+ foreach (array("blocks_dashboard_sidebar", "blocks_dashboard_center") as $key) {
+ $blocks = array();
+ foreach (unserialize(module::get_var("gallery", $key)) as $rnd => $value) {
+ $blocks[++$i] = $value;
+ }
+ module::set_var("gallery", $key, serialize($blocks));
+ }
+
+ $db = Database::instance();
+ $db->query("TRUNCATE {sessions}");
+ $db->query("TRUNCATE {logs}");
+ $db->query("DELETE FROM {vars} WHERE `module_name` = 'core' AND `name` = '_cache'");
+ $db->update("users", array("password" => ""), array("id" => 1));
+ $db->update("users", array("password" => ""), array("id" => 2));
+
+ $dbconfig = Kohana::config('database.default');
+ $conn = $dbconfig["connection"];
+ $pass = $conn["pass"] ? "-p{$conn['pass']}" : "";
+ $sql_file = DOCROOT . "installer/install.sql";
+ if (!is_writable($sql_file)) {
+ print "$sql_file is not writeable";
+ return;
+ }
+ $command = "mysqldump --compact --add-drop-table -h{$conn['host']} " .
+ "-u{$conn['user']} $pass {$conn['database']} > $sql_file";
+ exec($command, $output, $status);
+ if ($status) {
+ print "<pre>";
+ print "$command\n";
+ print "Failed to dump database\n";
+ print implode("\n", $output);
+ return;
+ }
+
+ // Post-process the sql file
+ $buf = "";
+ $root = ORM::factory("item", 1);
+ $root_created_timestamp = $root->created;
+ $root_updated_timestamp = $root->updated;
+ foreach (file($sql_file) as $line) {
+ // Prefix tables
+ $line = preg_replace(
+ "/(CREATE TABLE|IF EXISTS|INSERT INTO) `{$dbconfig['table_prefix']}(\w+)`/", "\\1 {\\2}",
+ $line);
+
+ // Normalize dates
+ $line = preg_replace("/,$root_created_timestamp,/", ",UNIX_TIMESTAMP(),", $line);
+ $line = preg_replace("/,$root_updated_timestamp,/", ",UNIX_TIMESTAMP(),", $line);
+ $buf .= $line;
+ }
+ $fd = fopen($sql_file, "wb");
+ fwrite($fd, $buf);
+ fclose($fd);
+ }
+
+ private function _dump_var() {
+ $objects = new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator(VARPATH),
+ RecursiveIteratorIterator::SELF_FIRST);
+
+ $var_file = DOCROOT . "installer/init_var.php";
+ if (!is_writable($var_file)) {
+ print "$var_file is not writeable";
+ return;
+ }
+
+ $paths = array();
+ foreach($objects as $name => $file){
+ if ($file->getBasename() == "database.php") {
+ continue;
+ } else if (basename($file->getPath()) == "logs") {
+ continue;
+ }
+
+ if ($file->isDir()) {
+ $paths[] = "VARPATH . \"" . substr($name, strlen(VARPATH)) . "\"";
+ } else {
+ // @todo: serialize non-directories
+ print "Unknown file: $name";
+ return;
+ }
+ }
+ // Sort the paths so that the var file is stable
+ sort($paths);
+
+ $fd = fopen($var_file, "w");
+ fwrite($fd, "<?php defined(\"SYSPATH\") or die(\"No direct script access.\") ?>\n");
+ fwrite($fd, "<?php\n");
+ foreach ($paths as $path) {
+ fwrite($fd, "!file_exists($path) && mkdir($path);\n");
+ }
+ fclose($fd);
+ }
+} \ No newline at end of file
diff --git a/modules/gallery/controllers/permissions.php b/modules/gallery/controllers/permissions.php
index b0cee303..c776a0fd 100644
--- a/modules/gallery/controllers/permissions.php
+++ b/modules/gallery/controllers/permissions.php
@@ -20,6 +20,7 @@
class Permissions_Controller extends Controller {
function browse($id) {
$item = ORM::factory("item", $id);
+ access::required("view", $item);
access::required("edit", $item);
if (!$item->is_album()) {
@@ -37,6 +38,7 @@ class Permissions_Controller extends Controller {
function form($id) {
$item = ORM::factory("item", $id);
+ access::required("view", $item);
access::required("edit", $item);
if (!$item->is_album()) {
@@ -48,9 +50,11 @@ class Permissions_Controller extends Controller {
function change($command, $group_id, $perm_id, $item_id) {
access::verify_csrf();
+
$group = ORM::factory("group", $group_id);
$perm = ORM::factory("permission", $perm_id);
$item = ORM::factory("item", $item_id);
+ access::required("view", $item);
access::required("edit", $item);
if ($group->loaded && $perm->loaded && $item->loaded) {
diff --git a/modules/gallery/controllers/photos.php b/modules/gallery/controllers/photos.php
index 5d4040cf..2de51bc7 100644
--- a/modules/gallery/controllers/photos.php
+++ b/modules/gallery/controllers/photos.php
@@ -62,10 +62,13 @@ class Photos_Controller extends Items_Controller {
print $template;
}
+
/**
* @see REST_Controller::_update($resource)
*/
public function _update($photo) {
+ access::verify_csrf();
+ access::required("view", $photo);
access::required("edit", $photo);
$form = photo::get_edit_form($photo);
@@ -110,7 +113,9 @@ class Photos_Controller extends Items_Controller {
* @see REST_Controller::_form_edit($resource)
*/
public function _form_edit($photo) {
+ access::required("view", $photo);
access::required("edit", $photo);
+
print photo::get_edit_form($photo);
}
}
diff --git a/modules/gallery/controllers/quick.php b/modules/gallery/controllers/quick.php
index 643dce30..6efcb9de 100644
--- a/modules/gallery/controllers/quick.php
+++ b/modules/gallery/controllers/quick.php
@@ -19,8 +19,8 @@
*/
class Quick_Controller extends Controller {
public function pane($id) {
- $item = ORM::factory("item", $id);
- if (!$item->loaded) {
+ $item = model_cache::get("item", $id);
+ if (!access::can("view", $item) || !access::can("edit", $item)) {
return "";
}
@@ -32,10 +32,9 @@ class Quick_Controller extends Controller {
public function rotate($id, $dir) {
access::verify_csrf();
- $item = ORM::factory("item", $id);
- if (!$item->loaded) {
- return "";
- }
+ $item = model_cache::get("item", $id);
+ access::required("view", $item);
+ access::required("edit", $item);
$degrees = 0;
switch($dir) {
@@ -82,14 +81,21 @@ class Quick_Controller extends Controller {
public function make_album_cover($id) {
access::verify_csrf();
- item::make_album_cover(ORM::factory("item", $id));
+
+ $item = model_cache::get("item", $id);
+ access::required("view", $item);
+ access::required("view", $item->parent());
+ access::required("edit", $item->parent());
+
+ item::make_album_cover($item);
print json_encode(array("result" => "success"));
}
public function delete($id) {
access::verify_csrf();
- $item = ORM::factory("item", $id);
+ $item = model_cache::get("item", $id);
+ access::required("view", $item);
access::required("edit", $item);
if ($item->is_album()) {
@@ -110,8 +116,10 @@ class Quick_Controller extends Controller {
}
public function form_edit($id) {
- $item = ORM::factory("item", $id);
+ $item = model_cache::get("item", $id);
+ access::required("view", $item);
access::required("edit", $item);
+
if ($item->is_album()) {
$form = album::get_edit_form($item);
} else {
diff --git a/modules/gallery/controllers/rest.php b/modules/gallery/controllers/rest.php
index 11a6bbac..2edf079f 100644
--- a/modules/gallery/controllers/rest.php
+++ b/modules/gallery/controllers/rest.php
@@ -86,21 +86,20 @@ class REST_Controller extends Controller {
return Kohana::show_404();
}
- if ($request_method != "get") {
- access::verify_csrf();
- }
-
switch ($request_method) {
case "get":
return $this->_show($resource);
case "put":
+ access::verify_csrf();
return $this->_update($resource);
case "delete":
+ access::verify_csrf();
return $this->_delete($resource);
case "post":
+ access::verify_csrf();
return $this->_create($resource);
}
}
@@ -111,17 +110,18 @@ class REST_Controller extends Controller {
throw new Exception("@todo ERROR_MISSING_RESOURCE_TYPE");
}
- // @todo this needs security checks
$resource = ORM::factory($this->resource_type, $resource_id);
if (!$resource->loaded) {
return Kohana::show_404();
}
+ // Security checks must be performed in _form_edit
return $this->_form_edit($resource);
}
/* We're adding a new item, pass along any additional parameters. */
public function form_add($parameters) {
+ // Security checks must be performed in _form_add
return $this->_form_add($parameters);
}
diff --git a/modules/gallery/controllers/simple_uploader.php b/modules/gallery/controllers/simple_uploader.php
index ec2a5ab9..dfbd4f17 100644
--- a/modules/gallery/controllers/simple_uploader.php
+++ b/modules/gallery/controllers/simple_uploader.php
@@ -20,6 +20,7 @@
class Simple_Uploader_Controller extends Controller {
public function app($id) {
$item = ORM::factory("item", $id);
+ access::required("view", $item);
access::required("add", $item);
$v = new View("simple_uploader.html");
@@ -33,13 +34,13 @@ class Simple_Uploader_Controller extends Controller {
public function add_photo($id) {
$album = ORM::factory("item", $id);
+ access::required("view", $album);
access::required("add", $album);
access::verify_csrf();
$file_validation = new Validation($_FILES);
$file_validation->add_rules("Filedata", "upload::valid", "upload::type[gif,jpg,png,flv,mp4]");
if ($file_validation->validate()) {
-
// SimpleUploader.swf does not yet call /start directly, so simulate it here for now.
if (!batch::in_progress()) {
batch::start();
@@ -48,7 +49,7 @@ class Simple_Uploader_Controller extends Controller {
$temp_filename = upload::save("Filedata");
try {
$name = substr(basename($temp_filename), 10); // Skip unique identifier Kohana adds
- $title = $this->convert_filename_to_title($name);
+ $title = item::convert_filename_to_title($name);
$path_info = pathinfo($temp_filename);
if (array_key_exists("extension", $path_info) &&
in_array(strtolower($path_info["extension"]), array("flv", "mp4"))) {
@@ -69,18 +70,11 @@ class Simple_Uploader_Controller extends Controller {
print "File Received";
}
- /**
- * We should move this into a helper somewhere.. but where is appropriate?
- */
- private function convert_filename_to_title($filename) {
- $title = strtr($filename, "_", " ");
- $title = preg_replace("/\..*?$/", "", $title);
- $title = preg_replace("/ +/", " ", $title);
- return $title;
- }
-
public function finish() {
+ access::verify_csrf();
+
batch::stop();
print json_encode(array("result" => "success"));
}
+
}
diff --git a/modules/gallery/css/l10n_client.css b/modules/gallery/css/l10n_client.css
index 8973715f..6616f511 100644
--- a/modules/gallery/css/l10n_client.css
+++ b/modules/gallery/css/l10n_client.css
@@ -145,7 +145,6 @@ how it wants to round. */
margin:0em;
}
-
#l10n-client-string-editor {
display:none;
float:left;
@@ -168,18 +167,13 @@ how it wants to round. */
#gL10nClientSaveForm {
padding:0em;}
- #gL10nClientSaveForm .form-textarea {
- height:13em;
- font-size:1em; line-height:1.25em;
- width:95%;}
-
- #gL10nClientSaveForm .form-submit {
- margin-top: 0em;}
-
-
#l10n-client form ul,
#l10n-client form li,
#l10n-client form input[type=submit],
#l10n-client form input[type=text] {
display: inline ! important ;
}
+
+#l10n-client form .hidden {
+ display: none;
+}
diff --git a/modules/gallery/helpers/gallery.php b/modules/gallery/helpers/gallery.php
index 34671f1f..1686571c 100644
--- a/modules/gallery/helpers/gallery.php
+++ b/modules/gallery/helpers/gallery.php
@@ -23,7 +23,7 @@ class gallery_Core {
* down for maintenance" page.
*/
static function maintenance_mode() {
- $maintenance_mode = Kohana::config("gallery.maintenance_mode", false, false);
+ $maintenance_mode = Kohana::config("core.maintenance_mode", false, false);
if (Router::$controller != "login" && !empty($maintenance_mode) && !user::active()->admin) {
Router::$controller = "maintenance";
diff --git a/modules/gallery/helpers/gallery_menu.php b/modules/gallery/helpers/gallery_menu.php
index 09c2d91a..d28e71c9 100644
--- a/modules/gallery/helpers/gallery_menu.php
+++ b/modules/gallery/helpers/gallery_menu.php
@@ -30,7 +30,14 @@ class gallery_menu_Core {
$can_edit = $item && access::can("edit", $item) || $is_admin;
$can_add = $item && (access::can("add", $item) || $is_admin);
-
+
+ if ($can_add) {
+ $menu->append(Menu::factory("dialog")
+ ->id("add_photos_item")
+ ->label(t("Add photos"))
+ ->url(url::site("simple_uploader/app/$item->id")));
+ }
+
if ($item && $can_edit || $can_add) {
$menu->append($options_menu = Menu::factory("submenu")
->id("options_menu")
@@ -49,10 +56,6 @@ class gallery_menu_Core {
if ($can_add) {
$options_menu
->append(Menu::factory("dialog")
- ->id("add_item")
- ->label(t("Add a photo"))
- ->url(url::site("simple_uploader/app/$item->id")))
- ->append(Menu::factory("dialog")
->id("add_album")
->label(t("Add an album"))
->url(url::site("form/add/albums/$item->id?type=album")));
diff --git a/modules/gallery/helpers/item.php b/modules/gallery/helpers/item.php
index 7daaf1e1..09870b45 100644
--- a/modules/gallery/helpers/item.php
+++ b/modules/gallery/helpers/item.php
@@ -19,6 +19,8 @@
*/
class item_Core {
static function move($source, $target) {
+ access::required("view", $source);
+ access::required("view", $target);
access::required("edit", $source);
access::required("edit", $target);
@@ -47,6 +49,8 @@ class item_Core {
static function make_album_cover($item) {
$parent = $item->parent();
+ access::required("view", $item);
+ access::required("view", $parent);
access::required("edit", $parent);
model_cache::clear("item", $parent->album_cover_item_id);
@@ -61,6 +65,7 @@ class item_Core {
}
static function remove_album_cover($album) {
+ access::required("view", $album);
access::required("edit", $album);
@unlink($album->thumb_path());
@@ -102,4 +107,16 @@ class item_Core {
$input->add_error("conflict", 1);
}
}
+
+ /**
+ * Sanitize a filename into something presentable as an item title
+ * @param string $filename
+ * @return string title
+ */
+ static function convert_filename_to_title($filename) {
+ $title = strtr($filename, "_", " ");
+ $title = preg_replace("/\..*?$/", "", $title);
+ $title = preg_replace("/ +/", " ", $title);
+ return $title;
+ }
} \ No newline at end of file
diff --git a/modules/gallery/helpers/l10n_client.php b/modules/gallery/helpers/l10n_client.php
index d26739f5..4e905c6c 100644
--- a/modules/gallery/helpers/l10n_client.php
+++ b/modules/gallery/helpers/l10n_client.php
@@ -200,4 +200,80 @@ class l10n_client_Core {
// @todo Move messages out of outgoing into incoming, using new rev?
// @todo show which messages have been rejected / are pending?
}
+
+ /**
+ * Plural forms.
+ */
+ static function plural_forms($locale) {
+ $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 array('other');
+
+ case 'ar':
+ return array('zero', 'one', 'two', 'few', 'many', 'other');
+
+ case 'lv':
+ return array('zero', 'one', 'other');
+
+ case 'ga':
+ case 'se':
+ case 'sma':
+ case 'smi':
+ case 'smj':
+ case 'smn':
+ case 'sms':
+ return array('one', 'two', 'other');
+
+ case 'ro':
+ case 'mo':
+ case 'lt':
+ case 'cs':
+ case 'sk':
+ case 'pl':
+ return array('one', 'few', 'other');
+
+ case 'hr':
+ case 'ru':
+ case 'sr':
+ case 'uk':
+ case 'be':
+ case 'bs':
+ case 'sh':
+ case 'mt':
+ return array('one', 'few', 'many', 'other');
+
+ case 'sl':
+ return array('one', 'two', 'few', 'other');
+
+ case 'cy':
+ return array('one', 'two', 'many', 'other');
+
+ default: // en, de, etc.
+ return array('one', 'other');
+ }
+ }
} \ No newline at end of file
diff --git a/modules/gallery/helpers/p.php b/modules/gallery/helpers/p.php
index c3074c23..0a6210dc 100644
--- a/modules/gallery/helpers/p.php
+++ b/modules/gallery/helpers/p.php
@@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class p_Core {
- function clean($dirty_html) {
+ static function clean($dirty_html) {
return html::specialchars($dirty_html);
}
}
diff --git a/modules/gallery/js/l10n_client.js b/modules/gallery/js/l10n_client.js
index f43671f1..efd956e2 100644
--- a/modules/gallery/js/l10n_client.js
+++ b/modules/gallery/js/l10n_client.js
@@ -90,6 +90,40 @@ jQuery.extend(Gallery, {
this.setString = function(index, data) {
l10n_client_data[index]['translation'] = data;
}
+ // Display the source message
+ this.showSourceMessage = function(source, is_plural) {
+ if (is_plural) {
+ var pretty_source = '[one] - ' + source['one'] + "\n";
+ pretty_source += '[other] - ' + source['other'];
+ } else {
+ var pretty_source = source;
+ }
+ $('#l10n-client-string-editor .source-text').text(pretty_source);
+ }
+ this.isPluralMessage = function(message) {
+ return typeof(message) == 'object';
+ }
+ this.updateTranslationForm = function(translation, is_plural) {
+ $('.translationField').addClass('hidden');
+ if (is_plural) {
+ if (typeof(translation) != 'object') {
+ translation = {};
+ }
+ var num_plural_forms = plural_forms.length;
+ for (var i = 0; i < num_plural_forms; i++) {
+ var form = plural_forms[i];
+ if (translation[form] == undefined) {
+ translation[form] = '';
+ }
+ $('#l10n-edit-plural-translation-' + form)
+ .attr('value', translation[form]);
+ $('#plural-' + form).removeClass('hidden');
+ }
+ } else {
+ $('#l10n-edit-translation').attr('value', translation);
+ $('#l10n-edit-translation').removeClass('hidden');
+ }
+ }
// Filter the the string list by a search string
this.filter = function(search) {
if(search == false || search == '') {
@@ -126,11 +160,12 @@ Gallery.behaviors.l10nClient = function(context) {
$('#l10n-client-string-select li').removeClass('active');
$(this).addClass('active');
var index = $('#l10n-client-string-select li').index(this);
-
- $('#l10n-client-string-editor .source-text').text(Gallery.l10nClient.getString(index, 'source'));
- $("#gL10nClientSaveForm input[name='l10n-message-source']").val(Gallery.l10nClient.getString(index, 'source'));
- $('#gL10nClientSaveForm #l10n-edit-target').val(Gallery.l10nClient.getString(index, 'translation'));
-
+ var source = Gallery.l10nClient.getString(index, 'source');
+ var key = Gallery.l10nClient.getString(index, 'key');
+ var is_plural = Gallery.l10nClient.isPluralMessage(source);
+ Gallery.l10nClient.showSourceMessage(source, is_plural);
+ Gallery.l10nClient.updateTranslationForm(Gallery.l10nClient.getString(index, 'translation'), is_plural);
+ $("#gL10nClientSaveForm input[name='l10n-message-key']").val(key);
Gallery.l10nClient.selected = index;
});
@@ -165,23 +200,46 @@ Gallery.behaviors.l10nClient = function(context) {
$('#gL10nClientSaveForm').ajaxForm({
dataType: "json",
success: function(data) {
- // Store string in local js
- Gallery.l10nClient.setString(Gallery.l10nClient.selected, $('#gL10nClientSaveForm #l10n-edit-target').val());
-
- // Mark string as translated.
- $('#l10n-client-string-select li').eq(Gallery.l10nClient.selected).removeClass('untranslated').removeClass('active').addClass('translated').text($('#gL10nClientSaveForm #l10n-edit-target').val());
-
- // Empty input fields.
- $('#l10n-client-string-editor .source-text').html('');
- $('#gL10nClientSaveForm #l10n-edit-target').val('');
- $("#gL10nClientSaveForm input[name='l10n-message-source']").val('');
- },
- error: function(xmlhttp) {
- // TODO: Localize this message
- alert('An HTTP error @status occured (or empty response).'.replace('@status', xmlhttp.status));
- }
- });
+ var source = Gallery.l10nClient.getString(Gallery.l10nClient.selected, 'source');
+ var is_plural = Gallery.l10nClient.isPluralMessage(source);
+ var num_plural_forms = plural_forms.length;
+
+ // Store translation in local js
+ if (is_plural) {
+ var translation = {};
+ for (var i = 0; i < num_plural_forms; i++) {
+ var form = plural_forms[i];
+ translation[form] = $('#gL10nClientSaveForm #l10n-edit-plural-translation-' + form).attr('value');
+ }
+ } else {
+ translation = $('#l10n-edit-translation').attr('value');
+ }
+ Gallery.l10nClient.setString(Gallery.l10nClient.selected, translation);
+
+ // Mark message as translated.
+ $('#l10n-client-string-select li').eq(Gallery.l10nClient.selected).removeClass('untranslated').removeClass('active').addClass('translated');
+
+ // Clear the translation form fields
+ Gallery.l10nClient.showSourceMessage('', false);
+ $('#gL10nClientSaveForm #l10n-edit-translation').val('');
+
+ for (var i = 0; i < num_plural_forms; i++) {
+ var form = plural_forms[i];
+ $('#gL10nClientSaveForm #l10n-edit-plural-translation-' + form).val('');
+ }
+ $("#gL10nClientSaveForm input[name='l10n-message-key']").val('');
+ },
+ error: function(xmlhttp) {
+ // TODO: Localize this message
+ alert('An HTTP error @status occured (or empty response).'.replace('@status', xmlhttp.status));
+ }
+ });
+ // TODO: Add copy/clear buttons (without ajax behavior)
+ /* <input type="submit" name="l10n-edit-copy" value="<?= t("Copy source") ?>"/>
+ <input type="submit" name="l10n-edit-clear" value="<?= t("Clear") ?>"/>
+ */
+ // TODO: Handle plurals in copy button
// Copy source text to translation field on button click.
$('#gL10nClientSaveForm #l10n-edit-copy').click(function() {
diff --git a/modules/gallery/libraries/I18n.php b/modules/gallery/libraries/I18n.php
index f2801169..03a6d8f6 100644
--- a/modules/gallery/libraries/I18n.php
+++ b/modules/gallery/libraries/I18n.php
@@ -148,30 +148,37 @@ class I18n_Core {
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)) {
+ } else if (!is_array($message)) {
return $entry !== '';
} else {
- $plural_key = self::get_plural_key($locale, $count);
- return isset($entry[$plural_key])
- && $entry[$plural_key] !== null
- && $entry[$plural_key] !== '';
+ if (!is_array($entry) || empty($entry)) {
+ return false;
+ }
+ // It would be better to verify that all the locale's plural forms have a non-empty
+ // translation, but this is fine for now.
+ foreach ($entry as $value) {
+ if ($value === '') {
+ return false;
+ }
+ }
+ return true;
}
}
- public static function get_message_key($message) {
+ static function get_message_key($message) {
$as_string = is_array($message) ? implode('|', $message) : $message;
return md5($as_string);
}
+ static function is_plural_message($message) {
+ return is_array($message);
+ }
+
private function interpolate($locale, $string, $values) {
// TODO: Handle locale specific number formatting.
diff --git a/modules/gallery/libraries/MY_Forge.php b/modules/gallery/libraries/MY_Forge.php
index 17d0465b..b40d067d 100644
--- a/modules/gallery/libraries/MY_Forge.php
+++ b/modules/gallery/libraries/MY_Forge.php
@@ -26,6 +26,7 @@ class Forge extends Forge_Core {
parent::__construct($action, $title, $method, $attr);
$this->hidden("csrf")->value("");
}
+
/**
* Use our own template
*/
diff --git a/modules/gallery/libraries/Menu.php b/modules/gallery/libraries/Menu.php
index d19d8b1e..83bd1616 100644
--- a/modules/gallery/libraries/Menu.php
+++ b/modules/gallery/libraries/Menu.php
@@ -171,10 +171,21 @@ class Menu_Core extends Menu_Element {
}
/**
+ * Remove an element from the menu
+ */
+ public function remove($target_id) {
+ unset($this->elements[$target_id]);
+ }
+
+ /**
* Retrieve a Menu_Element by id
*/
public function get($id) {
- return $this->elements[$id];
+ if (array_key_exists($id, $this->elements)) {
+ return $this->elements[$id];
+ }
+
+ return null;
}
public function __toString() {
diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php
index 4b8cac8e..10bad0b2 100644
--- a/modules/gallery/models/item.php
+++ b/modules/gallery/models/item.php
@@ -287,6 +287,10 @@ class Item_Model extends ORM_MPTT {
* @return string
*/
public function relative_path() {
+ if (!$this->loaded) {
+ return;
+ }
+
if (!isset($this->relative_path_cache)) {
$paths = array();
foreach (Database::instance()
@@ -391,7 +395,7 @@ class Item_Model extends ORM_MPTT {
* @param boolean (optional) $center_vertically Center vertically (default: false)
* @return string
*/
- public function thumb_tag($extra_attrs=array(), $max=null, $center_vertically=false) {
+ public function thumb_img($extra_attrs=array(), $max=null, $center_vertically=false) {
list ($height, $width) = $this->scale_dimensions($max);
if ($center_vertically && $max) {
// The constant is divide by 2 to calculate the file and 10 to convert to em
@@ -444,7 +448,7 @@ class Item_Model extends ORM_MPTT {
* @param array $extra_attrs Extra attributes to add to the img tag
* @return string
*/
- public function resize_tag($extra_attrs) {
+ public function resize_img($extra_attrs) {
$attrs = array_merge($extra_attrs,
array("src" => $this->resize_url(),
"alt" => $this->title,
@@ -460,7 +464,7 @@ class Item_Model extends ORM_MPTT {
* @param array $extra_attrs
* @return string
*/
- public function movie_tag($extra_attrs) {
+ public function movie_img($extra_attrs) {
$attrs = array_merge($extra_attrs,
array("id" => "player",
"style" => "display:block;width:400px;height:300px")
diff --git a/modules/gallery/tests/Access_Helper_Test.php b/modules/gallery/tests/Access_Helper_Test.php
index 7012a487..d71bf971 100644
--- a/modules/gallery/tests/Access_Helper_Test.php
+++ b/modules/gallery/tests/Access_Helper_Test.php
@@ -38,6 +38,10 @@ class Access_Helper_Test extends Unit_Test_Case {
$user->delete();
}
} catch (Exception $e) { }
+
+ // Reset some permissions that we mangle below
+ $root = ORM::factory("item", 1);
+ access::allow(group::everybody(), "view", $root);
}
public function setup() {
diff --git a/modules/gallery/tests/Albums_Controller_Test.php b/modules/gallery/tests/Albums_Controller_Test.php
index ef1fac77..7674e85f 100644
--- a/modules/gallery/tests/Albums_Controller_Test.php
+++ b/modules/gallery/tests/Albums_Controller_Test.php
@@ -20,17 +20,21 @@
class Albums_Controller_Test extends Unit_Test_Case {
public function setup() {
$this->_post = $_POST;
+ $this->_album = null;
}
public function teardown() {
$_POST = $this->_post;
+ if ($this->_album) {
+ $this->_album->delete();
+ }
}
public function change_album_test() {
$controller = new Albums_Controller();
$root = ORM::factory("item", 1);
- $album = album::create($root, "test", "test", "test");
- $orig_name = $album->name;
+ $this->_album = album::create($root, "test", "test", "test");
+ $orig_name = $this->_album->name;
$_POST["dirname"] = "test";
$_POST["name"] = "new name";
@@ -43,31 +47,31 @@ class Albums_Controller_Test extends Unit_Test_Case {
access::allow(group::everybody(), "edit", $root);
ob_start();
- $controller->_update($album);
+ $controller->_update($this->_album);
$results = ob_get_contents();
ob_end_clean();
$this->assert_equal(
json_encode(array("result" => "success", "location" => "http://./index.php/test")),
$results);
- $this->assert_equal("new title", $album->title);
- $this->assert_equal("new description", $album->description);
+ $this->assert_equal("new title", $this->_album->title);
+ $this->assert_equal("new description", $this->_album->description);
// We don't change the name, yet.
- $this->assert_equal($orig_name, $album->name);
+ $this->assert_equal($orig_name, $this->_album->name);
}
public function change_album_no_csrf_fails_test() {
$controller = new Albums_Controller();
$root = ORM::factory("item", 1);
- $album = album::create($root, "test", "test", "test");
+ $this->_album = album::create($root, "test", "test", "test");
$_POST["name"] = "new name";
$_POST["title"] = "new title";
$_POST["description"] = "new description";
access::allow(group::everybody(), "edit", $root);
try {
- $controller->_update($album);
+ $controller->_update($this->_album);
$this->assert_true(false, "This should fail");
} catch (Exception $e) {
// pass
diff --git a/modules/gallery/tests/Photos_Controller_Test.php b/modules/gallery/tests/Photos_Controller_Test.php
index 771cc90d..f7d3f72f 100644
--- a/modules/gallery/tests/Photos_Controller_Test.php
+++ b/modules/gallery/tests/Photos_Controller_Test.php
@@ -20,17 +20,22 @@
class Photos_Controller_Test extends Unit_Test_Case {
public function setup() {
$this->_post = $_POST;
+ $this->_photo = null;
}
public function teardown() {
$_POST = $this->_post;
+ if ($this->_photo) {
+ $this->_photo->delete();
+ }
}
public function change_photo_test() {
$controller = new Photos_Controller();
$root = ORM::factory("item", 1);
- $photo = photo::create($root, MODPATH . "gallery/tests/test.jpg", "test.jpeg", "test", "test");
- $orig_name = $photo->name;
+ $this->_photo = photo::create($root, MODPATH . "gallery/tests/test.jpg", "test.jpeg", "test",
+ "test");
+ $orig_name = $this->_photo->name;
$_POST["filename"] = "test.jpeg";
$_POST["name"] = "new name";
@@ -40,7 +45,7 @@ class Photos_Controller_Test extends Unit_Test_Case {
access::allow(group::everybody(), "edit", $root);
ob_start();
- $controller->_update($photo);
+ $controller->_update($this->_photo);
$results = ob_get_contents();
ob_end_clean();
@@ -48,24 +53,24 @@ class Photos_Controller_Test extends Unit_Test_Case {
json_encode(array("result" => "success",
"location" => "http://./index.php/test.jpeg")),
$results);
- $this->assert_equal("new title", $photo->title);
- $this->assert_equal("new description", $photo->description);
+ $this->assert_equal("new title", $this->_photo->title);
+ $this->assert_equal("new description", $this->_photo->description);
// We don't change the name, yet.
- $this->assert_equal($orig_name, $photo->name);
+ $this->assert_equal($orig_name, $this->_photo->name);
}
public function change_photo_no_csrf_fails_test() {
$controller = new Photos_Controller();
$root = ORM::factory("item", 1);
- $photo = photo::create($root, MODPATH . "gallery/tests/test.jpg", "test", "test", "test");
+ $this->_photo = photo::create($root, MODPATH . "gallery/tests/test.jpg", "test", "test", "test");
$_POST["name"] = "new name";
$_POST["title"] = "new title";
$_POST["description"] = "new description";
access::allow(group::everybody(), "edit", $root);
try {
- $controller->_update($photo);
+ $controller->_update($this->_photo);
$this->assert_true(false, "This should fail");
} catch (Exception $e) {
// pass
diff --git a/modules/gallery/tests/xss_data.txt b/modules/gallery/tests/xss_data.txt
index 4aaa520d..67f293dd 100644
--- a/modules/gallery/tests/xss_data.txt
+++ b/modules/gallery/tests/xss_data.txt
@@ -195,14 +195,14 @@ modules/gallery/views/l10n_client.html.php 29 DIRTY $string_l
modules/gallery/views/move_browse.html.php 4 DIRTY $source->id
modules/gallery/views/move_browse.html.php 39 DIRTY $tree
modules/gallery/views/move_browse.html.php 42 DIRTY $source->id
-modules/gallery/views/move_tree.html.php 2 DIRTY $parent->thumb_tag(array(), 25)
+modules/gallery/views/move_tree.html.php 2 DIRTY $parent->thumb_img(array(), 25)
modules/gallery/views/move_tree.html.php 4 DIRTY $parent->id
modules/gallery/views/move_tree.html.php 4 CLEAN $parent->title
modules/gallery/views/move_tree.html.php 6 DIRTY $parent->id
modules/gallery/views/move_tree.html.php 6 CLEAN $parent->title
modules/gallery/views/move_tree.html.php 8 DIRTY $parent->id
modules/gallery/views/move_tree.html.php 10 DIRTY $child->id
-modules/gallery/views/move_tree.html.php 11 DIRTY $child->thumb_tag(array(), 25)
+modules/gallery/views/move_tree.html.php 11 DIRTY $child->thumb_img(array(), 25)
modules/gallery/views/move_tree.html.php 13 DIRTY $child->id
modules/gallery/views/move_tree.html.php 13 CLEAN $child->title
modules/gallery/views/move_tree.html.php 15 DIRTY $child->id
@@ -335,7 +335,7 @@ modules/organize/views/organize_thumb_grid.html.php 7 DIRTY $child->i
modules/organize/views/organize_thumb_grid.html.php 7 DIRTY $child->id
modules/organize/views/organize_thumb_grid.html.php 8 DIRTY $child->id
modules/organize/views/organize_thumb_grid.html.php 8 DIRTY $item_class
-modules/organize/views/organize_thumb_grid.html.php 9 DIRTY $child->thumb_tag(array("class" => "gThumbnail"), $thumbsize, true)
+modules/organize/views/organize_thumb_grid.html.php 9 DIRTY $child->thumb_img(array("class" => "gThumbnail"), $thumbsize, true)
modules/recaptcha/views/admin_recaptcha.html.php 5 DIRTY $form->get_key_url
modules/recaptcha/views/admin_recaptcha.html.php 8 DIRTY $form
modules/recaptcha/views/admin_recaptcha.html.php 21 DIRTY $public_key
@@ -406,7 +406,7 @@ modules/rss/views/rss_block.html.php 8 DIRTY $title
modules/search/views/search.html.php 11 CLEAN $q
modules/search/views/search.html.php 30 DIRTY $item_class
modules/search/views/search.html.php 31 DIRTY $item->id
-modules/search/views/search.html.php 32 DIRTY $item->thumb_tag()
+modules/search/views/search.html.php 32 DIRTY $item->thumb_img()
modules/search/views/search.html.php 34 CLEAN $item->title
modules/search/views/search.html.php 37 CLEAN $item->description
modules/search/views/search.html.php 43 DIRTY $theme->pager()
@@ -518,7 +518,7 @@ themes/default/views/album.html.php 15 DIRTY $child->i
themes/default/views/album.html.php 15 DIRTY $item_class
themes/default/views/album.html.php 16 DIRTY $theme->thumb_top($child)
themes/default/views/album.html.php 17 DIRTY $child->url()
-themes/default/views/album.html.php 18 DIRTY $child->thumb_tag(array("class" => "gThumbnail"))
+themes/default/views/album.html.php 18 DIRTY $child->thumb_img(array("class" => "gThumbnail"))
themes/default/views/album.html.php 20 DIRTY $theme->thumb_bottom($child)
themes/default/views/album.html.php 21 DIRTY $child->url()
themes/default/views/album.html.php 21 CLEAN $child->title
@@ -607,7 +607,7 @@ themes/default/views/photo.html.php 15 DIRTY $position
themes/default/views/photo.html.php 15 DIRTY $sibling_count
themes/default/views/photo.html.php 18 DIRTY $next_item->url()
themes/default/views/photo.html.php 28 DIRTY $theme->resize_top($item)
-themes/default/views/photo.html.php 32 DIRTY $item->resize_tag(array("id" => "gPhotoId-{$item->id}", "class" => "gResize"))
+themes/default/views/photo.html.php 32 DIRTY $item->resize_img(array("id" => "gPhotoId-{$item->id}", "class" => "gResize"))
themes/default/views/photo.html.php 36 DIRTY $theme->resize_bottom($item)
themes/default/views/photo.html.php 40 CLEAN $item->title
themes/default/views/photo.html.php 41 CLEAN $item->description
diff --git a/modules/gallery/views/l10n_client.html.php b/modules/gallery/views/l10n_client.html.php
index 8f4092c7..faa6e939 100644
--- a/modules/gallery/views/l10n_client.html.php
+++ b/modules/gallery/views/l10n_client.html.php
@@ -11,21 +11,58 @@
<ul class="string-list">
<? foreach ($string_list as $string): ?>
<li class="<?= $string["translation"] === "" ? "untranslated" : "translated" ?>">
+ <? if (is_array($string["source"])): ?>
+ [one] - <?= $string["source"]["one"] ?><br/>
+ [other] - <?= $string["source"]["other"] ?>
+ <? else: ?>
<?= $string["source"] ?>
+ <? endif; ?>
</li>
<? endforeach; ?>
</ul>
+
<?= $l10n_search_form ?>
</div>
<div id="l10n-client-string-editor">
<div class="source">
- <div class="source-text"></div>
+ <pre class="source-text"></pre>
</div>
<div class="translation">
- <?= $l10n_form ?>
+ <form method="post" action="<?= url::site("l10n_client/save") ?>" id="gL10nClientSaveForm">
+ <?= access::csrf_form_field() ?>
+ <?= form::hidden("l10n-message-key") ?>
+ <?= form::textarea("l10n-edit-translation", "", ' rows="5" class="translationField"') ?>
+ <div id="plural-zero" class="translationField hidden">
+ <label for="l10n-edit-plural-translation-zero">[zero]</label>
+ <?= form::textarea("l10n-edit-plural-translation-zero", "", ' rows="2"') ?>
+ </div>
+ <div id="plural-one" class="translationField hidden">
+ <label for="l10n-edit-plural-translation-one">[one]</label>
+ <?= form::textarea("l10n-edit-plural-translation-one", "", ' rows="2"') ?>
+ </div>
+ <div id="plural-two" class="translationField hidden">
+ <label for="l10n-edit-plural-translation-two">[two]</label>
+ <?= form::textarea("l10n-edit-plural-translation-two", "", ' rows="2"') ?>
+ </div>
+ <div id="plural-few" class="translationField hidden">
+ <label for="l10n-edit-plural-translation-few">[few]</label>
+ <?= form::textarea("l10n-edit-plural-translation-few", "", ' rows="2"') ?>
+ </div>
+ <div id="plural-many" class="translationField hidden">
+ <label for="l10n-edit-plural-translation-many">[many]</label>
+ <?= form::textarea("l10n-edit-plural-translation-many", "", ' rows="2"') ?>
+ </div>
+ <div id="plural-other" class="translationField hidden">
+ <label for="l10n-edit-plural-translation-other">[other]</label>
+ (<a href="http://www.unicode.org/cldr/data/charts/supplemental/language_plural_rules.html"><?= t("learn more about plural forms") ?></a>)
+ <?= form::textarea("l10n-edit-plural-translation-other", "", ' rows="2"') ?>
+ </div>
+ <input type="submit" name="l10n-edit-save" value="<?= t("Save translation") ?>"/>
+ </form>
</div>
</div>
<script type="text/javascript">
var l10n_client_data = <?= json_encode($string_list) ?>;
+ var plural_forms = <?= json_encode($plural_forms) ?>;
</script>
</div>
diff --git a/modules/gallery/views/move_tree.html.php b/modules/gallery/views/move_tree.html.php
index 91a2f9da..5f70cf67 100644
--- a/modules/gallery/views/move_tree.html.php
+++ b/modules/gallery/views/move_tree.html.php
@@ -1,5 +1,5 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<?= $parent->thumb_tag(array(), 25); ?>
+<?= $parent->thumb_img(array(), 25); ?>
<? if (!access::can("edit", $parent) || $source->is_descendant($parent)): ?>
<a href="javascript:load_tree('<?= $parent->id ?>',1)"> <?= p::clean($parent->title) ?> <?= t("(locked)") ?> </a>
<? else: ?>
@@ -8,7 +8,7 @@
<ul id="tree_<?= $parent->id ?>">
<? foreach ($children as $child): ?>
<li id="node_<?= $child->id ?>" class="node">
- <?= $child->thumb_tag(array(), 25); ?>
+ <?= $child->thumb_img(array(), 25); ?>
<? if (!access::can("edit", $child) || $source->is_descendant($child)): ?>
<a href="javascript:load_tree('<?= $child->id ?>',1)"> <?= p::clean($child->title) ?> <?= t("(locked)") ?></a>
<? else: ?>
diff --git a/modules/gallery/views/permissions_browse.html.php b/modules/gallery/views/permissions_browse.html.php
index 5cd9cf82..8bb2e830 100644
--- a/modules/gallery/views/permissions_browse.html.php
+++ b/modules/gallery/views/permissions_browse.html.php
@@ -27,7 +27,7 @@
<? if (!$htaccess_works): ?>
<ul id="gMessage">
<li class="gError">
- <?= t("Oh no! Your server needs a configuration change in order for you to hide photos! Ask your server administrator to set <a href=\"%url\"><i>AllowOverride FileInfo Options</i></a> to fix this.", array("url" => "http://httpd.apache.org/docs/2.0/mod/gallery.html#allowoverride")) ?>
+ <?= t("Oh no! Your server needs a configuration change in order for you to hide photos! Ask your server administrator to set <a %attrs><i>AllowOverride FileInfo Options</i></a> to fix this.", array("attrs" => "href=\"http://httpd.apache.org/docs/2.0/mod/core.html#allowoverride\" target=\"_blank\"")) ?>
</li>
</ul>
<? endif ?>
diff --git a/modules/gallery/views/simple_uploader.html.php b/modules/gallery/views/simple_uploader.html.php
index abda6d26..7b90c5be 100644
--- a/modules/gallery/views/simple_uploader.html.php
+++ b/modules/gallery/views/simple_uploader.html.php
@@ -3,7 +3,7 @@
<script type="text/javascript" src="<?= url::file("lib/swfupload/swfupload.queue.js") ?>"></script>
<!-- hack to set the title for the dialog -->
-<form id="gAddPhotosForm" action="<?= url::site("simple_uploader/finish") ?>">
+<form id="gAddPhotosForm" action="<?= url::site("simple_uploader/finish?csrf=$csrf") ?>">
<fieldset>
<legend> <?= t("Add photos to %album_title", array("album_title" => p::clean($item->title))) ?> </legend>
</fieldset>