1
0

Merge branch 'master' of git@github.com:gallery/gallery3-contrib.git

Conflicts:
	modules/basket/controllers/admin_configure.php
	modules/basket/controllers/admin_postage_bands.php
	modules/basket/controllers/admin_product_lines.php
	modules/basket/controllers/basket.php
	modules/basket/helpers/basket.php
	modules/basket/helpers/basket_event.php
	modules/basket/helpers/basket_installer.php
	modules/basket/helpers/postage_band.php
	modules/basket/helpers/product.php
	modules/basket/views/add_to_basket.html.php
	modules/basket/views/admin_configure.html.php
	modules/basket/views/admin_postage_bands.html.php
	modules/basket/views/admin_product_lines.html.php
	modules/basket/views/basket.html.php
	modules/basket/views/checkout.html.php
	modules/basket/views/confirm_order.html.php
	modules/basket/views/order_complete.html.php
	modules/basket/views/view_basket.html.php
	modules/favourites/controllers/favourites.php
	modules/gwtorganise/controllers/json_album.php
	modules/user_homes/helpers/user_homes_event.php
This commit is contained in:
Ben Smith 2010-09-03 19:37:38 +12:00
commit 964d67f878
1435 changed files with 93897 additions and 1401 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.DS_Store
tmp
*~
*.swp

BIN
client/Java/Demo.class Normal file

Binary file not shown.

50
client/Java/Demo.java Normal file
View File

@ -0,0 +1,50 @@
import java.util.ArrayList;
import java.util.List;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import com.google.gson.Gson;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
public class Demo {
public static final String BASE_URL = "http://example.com/gallery3/index.php";
public static final String USERNAME = "admin";
public static final String PASSWORD = "admin";
public static void main(String[] argv) throws java.io.UnsupportedEncodingException, java.io.IOException {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
Gson gson = new Gson();
// Get the REST API key
HttpPost post = new HttpPost(BASE_URL + "/rest");
ArrayList<NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("user", USERNAME));
nvps.add(new BasicNameValuePair("password", USERNAME));
post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
response = httpclient.execute(post);
String api_key = gson.fromJson(new BufferedReader(
new InputStreamReader(response.getEntity().getContent())).readLine(), String.class);
System.out.println("API Key:" + api_key);
// Get the JSON representation of the root album, which we know has id 1
HttpGet get = new HttpGet(BASE_URL + "/rest/item/1");
get.setHeader("X-Gallery-Request-Method", "GET");
get.setHeader("X-Gallery-Request-Key", api_key);
response = httpclient.execute(get);
System.out.println(
"Response: " + new BufferedReader(new InputStreamReader(response.getEntity().getContent())).readLine());
}
}

10
client/Java/README Normal file
View File

@ -0,0 +1,10 @@
This is very, very rough sample code for how to do some Java REST
requests. To run this code:
1) Edit Demo.java and set the BASE_URL to your Gallery3 install.
2) Edit USERNAME and PASSWORD as appropriate
3) In a shell, do "sh build.sh"
4) In a shell, do "sh run.sh"
Note that there is NO error checking, so if something goes wrong
you'll have to debug it.

1
client/Java/build.sh Normal file
View File

@ -0,0 +1 @@
javac -classpath lib/httpclient-4.0.1.jar:lib/httpcore-4.0.1.jar:lib/gson-1.4.jar Demo.java

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

1
client/Java/run.sh Normal file
View File

@ -0,0 +1 @@
java -classpath lib/httpclient-4.0.1.jar:lib/httpcore-4.0.1.jar:lib/commons-logging-api-1.1.1.jar:lib/gson-1.4.jar:. Demo

205
client/PHP/Gallery3.php Normal file
View File

@ -0,0 +1,205 @@
<?php
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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.
*/
include("Mail.php");
include("Mail/mime.php");
include("HTTP/Request.php");
class Gallery3 {
var $url;
var $token;
var $data;
var $file;
protected $original_entity;
/**
* Connect to a remote Gallery3 instance
*
* @param string Gallery 3 API url, eg http://example.com/gallery3/index.php/rest
* @param string username
* @param string password
* @return string authentication token
*/
static function login($url, $user, $pass) {
$response = Gallery3_Helper::request(
"post", $url, null, array("user" => $user, "password" => $pass));
return $response;
}
/**
* Construct a new Gallery3 instance associated with a remote resource
* @param string remote url
* @param string authentication token
* @return object Gallery3
*/
static function factory($url=null, $token=null) {
$obj = new Gallery3();
$obj->token = $token;
$obj->url = $url;
if ($url && $token) {
$obj->load();
}
return $obj;
}
/**
* Constructor.
*/
public function __construct() {
$this->data = new stdClass();
$this->token = null;
$this->url = null;
}
/**
* Set a value on the remote resource's entity. You must call save for it to take effect.
*
* @param string key
* @param string value
* @return object Gallery3
* @chainable
*/
public function set($key, $value) {
$this->data->entity->$key = $value;
return $this;
}
/**
* Replace the members for the remote resource
*
* @param array members
* @return object Gallery3
* @chainable
*/
public function set_members($members) {
$this->data->members = $members;
return $this;
}
/**
* Attach a file to the remote resource.
*
* @param string path to a local file (eg: /tmp/foo.jpg)
* @return object Gallery3
*/
public function set_file($file) {
$this->file = $file;
return $this;
}
/**
* Save any local changes made to this resource. If this is an existing resource, we'll return
* the resource itself. If we're creating a new resource, return the newly created resource.
*
* @return object Gallery3
*/
public function create($url, $token) {
if (!is_string($url)) {
throw new Gallery3_Exception("Invalid url: " . var_export($url));
}
$response = Gallery3_Helper::request(
"post", $url, $token, array("entity" => $this->data->entity), $this->file);
$this->url = $response->url;
$this->token = $token;
return $this->load();
}
/**
* Save any local changes made to this resource. If this is an existing resource, we'll return
* the resource itself. If we're creating a new resource, return the newly created resource.
*
* @return object Gallery3
*/
public function save() {
$data = array();
$data["entity"] = array_diff((array)$this->data->entity, $this->original_entity);
if (isset($this->data->members)) {
$data["members"] = $this->data->members;
}
if ($this->file) {
$response = Gallery3_Helper::request("put", $this->url, $this->token, $data, $this->file);
} else {
$response = Gallery3_Helper::request("put", $this->url, $this->token, $data);
}
return $this->load();
}
/**
* Delete the remote resource.
*
* @return object Gallery3
*/
public function delete() {
Gallery3_Helper::request("delete", $this->url, $this->token);
$this->data = array();
$this->url = null;
return $this;
}
/**
* Reload the resource from a given url. This is useful after the remote resource has been
* modified.
*
* @return object Gallery3
*/
public function load() {
$response = Gallery3_Helper::request("get", $this->url, $this->token);
$this->data = $response;
$this->original_entity = isset($response->entity) ? (array)$response->entity : null;
return $this;
}
}
class Gallery3_Helper {
static function request($method, $url, $token=null, $params=array(), $file=null) {
$req = new HTTP_Request($url);
$req->setMethod($method == "get" ? HTTP_REQUEST_METHOD_GET : HTTP_REQUEST_METHOD_POST);
$req->addHeader("X-Gallery-Request-Method", $method);
if ($token) {
$req->addHeader("X-Gallery-Request-Key", $token);
}
foreach ($params as $key => $value) {
$req->addPostData($key, is_string($value) ? $value : json_encode($value));
}
if ($file) {
$req->addFile("file", $file, mime_content_type($file));
}
$req->sendRequest();
switch ($req->getResponseCode()) {
case 200:
case 201:
return json_decode($req->getResponseBody());
case 403:
throw new Gallery3_Forbidden_Exception($req->getResponseBody());
default:
throw new Gallery3_Exception($req->getResponseBody());
}
}
}
class Gallery3_Exception extends Exception {
}
class Gallery3_Forbidden_Exception extends Gallery3_Exception {
}

112
client/PHP/example.php Normal file
View File

@ -0,0 +1,112 @@
<?
include("Gallery3.php");
$SITE_URL = "http://example.com/gallery3/index.php/rest";
$USER = "admin";
$PASSWORD = "admin";
if (file_exists("local_config.php")) {
include("local_config.php");
}
alert("Connect to $SITE_URL");
$auth = Gallery3::login($SITE_URL, $USER, $PASSWORD);
$root = Gallery3::factory("$SITE_URL/item/1", $auth);
$tags = Gallery3::factory("$SITE_URL/tags", $auth);
$comments = Gallery3::factory("$SITE_URL/comments", $auth);
$tag = Gallery3::factory()
->set("name", "My Tag")
->create($tags->url, $auth);
alert("Created tag: <b>{$tag->url}</b>");
$album = Gallery3::factory()
->set("type", "album")
->set("name", "Sample Album")
->set("title", "This is my Sample Album")
->create($root->url, $auth);
alert("Created album: <b>{$album->url} {$album->data->entity->title}</b>");
alert("Modify the album");
$album
->set("title", "This is the new title")
->save();
alert("New title: <b>{$album->data->entity->title}</b>");
for ($i = 0; $i < 2; $i++) {
$photo = Gallery3::factory()
->set("type", "photo")
->set("name", "Sample Photo.png")
->set("title", "Sample Photo")
->set_file("test1.png")
->create($album->url, $auth);
alert("Uploaded photo: <b>{$photo->url}</b>");
}
$album->load();
alert("Album members: <b>" . join(", ", $album->data->members) . "</b>");
alert("Replace the data file");
$photo->set_file("test2.png")
->save();
$comment = Gallery3::factory()
->set("item", $album->data->members[0])
->set("type", "comment")
->set("text", "This is a random comment-- whee!")
->create($comments->url, $auth);
alert("Comment: <b>{$comment->url}</b>");
alert("Reorder the album");
$album
->set_members(array($album->data->members[1], $album->data->members[0]))
->set("sort_column", "weight")
->save();
alert("New order: <b>" . join(", ", $album->data->members) . "</b>");
alert("Search for the photo");
$photos = Gallery3::factory($root->url, $auth)
->set("name", "Sample")
->load();
alert("Found: {$photos->data->members[0]}");
alert("Grab a random photo");
$photos = Gallery3::factory("{$root->url}?random=true", $auth)
->load();
alert("Found: {$photos->data->members[0]}");
alert("Tag the album (using the album's relationships: {$album->data->relationships->tags->url})");
$tag_relationship1 = Gallery3::factory()
->set("tag", $tag->url)
->set("item", $root->url)
->create($album->data->relationships->tags->url, $auth);
alert("Tag: {$tag_relationship1->url}");
alert("Tag the photo (using the tag's relationships: {$tag->data->relationships->items->url})");
$tag_relationship2 = Gallery3::factory()
->set("tag", $tag->url)
->set("item", $photo->url)
->create($tag->data->relationships->items->url, $auth);
alert("Tag: {$tag_relationship2->url}");
alert("Un-tag the photo");
$tag_relationship2->delete();
$tag->load();
alert("1 remaining tag: <b>{$tag->data->relationships->items->members[0]}</b>");
alert("Delete the album and tag");
$album->delete();
$tag->delete();
alert("Done!");
function alert($msg) {
print "$msg <br/>\n";
flush();
}
?>

BIN
client/PHP/test1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
client/PHP/test2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -0,0 +1,57 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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_adsense_Controller extends Admin_Controller {
public function index() {
$view = new Admin_View("admin.html");
$view->page_title = t("Adsense settings");
$view->content = new View("admin_adsense.html");
$view->content->form = $this->_get_admin_form();
print $view;
}
public function save() {
access::verify_csrf();
$form = $this->_get_admin_form();
if ($form->validate()) {
module::set_var("adsense", "code", $form->adsense->code->value);
module::set_var("adsense", "location", $form->adsense->location->value);
message::success(t("Adsense settings updated"));
url::redirect("admin/adsense");
} else {
print $form;
}
}
private function _get_admin_form() {
$form = new Forge("admin/adsense/save", "", "post", array("id" => "g-adsense-admin-form"));
$adsense_settings = $form->group("adsense")->label(t("Adsense settings"));
$adsense_settings->textarea("code")->label(t("Adsense code"))
->value(module::get_var("adsense", "code"));
$adsense_settings->dropdown("location")
->label(t("Where should the ads be displayed?"))
->options(array("header" => t("In the header"),
"sidebar" => t("In the sidebar"),
"footer" => t("In the footer")))
->selected(module::get_var("adsense", "location"));
$adsense_settings->submit("save")->value(t("Save"));
return $form;
}
}

View File

@ -0,0 +1,39 @@
<?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 adsense_block_Core {
static function get_site_list() {
return array("adsense" => t("Adsense"));
}
static function get($block_id, $theme) {
$block = "";
switch ($block_id) {
case "adsense":
if (module::get_var("adsense", "location") == "sidebar") {
$block = new Block();
$block->css_id = "g-adsense";
$block->title = t("Adsense");
$block->content = new View("adsense_block.html");
}
break;
}
return $block;
}
}

View File

@ -0,0 +1,28 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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 adsense_event_Core {
static function admin_menu($menu, $theme) {
$menu->get("settings_menu")
->append(Menu::factory("link")
->id("adsense_menu")
->label(t("Adsense"))
->url(url::site("admin/adsense")));
}
}

View File

@ -0,0 +1,54 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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.
*/
//header_bottom or footer
class adsense_theme {
static function header_bottom($theme) {
if(module::get_var("adsense","location") == "header") {
$code = module::get_var("adsense", "code");
if (!$code) {
return;
}
$google_code = '
<script type="text/javascript">' . $code . '</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>';
return $google_code;
}
}
static function footer($theme) {
if(module::get_var("adsense","location") == "footer") {
$code = module::get_var("adsense", "code");
if (!$code) {
return;
}
$google_code = '
<script type="text/javascript">' . $code . '</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>';
return $google_code;
}
}
}

View File

@ -0,0 +1,3 @@
name = "Adsense"
description = "Display Google Adsense ads"
version = 1

View File

@ -0,0 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<div class="g-block">
<h1> <?= t("Adsense settings") ?> </h1>
<div class="g-block-content">
<?= $form ?>
</div>
</div>

View File

@ -0,0 +1,17 @@
<?php
defined("SYSPATH") or die("No direct script access.");
if(module::get_var("adsense","location") == "sidebar") {
$code = module::get_var("adsense", "code");
if (!$code) {
return;
}
$google_code = '
<script type="text/javascript">' . $code . '</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>';
echo $google_code;
}
?>

View File

@ -36,7 +36,7 @@ class Atom_Entry_Core extends Atom_Base {
}
public function content($text, $type="html") {
$content = $this->dom->createElement("content", html::specialchars($text));
$content = $this->dom->createElement("content", html::chars($text));
$content->setAttribute("type", $type);
$this->element->appendChild($content);
return $this;

View File

@ -27,7 +27,7 @@ class Gallery_Atom_Entry_Core extends Atom_Entry {
parent::__construct("entry");
/* Set feed ID and self link. */
$this->id(html::specialchars(url::abs_current()));
$this->id(html::chars(url::abs_current()));
$this->link()
->rel("self")
->href(url::abs_current());

View File

@ -27,7 +27,7 @@ class Gallery_Atom_Feed_Core extends Atom_Feed {
parent::__construct("feed");
/* Set feed ID and self link. */
$this->id(html::specialchars(url::abs_current()));
$this->id(html::chars(url::abs_current()));
$this->link()
->rel("self")
->href(url::abs_current());

View File

@ -0,0 +1,68 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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 autorotate {
static function rotate_item($item) {
require_once(MODPATH . 'autorotate/lib/pel/PelDataWindow.php');
require_once(MODPATH . 'autorotate/lib/pel/PelJpeg.php');
require_once(MODPATH . 'autorotate/lib/pel/PelTiff.php');
// Only try to rotate photos based on EXIF
if ($item->is_photo() && $item->mime_type == "image/jpeg") {
require_once(MODPATH . "exif/lib/exif.php");
$exif_raw = read_exif_data_raw($item->file_path(), false);
if (isset($exif_raw['ValidEXIFData'])) {
$orientation = $exif_raw["IFD0"]["Orientation"];
$degrees = 0;
if ($orientation == '3: Upside-down') {
$degrees = 180;
}
else if ($orientation == '8: 90 deg CW') {
$degrees = -90;
}
else if ($orientation == '6: 90 deg CCW') {
$degrees = 90;
}
if($degrees) {
$tmpfile = tempnam(TMPPATH, "rotate");
gallery_graphics::rotate($item->file_path(), $tmpfile, array("degrees" => $degrees));
// Update EXIF info
$data = new PelDataWindow(file_get_contents($tmpfile));
if (PelJpeg::isValid($data)) {
$jpeg = $file = new PelJpeg();
$jpeg->load($data);
$exif = $jpeg->getExif();
if($exif !== null) {
$tiff = $exif->getTiff();
$ifd0 = $tiff->getIfd();
$orientation = $ifd0->getEntry(PelTag::ORIENTATION);
$orientation->setValue(1);
file_put_contents($tmpfile, $file->getBytes());
}
}
$item->set_data_file($tmpfile);
$item->save();
unlink($tmpfile);
}
}
}
return;
}
}

View File

@ -0,0 +1,32 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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 autorotate_event_Core {
// The assumption is that the exception was logged at a lower level, but we
// don't want to screw up the processing that was generating the notification
// so we don't pass the exception up the call stack
static function add_photos_form_completed($item, $form) {
try {
autorotate::rotate_item($item);
} catch (Exception $e) {
Kohana_Log::add("error", "@todo autorotate_event::item_created() failed");
Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString());
}
}
}

View File

@ -0,0 +1,42 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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 autorotate_installer {
static function install() {
module::set_version("autorotate", 1);
}
static function upgrade($version) {
if ($version == 1) {
module::set_version("autorotate", $version = 1);
}
}
static function deactivate() {
site_status::clear("autorotate_needs_exif");
}
static function can_activate() {
$messages = array();
if (!module::is_active("exif")) {
$messages["warn"][] = t("The autorotate module requires the EXIF module.");
}
return $messages;
}
}

View File

@ -0,0 +1,337 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005, 2006 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: Pel.php 463 2006-11-18 22:25:24Z mgeisler $ */
/**
* Miscellaneous stuff for the overall behavior of PEL.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 463 $
* @date $Date: 2006-11-18 23:25:24 +0100 (Sat, 18 Nov 2006) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/* Initialize Gettext, if available. This must be done before any
* part of PEL calls Pel::tra() or Pel::fmt() --- this is ensured if
* every piece of code using those two functions require() this file.
*
* If Gettext is not available, wrapper functions will be created,
* allowing PEL to function, but without any translations.
*
* The PEL translations are stored in './locale'. It is important to
* use an absolute path here because the lookups will be relative to
* the current directory. */
if (function_exists('dgettext')) {
bindtextdomain('pel', dirname(__FILE__) . '/locale');
} else {
/**
* Pretend to lookup a message in a specific domain.
*
* This is just a stub which will return the original message
* untranslated. The function will only be defined if the Gettext
* extension has not already defined it.
*
* @param string $domain the domain.
*
* @param string $str the message to be translated.
*
* @return string the original, untranslated message.
*/
function dgettext($domain, $str) {
return $str;
}
}
/**
* Class with miscellaneous static methods.
*
* This class will contain various methods that govern the overall
* behavior of PEL.
*
* Debugging output from PEL can be turned on and off by assigning
* true or false to {@link Pel::$debug}.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class Pel {
/**
* Flag for controlling debug information.
*
* The methods producing debug information ({@link debug()} and
* {@link warning()}) will only output something if this variable is
* set to true.
*
* @var boolean
*/
private static $debug = false;
/**
* Flag for strictness of parsing.
*
* If this variable is set to true, then most errors while loading
* images will result in exceptions being thrown. Otherwise a
* warning will be emitted (using {@link Pel::warning}) and the
* exceptions will be appended to {@link Pel::$exceptions}.
*
* Some errors will still be fatal and result in thrown exceptions,
* but an effort will be made to skip over as much garbage as
* possible.
*
* @var boolean
*/
private static $strict = false;
/**
* Stored exceptions.
*
* When {@link Pel::$strict} is set to false exceptions will be
* accumulated here instead of being thrown.
*/
private static $exceptions = array();
/**
* Return list of stored exceptions.
*
* When PEL is parsing in non-strict mode, it will store most
* exceptions instead of throwing them. Use this method to get hold
* of them when a call returns.
*
* Code for using this could look like this:
*
* <code>
* Pel::setStrictParsing(true);
* Pel::clearExceptions();
*
* $jpeg = new PelJpeg($file);
*
* // Check for exceptions.
* foreach (Pel::getExceptions() as $e) {
* printf("Exception: %s\n", $e->getMessage());
* if ($e instanceof PelEntryException) {
* // Warn about entries that couldn't be loaded.
* printf("Warning: Problem with %s.\n",
* PelTag::getName($e->getType(), $e->getTag()));
* }
* }
* </code>
*
* This gives applications total control over the amount of error
* messages shown and (hopefully) provides the necessary information
* for proper error recovery.
*
* @return array the exceptions.
*/
static function getExceptions() {
return self::$exceptions;
}
/**
* Clear list of stored exceptions.
*
* Use this function before a call to some method if you intend to
* check for exceptions afterwards.
*/
static function clearExceptions() {
self::$exceptions = array();
}
/**
* Conditionally throw an exception.
*
* This method will throw the passed exception when strict parsing
* in effect (see {@link setStrictParsing()}). Otherwise the
* exception is stored (it can be accessed with {@link
* getExceptions()}) and a warning is issued (with {@link
* Pel::warning}).
*
* @param PelException $e the exceptions.
*/
static function maybeThrow(PelException $e) {
if (self::$strict) {
throw $e;
} else {
self::$exceptions[] = $e;
self::warning('%s (%s:%s)', $e->getMessage(),
basename($e->getFile()), $e->getLine());
}
}
/**
* Enable/disable strict parsing.
*
* If strict parsing is enabled, then most errors while loading
* images will result in exceptions being thrown. Otherwise a
* warning will be emitted (using {@link Pel::warning}) and the
* exceptions will be stored for later use via {@link
* getExceptions()}.
*
* Some errors will still be fatal and result in thrown exceptions,
* but an effort will be made to skip over as much garbage as
* possible.
*
* @param boolean $flag use true to enable strict parsing, false to
* diable.
*/
function setStrictParsing($flag) {
self::$strict = $flag;
}
/**
* Get current setting for strict parsing.
*
* @return boolean true if strict parsing is in effect, false
* otherwise.
*/
function getStrictParsing() {
return self::$strict;
}
/**
* Enable/disable debugging output.
*
* @param boolean $flag use true to enable debug output, false to
* diable.
*/
function setDebug($flag) {
self::$debug = $flag;
}
/**
* Get current setting for debug output.
*
* @return boolean true if debug is enabled, false otherwise.
*/
function getDebug() {
return self::$debug;
}
/**
* Conditionally output debug information.
*
* This method works just like printf() except that it always
* terminates the output with a newline, and that it only outputs
* something if the {@link Pel::$debug} is true.
*
* @param string $format the format string.
*
* @param mixed $args,... any number of arguments can be given. The
* arguments will be available for the format string as usual with
* sprintf().
*/
static function debug() {
if (self::$debug) {
$args = func_get_args();
$str = array_shift($args);
vprintf($str . "\n", $args);
}
}
/**
* Conditionally output a warning.
*
* This method works just like printf() except that it prepends the
* output with the string 'Warning: ', terminates the output with a
* newline, and that it only outputs something if the PEL_DEBUG
* defined to some true value.
*
* @param string $format the format string.
*
* @param mixed $args,... any number of arguments can be given. The
* arguments will be available for the format string as usual with
* sprintf().
*/
static function warning() {
if (self::$debug) {
$args = func_get_args();
$str = array_shift($args);
vprintf('Warning: ' . $str . "\n", $args);
}
}
/**
* Translate a string.
*
* This static function will use Gettext to translate a string. By
* always using this function for static string one is assured that
* the translation will be taken from the correct text domain.
* Dynamic strings should be passed to {@link fmt} instead.
*
* @param string the string that should be translated.
*
* @return string the translated string, or the original string if
* no translation could be found.
*/
static function tra($str) {
return dgettext('pel', $str);
}
/**
* Translate and format a string.
*
* This static function will first use Gettext to translate a format
* string, which will then have access to any extra arguments. By
* always using this function for dynamic string one is assured that
* the translation will be taken from the correct text domain. If
* the string is static, use {@link tra} instead as it will be
* faster.
*
* @param string $format the format string. This will be translated
* before being used as a format string.
*
* @param mixed $args,... any number of arguments can be given. The
* arguments will be available for the format string as usual with
* sprintf().
*
* @return string the translated string, or the original string if
* no translation could be found.
*/
static function fmt() {
$args = func_get_args();
$str = array_shift($args);
return vsprintf(dgettext('pel', $str), $args);
}
}
?>

View File

@ -0,0 +1,397 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelConvert.php 387 2005-10-05 11:02:52Z mgeisler $ */
/**
* Routines for converting back and forth between bytes and integers.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 387 $
* @date $Date: 2005-10-05 13:02:52 +0200 (Wed, 05 Oct 2005) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**
* Conversion functions to and from bytes and integers.
*
* The functions found in this class are used to convert bytes into
* integers of several sizes ({@link bytesToShort}, {@link
* bytesToLong}, and {@link bytesToRational}) and convert integers of
* several sizes into bytes ({@link shortToBytes} and {@link
* longToBytes}).
*
* All the methods are static and they all rely on an argument that
* specifies the byte order to be used, this must be one of the class
* constants {@link LITTLE_ENDIAN} or {@link BIG_ENDIAN}. These
* constants will be referred to as the pseudo type PelByteOrder
* throughout the documentation.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelConvert {
/**
* Little-endian (Intel) byte order.
*
* Data stored in little-endian byte order store the least
* significant byte first, so the number 0x12345678 becomes 0x78
* 0x56 0x34 0x12 when stored with little-endian byte order.
*/
const LITTLE_ENDIAN = true;
/**
* Big-endian (Motorola) byte order.
*
* Data stored in big-endian byte order store the most significant
* byte first, so the number 0x12345678 becomes 0x12 0x34 0x56 0x78
* when stored with big-endian byte order.
*/
const BIG_ENDIAN = false;
/**
* Convert an unsigned short into two bytes.
*
* @param int the unsigned short that will be converted. The lower
* two bytes will be extracted regardless of the actual size passed.
*
* @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link
* BIG_ENDIAN}.
*
* @return string the bytes representing the unsigned short.
*/
static function shortToBytes($value, $endian) {
if ($endian == self::LITTLE_ENDIAN)
return chr($value) . chr($value >> 8);
else
return chr($value >> 8) . chr($value);
}
/**
* Convert a signed short into two bytes.
*
* @param int the signed short that will be converted. The lower
* two bytes will be extracted regardless of the actual size passed.
*
* @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link
* BIG_ENDIAN}.
*
* @return string the bytes representing the signed short.
*/
static function sShortToBytes($value, $endian) {
/* We can just use shortToBytes, since signed shorts fits well
* within the 32 bit signed integers used in PHP. */
return self::shortToBytes($value, $endian);
}
/**
* Convert an unsigned long into four bytes.
*
* Because PHP limits the size of integers to 32 bit signed, one
* cannot really have an unsigned integer in PHP. But integers
* larger than 2^31-1 will be promoted to 64 bit signed floating
* point numbers, and so such large numbers can be handled too.
*
* @param int the unsigned long that will be converted. The
* argument will be treated as an unsigned 32 bit integer and the
* lower four bytes will be extracted. Treating the argument as an
* unsigned integer means that the absolute value will be used. Use
* {@link sLongToBytes} to convert signed integers.
*
* @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link
* BIG_ENDIAN}.
*
* @return string the bytes representing the unsigned long.
*/
static function longToBytes($value, $endian) {
/* We cannot convert the number to bytes in the normal way (using
* shifts and modulo calculations) because the PHP operator >> and
* function chr() clip their arguments to 2^31-1, which is the
* largest signed integer known to PHP. But luckily base_convert
* handles such big numbers. */
$hex = str_pad(base_convert($value, 10, 16), 8, '0', STR_PAD_LEFT);
if ($endian == self::LITTLE_ENDIAN)
return (chr(hexdec($hex{6} . $hex{7})) .
chr(hexdec($hex{4} . $hex{5})) .
chr(hexdec($hex{2} . $hex{3})) .
chr(hexdec($hex{0} . $hex{1})));
else
return (chr(hexdec($hex{0} . $hex{1})) .
chr(hexdec($hex{2} . $hex{3})) .
chr(hexdec($hex{4} . $hex{5})) .
chr(hexdec($hex{6} . $hex{7})));
}
/**
* Convert a signed long into four bytes.
*
* @param int the signed long that will be converted. The argument
* will be treated as a signed 32 bit integer, from which the lower
* four bytes will be extracted.
*
* @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link
* BIG_ENDIAN}.
*
* @return string the bytes representing the signed long.
*/
static function sLongToBytes($value, $endian) {
/* We can convert the number into bytes in the normal way using
* shifts and modulo calculations here (in contrast with
* longToBytes) because PHP automatically handles 32 bit signed
* integers for us. */
if ($endian == self::LITTLE_ENDIAN)
return (chr($value) .
chr($value >> 8) .
chr($value >> 16) .
chr($value >> 24));
else
return (chr($value >> 24) .
chr($value >> 16) .
chr($value >> 8) .
chr($value));
}
/**
* Extract an unsigned byte from a string of bytes.
*
* @param string the bytes.
*
* @param int the offset. The byte found at the offset will be
* returned as an integer. The must be at least one byte available
* at offset.
*
* @return int the unsigned byte found at offset, e.g., an integer
* in the range 0 to 255.
*/
static function bytesToByte($bytes, $offset) {
return ord($bytes{$offset});
}
/**
* Extract a signed byte from bytes.
*
* @param string the bytes.
*
* @param int the offset. The byte found at the offset will be
* returned as an integer. The must be at least one byte available
* at offset.
*
* @return int the signed byte found at offset, e.g., an integer in
* the range -128 to 127.
*/
static function bytesToSByte($bytes, $offset) {
$n = self::bytesToByte($bytes, $offset);
if ($n > 127)
return $n - 256;
else
return $n;
}
/**
* Extract an unsigned short from bytes.
*
* @param string the bytes.
*
* @param int the offset. The short found at the offset will be
* returned as an integer. There must be at least two bytes
* available beginning at the offset given.
*
* @return int the unsigned short found at offset, e.g., an integer
* in the range 0 to 65535.
*
* @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link
* BIG_ENDIAN}.
*/
static function bytesToShort($bytes, $offset, $endian) {
if ($endian == self::LITTLE_ENDIAN)
return (ord($bytes{$offset+1}) * 256 +
ord($bytes{$offset}));
else
return (ord($bytes{$offset}) * 256 +
ord($bytes{$offset+1}));
}
/**
* Extract a signed short from bytes.
*
* @param string the bytes.
*
* @param int the offset. The short found at offset will be returned
* as an integer. There must be at least two bytes available
* beginning at the offset given.
*
* @return int the signed byte found at offset, e.g., an integer in
* the range -32768 to 32767.
*
* @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link
* BIG_ENDIAN}.
*/
static function bytesToSShort($bytes, $offset, $endian) {
$n = self::bytesToShort($bytes, $offset, $endian);
if ($n > 32767)
return $n - 65536;
else
return $n;
}
/**
* Extract an unsigned long from bytes.
*
* @param string the bytes.
*
* @param int the offset. The long found at offset will be returned
* as an integer. There must be at least four bytes available
* beginning at the offset given.
*
* @return int the unsigned long found at offset, e.g., an integer
* in the range 0 to 4294967295.
*
* @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link
* BIG_ENDIAN}.
*/
static function bytesToLong($bytes, $offset, $endian) {
if ($endian == self::LITTLE_ENDIAN)
return (ord($bytes{$offset+3}) * 16777216 +
ord($bytes{$offset+2}) * 65536 +
ord($bytes{$offset+1}) * 256 +
ord($bytes{$offset}));
else
return (ord($bytes{$offset}) * 16777216 +
ord($bytes{$offset+1}) * 65536 +
ord($bytes{$offset+2}) * 256 +
ord($bytes{$offset+3}));
}
/**
* Extract a signed long from bytes.
*
* @param string the bytes.
*
* @param int the offset. The long found at offset will be returned
* as an integer. There must be at least four bytes available
* beginning at the offset given.
*
* @return int the signed long found at offset, e.g., an integer in
* the range -2147483648 to 2147483647.
*
* @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link
* BIG_ENDIAN}.
*/
static function bytesToSLong($bytes, $offset, $endian) {
$n = self::bytesToLong($bytes, $offset, $endian);
if ($n > 2147483647)
return $n - 4294967296;
else
return $n;
}
/**
* Extract an unsigned rational from bytes.
*
* @param string the bytes.
*
* @param int the offset. The rational found at offset will be
* returned as an array. There must be at least eight bytes
* available beginning at the offset given.
*
* @return array the unsigned rational found at offset, e.g., an
* array with two integers in the range 0 to 4294967295.
*
* @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link
* BIG_ENDIAN}.
*/
static function bytesToRational($bytes, $offset, $endian) {
return array(self::bytesToLong($bytes, $offset, $endian),
self::bytesToLong($bytes, $offset+4, $endian));
}
/**
* Extract a signed rational from bytes.
*
* @param string the bytes.
*
* @param int the offset. The rational found at offset will be
* returned as an array. There must be at least eight bytes
* available beginning at the offset given.
*
* @return array the signed rational found at offset, e.g., an array
* with two integers in the range -2147483648 to 2147483647.
*
* @param PelByteOrder one of {@link LITTLE_ENDIAN} and {@link
* BIG_ENDIAN}.
*/
static function bytesToSRational($bytes, $offset, $endian) {
return array(self::bytesToSLong($bytes, $offset, $endian),
self::bytesToSLong($bytes, $offset+4, $endian));
}
/**
* Format bytes for dumping.
*
* This method is for debug output, it will format a string as a
* hexadecimal dump suitable for display on a terminal. The output
* is printed directly to standard out.
*
* @param string the bytes that will be dumped.
*
* @param int the maximum number of bytes to dump. If this is left
* out (or left to the default of 0), then the entire string will be
* dumped.
*/
static function bytesToDump($bytes, $max = 0) {
$s = strlen($bytes);
if ($max > 0)
$s = min($max, $s);
$line = 24;
for ($i = 0; $i < $s; $i++) {
printf('%02X ', ord($bytes{$i}));
if (($i+1) % $line == 0)
print("\n");
}
print("\n");
}
}
?>

View File

@ -0,0 +1,525 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelDataWindow.php 387 2005-10-05 11:02:52Z mgeisler $ */
/**
* A container for bytes with a limited window of accessible bytes.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 387 $
* @date $Date: 2005-10-05 13:02:52 +0200 (Wed, 05 Oct 2005) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('PelException.php');
require_once('PelConvert.php');
/**#@-*/
/**
* An exception thrown when an invalid offset is encountered.
*
* @package PEL
* @subpackage Exception
*/
class PelDataWindowOffsetException extends PelException {}
/**
* An exception thrown when an invalid window is encountered.
*
* @package PEL
* @subpackage Exception
*/
class PelDataWindowWindowException extends PelException {}
/**
* The window.
*
* @package PEL
*/
class PelDataWindow {
/**
* The data held by this window.
*
* The string can contain any kind of data, including binary data.
*
* @var string
*/
private $data = '';
/**
* The byte order currently in use.
*
* This will be the byte order used when data is read using the for
* example the {@link getShort} function. It must be one of {@link
* PelConvert::LITTLE_ENDIAN} and {@link PelConvert::BIG_ENDIAN}.
*
* @var PelByteOrder
* @see setByteOrder, getByteOrder
*/
private $order;
/**
* The start of the current window.
*
* All offsets used for access into the data will count from this
* offset, effectively limiting access to a window starting at this
* byte.
*
* @var int
* @see setWindowStart
*/
private $start = 0;
/**
* The size of the current window.
*
* All offsets used for access into the data will be limited by this
* variable. A valid offset must be strictly less than this
* variable.
*
* @var int
* @see setWindowSize
*/
private $size = 0;
/**
* Construct a new data window with the data supplied.
*
* @param string the data that this window will contain. The data
* will be copied into the new data window.
*
* @param boolean the initial byte order of the window. This must
* be either {@link PelConvert::LITTLE_ENDIAN} or {@link
* PelConvert::BIG_ENDIAN}. This will be used when integers are
* read from the data, and it can be changed later with {@link
* setByteOrder()}.
*/
function __construct($d = '', $e = PelConvert::LITTLE_ENDIAN) {
$this->data = $d;
$this->order = $e;
$this->size = strlen($d);
}
/**
* Get the size of the data window.
*
* @return int the number of bytes covered by the window. The
* allowed offsets go from 0 up to this number minus one.
*
* @see getBytes()
*/
function getSize() {
return $this->size;
}
/**
* Change the byte order of the data.
*
* @param PelByteOrder the new byte order. This must be either
* {@link PelConvert::LITTLE_ENDIAN} or {@link
* PelConvert::BIG_ENDIAN}.
*/
function setByteOrder($o) {
$this->order = $o;
}
/**
* Get the currently used byte order.
*
* @return PelByteOrder this will be either {@link
* PelConvert::LITTLE_ENDIAN} or {@link PelConvert::BIG_ENDIAN}.
*/
function getByteOrder() {
return $this->order;
}
/* Move the start of the window forward.
*
* @param int the new start of the window. All new offsets will be
* calculated from this new start offset, and the size of the window
* will shrink to keep the end of the window in place.
*/
function setWindowStart($start) {
if ($start < 0 || $start > $this->size)
throw new PelDataWindowWindowException('Window [%d, %d] does ' .
'not fit in window [0, %d]',
$start, $this->size, $this->size);
$this->start += $start;
$this->size -= $start;
}
/**
* Adjust the size of the window.
*
* The size can only be made smaller.
*
* @param int the desired size of the window. If the argument is
* negative, the window will be shrunk by the argument.
*/
function setWindowSize($size) {
if ($size < 0)
$size += $this->size;
if ($size < 0 || $size > $this->size)
throw new PelDataWindowWindowException('Window [0, %d] ' .
'does not fit in window [0, %d]',
$size, $this->size);
$this->size = $size;
}
/**
* Make a new data window with the same data as the this window.
*
* @param mixed if an integer is supplied, then it will be the start
* of the window in the clone. If left unspecified, then the clone
* will inherit the start from this object.
*
* @param mixed if an integer is supplied, then it will be the size
* of the window in the clone. If left unspecified, then the clone
* will inherit the size from this object.
*
* @return PelDataWindow a new window that operates on the same data
* as this window, but (optionally) with a smaller window size.
*/
function getClone($start = false, $size = false) {
$c = clone $this;
if (is_int($start))
$c->setWindowStart($start);
if (is_int($size))
$c->setWindowSize($size);
return $c;
}
/**
* Validate an offset against the current window.
*
* @param int the offset to be validated. If the offset is negative
* or if it is greater than or equal to the current window size,
* then a {@link PelDataWindowOffsetException} is thrown.
*
* @return void if the offset is valid nothing is returned, if it is
* invalid a new {@link PelDataWindowOffsetException} is thrown.
*/
private function validateOffset($o) {
if ($o < 0 || $o >= $this->size)
throw new PelDataWindowOffsetException('Offset %d not within [%d, %d]',
$o, 0, $this->size-1);
}
/**
* Return some or all bytes visible in the window.
*
* This method works just like the standard {@link substr()}
* function in PHP with the exception that it works within the
* window of accessible bytes and does strict range checking.
*
* @param int the offset to the first byte returned. If a negative
* number is given, then the counting will be from the end of the
* window. Invalid offsets will result in a {@link
* PelDataWindowOffsetException} being thrown.
*
* @param int the size of the sub-window. If a negative number is
* given, then that many bytes will be omitted from the result.
*
* @return string a subset of the bytes in the window. This will
* always return no more than {@link getSize()} bytes.
*/
function getBytes($start = false, $size = false) {
if (is_int($start)) {
if ($start < 0)
$start += $this->size;
$this->validateOffset($start);
} else {
$start = 0;
}
if (is_int($size)) {
if ($size <= 0)
$size += $this->size - $start;
$this->validateOffset($start+$size);
} else {
$size = $this->size - $start;
}
return substr($this->data, $this->start + $start, $size);
}
/**
* Return an unsigned byte from the data.
*
* @param int the offset into the data. An offset of zero will
* return the first byte in the current allowed window. The last
* valid offset is equal to {@link getSize()}-1. Invalid offsets
* will result in a {@link PelDataWindowOffsetException} being
* thrown.
*
* @return int the unsigned byte found at offset.
*/
function getByte($o = 0) {
/* Validate the offset --- this throws an exception if offset is
* out of range. */
$this->validateOffset($o);
/* Translate the offset into an offset into the data. */
$o += $this->start;
/* Return an unsigned byte. */
return PelConvert::bytesToByte($this->data, $o);
}
/**
* Return a signed byte from the data.
*
* @param int the offset into the data. An offset of zero will
* return the first byte in the current allowed window. The last
* valid offset is equal to {@link getSize()}-1. Invalid offsets
* will result in a {@link PelDataWindowOffsetException} being
* thrown.
*
* @return int the signed byte found at offset.
*/
function getSByte($o = 0) {
/* Validate the offset --- this throws an exception if offset is
* out of range. */
$this->validateOffset($o);
/* Translate the offset into an offset into the data. */
$o += $this->start;
/* Return a signed byte. */
return PelConvert::bytesToSByte($this->data, $o);
}
/**
* Return an unsigned short read from the data.
*
* @param int the offset into the data. An offset of zero will
* return the first short available in the current allowed window.
* The last valid offset is equal to {@link getSize()}-2. Invalid
* offsets will result in a {@link PelDataWindowOffsetException}
* being thrown.
*
* @return int the unsigned short found at offset.
*/
function getShort($o = 0) {
/* Validate the offset+1 to see if we can safely get two bytes ---
* this throws an exception if offset is out of range. */
$this->validateOffset($o);
$this->validateOffset($o+1);
/* Translate the offset into an offset into the data. */
$o += $this->start;
/* Return an unsigned short. */
return PelConvert::bytesToShort($this->data, $o, $this->order);
}
/**
* Return a signed short read from the data.
*
* @param int the offset into the data. An offset of zero will
* return the first short available in the current allowed window.
* The last valid offset is equal to {@link getSize()}-2. Invalid
* offsets will result in a {@link PelDataWindowOffsetException}
* being thrown.
*
* @return int the signed short found at offset.
*/
function getSShort($o = 0) {
/* Validate the offset+1 to see if we can safely get two bytes ---
* this throws an exception if offset is out of range. */
$this->validateOffset($o);
$this->validateOffset($o+1);
/* Translate the offset into an offset into the data. */
$o += $this->start;
/* Return a signed short. */
return PelConvert::bytesToSShort($this->data, $o, $this->order);
}
/**
* Return an unsigned long read from the data.
*
* @param int the offset into the data. An offset of zero will
* return the first long available in the current allowed window.
* The last valid offset is equal to {@link getSize()}-4. Invalid
* offsets will result in a {@link PelDataWindowOffsetException}
* being thrown.
*
* @return int the unsigned long found at offset.
*/
function getLong($o = 0) {
/* Validate the offset+3 to see if we can safely get four bytes
* --- this throws an exception if offset is out of range. */
$this->validateOffset($o);
$this->validateOffset($o+3);
/* Translate the offset into an offset into the data. */
$o += $this->start;
/* Return an unsigned long. */
return PelConvert::bytesToLong($this->data, $o, $this->order);
}
/**
* Return a signed long read from the data.
*
* @param int the offset into the data. An offset of zero will
* return the first long available in the current allowed window.
* The last valid offset is equal to {@link getSize()}-4. Invalid
* offsets will result in a {@link PelDataWindowOffsetException}
* being thrown.
*
* @return int the signed long found at offset.
*/
function getSLong($o = 0) {
/* Validate the offset+3 to see if we can safely get four bytes
* --- this throws an exception if offset is out of range. */
$this->validateOffset($o);
$this->validateOffset($o+3);
/* Translate the offset into an offset into the data. */
$o += $this->start;
/* Return a signed long. */
return PelConvert::bytesToSLong($this->data, $o, $this->order);
}
/**
* Return an unsigned rational read from the data.
*
* @param int the offset into the data. An offset of zero will
* return the first rational available in the current allowed
* window. The last valid offset is equal to {@link getSize()}-8.
* Invalid offsets will result in a {@link
* PelDataWindowOffsetException} being thrown.
*
* @return array the unsigned rational found at offset. A rational
* number is represented as an array of two numbers: the enumerator
* and denominator. Both of these numbers will be unsigned longs.
*/
function getRational($o = 0) {
return array($this->getLong($o), $this->getLong($o+4));
}
/**
* Return a signed rational read from the data.
*
* @param int the offset into the data. An offset of zero will
* return the first rational available in the current allowed
* window. The last valid offset is equal to {@link getSize()}-8.
* Invalid offsets will result in a {@link
* PelDataWindowOffsetException} being thrown.
*
* @return array the signed rational found at offset. A rational
* number is represented as an array of two numbers: the enumerator
* and denominator. Both of these numbers will be signed longs.
*/
function getSRational($o = 0) {
return array($this->getSLong($o), $this->getSLong($o+4));
}
/**
* String comparison on substrings.
*
* @param int the offset into the data. An offset of zero will make
* the comparison start with the very first byte available in the
* window. The last valid offset is equal to {@link getSize()}
* minus the length of the string. If the string is too long, then
* a {@link PelDataWindowOffsetException} will be thrown.
*
* @param string the string to compare with.
*
* @return boolean true if the string given matches the data in the
* window, at the specified offset, false otherwise. The comparison
* will stop as soon as a mismatch if found.
*/
function strcmp($o, $str) {
/* Validate the offset of the final character we might have to
* check. */
$s = strlen($str);
$this->validateOffset($o);
$this->validateOffset($o + $s - 1);
/* Translate the offset into an offset into the data. */
$o += $this->start;
/* Check each character, return as soon as the answer is known. */
for ($i = 0; $i < $s; $i++) {
if ($this->data{$o + $i} != $str{$i})
return false;
}
/* All characters matches each other, return true. */
return true;
}
/**
* Return a string representation of the data window.
*
* @return string a description of the window with information about
* the number of bytes accessible, the total number of bytes, and
* the window start and stop.
*/
function __toString() {
return Pel::fmt('DataWindow: %d bytes in [%d, %d] of %d bytes',
$this->size,
$this->start, $this->start + $this->size,
strlen($this->data));
}
}
?>

View File

@ -0,0 +1,382 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005, 2006 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelEntry.php 442 2006-09-17 12:45:10Z mgeisler $ */
/**
* Classes for dealing with Exif entries.
*
* This file defines two exception classes and the abstract class
* {@link PelEntry} which provides the basic methods that all Exif
* entries will have. All Exif entries will be represented by
* descendants of the {@link PelEntry} class --- the class itself is
* abstract and so it cannot be instantiated.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 442 $
* @date $Date: 2006-09-17 14:45:10 +0200 (Sun, 17 Sep 2006) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('PelException.php');
require_once('PelFormat.php');
require_once('PelTag.php');
require_once('Pel.php');
/**#@-*/
/**
* Exception indicating a problem with an entry.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
* @subpackage Exception
*/
class PelEntryException extends PelException {
/**
* The IFD type (if known).
*
* @var int
*/
protected $type;
/**
* The tag of the entry (if known).
*
* @var PelTag
*/
protected $tag;
/**
* Get the IFD type associated with the exception.
*
* @return int one of {@link PelIfd::IFD0}, {@link PelIfd::IFD1},
* {@link PelIfd::EXIF}, {@link PelIfd::GPS}, or {@link
* PelIfd::INTEROPERABILITY}. If no type is set, null is returned.
*/
function getIfdType() {
return $this->type;
}
/**
* Get the tag associated with the exception.
*
* @return PelTag the tag. If no tag is set, null is returned.
*/
function getTag() {
return $this->tag;
}
}
/**
* Exception indicating that an unexpected format was found.
*
* The documentation for each tag in {@link PelTag} will detail any
* constrains.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
* @subpackage Exception
*/
class PelUnexpectedFormatException extends PelEntryException {
/**
* Construct a new exception indicating an invalid format.
*
* @param int the type of IFD.
*
* @param PelTag the tag for which the violation was found.
*
* @param PelFormat the format found.
*
* @param PelFormat the expected format.
*/
function __construct($type, $tag, $found, $expected) {
parent::__construct('Unexpected format found for %s tag: PelFormat::%s. ' .
'Expected PelFormat::%s instead.',
PelTag::getName($type, $tag),
strtoupper(PelFormat::getName($found)),
strtoupper(PelFormat::getName($expected)));
$this->tag = $tag;
$this->type = $type;
}
}
/**
* Exception indicating that an unexpected number of components was
* found.
*
* Some tags have strict limits as to the allowed number of
* components, and this exception is thrown if the data violates such
* a constraint. The documentation for each tag in {@link PelTag}
* explains the expected number of components.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
* @subpackage Exception
*/
class PelWrongComponentCountException extends PelEntryException {
/**
* Construct a new exception indicating a wrong number of
* components.
*
* @param int the type of IFD.
*
* @param PelTag the tag for which the violation was found.
*
* @param int the number of components found.
*
* @param int the expected number of components.
*/
function __construct($type, $tag, $found, $expected) {
parent::__construct('Wrong number of components found for %s tag: %d. ' .
'Expected %d.',
PelTag::getName($type, $tag), $found, $expected);
$this->tag = $tag;
$this->type = $type;
}
}
/**
* Common ancestor class of all {@link PelIfd} entries.
*
* As this class is abstract you cannot instantiate objects from it.
* It only serves as a common ancestor to define the methods common to
* all entries. The most important methods are {@link getValue()} and
* {@link setValue()}, both of which is abstract in this class. The
* descendants will give concrete implementations for them.
*
* If you have some data coming from an image (some raw bytes), then
* the static method {@link newFromData()} is helpful --- it will look
* at the data and give you a proper decendent of {@link PelEntry}
* back.
*
* If you instead want to have an entry for some data which take the
* form of an integer, a string, a byte, or some other PHP type, then
* don't use this class. You should instead create an object of the
* right subclass ({@link PelEntryShort} for short integers, {@link
* PelEntryAscii} for strings, and so on) directly.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
abstract class PelEntry {
/**
* Type of IFD containing this tag.
*
* This must be one of the constants defined in {@link PelIfd}:
* {@link PelIfd::IFD0} for the main image IFD, {@link PelIfd::IFD1}
* for the thumbnail image IFD, {@link PelIfd::EXIF} for the Exif
* sub-IFD, {@link PelIfd::GPS} for the GPS sub-IFD, or {@link
* PelIfd::INTEROPERABILITY} for the interoperability sub-IFD.
*
* @var int
*/
protected $ifd_type;
/**
* The bytes representing this entry.
*
* Subclasses must either override {@link getBytes()} or, if
* possible, maintain this property so that it always contains a
* true representation of the entry.
*
* @var string
*/
protected $bytes = '';
/**
* The {@link PelTag} of this entry.
*
* @var PelTag
*/
protected $tag;
/**
* The {@link PelFormat} of this entry.
*
* @var PelFormat
*/
protected $format;
/**
* The number of components of this entry.
*
* @var int
*/
protected $components;
/**
* Return the tag of this entry.
*
* @return PelTag the tag of this entry.
*/
function getTag() {
return $this->tag;
}
/**
* Return the type of IFD which holds this entry.
*
* @return int one of the constants defined in {@link PelIfd}:
* {@link PelIfd::IFD0} for the main image IFD, {@link PelIfd::IFD1}
* for the thumbnail image IFD, {@link PelIfd::EXIF} for the Exif
* sub-IFD, {@link PelIfd::GPS} for the GPS sub-IFD, or {@link
* PelIfd::INTEROPERABILITY} for the interoperability sub-IFD.
*/
function getIfdType() {
return $this->ifd_type;
}
/**
* Update the IFD type.
*
* @param int must be one of the constants defined in {@link
* PelIfd}: {@link PelIfd::IFD0} for the main image IFD, {@link
* PelIfd::IFD1} for the thumbnail image IFD, {@link PelIfd::EXIF}
* for the Exif sub-IFD, {@link PelIfd::GPS} for the GPS sub-IFD, or
* {@link PelIfd::INTEROPERABILITY} for the interoperability
* sub-IFD.
*/
function setIfdType($type) {
$this->ifd_type = $type;
}
/**
* Return the format of this entry.
*
* @return PelFormat the format of this entry.
*/
function getFormat() {
return $this->format;
}
/**
* Return the number of components of this entry.
*
* @return int the number of components of this entry.
*/
function getComponents() {
return $this->components;
}
/**
* Turn this entry into bytes.
*
* @param PelByteOrder the desired byte order, which must be either
* {@link Convert::LITTLE_ENDIAN} or {@link Convert::BIG_ENDIAN}.
*
* @return string bytes representing this entry.
*/
function getBytes($o) {
return $this->bytes;
}
/**
* Get the value of this entry as text.
*
* The value will be returned in a format suitable for presentation,
* e.g., rationals will be returned as 'x/y', ASCII strings will be
* returned as themselves etc.
*
* @param boolean some values can be returned in a long or more
* brief form, and this parameter controls that.
*
* @return string the value as text.
*/
abstract function getText($brief = false);
/**
* Get the value of this entry.
*
* The value returned will generally be the same as the one supplied
* to the constructor or with {@link setValue()}. For a formatted
* version of the value, one should use {@link getText()} instead.
*
* @return mixed the unformatted value.
*/
abstract function getValue();
/**
* Set the value of this entry.
*
* The value should be in the same format as for the constructor.
*
* @param mixed the new value.
*
* @abstract
*/
function setValue($value) {
/* This (fake) abstract method is here to make it possible for the
* documentation to refer to PelEntry::setValue().
*
* It cannot declared abstract in the proper PHP way, for then PHP
* wont allow subclasses to define it with two arguments (which is
* what PelEntryCopyright does).
*/
throw new PelException('setValue() is abstract.');
}
/**
* Turn this entry into a string.
*
* @return string a string representation of this entry. This is
* mostly for debugging.
*/
function __toString() {
$str = Pel::fmt(" Tag: 0x%04X (%s)\n",
$this->tag, PelTag::getName($this->ifd_type, $this->tag));
$str .= Pel::fmt(" Format : %d (%s)\n",
$this->format, PelFormat::getName($this->format));
$str .= Pel::fmt(" Components: %d\n", $this->components);
if ($this->getTag() != PelTag::MAKER_NOTE &&
$this->getTag() != PelTag::PRINT_IM)
$str .= Pel::fmt(" Value : %s\n", print_r($this->getValue(), true));
$str .= Pel::fmt(" Text : %s\n", $this->getText());
return $str;
}
}
?>

View File

@ -0,0 +1,482 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005, 2006 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelEntryAscii.php 443 2006-09-17 18:32:04Z mgeisler $ */
/**
* Classes used to hold ASCII strings.
*
* The classes defined here are to be used for Exif entries holding
* ASCII strings, such as {@link PelTag::MAKE}, {@link
* PelTag::SOFTWARE}, and {@link PelTag::DATE_TIME}. For
* entries holding normal textual ASCII strings the class {@link
* PelEntryAscii} should be used, but for entries holding
* timestamps the class {@link PelEntryTime} would be more
* convenient instead. Copyright information is handled by the {@link
* PelEntryCopyright} class.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 443 $
* @date $Date: 2006-09-17 20:32:04 +0200 (Sun, 17 Sep 2006) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('PelEntry.php');
/**#@-*/
/**
* Class for holding a plain ASCII string.
*
* This class can hold a single ASCII string, and it will be used as in
* <code>
* $entry = $ifd->getEntry(PelTag::IMAGE_DESCRIPTION);
* print($entry->getValue());
* $entry->setValue('This is my image. I like it.');
* </code>
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntryAscii extends PelEntry {
/**
* The string hold by this entry.
*
* This is the string that was given to the {@link __construct
* constructor} or later to {@link setValue}, without any final NULL
* character.
*
* @var string
*/
private $str;
/**
* Make a new PelEntry that can hold an ASCII string.
*
* @param int the tag which this entry represents. This should be
* one of the constants defined in {@link PelTag}, e.g., {@link
* PelTag::IMAGE_DESCRIPTION}, {@link PelTag::MODEL}, or any other
* tag with format {@link PelFormat::ASCII}.
*
* @param string the string that this entry will represent. The
* string must obey the same rules as the string argument to {@link
* setValue}, namely that it should be given without any trailing
* NULL character and that it must be plain 7-bit ASCII.
*/
function __construct($tag, $str = '') {
$this->tag = $tag;
$this->format = PelFormat::ASCII;
$this->setValue($str);
}
/**
* Give the entry a new ASCII value.
*
* This will overwrite the previous value. The value can be
* retrieved later with the {@link getValue} method.
*
* @param string the new value of the entry. This should be given
* without any trailing NULL character. The string must be plain
* 7-bit ASCII, the string should contain no high bytes.
*
* @todo Implement check for high bytes?
*/
function setValue($str) {
$this->components = strlen($str)+1;
$this->str = $str;
$this->bytes = $str . chr(0x00);
}
/**
* Return the ASCII string of the entry.
*
* @return string the string held, without any final NULL character.
* The string will be the same as the one given to {@link setValue}
* or to the {@link __construct constructor}.
*/
function getValue() {
return $this->str;
}
/**
* Return the ASCII string of the entry.
*
* This methods returns the same as {@link getValue}.
*
* @param boolean not used with ASCII entries.
*
* @return string the string held, without any final NULL character.
* The string will be the same as the one given to {@link setValue}
* or to the {@link __construct constructor}.
*/
function getText($brief = false) {
return $this->str;
}
}
/**
* Class for holding a date and time.
*
* This class can hold a timestamp, and it will be used as
* in this example where the time is advanced by one week:
* <code>
* $entry = $ifd->getEntry(PelTag::DATE_TIME_ORIGINAL);
* $time = $entry->getValue();
* print('The image was taken on the ' . date($time, 'jS'));
* $entry->setValue($time + 7 * 24 * 3600);
* </code>
*
* The example used a standard UNIX timestamp, which is the default
* for this class.
*
* But the Exif format defines dates outside the range of a UNIX
* timestamp (about 1970 to 2038) and so you can also get access to
* the timestamp in two other formats: a simple string or a Julian Day
* Count. Please see the Calendar extension in the PHP Manual for more
* information about the Julian Day Count.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntryTime extends PelEntryAscii {
/**
* Constant denoting a UNIX timestamp.
*/
const UNIX_TIMESTAMP = 1;
/**
* Constant denoting a Exif string.
*/
const EXIF_STRING = 2;
/**
* Constant denoting a Julian Day Count.
*/
const JULIAN_DAY_COUNT = 3;
/**
* The Julian Day Count of the timestamp held by this entry.
*
* This is an integer counting the number of whole days since
* January 1st, 4713 B.C. The fractional part of the timestamp held
* by this entry is stored in {@link $seconds}.
*
* @var int
*/
private $day_count;
/**
* The number of seconds into the day of the timestamp held by this
* entry.
*
* The number of whole days is stored in {@link $day_count} and the
* number of seconds left-over is stored here.
*
* @var int
*/
private $seconds;
/**
* Make a new entry for holding a timestamp.
*
* @param int the Exif tag which this entry represents. There are
* only three standard tags which hold timestamp, so this should be
* one of the constants {@link PelTag::DATE_TIME}, {@link
* PelTag::DATE_TIME_ORIGINAL}, or {@link
* PelTag::DATE_TIME_DIGITIZED}.
*
* @param int the timestamp held by this entry in the correct form
* as indicated by the third argument. For {@link UNIX_TIMESTAMP}
* this is an integer counting the number of seconds since January
* 1st 1970, for {@link EXIF_STRING} this is a string of the form
* 'YYYY:MM:DD hh:mm:ss', and for {@link JULIAN_DAY_COUNT} this is a
* floating point number where the integer part denotes the day
* count and the fractional part denotes the time of day (0.25 means
* 6:00, 0.75 means 18:00).
*
* @param int the type of the timestamp. This must be one of
* {@link UNIX_TIMESTAMP}, {@link EXIF_STRING}, or
* {@link JULIAN_DAY_COUNT}.
*/
function __construct($tag, $timestamp, $type = self::UNIX_TIMESTAMP) {
parent::__construct($tag);
$this->setValue($timestamp, $type);
}
/**
* Return the timestamp of the entry.
*
* The timestamp held by this entry is returned in one of three
* formats: as a standard UNIX timestamp (default), as a fractional
* Julian Day Count, or as a string.
*
* @param int the type of the timestamp. This must be one of
* {@link UNIX_TIMESTAMP}, {@link EXIF_STRING}, or
* {@link JULIAN_DAY_COUNT}.
*
* @return int the timestamp held by this entry in the correct form
* as indicated by the type argument. For {@link UNIX_TIMESTAMP}
* this is an integer counting the number of seconds since January
* 1st 1970, for {@link EXIF_STRING} this is a string of the form
* 'YYYY:MM:DD hh:mm:ss', and for {@link JULIAN_DAY_COUNT} this is a
* floating point number where the integer part denotes the day
* count and the fractional part denotes the time of day (0.25 means
* 6:00, 0.75 means 18:00).
*/
function getValue($type = self::UNIX_TIMESTAMP) {
switch ($type) {
case self::UNIX_TIMESTAMP:
$seconds = jdtounix($this->day_count);
if ($seconds === false)
/* jdtounix() return false if the Julian Day Count is outside
* the range of a UNIX timestamp. */
return false;
else
return $seconds + $this->seconds;
case self::EXIF_STRING:
list($month, $day, $year) = explode('/', jdtogregorian($this->day_count));
$hours = (int)($this->seconds / 3600);
$minutes = (int)($this->seconds % 3600 / 60);
$seconds = $this->seconds % 60;
return sprintf('%04d:%02d:%02d %02d:%02d:%02d',
$year, $month, $day, $hours, $minutes, $seconds);
case self::JULIAN_DAY_COUNT:
return $this->day_count + $this->seconds / 86400;
default:
throw new PelInvalidArgumentException('Expected UNIX_TIMESTAMP (%d), ' .
'EXIF_STRING (%d), or ' .
'JULIAN_DAY_COUNT (%d) for $type, '.
'got %d.',
self::UNIX_TIMESTAMP,
self::EXIF_STRING,
self::JULIAN_DAY_COUNT,
$type);
}
}
/**
* Update the timestamp held by this entry.
*
* @param int the timestamp held by this entry in the correct form
* as indicated by the third argument. For {@link UNIX_TIMESTAMP}
* this is an integer counting the number of seconds since January
* 1st 1970, for {@link EXIF_STRING} this is a string of the form
* 'YYYY:MM:DD hh:mm:ss', and for {@link JULIAN_DAY_COUNT} this is a
* floating point number where the integer part denotes the day
* count and the fractional part denotes the time of day (0.25 means
* 6:00, 0.75 means 18:00).
*
* @param int the type of the timestamp. This must be one of
* {@link UNIX_TIMESTAMP}, {@link EXIF_STRING}, or
* {@link JULIAN_DAY_COUNT}.
*
* @todo How to deal with timezones? Use the TimeZoneOffset tag
* 0x882A?
*/
function setValue($timestamp, $type = self::UNIX_TIMESTAMP) {
switch ($type) {
case self::UNIX_TIMESTAMP:
$this->day_count = unixtojd($timestamp);
$this->seconds = $timestamp % 86400;
break;
case self::EXIF_STRING:
/* Clean the timestamp: some timestamps are broken other
* separators than ':' and ' '. */
$d = split('[^0-9]+', $timestamp);
$this->day_count = gregoriantojd($d[1], $d[2], $d[0]);
$this->seconds = $d[3]*3600 + $d[4]*60 + $d[5];
break;
case self::JULIAN_DAY_COUNT:
$this->day_count = (int)floor($timestamp);
$this->seconds = (int)(86400 * ($timestamp - floor($timestamp)));
break;
default:
throw new PelInvalidArgumentException('Expected UNIX_TIMESTAMP (%d), ' .
'EXIF_STRING (%d), or ' .
'JULIAN_DAY_COUNT (%d) for $type, '.
'got %d.',
self::UNIX_TIMESTAMP,
self::EXIF_STRING,
self::JULIAN_DAY_COUNT,
$type);
}
/* Now finally update the string which will be used when this is
* turned into bytes. */
parent::setValue($this->getValue(self::EXIF_STRING));
}
}
/**
* Class for holding copyright information.
*
* The Exif standard specifies a certain format for copyright
* information where the one {@link PelTag::COPYRIGHT copyright
* tag} holds both the photographer and editor copyrights, separated
* by a NULL character.
*
* This class is used to manipulate that tag so that the format is
* kept to the standard. A common use would be to add a new copyright
* tag to an image, since most cameras do not add this tag themselves.
* This would be done like this:
*
* <code>
* $entry = new PelEntryCopyright('Copyright, Martin Geisler, 2004');
* $ifd0->addEntry($entry);
* </code>
*
* Here we only set the photographer copyright, use the optional
* second argument to specify the editor copyright. If there is only
* an editor copyright, then let the first argument be the empty
* string.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntryCopyright extends PelEntryAscii {
/**
* The photographer copyright.
*
* @var string
*/
private $photographer;
/**
* The editor copyright.
*
* @var string
*/
private $editor;
/**
* Make a new entry for holding copyright information.
*
* @param string the photographer copyright. Use the empty string
* if there is no photographer copyright.
*
* @param string the editor copyright. Use the empty string if
* there is no editor copyright.
*/
function __construct($photographer = '', $editor = '') {
parent::__construct(PelTag::COPYRIGHT);
$this->setValue($photographer, $editor);
}
/**
* Update the copyright information.
*
* @param string the photographer copyright. Use the empty string
* if there is no photographer copyright.
*
* @param string the editor copyright. Use the empty string if
* there is no editor copyright.
*/
function setValue($photographer = '', $editor = '') {
$this->photographer = $photographer;
$this->editor = $editor;
if ($photographer == '' && $editor != '')
$photographer = ' ';
if ($editor == '')
parent::setValue($photographer);
else
parent::setValue($photographer . chr(0x00) . $editor);
}
/**
* Retrive the copyright information.
*
* The strings returned will be the same as the one used previously
* with either {@link __construct the constructor} or with {@link
* setValue}.
*
* @return array an array with two strings, the photographer and
* editor copyrights. The two fields will be returned in that
* order, so that the first array index will be the photographer
* copyright, and the second will be the editor copyright.
*/
function getValue() {
return array($this->photographer, $this->editor);
}
/**
* Return a text string with the copyright information.
*
* The photographer and editor copyright fields will be returned
* with a '-' in between if both copyright fields are present,
* otherwise only one of them will be returned.
*
* @param boolean if false, then the strings '(Photographer)' and
* '(Editor)' will be appended to the photographer and editor
* copyright fields (if present), otherwise the fields will be
* returned as is.
*
* @return string the copyright information in a string.
*/
function getText($brief = false) {
if ($brief) {
$p = '';
$e = '';
} else {
$p = ' ' . Pel::tra('(Photographer)');
$e = ' ' . Pel::tra('(Editor)');
}
if ($this->photographer != '' && $this->editor != '')
return $this->photographer . $p . ' - ' . $this->editor . $e;
if ($this->photographer != '')
return $this->photographer . $p;
if ($this->editor != '')
return $this->editor . $e;
return '';
}
}
?>

View File

@ -0,0 +1,275 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005, 2006 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelEntryByte.php 419 2006-02-20 16:22:36Z mgeisler $ */
/**
* Classes used to hold bytes, both signed and unsigned. The {@link
* PelEntryWindowsString} class is used to manipulate strings in the
* format Windows XP needs.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 419 $
* @date $Date: 2006-02-20 17:22:36 +0100 (Mon, 20 Feb 2006) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('PelEntryNumber.php');
/**#@-*/
/**
* Class for holding unsigned bytes.
*
* This class can hold bytes, either just a single byte or an array of
* bytes. The class will be used to manipulate any of the Exif tags
* which has format {@link PelFormat::BYTE}.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntryByte extends PelEntryNumber {
/**
* Make a new entry that can hold an unsigned byte.
*
* The method accept several integer arguments. The {@link
* getValue} method will always return an array except for when a
* single integer argument is given here.
*
* @param PelTag the tag which this entry represents. This
* should be one of the constants defined in {@link PelTag}
* which has format {@link PelFormat::BYTE}.
*
* @param int $value... the byte(s) that this entry will represent.
* The argument passed must obey the same rules as the argument to
* {@link setValue}, namely that it should be within range of an
* unsigned byte, that is between 0 and 255 (inclusive). If not,
* then a {@link PelOverflowException} will be thrown.
*/
function __construct($tag /* $value... */) {
$this->tag = $tag;
$this->min = 0;
$this->max = 255;
$this->format = PelFormat::BYTE;
$value = func_get_args();
array_shift($value);
$this->setValueArray($value);
}
/**
* Convert a number into bytes.
*
* @param int the number that should be converted.
*
* @param PelByteOrder one of {@link PelConvert::LITTLE_ENDIAN} and
* {@link PelConvert::BIG_ENDIAN}, specifying the target byte order.
*
* @return string bytes representing the number given.
*/
function numberToBytes($number, $order) {
return chr($number);
}
}
/**
* Class for holding signed bytes.
*
* This class can hold bytes, either just a single byte or an array of
* bytes. The class will be used to manipulate any of the Exif tags
* which has format {@link PelFormat::BYTE}.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntrySByte extends PelEntryNumber {
/**
* Make a new entry that can hold a signed byte.
*
* The method accept several integer arguments. The {@link getValue}
* method will always return an array except for when a single
* integer argument is given here.
*
* @param PelTag the tag which this entry represents. This
* should be one of the constants defined in {@link PelTag}
* which has format {@link PelFormat::BYTE}.
*
* @param int $value... the byte(s) that this entry will represent.
* The argument passed must obey the same rules as the argument to
* {@link setValue}, namely that it should be within range of a
* signed byte, that is between -128 and 127 (inclusive). If not,
* then a {@link PelOverflowException} will be thrown.
*/
function __construct($tag /* $value... */) {
$this->tag = $tag;
$this->min = -128;
$this->max = 127;
$this->format = PelFormat::SBYTE;
$value = func_get_args();
array_shift($value);
$this->setValueArray($value);
}
/**
* Convert a number into bytes.
*
* @param int the number that should be converted.
*
* @param PelByteOrder one of {@link PelConvert::LITTLE_ENDIAN} and
* {@link PelConvert::BIG_ENDIAN}, specifying the target byte order.
*
* @return string bytes representing the number given.
*/
function numberToBytes($number, $order) {
return chr($number);
}
}
/**
* Class used to manipulate strings in the format Windows XP uses.
*
* When examining the file properties of an image in Windows XP one
* can fill in title, comment, author, keyword, and subject fields.
* Filling those fields and pressing OK will result in the data being
* written into the Exif data in the image.
*
* The data is written in a non-standard format and can thus not be
* loaded directly --- this class is needed to translate it into
* normal strings.
*
* It is important that entries from this class are only created with
* the {@link PelTag::XP_TITLE}, {@link PelTag::XP_COMMENT}, {@link
* PelTag::XP_AUTHOR}, {@link PelTag::XP_KEYWORD}, and {@link
* PelTag::XP_SUBJECT} tags. If another tag is used the data will no
* longer be correctly decoded when reloaded with PEL. (The data will
* be loaded as an {@link PelEntryByte} entry, which isn't as useful.)
*
* This class is to be used as in
* <code>
* $entry = $ifd->getEntry(PelTag::XP_TITLE);
* print($entry->getValue());
* $entry->setValue('My favorite cat');
* </code>
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntryWindowsString extends PelEntry {
/**
* The string hold by this entry.
*
* This is the string that was given to the {@link __construct
* constructor} or later to {@link setValue}, without any extra NULL
* characters or any such nonsense.
*
* @var string
*/
private $str;
/**
* Make a new PelEntry that can hold a Windows XP specific string.
*
* @param int the tag which this entry represents. This should be
* one of {@link PelTag::XP_TITLE}, {@link PelTag::XP_COMMENT},
* {@link PelTag::XP_AUTHOR}, {@link PelTag::XP_KEYWORD}, and {@link
* PelTag::XP_SUBJECT} tags. If another tag is used, then this
* entry will be incorrectly reloaded as a {@link PelEntryByte}.
*
* @param string the string that this entry will represent. It will
* be passed to {@link setValue} and thus has to obey its
* requirements.
*/
function __construct($tag, $str = '') {
$this->tag = $tag;
$this->format = PelFormat::BYTE;
$this->setValue($str);
}
/**
* Give the entry a new value.
*
* This will overwrite the previous value. The value can be
* retrieved later with the {@link getValue} method.
*
* @param string the new value of the entry. This should be use the
* Latin-1 encoding and be given without any extra NULL characters.
*/
function setValue($str) {
$l = strlen($str);
$this->components = 2 * ($l + 1);
$this->str = $str;
$this->bytes = '';
for ($i = 0; $i < $l; $i++)
$this->bytes .= $str{$i} . chr(0x00);
$this->bytes .= chr(0x00) . chr(0x00);
}
/**
* Return the string of the entry.
*
* @return string the string held, without any extra NULL
* characters. The string will be the same as the one given to
* {@link setValue} or to the {@link __construct constructor}.
*/
function getValue() {
return $this->str;
}
/**
* Return the string of the entry.
*
* This methods returns the same as {@link getValue}.
*
* @param boolean not used.
*
* @return string the string held, without any extra NULL
* characters. The string will be the same as the one given to
* {@link setValue} or to the {@link __construct constructor}.
*/
function getText($brief = false) {
return $this->str;
}
}
?>

View File

@ -0,0 +1,182 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005, 2006 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelEntryLong.php 419 2006-02-20 16:22:36Z mgeisler $ */
/**
* Classes used to hold longs, both signed and unsigned.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 419 $
* @date $Date: 2006-02-20 17:22:36 +0100 (Mon, 20 Feb 2006) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('PelEntryNumber.php');
/**#@-*/
/**
* Class for holding unsigned longs.
*
* This class can hold longs, either just a single long or an array of
* longs. The class will be used to manipulate any of the Exif tags
* which can have format {@link PelFormat::LONG} like in this
* example:
* <code>
* $w = $ifd->getEntry(PelTag::EXIF_IMAGE_WIDTH);
* $w->setValue($w->getValue() / 2);
* $h = $ifd->getEntry(PelTag::EXIF_IMAGE_HEIGHT);
* $h->setValue($h->getValue() / 2);
* </code>
* Here the width and height is updated to 50% of their original
* values.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntryLong extends PelEntryNumber {
/**
* Make a new entry that can hold an unsigned long.
*
* The method accept its arguments in two forms: several integer
* arguments or a single array argument. The {@link getValue}
* method will always return an array except for when a single
* integer argument is given here, or when an array with just a
* single integer is given.
*
* This means that one can conveniently use objects like this:
* <code>
* $a = new PelEntryLong(PelTag::EXIF_IMAGE_WIDTH, 123456);
* $b = $a->getValue() - 654321;
* </code>
* where the call to {@link getValue} will return an integer instead
* of an array with one integer element, which would then have to be
* extracted.
*
* @param PelTag the tag which this entry represents. This
* should be one of the constants defined in {@link PelTag},
* e.g., {@link PelTag::IMAGE_WIDTH}, or any other tag which can
* have format {@link PelFormat::LONG}.
*
* @param int $value... the long(s) that this entry will
* represent or an array of longs. The argument passed must obey
* the same rules as the argument to {@link setValue}, namely that
* it should be within range of an unsigned long (32 bit), that is
* between 0 and 4294967295 (inclusive). If not, then a {@link
* PelExifOverflowException} will be thrown.
*/
function __construct($tag /* $value... */) {
$this->tag = $tag;
$this->min = 0;
$this->max = 4294967295;
$this->format = PelFormat::LONG;
$value = func_get_args();
array_shift($value);
$this->setValueArray($value);
}
/**
* Convert a number into bytes.
*
* @param int the number that should be converted.
*
* @param PelByteOrder one of {@link PelConvert::LITTLE_ENDIAN} and
* {@link PelConvert::BIG_ENDIAN}, specifying the target byte order.
*
* @return string bytes representing the number given.
*/
function numberToBytes($number, $order) {
return PelConvert::longToBytes($number, $order);
}
}
/**
* Class for holding signed longs.
*
* This class can hold longs, either just a single long or an array of
* longs. The class will be used to manipulate any of the Exif tags
* which can have format {@link PelFormat::SLONG}.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntrySLong extends PelEntryNumber {
/**
* Make a new entry that can hold a signed long.
*
* The method accept its arguments in two forms: several integer
* arguments or a single array argument. The {@link getValue}
* method will always return an array except for when a single
* integer argument is given here, or when an array with just a
* single integer is given.
*
* @param PelTag the tag which this entry represents. This
* should be one of the constants defined in {@link PelTag}
* which have format {@link PelFormat::SLONG}.
*
* @param int $value... the long(s) that this entry will represent
* or an array of longs. The argument passed must obey the same
* rules as the argument to {@link setValue}, namely that it should
* be within range of a signed long (32 bit), that is between
* -2147483648 and 2147483647 (inclusive). If not, then a {@link
* PelOverflowException} will be thrown.
*/
function __construct($tag /* $value... */) {
$this->tag = $tag;
$this->min = -2147483648;
$this->max = 2147483647;
$this->format = PelFormat::SLONG;
$value = func_get_args();
array_shift($value);
$this->setValueArray($value);
}
/**
* Convert a number into bytes.
*
* @param int the number that should be converted.
*
* @param PelByteOrder one of {@link PelConvert::LITTLE_ENDIAN} and
* {@link PelConvert::BIG_ENDIAN}, specifying the target byte order.
*
* @return string bytes representing the number given.
*/
function numberToBytes($number, $order) {
return PelConvert::sLongToBytes($number, $order);
}
}
?>

View File

@ -0,0 +1,309 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005, 2006 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelEntryNumber.php 419 2006-02-20 16:22:36Z mgeisler $ */
/**
* Abstract class for numbers.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 419 $
* @date $Date: 2006-02-20 17:22:36 +0100 (Mon, 20 Feb 2006) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('PelException.php');
require_once('PelEntry.php');
/**#@-*/
/**
* Exception cast when numbers overflow.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
* @subpackage Exception
*/
class PelOverflowException extends PelException {
/**
* Construct a new overflow exception.
*
* @param int the value that is out of range.
*
* @param int the minimum allowed value.
*
* @param int the maximum allowed value.
*/
function __construct($v, $min, $max) {
parent::__construct('Value %.0f out of range [%.0f, %.0f]',
$v, $min, $max);
}
}
/**
* Class for holding numbers.
*
* This class can hold numbers, with range checks.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
abstract class PelEntryNumber extends PelEntry {
/**
* The value held by this entry.
*
* @var array
*/
protected $value = array();
/**
* The minimum allowed value.
*
* Any attempt to change the value below this variable will result
* in a {@link PelOverflowException} being thrown.
*
* @var int
*/
protected $min;
/**
* The maximum allowed value.
*
* Any attempt to change the value over this variable will result in
* a {@link PelOverflowException} being thrown.
*
* @var int
*/
protected $max;
/**
* The dimension of the number held.
*
* Normal numbers have a dimension of one, pairs have a dimension of
* two, etc.
*
* @var int
*/
protected $dimension = 1;
/**
* Change the value.
*
* This method can change both the number of components and the
* value of the components. Range checks will be made on the new
* value, and a {@link PelOverflowException} will be thrown if the
* value is found to be outside the legal range.
*
* The method accept several number arguments. The {@link getValue}
* method will always return an array except for when a single
* number is given here.
*
* @param int|array $value... the new value(s). This can be zero or
* more numbers, that is, either integers or arrays. The input will
* be checked to ensure that the numbers are within the valid range.
* If not, then a {@link PelOverflowException} will be thrown.
*
* @see getValue
*/
function setValue(/* $value... */) {
$value = func_get_args();
$this->setValueArray($value);
}
/**
* Change the value.
*
* This method can change both the number of components and the
* value of the components. Range checks will be made on the new
* value, and a {@link PelOverflowException} will be thrown if the
* value is found to be outside the legal range.
*
* @param array the new values. The array must contain the new
* numbers.
*
* @see getValue
*/
function setValueArray($value) {
foreach ($value as $v)
$this->validateNumber($v);
$this->components = count($value);
$this->value = $value;
}
/**
* Return the numeric value held.
*
* @return int|array this will either be a single number if there is
* only one component, or an array of numbers otherwise.
*/
function getValue() {
if ($this->components == 1)
return $this->value[0];
else
return $this->value;
}
/**
* Validate a number.
*
* This method will check that the number given is within the range
* given my {@link getMin()} and {@link getMax()}, inclusive. If
* not, then a {@link PelOverflowException} is thrown.
*
* @param int|array the number in question.
*
* @return void nothing, but will throw a {@link
* PelOverflowException} if the number is found to be outside the
* legal range and {@link Pel::$strict} is true.
*/
function validateNumber($n) {
if ($this->dimension == 1) {
if ($n < $this->min || $n > $this->max)
Pel::maybeThrow(new PelOverflowException($n,
$this->min,
$this->max));
} else {
for ($i = 0; $i < $this->dimension; $i++)
if ($n[$i] < $this->min || $n[$i] > $this->max)
Pel::maybeThrow(new PelOverflowException($n[$i],
$this->min,
$this->max));
}
}
/**
* Add a number.
*
* This appends a number to the numbers already held by this entry,
* thereby increasing the number of components by one.
*
* @param int|array the number to be added.
*/
function addNumber($n) {
$this->validateNumber($n);
$this->value[] = $n;
$this->components++;
}
/**
* Convert a number into bytes.
*
* The concrete subclasses will have to implement this method so
* that the numbers represented can be turned into bytes.
*
* The method will be called once for each number held by the entry.
*
* @param int the number that should be converted.
*
* @param PelByteOrder one of {@link PelConvert::LITTLE_ENDIAN} and
* {@link PelConvert::BIG_ENDIAN}, specifying the target byte order.
*
* @return string bytes representing the number given.
*/
abstract function numberToBytes($number, $order);
/**
* Turn this entry into bytes.
*
* @param PelByteOrder the desired byte order, which must be either
* {@link PelConvert::LITTLE_ENDIAN} or {@link
* PelConvert::BIG_ENDIAN}.
*
* @return string bytes representing this entry.
*/
function getBytes($o) {
$bytes = '';
for ($i = 0; $i < $this->components; $i++) {
if ($this->dimension == 1) {
$bytes .= $this->numberToBytes($this->value[$i], $o);
} else {
for ($j = 0; $j < $this->dimension; $j++) {
$bytes .= $this->numberToBytes($this->value[$i][$j], $o);
}
}
}
return $bytes;
}
/**
* Format a number.
*
* This method is called by {@link getText} to format numbers.
* Subclasses should override this method if they need more
* sophisticated behavior than the default, which is to just return
* the number as is.
*
* @param int the number which will be formatted.
*
* @param boolean it could be that there is both a verbose and a
* brief formatting available, and this argument controls that.
*
* @return string the number formatted as a string suitable for
* display.
*/
function formatNumber($number, $brief = false) {
return $number;
}
/**
* Get the numeric value of this entry as text.
*
* @param boolean use brief output? The numbers will be separated
* by a single space if brief output is requested, otherwise a space
* and a comma will be used.
*
* @return string the numbers(s) held by this entry.
*/
function getText($brief = false) {
if ($this->components == 0)
return '';
$str = $this->formatNumber($this->value[0]);
for ($i = 1; $i < $this->components; $i++) {
$str .= ($brief ? ' ' : ', ');
$str .= $this->formatNumber($this->value[$i]);
}
return $str;
}
}
?>

View File

@ -0,0 +1,290 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005, 2006 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelEntryRational.php 419 2006-02-20 16:22:36Z mgeisler $ */
/**
* Classes used to manipulate rational numbers.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 419 $
* @date $Date: 2006-02-20 17:22:36 +0100 (Mon, 20 Feb 2006) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('PelEntryLong.php');
/**#@-*/
/**
* Class for holding unsigned rational numbers.
*
* This class can hold rational numbers, consisting of a numerator and
* denominator both of which are of type unsigned long. Each rational
* is represented by an array with just two entries: the numerator and
* the denominator, in that order.
*
* The class can hold either just a single rational or an array of
* rationals. The class will be used to manipulate any of the Exif
* tags which can have format {@link PelFormat::RATIONAL} like in this
* example:
*
* <code>
* $resolution = $ifd->getEntry(PelTag::X_RESOLUTION);
* $resolution->setValue(array(1, 300));
* </code>
*
* Here the x-resolution is adjusted to 1/300, which will be 300 DPI,
* unless the {@link PelTag::RESOLUTION_UNIT resolution unit} is set
* to something different than 2 which means inches.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntryRational extends PelEntryLong {
/**
* Make a new entry that can hold an unsigned rational.
*
* @param PelTag the tag which this entry represents. This should
* be one of the constants defined in {@link PelTag}, e.g., {@link
* PelTag::X_RESOLUTION}, or any other tag which can have format
* {@link PelFormat::RATIONAL}.
*
* @param array $value... the rational(s) that this entry will
* represent. The arguments passed must obey the same rules as the
* argument to {@link setValue}, namely that each argument should be
* an array with two entries, both of which must be within range of
* an unsigned long (32 bit), that is between 0 and 4294967295
* (inclusive). If not, then a {@link PelOverflowException} will be
* thrown.
*/
function __construct($tag /* $value... */) {
$this->tag = $tag;
$this->format = PelFormat::RATIONAL;
$this->dimension = 2;
$this->min = 0;
$this->max = 4294967295;
$value = func_get_args();
array_shift($value);
$this->setValueArray($value);
}
/**
* Format a rational number.
*
* The rational will be returned as a string with a slash '/'
* between the numerator and denominator.
*
* @param array the rational which will be formatted.
*
* @param boolean not used.
*
* @return string the rational formatted as a string suitable for
* display.
*/
function formatNumber($number, $brief = false) {
return $number[0] . '/' . $number[1];
}
/**
* Get the value of an entry as text.
*
* The value will be returned in a format suitable for presentation,
* e.g., rationals will be returned as 'x/y', ASCII strings will be
* returned as themselves etc.
*
* @param boolean some values can be returned in a long or more
* brief form, and this parameter controls that.
*
* @return string the value as text.
*/
function getText($brief = false) {
if (isset($this->value[0]))
$v = $this->value[0];
switch ($this->tag) {
case PelTag::FNUMBER:
//CC (e->components, 1, v);
return Pel::fmt('f/%.01f', $v[0]/$v[1]);
case PelTag::APERTURE_VALUE:
//CC (e->components, 1, v);
//if (!v_rat.denominator) return (NULL);
return Pel::fmt('f/%.01f', pow(2, $v[0]/$v[1]/2));
case PelTag::FOCAL_LENGTH:
//CC (e->components, 1, v);
//if (!v_rat.denominator) return (NULL);
return Pel::fmt('%.1f mm', $v[0]/$v[1]);
case PelTag::SUBJECT_DISTANCE:
//CC (e->components, 1, v);
//if (!v_rat.denominator) return (NULL);
return Pel::fmt('%.1f m', $v[0]/$v[1]);
case PelTag::EXPOSURE_TIME:
//CC (e->components, 1, v);
//if (!v_rat.denominator) return (NULL);
if ($v[0]/$v[1] < 1)
return Pel::fmt('1/%d sec.', $v[1]/$v[0]);
else
return Pel::fmt('%d sec.', $v[0]/$v[1]);
case PelTag::GPS_LATITUDE:
case PelTag::GPS_LONGITUDE:
$degrees = $this->value[0][0]/$this->value[0][1];
$minutes = $this->value[1][0]/$this->value[1][1];
$seconds = $this->value[2][0]/$this->value[2][1];
return sprintf('%s° %s\' %s" (%.2f°)',
$degrees, $minutes, $seconds,
$degrees + $minutes/60 + $seconds/3600);
default:
return parent::getText($brief);
}
}
}
/**
* Class for holding signed rational numbers.
*
* This class can hold rational numbers, consisting of a numerator and
* denominator both of which are of type unsigned long. Each rational
* is represented by an array with just two entries: the numerator and
* the denominator, in that order.
*
* The class can hold either just a single rational or an array of
* rationals. The class will be used to manipulate any of the Exif
* tags which can have format {@link PelFormat::SRATIONAL}.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntrySRational extends PelEntrySLong {
/**
* Make a new entry that can hold a signed rational.
*
* @param PelTag the tag which this entry represents. This should
* be one of the constants defined in {@link PelTag}, e.g., {@link
* PelTag::SHUTTER_SPEED_VALUE}, or any other tag which can have
* format {@link PelFormat::SRATIONAL}.
*
* @param array $value... the rational(s) that this entry will
* represent. The arguments passed must obey the same rules as the
* argument to {@link setValue}, namely that each argument should be
* an array with two entries, both of which must be within range of
* a signed long (32 bit), that is between -2147483648 and
* 2147483647 (inclusive). If not, then a {@link
* PelOverflowException} will be thrown.
*/
function __construct($tag /* $value... */) {
$this->tag = $tag;
$this->format = PelFormat::SRATIONAL;
$this->dimension = 2;
$this->min = -2147483648;
$this->max = 2147483647;
$value = func_get_args();
array_shift($value);
$this->setValueArray($value);
}
/**
* Format a rational number.
*
* The rational will be returned as a string with a slash '/'
* between the numerator and denominator. Care is taken to display
* '-1/2' instead of the ugly but mathematically equivalent '1/-2'.
*
* @param array the rational which will be formatted.
*
* @param boolean not used.
*
* @return string the rational formatted as a string suitable for
* display.
*/
function formatNumber($number, $brief = false) {
if ($number[1] < 0)
/* Turn output like 1/-2 into -1/2. */
return (-$number[0]) . '/' . (-$number[1]);
else
return $number[0] . '/' . $number[1];
}
/**
* Get the value of an entry as text.
*
* The value will be returned in a format suitable for presentation,
* e.g., rationals will be returned as 'x/y', ASCII strings will be
* returned as themselves etc.
*
* @param boolean some values can be returned in a long or more
* brief form, and this parameter controls that.
*
* @return string the value as text.
*/
function getText($brief = false) {
if (isset($this->value[0]))
$v = $this->value[0];
switch ($this->tag) {
case PelTag::SHUTTER_SPEED_VALUE:
//CC (e->components, 1, v);
//if (!v_srat.denominator) return (NULL);
return Pel::fmt('%.0f/%.0f sec. (APEX: %d)',
$v[0], $v[1], pow(sqrt(2), $v[0]/$v[1]));
case PelTag::BRIGHTNESS_VALUE:
//CC (e->components, 1, v);
//
// TODO: figure out the APEX thing, or remove this so that it is
// handled by the default clause at the bottom.
return sprintf('%d/%d', $v[0], $v[1]);
//FIXME: How do I calculate the APEX value?
case PelTag::EXPOSURE_BIAS_VALUE:
//CC (e->components, 1, v);
//if (!v_srat.denominator) return (NULL);
return sprintf('%s%.01f', $v[0]*$v[1] > 0 ? '+' : '', $v[0]/$v[1]);
default:
return parent::getText($brief);
}
}
}
?>

View File

@ -0,0 +1,599 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005, 2006 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelEntryShort.php 419 2006-02-20 16:22:36Z mgeisler $ */
/**
* Classes used to hold shorts, both signed and unsigned.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 419 $
* @date $Date: 2006-02-20 17:22:36 +0100 (Mon, 20 Feb 2006) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('PelEntryNumber.php');
require_once('PelConvert.php');
require_once('Pel.php');
/**#@-*/
/**
* Class for holding signed shorts.
*
* This class can hold shorts, either just a single short or an array
* of shorts. The class will be used to manipulate any of the Exif
* tags which has format {@link PelFormat::SHORT} like in this
* example:
*
* <code>
* $w = $ifd->getEntry(PelTag::EXIF_IMAGE_WIDTH);
* $w->setValue($w->getValue() / 2);
* $h = $ifd->getEntry(PelTag::EXIF_IMAGE_HEIGHT);
* $h->setValue($h->getValue() / 2);
* </code>
*
* Here the width and height is updated to 50% of their original
* values.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntryShort extends PelEntryNumber {
/**
* Make a new entry that can hold an unsigned short.
*
* The method accept several integer arguments. The {@link
* getValue} method will always return an array except for when a
* single integer argument is given here.
*
* This means that one can conveniently use objects like this:
* <code>
* $a = new PelEntryShort(PelTag::EXIF_IMAGE_HEIGHT, 42);
* $b = $a->getValue() + 314;
* </code>
* where the call to {@link getValue} will return an integer
* instead of an array with one integer element, which would then
* have to be extracted.
*
* @param PelTag the tag which this entry represents. This should be
* one of the constants defined in {@link PelTag}, e.g., {@link
* PelTag::IMAGE_WIDTH}, {@link PelTag::ISO_SPEED_RATINGS},
* or any other tag with format {@link PelFormat::SHORT}.
*
* @param int $value... the short(s) that this entry will
* represent. The argument passed must obey the same rules as the
* argument to {@link setValue}, namely that it should be within
* range of an unsigned short, that is between 0 and 65535
* (inclusive). If not, then a {@link PelOverFlowException} will be
* thrown.
*/
function __construct($tag /* $value... */) {
$this->tag = $tag;
$this->min = 0;
$this->max = 65535;
$this->format = PelFormat::SHORT;
$value = func_get_args();
array_shift($value);
$this->setValueArray($value);
}
/**
* Convert a number into bytes.
*
* @param int the number that should be converted.
*
* @param PelByteOrder one of {@link PelConvert::LITTLE_ENDIAN} and
* {@link PelConvert::BIG_ENDIAN}, specifying the target byte order.
*
* @return string bytes representing the number given.
*/
function numberToBytes($number, $order) {
return PelConvert::shortToBytes($number, $order);
}
/**
* Get the value of an entry as text.
*
* The value will be returned in a format suitable for presentation,
* e.g., instead of returning '2' for a {@link
* PelTag::METERING_MODE} tag, 'Center-Weighted Average' is
* returned.
*
* @param boolean some values can be returned in a long or more
* brief form, and this parameter controls that.
*
* @return string the value as text.
*/
function getText($brief = false) {
switch ($this->tag) {
case PelTag::METERING_MODE:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 0:
return Pel::tra('Unknown');
case 1:
return Pel::tra('Average');
case 2:
return Pel::tra('Center-Weighted Average');
case 3:
return Pel::tra('Spot');
case 4:
return Pel::tra('Multi Spot');
case 5:
return Pel::tra('Pattern');
case 6:
return Pel::tra('Partial');
case 255:
return Pel::tra('Other');
default:
return $this->value[0];
}
case PelTag::COMPRESSION:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 1:
return Pel::tra('Uncompressed');
case 6:
return Pel::tra('JPEG compression');
default:
return $this->value[0];
}
case PelTag::PLANAR_CONFIGURATION:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 1:
return Pel::tra('chunky format');
case 2:
return Pel::tra('planar format');
default:
return $this->value[0];
}
case PelTag::SENSING_METHOD:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 1:
return Pel::tra('Not defined');
case 2:
return Pel::tra('One-chip color area sensor');
case 3:
return Pel::tra('Two-chip color area sensor');
case 4:
return Pel::tra('Three-chip color area sensor');
case 5:
return Pel::tra('Color sequential area sensor');
case 7:
return Pel::tra('Trilinear sensor');
case 8:
return Pel::tra('Color sequential linear sensor');
default:
return $this->value[0];
}
case PelTag::LIGHT_SOURCE:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 0:
return Pel::tra('Unknown');
case 1:
return Pel::tra('Daylight');
case 2:
return Pel::tra('Fluorescent');
case 3:
return Pel::tra('Tungsten (incandescent light)');
case 4:
return Pel::tra('Flash');
case 9:
return Pel::tra('Fine weather');
case 10:
return Pel::tra('Cloudy weather');
case 11:
return Pel::tra('Shade');
case 12:
return Pel::tra('Daylight fluorescent');
case 13:
return Pel::tra('Day white fluorescent');
case 14:
return Pel::tra('Cool white fluorescent');
case 15:
return Pel::tra('White fluorescent');
case 17:
return Pel::tra('Standard light A');
case 18:
return Pel::tra('Standard light B');
case 19:
return Pel::tra('Standard light C');
case 20:
return Pel::tra('D55');
case 21:
return Pel::tra('D65');
case 22:
return Pel::tra('D75');
case 24:
return Pel::tra('ISO studio tungsten');
case 255:
return Pel::tra('Other');
default:
return $this->value[0];
}
case PelTag::FOCAL_PLANE_RESOLUTION_UNIT:
case PelTag::RESOLUTION_UNIT:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 2:
return Pel::tra('Inch');
case 3:
return Pel::tra('Centimeter');
default:
return $this->value[0];
}
case PelTag::EXPOSURE_PROGRAM:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 0:
return Pel::tra('Not defined');
case 1:
return Pel::tra('Manual');
case 2:
return Pel::tra('Normal program');
case 3:
return Pel::tra('Aperture priority');
case 4:
return Pel::tra('Shutter priority');
case 5:
return Pel::tra('Creative program (biased toward depth of field)');
case 6:
return Pel::tra('Action program (biased toward fast shutter speed)');
case 7:
return Pel::tra('Portrait mode (for closeup photos with the background out of focus');
case 8:
return Pel::tra('Landscape mode (for landscape photos with the background in focus');
default:
return $this->value[0];
}
case PelTag::ORIENTATION:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 1:
return Pel::tra('top - left');
case 2:
return Pel::tra('top - right');
case 3:
return Pel::tra('bottom - right');
case 4:
return Pel::tra('bottom - left');
case 5:
return Pel::tra('left - top');
case 6:
return Pel::tra('right - top');
case 7:
return Pel::tra('right - bottom');
case 8:
return Pel::tra('left - bottom');
default:
return $this->value[0];
}
case PelTag::YCBCR_POSITIONING:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 1:
return Pel::tra('centered');
case 2:
return Pel::tra('co-sited');
default:
return $this->value[0];
}
case PelTag::YCBCR_SUB_SAMPLING:
//CC (e->components, 2, v);
if ($this->value[0] == 2 && $this->value[1] == 1)
return 'YCbCr4:2:2';
if ($this->value[0] == 2 && $this->value[1] == 2)
return 'YCbCr4:2:0';
return $this->value[0] . ', ' . $this->value[1];
case PelTag::PHOTOMETRIC_INTERPRETATION:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 2:
return 'RGB';
case 6:
return 'YCbCr';
default:
return $this->value[0];
}
case PelTag::COLOR_SPACE:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 1:
return 'sRGB';
case 2:
return 'Adobe RGB';
case 0xffff:
return Pel::tra('Uncalibrated');
default:
return $this->value[0];
}
case PelTag::FLASH:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 0x0000:
return Pel::tra('Flash did not fire.');
case 0x0001:
return Pel::tra('Flash fired.');
case 0x0005:
return Pel::tra('Strobe return light not detected.');
case 0x0007:
return Pel::tra('Strobe return light detected.');
case 0x0009:
return Pel::tra('Flash fired, compulsory flash mode.');
case 0x000d:
return Pel::tra('Flash fired, compulsory flash mode, return light not detected.');
case 0x000f:
return Pel::tra('Flash fired, compulsory flash mode, return light detected.');
case 0x0010:
return Pel::tra('Flash did not fire, compulsory flash mode.');
case 0x0018:
return Pel::tra('Flash did not fire, auto mode.');
case 0x0019:
return Pel::tra('Flash fired, auto mode.');
case 0x001d:
return Pel::tra('Flash fired, auto mode, return light not detected.');
case 0x001f:
return Pel::tra('Flash fired, auto mode, return light detected.');
case 0x0020:
return Pel::tra('No flash function.');
case 0x0041:
return Pel::tra('Flash fired, red-eye reduction mode.');
case 0x0045:
return Pel::tra('Flash fired, red-eye reduction mode, return light not detected.');
case 0x0047:
return Pel::tra('Flash fired, red-eye reduction mode, return light detected.');
case 0x0049:
return Pel::tra('Flash fired, compulsory flash mode, red-eye reduction mode.');
case 0x004d:
return Pel::tra('Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected.');
case 0x004f:
return Pel::tra('Flash fired, compulsory flash mode, red-eye reduction mode, return light detected.');
case 0x0058:
return Pel::tra('Flash did not fire, auto mode, red-eye reduction mode.');
case 0x0059:
return Pel::tra('Flash fired, auto mode, red-eye reduction mode.');
case 0x005d:
return Pel::tra('Flash fired, auto mode, return light not detected, red-eye reduction mode.');
case 0x005f:
return Pel::tra('Flash fired, auto mode, return light detected, red-eye reduction mode.');
default:
return $this->value[0];
}
case PelTag::CUSTOM_RENDERED:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 0:
return Pel::tra('Normal process');
case 1:
return Pel::tra('Custom process');
default:
return $this->value[0];
}
case PelTag::EXPOSURE_MODE:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 0:
return Pel::tra('Auto exposure');
case 1:
return Pel::tra('Manual exposure');
case 2:
return Pel::tra('Auto bracket');
default:
return $this->value[0];
}
case PelTag::WHITE_BALANCE:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 0:
return Pel::tra('Auto white balance');
case 1:
return Pel::tra('Manual white balance');
default:
return $this->value[0];
}
case PelTag::SCENE_CAPTURE_TYPE:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 0:
return Pel::tra('Standard');
case 1:
return Pel::tra('Landscape');
case 2:
return Pel::tra('Portrait');
case 3:
return Pel::tra('Night scene');
default:
return $this->value[0];
}
case PelTag::GAIN_CONTROL:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 0:
return Pel::tra('Normal');
case 1:
return Pel::tra('Low gain up');
case 2:
return Pel::tra('High gain up');
case 3:
return Pel::tra('Low gain down');
case 4:
return Pel::tra('High gain down');
default:
return $this->value[0];
}
case PelTag::SATURATION:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 0:
return Pel::tra('Normal');
case 1:
return Pel::tra('Low saturation');
case 2:
return Pel::tra('High saturation');
default:
return $this->value[0];
}
case PelTag::CONTRAST:
case PelTag::SHARPNESS:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 0:
return Pel::tra('Normal');
case 1:
return Pel::tra('Soft');
case 2:
return Pel::tra('Hard');
default:
return $this->value[0];
}
case PelTag::SUBJECT_DISTANCE_RANGE:
//CC (e->components, 1, v);
switch ($this->value[0]) {
case 0:
return Pel::tra('Unknown');
case 1:
return Pel::tra('Macro');
case 2:
return Pel::tra('Close view');
case 3:
return Pel::tra('Distant view');
default:
return $this->value[0];
}
case PelTag::SUBJECT_AREA:
switch ($this->components) {
case 2:
return Pel::fmt('(x,y) = (%d,%d)', $this->value[0], $this->value[1]);
case 3:
return Pel::fmt('Within distance %d of (x,y) = (%d,%d)',
$this->value[0], $this->value[1], $this->value[2]);
case 4:
return Pel::fmt('Within rectangle (width %d, height %d) around (x,y) = (%d,%d)',
$this->value[0], $this->value[1],
$this->value[2], $this->value[3]);
default:
return Pel::fmt('Unexpected number of components (%d, expected 2, 3, or 4).', $this->components);
}
default:
return parent::getText($brief);
}
}
}
/**
* Class for holding signed shorts.
*
* This class can hold shorts, either just a single short or an array
* of shorts. The class will be used to manipulate any of the Exif
* tags which has format {@link PelFormat::SSHORT}.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntrySShort extends PelEntryNumber {
/**
* Make a new entry that can hold a signed short.
*
* The method accept several integer arguments. The {@link
* getValue} method will always return an array except for when a
* single integer argument is given here.
*
* @param PelTag the tag which this entry represents. This
* should be one of the constants defined in {@link PelTag}
* which has format {@link PelFormat::SSHORT}.
*
* @param int $value... the signed short(s) that this entry will
* represent. The argument passed must obey the same rules as the
* argument to {@link setValue}, namely that it should be within
* range of a signed short, that is between -32768 to 32767
* (inclusive). If not, then a {@link PelOverFlowException} will be
* thrown.
*/
function __construct($tag /* $value... */) {
$this->tag = $tag;
$this->min = -32768;
$this->max = 32767;
$this->format = PelFormat::SSHORT;
$value = func_get_args();
array_shift($value);
$this->setValueArray($value);
}
/**
* Convert a number into bytes.
*
* @param int the number that should be converted.
*
* @param PelByteOrder one of {@link PelConvert::LITTLE_ENDIAN} and
* {@link PelConvert::BIG_ENDIAN}, specifying the target byte order.
*
* @return string bytes representing the number given.
*/
function numberToBytes($number, $order) {
return PelConvert::sShortToBytes($number, $order);
}
}
?>

View File

@ -0,0 +1,416 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelEntryUndefined.php 380 2005-10-03 12:01:28Z mgeisler $ */
/**
* Classes used to hold data for Exif tags of format undefined.
*
* This file contains the base class {@link PelEntryUndefined} and
* the subclasses {@link PelEntryUserComment} which should be used
* to manage the {@link PelTag::USER_COMMENT} tag, and {@link
* PelEntryVersion} which is used to manage entries with version
* information.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 380 $
* @date $Date: 2005-10-03 14:01:28 +0200 (Mon, 03 Oct 2005) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('PelEntry.php');
/**#@-*/
/**
* Class for holding data of any kind.
*
* This class can hold bytes of undefined format.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntryUndefined extends PelEntry {
/**
* Make a new PelEntry that can hold undefined data.
*
* @param PelTag the tag which this entry represents. This
* should be one of the constants defined in {@link PelTag},
* e.g., {@link PelTag::SCENE_TYPE}, {@link
* PelTag::MAKER_NOTE} or any other tag with format {@link
* PelFormat::UNDEFINED}.
*
* @param string the data that this entry will be holding. Since
* the format is undefined, no checking will be done on the data.
*/
function __construct($tag, $data = '') {
$this->tag = $tag;
$this->format = PelFormat::UNDEFINED;
$this->setValue($data);
}
/**
* Set the data of this undefined entry.
*
* @param string the data that this entry will be holding. Since
* the format is undefined, no checking will be done on the data.
*/
function setValue($data) {
$this->components = strlen($data);
$this->bytes = $data;
}
/**
* Get the data of this undefined entry.
*
* @return string the data that this entry is holding.
*/
function getValue() {
return $this->bytes;
}
/**
* Get the value of this entry as text.
*
* The value will be returned in a format suitable for presentation.
*
* @param boolean some values can be returned in a long or more
* brief form, and this parameter controls that.
*
* @return string the value as text.
*/
function getText($brief = false) {
switch ($this->tag) {
case PelTag::FILE_SOURCE:
//CC (e->components, 1, v);
switch (ord($this->bytes{0})) {
case 0x03:
return 'DSC';
default:
return sprintf('0x%02X', ord($this->bytes{0}));
}
case PelTag::SCENE_TYPE:
//CC (e->components, 1, v);
switch (ord($this->bytes{0})) {
case 0x01:
return 'Directly photographed';
default:
return sprintf('0x%02X', ord($this->bytes{0}));
}
case PelTag::COMPONENTS_CONFIGURATION:
//CC (e->components, 4, v);
$v = '';
for ($i = 0; $i < 4; $i++) {
switch (ord($this->bytes{$i})) {
case 0:
$v .= '-';
break;
case 1:
$v .= 'Y';
break;
case 2:
$v .= 'Cb';
break;
case 3:
$v .= 'Cr';
break;
case 4:
$v .= 'R';
break;
case 5:
$v .= 'G';
break;
case 6:
$v .= 'B';
break;
default:
$v .= 'reserved';
break;
}
if ($i < 3) $v .= ' ';
}
return $v;
case PelTag::MAKER_NOTE:
// TODO: handle maker notes.
return $this->components . ' bytes unknown MakerNote data';
default:
return '(undefined)';
}
}
}
/**
* Class for a user comment.
*
* This class is used to hold user comments, which can come in several
* different character encodings. The Exif standard specifies a
* certain format of the {@link PelTag::USER_COMMENT user comment
* tag}, and this class will make sure that the format is kept.
*
* The most basic use of this class simply stores an ASCII encoded
* string for later retrieval using {@link getValue}:
*
* <code>
* $entry = new PelEntryUserComment('An ASCII string');
* echo $entry->getValue();
* </code>
*
* The string can be encoded with a different encoding, and if so, the
* encoding must be given using the second argument. The Exif
* standard specifies three known encodings: 'ASCII', 'JIS', and
* 'Unicode'. If the user comment is encoded using a character
* encoding different from the tree known encodings, then the empty
* string should be passed as encoding, thereby specifying that the
* encoding is undefined.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntryUserComment extends PelEntryUndefined {
/**
* The user comment.
*
* @var string
*/
private $comment;
/**
* The encoding.
*
* This should be one of 'ASCII', 'JIS', 'Unicode', or ''.
*
* @var string
*/
private $encoding;
/**
* Make a new entry for holding a user comment.
*
* @param string the new user comment.
*
* @param string the encoding of the comment. This should be either
* 'ASCII', 'JIS', 'Unicode', or the empty string specifying an
* undefined encoding.
*/
function __construct($comment = '', $encoding = 'ASCII') {
parent::__construct(PelTag::USER_COMMENT);
$this->setValue($comment, $encoding);
}
/**
* Set the user comment.
*
* @param string the new user comment.
*
* @param string the encoding of the comment. This should be either
* 'ASCII', 'JIS', 'Unicode', or the empty string specifying an
* unknown encoding.
*/
function setValue($comment = '', $encoding = 'ASCII') {
$this->comment = $comment;
$this->encoding = $encoding;
parent::setValue(str_pad($encoding, 8, chr(0)) . $comment);
}
/**
* Returns the user comment.
*
* The comment is returned with the same character encoding as when
* it was set using {@link setValue} or {@link __construct the
* constructor}.
*
* @return string the user comment.
*/
function getValue() {
return $this->comment;
}
/**
* Returns the encoding.
*
* @return string the encoding of the user comment.
*/
function getEncoding() {
return $this->encoding;
}
/**
* Returns the user comment.
*
* @return string the user comment.
*/
function getText($brief = false) {
return $this->comment;
}
}
/**
* Class to hold version information.
*
* There are three Exif entries that hold version information: the
* {@link PelTag::EXIF_VERSION}, {@link
* PelTag::FLASH_PIX_VERSION}, and {@link
* PelTag::INTEROPERABILITY_VERSION} tags. This class manages
* those tags.
*
* The class is used in a very straight-forward way:
* <code>
* $entry = new PelEntryVersion(PelTag::EXIF_VERSION, 2.2);
* </code>
* This creates an entry for an file complying to the Exif 2.2
* standard. It is easy to test for standards level of an unknown
* entry:
* <code>
* if ($entry->getTag() == PelTag::EXIF_VERSION &&
* $entry->getValue() > 2.0) {
* echo 'Recent Exif version.';
* }
* </code>
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelEntryVersion extends PelEntryUndefined {
/**
* The version held by this entry.
*
* @var float
*/
private $version;
/**
* Make a new entry for holding a version.
*
* @param PelTag the tag. This should be one of {@link
* PelTag::EXIF_VERSION}, {@link PelTag::FLASH_PIX_VERSION},
* or {@link PelTag::INTEROPERABILITY_VERSION}.
*
* @param float the version. The size of the entries leave room for
* exactly four digits: two digits on either side of the decimal
* point.
*/
function __construct($tag, $version = 0.0) {
parent::__construct($tag);
$this->setValue($version);
}
/**
* Set the version held by this entry.
*
* @param float the version. The size of the entries leave room for
* exactly four digits: two digits on either side of the decimal
* point.
*/
function setValue($version = 0.0) {
$this->version = $version;
$major = floor($version);
$minor = ($version - $major)*100;
parent::setValue(sprintf('%02.0f%02.0f', $major, $minor));
}
/**
* Return the version held by this entry.
*
* @return float the version. This will be the same as the value
* given to {@link setValue} or {@link __construct the
* constructor}.
*/
function getValue() {
return $this->version;
}
/**
* Return a text string with the version.
*
* @param boolean controls if the output should be brief. Brief
* output omits the word 'Version' so the result is just 'Exif x.y'
* instead of 'Exif Version x.y' if the entry holds information
* about the Exif version --- the output for FlashPix is similar.
*
* @return string the version number with the type of the tag,
* either 'Exif' or 'FlashPix'.
*/
function getText($brief = false) {
$v = $this->version;
/* Versions numbers like 2.0 would be output as just 2 if we don't
* add the '.0' ourselves. */
if (floor($this->version) == $this->version)
$v .= '.0';
switch ($this->tag) {
case PelTag::EXIF_VERSION:
if ($brief)
return Pel::fmt('Exif %s', $v);
else
return Pel::fmt('Exif Version %s', $v);
case PelTag::FLASH_PIX_VERSION:
if ($brief)
return Pel::fmt('FlashPix %s', $v);
else
return Pel::fmt('FlashPix Version %s', $v);
case PelTag::INTEROPERABILITY_VERSION:
if ($brief)
return Pel::fmt('Interoperability %s', $v);
else
return Pel::fmt('Interoperability Version %s', $v);
}
if ($brief)
return $v;
else
return Pel::fmt('Version %s', $v);
}
}
?>

View File

@ -0,0 +1,87 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelException.php 396 2005-10-23 22:36:10Z mgeisler $ */
/**
* Standard PEL exception.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 396 $
* @date $Date: 2005-10-24 00:36:10 +0200 (Mon, 24 Oct 2005) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**
* A printf() capable exception.
*
* This class is a simple extension of the standard Exception class in
* PHP, and all the methods defined there retain their original
* meaning.
*
* @package PEL
* @subpackage Exception
*/
class PelException extends Exception {
/**
* Construct a new PEL exception.
*
* @param string $fmt an optional format string can be given. It
* will be used as a format string for vprintf(). The remaining
* arguments will be available for the format string as usual with
* vprintf().
*
* @param mixed $args,... any number of arguments to be used with
* the format string.
*/
function __construct(/* fmt, args... */) {
$args = func_get_args();
$fmt = array_shift($args);
parent::__construct(vsprintf($fmt, $args));
}
}
/**
* Exception throw if invalid data is found.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
* @subpackage Exception
*/
class PelInvalidDataException extends PelException {}
/**
* Exception throw if an invalid argument is passed.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
* @subpackage Exception
*/
class PelInvalidArgumentException extends PelException {}
?>

View File

@ -0,0 +1,175 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelExif.php 380 2005-10-03 12:01:28Z mgeisler $ */
/**
* Classes for dealing with Exif data.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 380 $
* @date $Date: 2005-10-03 14:01:28 +0200 (Mon, 03 Oct 2005) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('PelJpegContent.php');
require_once('PelException.php');
require_once('PelFormat.php');
require_once('PelEntry.php');
require_once('PelTiff.php');
require_once('PelIfd.php');
require_once('PelTag.php');
require_once('Pel.php');
/**#@-*/
/**
* Class representing Exif data.
*
* Exif data resides as {@link PelJpegContent data} and consists of a
* header followed by a number of {@link PelJpegIfd IFDs}.
*
* The interesting method in this class is {@link getTiff()} which
* will return the {@link PelTiff} object which really holds the data
* which one normally think of when talking about Exif data. This is
* because Exif data is stored as an extension of the TIFF file
* format.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelExif extends PelJpegContent {
/**
* Exif header.
*
* The Exif data must start with these six bytes to be considered
* valid.
*/
const EXIF_HEADER = "Exif\0\0";
/**
* The PelTiff object contained within.
*
* @var PelTiff
*/
private $tiff = null;
/**
* Construct a new Exif object.
*
* The new object will be empty --- use the {@link load()} method to
* load Exif data from a {@link PelDataWindow} object, or use the
* {@link setTiff()} to change the {@link PelTiff} object, which is
* the true holder of the Exif {@link PelEntry entries}.
*/
function __construct() {
}
/**
* Load and parse Exif data.
*
* This will populate the object with Exif data, contained as a
* {@link PelTiff} object. This TIFF object can be accessed with
* the {@link getTiff()} method.
*/
function load(PelDataWindow $d) {
Pel::debug('Parsing %d bytes of Exif data...', $d->getSize());
/* There must be at least 6 bytes for the Exif header. */
if ($d->getSize() < 6)
throw new PelInvalidDataException('Expected at least 6 bytes of Exif ' .
'data, found just %d bytes.',
$d->getSize());
/* Verify the Exif header */
if ($d->strcmp(0, self::EXIF_HEADER)) {
$d->setWindowStart(strlen(self::EXIF_HEADER));
} else {
throw new PelInvalidDataException('Exif header not found.');
}
/* The rest of the data is TIFF data. */
$this->tiff = new PelTiff();
$this->tiff->load($d);
}
/**
* Change the TIFF information.
*
* Exif data is really stored as TIFF data, and this method can be
* used to change this data from one {@link PelTiff} object to
* another.
*
* @param PelTiff the new TIFF object.
*/
function setTiff(PelTiff $tiff) {
$this->tiff = $tiff;
}
/**
* Get the underlying TIFF object.
*
* The actual Exif data is stored in a {@link PelTiff} object, and
* this method provides access to it.
*
* @return PelTiff the TIFF object with the Exif data.
*/
function getTiff() {
return $this->tiff;
}
/**
* Produce bytes for the Exif data.
*
* @return string bytes representing this object.
*/
function getBytes() {
return self::EXIF_HEADER . $this->tiff->getBytes();
}
/**
* Return a string representation of this object.
*
* @return string a string describing this object. This is mostly
* useful for debugging.
*/
function __toString() {
return Pel::tra("Dumping Exif data...\n") .
$this->tiff->__toString();
}
}
?>

View File

@ -0,0 +1,225 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelFormat.php 380 2005-10-03 12:01:28Z mgeisler $ */
/**
* Namespace for functions operating on Exif formats.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 380 $
* @date $Date: 2005-10-03 14:01:28 +0200 (Mon, 03 Oct 2005) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**
* Namespace for functions operating on Exif formats.
*
* This class defines the constants that are to be used whenever one
* has to refer to the format of an Exif tag. They will be
* collectively denoted by the pseudo-type PelFormat throughout the
* documentation.
*
* All the methods defined here are static, and they all operate on a
* single argument which should be one of the class constants.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelFormat {
/**
* Unsigned byte.
*
* Each component will be an unsigned 8-bit integer with a value
* between 0 and 255.
*
* Modelled with the {@link PelEntryByte} class.
*/
const BYTE = 1;
/**
* ASCII string.
*
* Each component will be an ASCII character.
*
* Modelled with the {@link PelEntryAscii} class.
*/
const ASCII = 2;
/**
* Unsigned short.
*
* Each component will be an unsigned 16-bit integer with a value
* between 0 and 65535.
*
* Modelled with the {@link PelEntryShort} class.
*/
const SHORT = 3;
/**
* Unsigned long.
*
* Each component will be an unsigned 32-bit integer with a value
* between 0 and 4294967295.
*
* Modelled with the {@link PelEntryLong} class.
*/
const LONG = 4;
/**
* Unsigned rational number.
*
* Each component will consist of two unsigned 32-bit integers
* denoting the enumerator and denominator. Each integer will have
* a value between 0 and 4294967295.
*
* Modelled with the {@link PelEntryRational} class.
*/
const RATIONAL = 5;
/**
* Signed byte.
*
* Each component will be a signed 8-bit integer with a value
* between -128 and 127.
*
* Modelled with the {@link PelEntrySByte} class.
*/
const SBYTE = 6;
/**
* Undefined byte.
*
* Each component will be a byte with no associated interpretation.
*
* Modelled with the {@link PelEntryUndefined} class.
*/
const UNDEFINED = 7;
/**
* Signed short.
*
* Each component will be a signed 16-bit integer with a value
* between -32768 and 32767.
*
* Modelled with the {@link PelEntrySShort} class.
*/
const SSHORT = 8;
/**
* Signed long.
*
* Each component will be a signed 32-bit integer with a value
* between -2147483648 and 2147483647.
*
* Modelled with the {@link PelEntrySLong} class.
*/
const SLONG = 9;
/**
* Signed rational number.
*
* Each component will consist of two signed 32-bit integers
* denoting the enumerator and denominator. Each integer will have
* a value between -2147483648 and 2147483647.
*
* Modelled with the {@link PelEntrySRational} class.
*/
const SRATIONAL = 10;
/**
* Floating point number.
*
* Entries with this format are not currently implemented.
*/
const FLOAT = 11;
/**
* Double precision floating point number.
*
* Entries with this format are not currently implemented.
*/
const DOUBLE = 12;
/**
* Returns the name of a format.
*
* @param PelFormat the format.
*
* @return string the name of the format, e.g., 'Ascii' for the
* {@link ASCII} format etc.
*/
static function getName($type) {
switch ($type) {
case self::ASCII: return 'Ascii';
case self::BYTE: return 'Byte';
case self::SHORT: return 'Short';
case self::LONG: return 'Long';
case self::RATIONAL: return 'Rational';
case self::SBYTE: return 'SByte';
case self::SSHORT: return 'SShort';
case self::SLONG: return 'SLong';
case self::SRATIONAL: return 'SRational';
case self::FLOAT: return 'Float';
case self::DOUBLE: return 'Double';
case self::UNDEFINED: return 'Undefined';
default:
return Pel::fmt('Unknown format: 0x%X', $type);
}
}
/**
* Return the size of components in a given format.
*
* @param PelFormat the format.
*
* @return the size in bytes needed to store one component with the
* given format.
*/
static function getSize($type) {
switch ($type) {
case self::ASCII: return 1;
case self::BYTE: return 1;
case self::SHORT: return 2;
case self::LONG: return 4;
case self::RATIONAL: return 8;
case self::SBYTE: return 1;
case self::SSHORT: return 2;
case self::SLONG: return 4;
case self::SRATIONAL: return 8;
case self::FLOAT: return 4;
case self::DOUBLE: return 8;
case self::UNDEFINED: return 1;
default:
return Pel::fmt('Unknown format: 0x%X', $type);
}
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,599 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005, 2006 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelJpeg.php 473 2006-11-23 23:12:21Z mgeisler $ */
/**
* Classes representing JPEG data.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 473 $
* @date $Date: 2006-11-24 00:12:21 +0100 (Fri, 24 Nov 2006) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('PelJpegComment.php');
require_once('PelJpegContent.php');
require_once('PelDataWindow.php');
require_once('PelJpegMarker.php');
require_once('PelException.php');
require_once('PelExif.php');
require_once('Pel.php');
/**#@-*/
/**
* Exception thrown when an invalid marker is found.
*
* This exception is thrown when PEL expects to find a {@link
* PelJpegMarker} and instead finds a byte that isn't a known marker.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
* @subpackage Exception
*/
class PelJpegInvalidMarkerException extends PelException {
/**
* Construct a new invalid marker exception.
*
* The exception will contain a message describing the error,
* including the byte found and the offset of the offending byte.
*
* @param int the byte found.
*
* @param int the offset in the data.
*/
function __construct($marker, $offset) {
parent::__construct('Invalid marker found at offset %d: 0x%2X',
$offset, $marker);
}
}
/**
* Class for handling JPEG data.
*
* The {@link PelJpeg} class defined here provides an abstraction for
* dealing with a JPEG file. The file will be contain a number of
* sections containing some {@link PelJpegContent content} identified
* by a {@link PelJpegMarker marker}.
*
* The {@link getExif()} method is used get hold of the {@link
* PelJpegMarker::APP1 APP1} section which stores Exif data. So if
* the name of the JPEG file is stored in $filename, then one would
* get hold of the Exif data by saying:
*
* <code>
* $jpeg = new PelJpeg($filename);
* $exif = $jpeg->getExif();
* $tiff = $exif->getTiff();
* $ifd0 = $tiff->getIfd();
* $exif = $ifd0->getSubIfd(PelIfd::EXIF);
* $ifd1 = $ifd0->getNextIfd();
* </code>
*
* The $idf0 and $ifd1 variables will then be two {@link PelTiff TIFF}
* {@link PelIfd Image File Directories}, in which the data is stored
* under the keys found in {@link PelTag}.
*
* Should one have some image data (in the form of a {@link
* PelDataWindow}) of an unknown type, then the {@link
* PelJpeg::isValid()} function is handy: it will quickly test if the
* data could be valid JPEG data. The {@link PelTiff::isValid()}
* function does the same for TIFF images.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelJpeg {
/**
* The sections in the JPEG data.
*
* A JPEG file is built up as a sequence of sections, each section
* is identified with a {@link PelJpegMarker}. Some sections can
* occur more than once in the JPEG stream (the {@link
* PelJpegMarker::DQT DQT} and {@link PelJpegMarker::DHT DTH}
* markers for example) and so this is an array of ({@link
* PelJpegMarker}, {@link PelJpegContent}) pairs.
*
* The content can be either generic {@link PelJpegContent JPEG
* content} or {@link PelExif Exif data}.
*
* @var array
*/
private $sections = array();
/**
* The JPEG image data.
*
* @var PelDataWindow
*/
private $jpeg_data = null;
/**
* Construct a new JPEG object.
*
* The new object will be empty unless an argument is given from
* which it can initialize itself. This can either be the filename
* of a JPEG image, a {@link PelDataWindow} object or a PHP image
* resource handle.
*
* New Exif data (in the form of a {@link PelExif} object) can be
* inserted with the {@link setExif()} method:
*
* <code>
* $jpeg = new PelJpeg($data);
* // Create container for the Exif information:
* $exif = new PelExif();
* // Now Add a PelTiff object with a PelIfd object with one or more
* // PelEntry objects to $exif... Finally add $exif to $jpeg:
* $jpeg->setExif($exif);
* </code>
*/
function __construct($data = false) {
if ($data === false)
return;
if (is_string($data)) {
Pel::debug('Initializing PelJpeg object from %s', $data);
$this->loadFile($data);
} elseif ($data instanceof PelDataWindow) {
Pel::debug('Initializing PelJpeg object from PelDataWindow.');
$this->load($data);
} elseif (is_resource($data) && get_resource_type($data) == 'gd') {
Pel::debug('Initializing PelJpeg object from image resource.');
/* The ImageJpeg() function insists on printing the bytes
* instead of returning them in a more civil way as a string, so
* we have to buffer the output... */
ob_start();
ImageJpeg($data);
$bytes = ob_get_clean();
$this->load(new PelDataWindow($bytes));
} else {
throw new PelInvalidArgumentException('Bad type for $data: %s',
gettype($data));
}
}
/**
* Load data into a JPEG object.
*
* The data supplied will be parsed and turned into an object
* structure representing the image. This structure can then be
* manipulated and later turned back into an string of bytes.
*
* This methods can be called at any time after a JPEG object has
* been constructed, also after the {@link appendSection()} has been
* called to append custom sections. Loading several JPEG images
* into one object will accumulate the sections, but there will only
* be one {@link PelJpegMarker::SOS} section at any given time.
*
* @param PelDataWindow the data that will be turned into JPEG
* sections.
*/
function load(PelDataWindow $d) {
Pel::debug('Parsing %d bytes...', $d->getSize());
/* JPEG data is stored in big-endian format. */
$d->setByteOrder(PelConvert::BIG_ENDIAN);
/* Run through the data to read the sections in the image. After
* each section is read, the start of the data window will be
* moved forward, and after the last section we'll terminate with
* no data left in the window. */
while ($d->getSize() > 0) {
/* JPEG sections start with 0xFF. The first byte that is not
* 0xFF is a marker (hopefully).
*/
for ($i = 0; $i < 7; $i++)
if ($d->getByte($i) != 0xFF)
break;
$marker = $d->getByte($i);
if (!PelJpegMarker::isValid($marker))
throw new PelJpegInvalidMarkerException($marker, $i);
/* Move window so first byte becomes first byte in this
* section. */
$d->setWindowStart($i+1);
if ($marker == PelJpegMarker::SOI || $marker == PelJpegMarker::EOI) {
$content = new PelJpegContent(new PelDataWindow());
$this->appendSection($marker, $content);
} else {
/* Read the length of the section. The length includes the
* two bytes used to store the length. */
$len = $d->getShort(0) - 2;
Pel::debug('Found %s section of length %d',
PelJpegMarker::getName($marker), $len);
/* Skip past the length. */
$d->setWindowStart(2);
if ($marker == PelJpegMarker::APP1) {
try {
$content = new PelExif();
$content->load($d->getClone(0, $len));
} catch (PelInvalidDataException $e) {
/* We store the data as normal JPEG content if it could
* not be parsed as Exif data. */
$content = new PelJpegContent($d->getClone(0, $len));
}
$this->appendSection($marker, $content);
/* Skip past the data. */
$d->setWindowStart($len);
} elseif ($marker == PelJpegMarker::COM) {
$content = new PelJpegComment();
$content->load($d->getClone(0, $len));
$this->appendSection($marker, $content);
$d->setWindowStart($len);
} else {
$content = new PelJpegContent($d->getClone(0, $len));
$this->appendSection($marker, $content);
/* Skip past the data. */
$d->setWindowStart($len);
/* In case of SOS, image data will follow. */
if ($marker == PelJpegMarker::SOS) {
/* Some images have some trailing (garbage?) following the
* EOI marker. To handle this we seek backwards until we
* find the EOI marker. Any trailing content is stored as
* a PelJpegContent object. */
$length = $d->getSize();
while ($d->getByte($length-2) != 0xFF ||
$d->getByte($length-1) != PelJpegMarker::EOI) {
$length--;
}
$this->jpeg_data = $d->getClone(0, $length-2);
Pel::debug('JPEG data: ' . $this->jpeg_data->__toString());
/* Append the EOI. */
$this->appendSection(PelJpegMarker::EOI,
new PelJpegContent(new PelDataWindow()));
/* Now check to see if there are any trailing data. */
if ($length != $d->getSize()) {
Pel::maybeThrow(new PelException('Found trailing content ' .
'after EOI: %d bytes',
$d->getSize() - $length));
$content = new PelJpegContent($d->getClone($length));
/* We don't have a proper JPEG marker for trailing
* garbage, so we just use 0x00... */
$this->appendSection(0x00, $content);
}
/* Done with the loop. */
break;
}
}
}
} /* while ($d->getSize() > 0) */
}
/**
* Load data from a file into a JPEG object.
*
* @param string the filename. This must be a readable file.
*/
function loadFile($filename) {
$this->load(new PelDataWindow(file_get_contents($filename)));
}
/**
* Set Exif data.
*
* Use this to set the Exif data in the image. This will overwrite
* any old Exif information in the image.
*
* @param PelExif the Exif data.
*/
function setExif(PelExif $exif) {
$app0_offset = 1;
$app1_offset = -1;
/* Search through all sections looking for APP0 or APP1. */
for ($i = 0; $i < count($this->sections); $i++) {
if ($this->sections[$i][0] == PelJpegMarker::APP0) {
$app0_offset = $i;
} elseif ($this->sections[$i][0] == PelJpegMarker::APP1) {
$app1_offset = $i;
break;
}
}
/* Store the Exif data at the appropriate place, either where the
* old Exif data was stored ($app1_offset) or right after APP0
* ($app0_offset+1). */
if ($app1_offset > 0)
$this->sections[$app1_offset][1] = $exif;
else
$this->insertSection(PelJpegMarker::APP1, $exif, $app0_offset+1);
}
/**
* Get Exif data.
*
* Use this to get the @{link PelExif Exif data} stored.
*
* @return PelExif the Exif data found or null if the image has no
* Exif data.
*/
function getExif() {
$exif = $this->getSection(PelJpegMarker::APP1);
if ($exif instanceof PelExif)
return $exif;
else
return null;
}
/**
* Clear any Exif data.
*
* This method will only clear the first @{link PelJpegMarker::APP1}
* section found (there should normally be just one).
*/
function clearExif() {
for ($i = 0; $i < count($this->sections); $i++) {
if ($this->sections[$i][0] == PelJpegMarker::APP1) {
unset($this->sections[$i]);
return;
}
}
}
/**
* Append a new section.
*
* Used only when loading an image. If it used again later, then the
* section will end up after the @{link PelJpegMarker::EOI EOI
* marker} and will probably not be useful.
*
* Please use @{link setExif()} instead if you intend to add Exif
* information to an image as that function will know the right
* place to insert the data.
*
* @param PelJpegMarker the marker identifying the new section.
*
* @param PelJpegContent the content of the new section.
*/
function appendSection($marker, PelJpegContent $content) {
$this->sections[] = array($marker, $content);
}
/**
* Insert a new section.
*
* Please use @{link setExif()} instead if you intend to add Exif
* information to an image as that function will know the right
* place to insert the data.
*
* @param PelJpegMarker the marker for the new section.
*
* @param PelJpegContent the content of the new section.
*
* @param int the offset where the new section will be inserted ---
* use 0 to insert it at the very beginning, use 1 to insert it
* between sections 1 and 2, etc.
*/
function insertSection($marker, PelJpegContent $content, $offset) {
array_splice($this->sections, $offset, 0, array(array($marker, $content)));
}
/**
* Get a section corresponding to a particular marker.
*
* Please use the {@link getExif()} if you just need the Exif data.
*
* This will search through the sections of this JPEG object,
* looking for a section identified with the specified {@link
* PelJpegMarker marker}. The {@link PelJpegContent content} will
* then be returned. The optional argument can be used to skip over
* some of the sections. So if one is looking for the, say, third
* {@link PelJpegMarker::DHT DHT} section one would do:
*
* <code>
* $dht3 = $jpeg->getSection(PelJpegMarker::DHT, 2);
* </code>
*
* @param PelJpegMarker the marker identifying the section.
*
* @param int the number of sections to be skipped. This must be a
* non-negative integer.
*
* @return PelJpegContent the content found, or null if there is no
* content available.
*/
function getSection($marker, $skip = 0) {
foreach ($this->sections as $s) {
if ($s[0] == $marker)
if ($skip > 0)
$skip--;
else
return $s[1];
}
return null;
}
/**
* Get all sections.
*
* @return array an array of ({@link PelJpegMarker}, {@link
* PelJpegContent}) pairs. Each pair is an array with the {@link
* PelJpegMarker} as the first element and the {@link
* PelJpegContent} as the second element, so the return type is an
* array of arrays.
*
* So to loop through all the sections in a given JPEG image do
* this:
*
* <code>
* foreach ($jpeg->getSections() as $section) {
* $marker = $section[0];
* $content = $section[1];
* // Use $marker and $content here.
* }
* </code>
*
* instead of this:
*
* <code>
* foreach ($jpeg->getSections() as $marker => $content) {
* // Does not work the way you would think...
* }
* </code>
*
* The problem is that there could be several sections with the same
* marker, and thus a simple associative array does not suffice.
*/
function getSections() {
return $this->sections;
}
/**
* Turn this JPEG object into bytes.
*
* The bytes returned by this method is ready to be stored in a file
* as a valid JPEG image.
*
* @return string bytes representing this JPEG object, including all
* its sections and their associated data.
*/
function getBytes() {
$bytes = '';
foreach ($this->sections as $section) {
$m = $section[0];
$c = $section[1];
/* Write the marker */
$bytes .= "\xFF" . PelJpegMarker::getBytes($m);
/* Skip over empty markers. */
if ($m == PelJpegMarker::SOI || $m == PelJpegMarker::EOI)
continue;
$data = $c->getBytes();
$size = strlen($data) + 2;
$bytes .= PelConvert::shortToBytes($size, PelConvert::BIG_ENDIAN);
$bytes .= $data;
/* In case of SOS, we need to write the JPEG data. */
if ($m == PelJpegMarker::SOS)
$bytes .= $this->jpeg_data->getBytes();
}
return $bytes;
}
/**
* Make a string representation of this JPEG object.
*
* This is mainly usefull for debugging. It will show the structure
* of the image, and its sections.
*
* @return string debugging information about this JPEG object.
*/
function __toString() {
$str = Pel::tra("Dumping JPEG data...\n");
for ($i = 0; $i < count($this->sections); $i++) {
$m = $this->sections[$i][0];
$c = $this->sections[$i][1];
$str .= Pel::fmt("Section %d (marker 0x%02X - %s):\n",
$i, $m, PelJpegMarker::getName($m));
$str .= Pel::fmt(" Description: %s\n",
PelJpegMarker::getDescription($m));
if ($m == PelJpegMarker::SOI ||
$m == PelJpegMarker::EOI)
continue;
if ($c instanceof PelExif) {
$str .= Pel::tra(" Content : Exif data\n");
$str .= $c->__toString() . "\n";
} elseif ($c instanceof PelJpegComment) {
$str .= Pel::fmt(" Content : %s\n", $c->getValue());
} else {
$str .= Pel::tra(" Content : Unknown\n");
}
}
return $str;
}
/**
* Test data to see if it could be a valid JPEG image.
*
* The function will only look at the first few bytes of the data,
* and try to determine if it could be a valid JPEG image based on
* those bytes. This means that the check is more like a heuristic
* than a rigorous check.
*
* @param PelDataWindow the bytes that will be checked.
*
* @return boolean true if the bytes look like the beginning of a
* JPEG image, false otherwise.
*
* @see PelTiff::isValid()
*/
static function isValid(PelDataWindow $d) {
/* JPEG data is stored in big-endian format. */
$d->setByteOrder(PelConvert::BIG_ENDIAN);
for ($i = 0; $i < 7; $i++)
if ($d->getByte($i) != 0xFF)
break;
return $d->getByte($i) == PelJpegMarker::SOI;
}
}
?>

View File

@ -0,0 +1,121 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2005 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelJpegComment.php 397 2005-10-23 22:40:26Z mgeisler $ */
/**
* Class for dealing with JPEG comments.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 397 $
* @date $Date: 2005-10-24 00:40:26 +0200 (Mon, 24 Oct 2005) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('PelJpegContent.php');
/**#@-*/
/**
* Class representing JPEG comments.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelJpegComment extends PelJpegContent {
/**
* The comment.
*
* @var string
*/
private $comment = '';
/**
* Construct a new JPEG comment.
*
* The new comment will contain the string given.
*/
function __construct($comment = '') {
$this->comment = $comment;
}
/**
* Load and parse data.
*
* This will load the comment from the data window passed.
*/
function load(PelDataWindow $d) {
$this->comment = $d->getBytes();
}
/**
* Update the value with a new comment.
*
* Any old comment will be overwritten.
*
* @param string the new comment.
*/
function setValue($comment) {
$this->comment = $comment;
}
/**
* Get the comment.
*
* @return string the comment.
*/
function getValue() {
return $this->comment;
}
/**
* Turn this comment into bytes.
*
* @return string bytes representing this comment.
*/
function getBytes() {
$this->comment;
}
/**
* Return a string representation of this object.
*
* @return string the same as {@link getValue()}.
*/
function __toString() {
return $this->getValue();
}
}
?>

View File

@ -0,0 +1,82 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelJpegContent.php 380 2005-10-03 12:01:28Z mgeisler $ */
/**
* Class representing content in a JPEG file.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 380 $
* @date $Date: 2005-10-03 14:01:28 +0200 (Mon, 03 Oct 2005) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('PelDataWindow.php');
/**#@-*/
/**
* Class representing content in a JPEG file.
*
* A JPEG file consists of a sequence of each of which has an
* associated {@link PelJpegMarker marker} and some content. This
* class represents the content, and this basic type is just a simple
* holder of such content, represented by a {@link PelDataWindow}
* object. The {@link PelExif} class is an example of more
* specialized JPEG content.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelJpegContent {
private $data = null;
/**
* Make a new piece of JPEG content.
*
* @param PelDataWindow the content.
*/
function __construct(PelDataWindow $data) {
$this->data = $data;
}
/**
* Return the bytes of the content.
*
* @return string bytes representing this JPEG content. These bytes
* will match the bytes given to {@link __construct the
* constructor}.
*/
function getBytes() {
return $this->data->getBytes();
}
}
?>

View File

@ -0,0 +1,435 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005, 2006 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelJpegMarker.php 432 2006-09-05 22:13:00Z mgeisler $ */
/**
* Classes for dealing with JPEG markers.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 432 $
* @date $Date: 2006-09-06 00:13:00 +0200 (Wed, 06 Sep 2006) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('Pel.php');
/**#@-*/
/**
* Class with static methods for JPEG markers.
*
* This class defines the constants to be used whenever one refers to
* a JPEG marker. All the methods defined are static, and they all
* operate on one argument which should be one of the class constants.
* They will all be denoted by PelJpegMarker in the documentation.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelJpegMarker {
/** Encoding (baseline) */
const SOF0 = 0xC0;
/** Encoding (extended sequential) */
const SOF1 = 0xC1;
/** Encoding (progressive) */
const SOF2 = 0xC2;
/** Encoding (lossless) */
const SOF3 = 0xC3;
/** Define Huffman table */
const DHT = 0xC4;
/** Encoding (differential sequential) */
const SOF5 = 0xC5;
/** Encoding (differential progressive) */
const SOF6 = 0xC6;
/** Encoding (differential lossless) */
const SOF7 = 0xC7;
/** Extension */
const JPG = 0xC8;
/** Encoding (extended sequential, arithmetic) */
const SOF9 = 0xC9;
/** Encoding (progressive, arithmetic) */
const SOF10 = 0xCA;
/** Encoding (lossless, arithmetic) */
const SOF11 = 0xCB;
/** Define arithmetic coding conditioning */
const DAC = 0xCC;
/** Encoding (differential sequential, arithmetic) */
const SOF13 = 0xCD;
/** Encoding (differential progressive, arithmetic) */
const SOF14 = 0xCE;
/** Encoding (differential lossless, arithmetic) */
const SOF15 = 0xCF;
/** Restart 0 */
const RST0 = 0xD0;
/** Restart 1 */
const RST1 = 0xD1;
/** Restart 2 */
const RST2 = 0xD2;
/** Restart 3 */
const RST3 = 0xD3;
/** Restart 4 */
const RST4 = 0xD4;
/** Restart 5 */
const RST5 = 0xD5;
/** Restart 6 */
const RST6 = 0xD6;
/** Restart 7 */
const RST7 = 0xD7;
/** Start of image */
const SOI = 0xD8;
/** End of image */
const EOI = 0xD9;
/** Start of scan */
const SOS = 0xDA;
/** Define quantization table */
const DQT = 0xDB;
/** Define number of lines */
const DNL = 0xDC;
/** Define restart interval */
const DRI = 0xDD;
/** Define hierarchical progression */
const DHP = 0xDE;
/** Expand reference component */
const EXP = 0xDF;
/** Application segment 0 */
const APP0 = 0xE0;
/**
* Application segment 1
*
* When a JPEG image contains Exif data, the data will normally be
* stored in this section and a call to {@link PelJpeg::getExif()}
* will return a {@link PelExif} object representing it.
*/
const APP1 = 0xE1;
/** Application segment 2 */
const APP2 = 0xE2;
/** Application segment 3 */
const APP3 = 0xE3;
/** Application segment 4 */
const APP4 = 0xE4;
/** Application segment 5 */
const APP5 = 0xE5;
/** Application segment 6 */
const APP6 = 0xE6;
/** Application segment 7 */
const APP7 = 0xE7;
/** Application segment 8 */
const APP8 = 0xE8;
/** Application segment 9 */
const APP9 = 0xE9;
/** Application segment 10 */
const APP10 = 0xEA;
/** Application segment 11 */
const APP11 = 0xEB;
/** Application segment 12 */
const APP12 = 0xEC;
/** Application segment 13 */
const APP13 = 0xED;
/** Application segment 14 */
const APP14 = 0xEE;
/** Application segment 15 */
const APP15 = 0xEF;
/** Extension 0 */
const JPG0 = 0xF0;
/** Extension 1 */
const JPG1 = 0xF1;
/** Extension 2 */
const JPG2 = 0xF2;
/** Extension 3 */
const JPG3 = 0xF3;
/** Extension 4 */
const JPG4 = 0xF4;
/** Extension 5 */
const JPG5 = 0xF5;
/** Extension 6 */
const JPG6 = 0xF6;
/** Extension 7 */
const JPG7 = 0xF7;
/** Extension 8 */
const JPG8 = 0xF8;
/** Extension 9 */
const JPG9 = 0xF9;
/** Extension 10 */
const JPG10 = 0xFA;
/** Extension 11 */
const JPG11 = 0xFB;
/** Extension 12 */
const JPG12 = 0xFC;
/** Extension 13 */
const JPG13 = 0xFD;
/** Comment */
const COM = 0xFE;
/**
* Check if a byte is a valid JPEG marker.
*
* @param PelJpegMarker the byte that will be checked.
*
* @return boolean if the byte is recognized true is returned,
* otherwise false will be returned.
*/
static function isValid($m) {
return ($m >= self::SOF0 && $m <= self::COM);
}
/**
* Turn a JPEG marker into bytes.
*
* @param PelJpegMarker the marker.
*
* @return string the marker as a string. This will be a string
* with just a single byte since all JPEG markers are simply single
* bytes.
*/
static function getBytes($m) {
return chr($m);
}
/**
* Return the short name for a marker.
*
* @param PelJpegMarker the marker.
*
* @return string the name of the marker, e.g., 'SOI' for the Start
* of Image marker.
*/
static function getName($m) {
switch ($m) {
case self::SOF0: return 'SOF0';
case self::SOF1: return 'SOF1';
case self::SOF2: return 'SOF2';
case self::SOF3: return 'SOF3';
case self::SOF5: return 'SOF5';
case self::SOF6: return 'SOF6';
case self::SOF7: return 'SOF7';
case self::SOF9: return 'SOF9';
case self::SOF10: return 'SOF10';
case self::SOF11: return 'SOF11';
case self::SOF13: return 'SOF13';
case self::SOF14: return 'SOF14';
case self::SOF15: return 'SOF15';
case self::SOI: return 'SOI';
case self::EOI: return 'EOI';
case self::SOS: return 'SOS';
case self::COM: return 'COM';
case self::DHT: return 'DHT';
case self::JPG: return 'JPG';
case self::DAC: return 'DAC';
case self::RST0: return 'RST0';
case self::RST1: return 'RST1';
case self::RST2: return 'RST2';
case self::RST3: return 'RST3';
case self::RST4: return 'RST4';
case self::RST5: return 'RST5';
case self::RST6: return 'RST6';
case self::RST7: return 'RST7';
case self::DQT: return 'DQT';
case self::DNL: return 'DNL';
case self::DRI: return 'DRI';
case self::DHP: return 'DHP';
case self::EXP: return 'EXP';
case self::APP0: return 'APP0';
case self::APP1: return 'APP1';
case self::APP2: return 'APP2';
case self::APP3: return 'APP3';
case self::APP4: return 'APP4';
case self::APP5: return 'APP5';
case self::APP6: return 'APP6';
case self::APP7: return 'APP7';
case self::APP8: return 'APP8';
case self::APP9: return 'APP9';
case self::APP10: return 'APP10';
case self::APP11: return 'APP11';
case self::APP12: return 'APP12';
case self::APP13: return 'APP13';
case self::APP14: return 'APP14';
case self::APP15: return 'APP15';
case self::JPG0: return 'JPG0';
case self::JPG1: return 'JPG1';
case self::JPG2: return 'JPG2';
case self::JPG3: return 'JPG3';
case self::JPG4: return 'JPG4';
case self::JPG5: return 'JPG5';
case self::JPG6: return 'JPG6';
case self::JPG7: return 'JPG7';
case self::JPG8: return 'JPG8';
case self::JPG9: return 'JPG9';
case self::JPG10: return 'JPG10';
case self::JPG11: return 'JPG11';
case self::JPG12: return 'JPG12';
case self::JPG13: return 'JPG13';
case self::COM: return 'COM';
default: return Pel::fmt('Unknown marker: 0x%02X', $m);
}
}
/**
* Returns a description of a JPEG marker.
*
* @param PelJpegMarker the marker.
*
* @return string the description of the marker.
*/
static function getDescription($m) {
switch ($m) {
case self::SOF0:
return Pel::tra('Encoding (baseline)');
case self::SOF1:
return Pel::tra('Encoding (extended sequential)');
case self::SOF2:
return Pel::tra('Encoding (progressive)');
case self::SOF3:
return Pel::tra('Encoding (lossless)');
case self::SOF5:
return Pel::tra('Encoding (differential sequential)');
case self::SOF6:
return Pel::tra('Encoding (differential progressive)');
case self::SOF7:
return Pel::tra('Encoding (differential lossless)');
case self::SOF9:
return Pel::tra('Encoding (extended sequential, arithmetic)');
case self::SOF10:
return Pel::tra('Encoding (progressive, arithmetic)');
case self::SOF11:
return Pel::tra('Encoding (lossless, arithmetic)');
case self::SOF13:
return Pel::tra('Encoding (differential sequential, arithmetic)');
case self::SOF14:
return Pel::tra('Encoding (differential progressive, arithmetic)');
case self::SOF15:
return Pel::tra('Encoding (differential lossless, arithmetic)');
case self::SOI:
return Pel::tra('Start of image');
case self::EOI:
return Pel::tra('End of image');
case self::SOS:
return Pel::tra('Start of scan');
case self::COM:
return Pel::tra('Comment');
case self::DHT:
return Pel::tra('Define Huffman table');
case self::JPG:
return Pel::tra('Extension');
case self::DAC:
return Pel::tra('Define arithmetic coding conditioning');
case self::RST0:
return Pel::fmt('Restart %d', 0);
case self::RST1:
return Pel::fmt('Restart %d', 1);
case self::RST2:
return Pel::fmt('Restart %d', 2);
case self::RST3:
return Pel::fmt('Restart %d', 3);
case self::RST4:
return Pel::fmt('Restart %d', 4);
case self::RST5:
return Pel::fmt('Restart %d', 5);
case self::RST6:
return Pel::fmt('Restart %d', 6);
case self::RST7:
return Pel::fmt('Restart %d', 7);
case self::DQT:
return Pel::tra('Define quantization table');
case self::DNL:
return Pel::tra('Define number of lines');
case self::DRI:
return Pel::tra('Define restart interval');
case self::DHP:
return Pel::tra('Define hierarchical progression');
case self::EXP:
return Pel::tra('Expand reference component');
case self::APP0:
return Pel::fmt('Application segment %d', 0);
case self::APP1:
return Pel::fmt('Application segment %d', 1);
case self::APP2:
return Pel::fmt('Application segment %d', 2);
case self::APP3:
return Pel::fmt('Application segment %d', 3);
case self::APP4:
return Pel::fmt('Application segment %d', 4);
case self::APP5:
return Pel::fmt('Application segment %d', 5);
case self::APP6:
return Pel::fmt('Application segment %d', 6);
case self::APP7:
return Pel::fmt('Application segment %d', 7);
case self::APP8:
return Pel::fmt('Application segment %d', 8);
case self::APP9:
return Pel::fmt('Application segment %d', 9);
case self::APP10:
return Pel::fmt('Application segment %d', 10);
case self::APP11:
return Pel::fmt('Application segment %d', 11);
case self::APP12:
return Pel::fmt('Application segment %d', 12);
case self::APP13:
return Pel::fmt('Application segment %d', 13);
case self::APP14:
return Pel::fmt('Application segment %d', 14);
case self::APP15:
return Pel::fmt('Application segment %d', 15);
case self::JPG0:
return Pel::fmt('Extension %d', 0);
case self::JPG1:
return Pel::fmt('Extension %d', 1);
case self::JPG2:
return Pel::fmt('Extension %d', 2);
case self::JPG3:
return Pel::fmt('Extension %d', 3);
case self::JPG4:
return Pel::fmt('Extension %d', 4);
case self::JPG5:
return Pel::fmt('Extension %d', 5);
case self::JPG6:
return Pel::fmt('Extension %d', 6);
case self::JPG7:
return Pel::fmt('Extension %d', 7);
case self::JPG8:
return Pel::fmt('Extension %d', 8);
case self::JPG9:
return Pel::fmt('Extension %d', 9);
case self::JPG10:
return Pel::fmt('Extension %d', 10);
case self::JPG11:
return Pel::fmt('Extension %d', 11);
case self::JPG12:
return Pel::fmt('Extension %d', 12);
case self::JPG13:
return Pel::fmt('Extension %d', 13);
case self::COM:
return Pel::tra('Comment');
default:
return Pel::fmt('Unknown marker: 0x%02X', $m);
}
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,296 @@
<?php
/* PEL: PHP Exif Library. A library with support for reading and
* writing all Exif headers in JPEG and TIFF images using PHP.
*
* Copyright (C) 2004, 2005, 2006 Martin Geisler.
*
* 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 in the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* $Id: PelTiff.php 458 2006-11-18 21:22:58Z mgeisler $ */
/**
* Classes for dealing with TIFF data.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @version $Revision: 458 $
* @date $Date: 2006-11-18 22:22:58 +0100 (Sat, 18 Nov 2006) $
* @license http://www.gnu.org/licenses/gpl.html GNU General Public
* License (GPL)
* @package PEL
*/
/**#@+ Required class definitions. */
require_once('PelDataWindow.php');
require_once('PelIfd.php');
require_once('Pel.php');
/**#@-*/
/**
* Class for handling TIFF data.
*
* Exif data is actually an extension of the TIFF file format. TIFF
* images consist of a number of {@link PelIfd Image File Directories}
* (IFDs), each containing a number of {@link PelEntry entries}. The
* IFDs are linked to each other --- one can get hold of the first one
* with the {@link getIfd()} method.
*
* To parse a TIFF image for Exif data one would do:
*
* <code>
* $tiff = new PelTiff($data);
* $ifd0 = $tiff->getIfd();
* $exif = $ifd0->getSubIfd(PelIfd::EXIF);
* $ifd1 = $ifd0->getNextIfd();
* </code>
*
* Should one have some image data of an unknown type, then the {@link
* PelTiff::isValid()} function is handy: it will quickly test if the
* data could be valid TIFF data. The {@link PelJpeg::isValid()}
* function does the same for JPEG images.
*
* @author Martin Geisler <mgeisler@users.sourceforge.net>
* @package PEL
*/
class PelTiff {
/**
* TIFF header.
*
* This must follow after the two bytes indicating the byte order.
*/
const TIFF_HEADER = 0x002A;
/**
* The first Image File Directory, if any.
*
* If set, then the type of the IFD must be {@link PelIfd::IFD0}.
*
* @var PelIfd
*/
private $ifd = null;
/**
* Construct a new object for holding TIFF data.
*
* The new object will be empty (with no {@link PelIfd}) unless an
* argument is given from which it can initialize itself. This can
* either be the filename of a TIFF image or a {@link PelDataWindow}
* object.
*
* Use {@link setIfd()} to explicitly set the IFD.
*/
function __construct($data = false) {
if ($data === false)
return;
if (is_string($data)) {
Pel::debug('Initializing PelTiff object from %s', $data);
$this->loadFile($data);
} elseif ($data instanceof PelDataWindow) {
Pel::debug('Initializing PelTiff object from PelDataWindow.');
$this->load($data);
} else {
throw new PelInvalidArgumentException('Bad type for $data: %s',
gettype($data));
}
}
/**
* Load TIFF data.
*
* The data given will be parsed and an internal tree representation
* will be built. If the data cannot be parsed correctly, a {@link
* PelInvalidDataException} is thrown, explaining the problem.
*
* @param PelDataWindow the data from which the object will be
* constructed. This should be valid TIFF data, coming either
* directly from a TIFF image or from the Exif data in a JPEG image.
*/
function load(PelDataWindow $d) {
Pel::debug('Parsing %d bytes of TIFF data...', $d->getSize());
/* There must be at least 8 bytes available: 2 bytes for the byte
* order, 2 bytes for the TIFF header, and 4 bytes for the offset
* to the first IFD. */
if ($d->getSize() < 8)
throw new PelInvalidDataException('Expected at least 8 bytes of TIFF ' .
'data, found just %d bytes.',
$d->getSize());
/* Byte order */
if ($d->strcmp(0, 'II')) {
Pel::debug('Found Intel byte order');
$d->setByteOrder(PelConvert::LITTLE_ENDIAN);
} elseif ($d->strcmp(0, 'MM')) {
Pel::debug('Found Motorola byte order');
$d->setByteOrder(PelConvert::BIG_ENDIAN);
} else {
throw new PelInvalidDataException('Unknown byte order found in TIFF ' .
'data: 0x%2X%2X',
$d->getByte(0), $d->getByte(1));
}
/* Verify the TIFF header */
if ($d->getShort(2) != self::TIFF_HEADER)
throw new PelInvalidDataException('Missing TIFF magic value.');
/* IFD 0 offset */
$offset = $d->getLong(4);
Pel::debug('First IFD at offset %d.', $offset);
if ($offset > 0) {
/* Parse the first IFD, this will automatically parse the
* following IFDs and any sub IFDs. */
$this->ifd = new PelIfd(PelIfd::IFD0);
$this->ifd->load($d, $offset);
}
}
/**
* Load data from a file into a TIFF object.
*
* @param string the filename. This must be a readable file.
*/
function loadFile($filename) {
$this->load(new PelDataWindow(file_get_contents($filename)));
}
/**
* Set the first IFD.
*
* @param PelIfd the new first IFD, which must be of type {@link
* PelIfd::IFD0}.
*/
function setIfd(PelIfd $ifd) {
if ($ifd->getType() != PelIfd::IFD0)
throw new PelInvalidDataException('Invalid type of IFD: %d, expected %d.',
$ifd->getType(), PelIfd::IFD0);
$this->ifd = $ifd;
}
/**
* Return the first IFD.
*
* @return PelIfd the first IFD contained in the TIFF data, if any.
* If there is no IFD null will be returned.
*/
function getIfd() {
return $this->ifd;
}
/**
* Turn this object into bytes.
*
* TIFF images can have {@link PelConvert::LITTLE_ENDIAN
* little-endian} or {@link PelConvert::BIG_ENDIAN big-endian} byte
* order, and so this method takes an argument specifying that.
*
* @param PelByteOrder the desired byte order of the TIFF data.
* This should be one of {@link PelConvert::LITTLE_ENDIAN} or {@link
* PelConvert::BIG_ENDIAN}.
*
* @return string the bytes representing this object.
*/
function getBytes($order = PelConvert::LITTLE_ENDIAN) {
if ($order == PelConvert::LITTLE_ENDIAN)
$bytes = 'II';
else
$bytes = 'MM';
/* TIFF magic number --- fixed value. */
$bytes .= PelConvert::shortToBytes(self::TIFF_HEADER, $order);
if ($this->ifd != null) {
/* IFD 0 offset. We will always start IDF 0 at an offset of 8
* bytes (2 bytes for byte order, another 2 bytes for the TIFF
* header, and 4 bytes for the IFD 0 offset make 8 bytes
* together).
*/
$bytes .= PelConvert::longToBytes(8, $order);
/* The argument specifies the offset of this IFD. The IFD will
* use this to calculate offsets from the entries to their data,
* all those offsets are absolute offsets counted from the
* beginning of the data. */
$bytes .= $this->ifd->getBytes(8, $order);
} else {
$bytes .= PelConvert::longToBytes(0, $order);
}
return $bytes;
}
/**
* Return a string representation of this object.
*
* @return string a string describing this object. This is mostly useful
* for debugging.
*/
function __toString() {
$str = Pel::fmt("Dumping TIFF data...\n");
if ($this->ifd != null)
$str .= $this->ifd->__toString();
return $str;
}
/**
* Check if data is valid TIFF data.
*
* This will read just enough data from the data window to determine
* if the data could be a valid TIFF data. This means that the
* check is more like a heuristic than a rigorous check.
*
* @param PelDataWindow the bytes that will be examined.
*
* @return boolean true if the data looks like valid TIFF data,
* false otherwise.
*
* @see PelJpeg::isValid()
*/
static function isValid(PelDataWindow $d) {
/* First check that we have enough data. */
if ($d->getSize() < 8)
return false;
/* Byte order */
if ($d->strcmp(0, 'II')) {
$d->setByteOrder(PelConvert::LITTLE_ENDIAN);
} elseif ($d->strcmp(0, 'MM')) {
Pel::debug('Found Motorola byte order');
$d->setByteOrder(PelConvert::BIG_ENDIAN);
} else {
return false;
}
/* Verify the TIFF header */
return $d->getShort(2) == self::TIFF_HEADER;
}
}

View File

@ -0,0 +1,3 @@
name = "Autorotate"
description = "Rotate an image automatically on upload based on EXIF data"
version = 1

View File

@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -24,21 +24,33 @@ class BatchTag_Controller extends Controller {
// Prevent Cross Site Request Forgery
access::verify_csrf();
// Generate an array of all non-album items in the current album.
$children = ORM::factory("item")
->where("parent_id", $this->input->post("item_id"))
->where("type !=", "album")
->find_all();
$input = Input::instance();
// Figure out if the contents of sub-albums should also be tagged
$str_tag_subitems = $input->post("tag_subitems");
$children = "";
if ($str_tag_subitems == false) {
// Generate an array of all non-album items in the current album.
$children = ORM::factory("item")
->where("parent_id", "=", $input->post("item_id"))
->where("type", "!=", "album")
->find_all();
} else {
// Generate an array of all non-album items in the current album
// and any sub albums.
$item = ORM::factory("item", $input->post("item_id"));
$children = $item->descendants();
}
// Loop through each item in the album and make sure the user has
// access to view and edit it.
foreach ($children as $child) {
if (access::can("view", $child) && access::can("edit", $child)) {
if (access::can("view", $child) && access::can("edit", $child) && !$child->is_album()) {
// Assuming the user can view/edit the current item, loop
// through each tag that was submitted and apply it to
// the current item.
foreach (split(",", $this->input->post("name")) as $tag_name) {
foreach (explode(",", $input->post("name")) as $tag_name) {
$tag_name = trim($tag_name);
if ($tag_name) {
tag::add($child, $tag_name);
@ -48,7 +60,7 @@ class BatchTag_Controller extends Controller {
}
// Redirect back to the album.
$item = ORM::factory("item", $this->input->post("item_id"));
$item = ORM::factory("item", $input->post("item_id"));
url::redirect(url::abs_site("{$item->type}s/{$item->id}"));
}
}

View File

@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -17,33 +17,45 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class batchtag_theme_Core {
static function sidebar_blocks($theme) {
// Display form for tagging in the album sidebar.
class batchtag_block_Core {
static function get_site_list() {
return array("batch_tag" => t("Batch Tag"));
}
static function get($block_id, $theme) {
$block = "";
// Only display on album pages that the user can edit.
$item = $theme->item();
// Only display the form in albums that the user has edit permission in.
if ($item->is_album() && access::can("edit", $item)) {
if (!$item || !$item->is_album() || !access::can("edit", $item)) {
return;
}
switch ($block_id) {
case "batch_tag":
// Make a new sidebar block.
$block = new Block();
$block->css_id = "gBatchTag";
$block->css_id = "g-batch-tag";
$block->title = t("Batch Tag");
$block->content = new View("batchtag_block.html");
// Make a new form to place in the sidebar block.
$form = new Forge("batchtag/tagitems", "", "post",
array("id" => "gBatchTagForm"));
array("id" => "g-batch-tag-form"));
$label = t("Tag everything in this album:");
$group = $form->group("add_tag")->label("Add Tag");
$group->input("name")->label($label)->rules("required|length[1,64]");
$group->checkbox("tag_subitems")
->label(t("Include sub-albums?"))
->value(true)
->checked(false);
$group->hidden("item_id")->value($item->id);
$group->submit("")->value(t("Add Tag"));
$block->content->form = $form;
$block->content->batch_tag_form = $form;
// Display the block.
return $block;
}
break;
}
return $block;
}
}
}

View File

@ -0,0 +1,34 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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 batchtag_event_Core {
static function module_change($changes) {
// See if the Tags module is installed,
// tell the user to install it if it isn't.
if (!module::is_active("tag") || in_array("tag", $changes->deactivate)) {
site_status::warning(
t("The BatchTag module requires the Tags module. " .
"<a href=\"%url\">Activate the Tags module now</a>",
array("url" => url::site("admin/modules"))),
"batchtag_needs_tag");
} else {
site_status::clear("batchtag_needs_tag");
}
}
}

View File

@ -1,6 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");/**
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -18,9 +19,15 @@
*/
class batchtag_installer {
static function install() {
// Set the module's version number.
module::set_version("batchtag", 1);
}
static function deactivate() {
// Clear the require tags message when metadescription is deactivated.
site_status::clear("batchtag_needs_tag");
}
static function uninstall() {
module::delete("batchtag");
}

View File

@ -1,3 +1,3 @@
name = BatchTag
description = Automatically apply a tag to the entire contents of an album.
name = "BatchTag"
description = "Automatically apply a tag to the entire contents of an album."
version = 1

View File

@ -1,2 +1,2 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<?= $form ?>
<?= $batch_tag_form ?>

View File

@ -0,0 +1,270 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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 CalendarView_Controller extends Controller {
public function calendar($display_year="", $display_user="") {
// Draw a calendar for the year specified by $display_year.
// Make sure the function parameters aren't null,
// give them default values if they are.
if ($display_year == "") {
$display_year = date('Y');
}
if ($display_user == "") {
$display_user = "-1";
}
// Draw the page.
$template = new Theme_View("calpage.html", "other", "CalendarView");
$template->css("calendarview_calendar.css");
$template->set_global("calendar_user", $display_user);
$template->page_title = t("Gallery :: Calendar");
$template->content = new View("calendarview_year.html");
$template->content->calendar_year = $display_year;
$template->content->calendar_user = $display_user;
$template->content->calendar_user_year_form = $this->_get_calenderprefs_form($display_year, $display_user);
$template->content->title = t("Calendar") . ": " . $display_year;
// Set up breadcrumbs
$calendar_breadcrumbs[0] = new Calendar_Breadcrumb(item::root()->title, item::root()->url());
$calendar_breadcrumbs[1] = new Calendar_Breadcrumb($display_year, "");
$template->set_global("breadcrumbs", $calendar_breadcrumbs);
print $template;
}
public function day($display_year, $display_user, $display_month, $display_day) {
// Display all images for the specified day.
// Figure out the total number of photos to display.
$day_count = 0;
if ($display_user == "-1") {
$day_count = ORM::factory("item")
->viewable()
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $display_month, $display_day, $display_year))
->where("captured", "<", mktime(0, 0, 0, $display_month, ($display_day + 1), $display_year))
->find_all()
->count();
} else {
$day_count = ORM::factory("item")
->viewable()
->where("owner_id", "=", $display_user)
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $display_month, $display_day, $display_year))
->where("captured", "<", mktime(0, 0, 0, $display_month, ($display_day + 1), $display_year))
->find_all()
->count();
}
// Figure out paging stuff.
$page_size = module::get_var("gallery", "page_size", 9);
$page = (int) Input::instance()->get("page", "1");
$offset = ($page-1) * $page_size;
$max_pages = max(ceil($day_count / $page_size), 1);
// Make sure that the page references a valid offset
if (($page < 1) || ($page > $max_pages)) {
throw new Kohana_404_Exception();
}
// Set up the page.
$template = new Theme_View("calpage.html", "collection", "CalendarDayView");
$template->set_global("page", $page);
$template->set_global("max_pages", $max_pages);
$template->set_global("page_size", $page_size);
$template->page_title = t("Gallery :: Calendar");
// Figure out which photos go on this page.
if ($display_user == "-1") {
$template->set_global("children", ORM::factory("item")
->viewable()
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $display_month, $display_day, $display_year))
->where("captured", "<", mktime(0, 0, 0, $display_month, ($display_day + 1), $display_year))
->order_by("captured", "ASC")
->find_all($page_size, $offset));
} else {
$template->set_global("children", ORM::factory("item")
->viewable()
->where("owner_id", "=", $display_user)
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $display_month, $display_day, $display_year))
->where("captured", "<", mktime(0, 0, 0, $display_month, ($display_day + 1), $display_year))
->order_by("captured", "ASC")
->find_all($page_size, $offset));
}
// Set up breadcrumbs
$calendar_breadcrumbs[0] = new Calendar_Breadcrumb(item::root()->title, item::root()->url());
$calendar_breadcrumbs[1] = new Calendar_Breadcrumb($display_year, url::site("calendarview/calendar/" . $display_year . "/" . $display_user));
$calendar_breadcrumbs[2] = new Calendar_Breadcrumb(t(date("F", mktime(0, 0, 0, $display_month, $display_day, $display_year))), url::site("calendarview/month/" . $display_year . "/" . $display_user . "/" . $display_month));
$calendar_breadcrumbs[3] = new Calendar_Breadcrumb($display_day, "");
$template->set_global("breadcrumbs", $calendar_breadcrumbs);
// Finish setting up and then display the page.
$template->set_global("children_count", $day_count);
$template->content = new View("dynamic.html");
$template->content->title = t("Photos From ") . date("d", mktime(0, 0, 0, $display_month, $display_day, $display_year)) . " " . t(date("F", mktime(0, 0, 0, $display_month, $display_day, $display_year))) . " " . date("Y", mktime(0, 0, 0, $display_month, $display_day, $display_year));
print $template;
}
public function month($display_year, $display_user, $display_month) {
// Display all images for the specified month.
// Figure out the total number of photos to display.
$day_count = 0;
if ($display_user == "-1") {
$day_count = ORM::factory("item")
->viewable()
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $display_month, 1, $display_year))
->where("captured", "<", mktime(0, 0, 0, $display_month+1, 1, $display_year))
->find_all()
->count();
} else {
$day_count = ORM::factory("item")
->viewable()
->where("owner_id", "=", $display_user)
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $display_month, 1, $display_year))
->where("captured", "<", mktime(0, 0, 0, $display_month+1, 1, $display_year))
->find_all()
->count();
}
// Figure out paging stuff.
$page_size = module::get_var("gallery", "page_size", 9);
$page = (int) Input::instance()->get("page", "1");
$offset = ($page-1) * $page_size;
$max_pages = max(ceil($day_count / $page_size), 1);
// Make sure that the page references a valid offset
if (($page < 1) || ($page > $max_pages)) {
throw new Kohana_404_Exception();
}
// Set up the page.
$template = new Theme_View("calpage.html", "collection", "CalendarMonthView");
$template->set_global("page", $page);
$template->set_global("max_pages", $max_pages);
$template->set_global("page_size", $page_size);
$template->page_title = t("Gallery :: Calendar");
// Figure out which photos go on this page.
if ($display_user == "-1") {
$template->set_global("children", ORM::factory("item")
->viewable()
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $display_month, 1, $display_year))
->where("captured", "<", mktime(0, 0, 0, $display_month+1, 1, $display_year))
->order_by("captured", "ASC")
->find_all($page_size, $offset));
} else {
$template->set_global("children", ORM::factory("item")
->viewable()
->where("owner_id", "=", $display_user)
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $display_month, 1, $display_year))
->where("captured", "<", mktime(0, 0, 0, $display_month+1, 1, $display_year))
->order_by("captured", "ASC")
->find_all($page_size, $offset));
}
// Set up breadcrumbs
$calendar_breadcrumbs[0] = new Calendar_Breadcrumb(item::root()->title, item::root()->url());
$calendar_breadcrumbs[1] = new Calendar_Breadcrumb($display_year, url::site("calendarview/calendar/" . $display_year . "/" . $display_user));
$calendar_breadcrumbs[2] = new Calendar_Breadcrumb(t(date("F", mktime(0, 0, 0, $display_month, 1, $display_year))), "");
$template->set_global("breadcrumbs", $calendar_breadcrumbs);
// Finish setting up and then display the page.
$template->set_global("children_count", $day_count);
$template->content = new View("dynamic.html");
$template->content->title = t("Photos From ") . t(date("F", mktime(0, 0, 0, $display_month, 1, $display_year))) . " " . date("Y", mktime(0, 0, 0, $display_month, 1, $display_year));
print $template;
}
private function _get_calenderprefs_form($display_year, $display_user) {
// Generate a form to allow the visitor to select a year and a gallery photo owner.
$calendar_group = new Forge("calendarview/setprefs", "", "post",
array("id" => "g-view-calendar-form"));
// Generate a list of all Gallery users who have uploaded photos.
$valid_users[-1] = "(All Users)";
$gallery_users = ORM::factory("user")->find_all();
foreach ($gallery_users as $one_user) {
$count = ORM::factory("item")
->viewable()
->where("owner_id", "=", $one_user->id)
->where("type", "!=", "album")
->where("captured", "!=", "")
->find_all()
->count();
if ($count > 0) {
$valid_users[$one_user->id] = $one_user->full_name;
}
}
// Generate a list of years, starting with the year the earliest photo was
// taken, and ending with the year of the most recent photo.
$valid_years = Array();
$all_photos = ORM::factory("item")
->viewable()
//->where("owner_id", "=", $one_user->id)
->where("type", "!=", "album")
->where("captured", "!=", "")
->order_by("captured", "DESC")
->find_all();
$counter = date('Y', $all_photos[count($all_photos)-1]->captured);
while ($counter <= date('Y', $all_photos[0]->captured)) {
$valid_years[$counter] = $counter;
$counter++;
}
// Create the form.
$calendar_group->dropdown('cal_user')
->label(t("Display Photos From User: "))
->id('cal_user')
->options($valid_users)
->selected($display_user);
$calendar_group->dropdown('cal_year')
->label(t("For Year: "))
->id('cal_year')
->options($valid_years)
->selected($display_year);
// Add a save button to the form.
$calendar_group->submit("SaveSettings")->value(t("Go"))->id('cal_go');
// Return the newly generated form.
return $calendar_group;
}
public function setprefs() {
// Change the calendar year and / or user.
// Prevent Cross Site Request Forgery
access::verify_csrf();
// Get user specified settings.
$str_user_id = Input::instance()->post("cal_user");
$str_year_id = Input::instance()->post("cal_year");
// redirect to the currect page.
url::redirect(url::site("calendarview/calendar/" . $str_year_id . "/" . $str_user_id, request::protocol()));
}
}

View File

@ -0,0 +1,50 @@
/* Grid view ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
#g-calendar-grid {
position: relative;
align: center;
float: left;
width: 200px;
height: 220px;
margin: 10px 10px 10px 10px;
}
/* Search form ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
#cal_user {
top: 0px;
left: 60px;
display: inline;
}
#cal_year {
top: 0px;
left: 240px;
display: inline;
}
#cal_go {
top: 0px;
left: 328px;
display: inline;
}
/* Content ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
table.calendar {
text-align: center;
}
table.calendar caption {
font-size: 1.5em;
padding: 0.2em;
}
table.calendar th, table.calendar td {
padding: 0.2em;
border: 0px;
}
table.calendar td:hover {
background: #ddf;
}
/* For RTL Languages ~~~~~~~~~~~~~~~~~~~~~~~ */
.rtl #g-calendar-grid {
float: right;
}

View File

@ -0,0 +1,3 @@
#g-view-menu #g-calendarview-link {
background-image: url('../images/ico-view-calendarview.png');
}

View File

@ -0,0 +1,72 @@
<?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 calendarview_block_Core {
static function get_site_list() {
return array("calendarview_photo" => t("More Photos From This Date"));
}
static function get($block_id, $theme) {
$block = "";
// Make sure the current page belongs to an item.
if (!$theme->item()) {
return;
}
$item = $theme->item;
$display_date = "";
if (isset($item->captured)) {
$display_date = $item->captured;
}elseif (isset($item->created)) {
$display_date = $item->created;
}
// Make sure there are photo's to display.
$day_count = ORM::factory("item")
->viewable()
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, date("n", $display_date), date("j", $display_date), date("Y", $display_date)))
->where("captured", "<", mktime(0, 0, 0, date("n", $display_date), date("j", $display_date)+1, date("Y", $display_date)))
->find_all()
->count();
$month_count = ORM::factory("item")
->viewable()
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, date("n", $display_date), 1, date("Y", $display_date)))
->where("captured", "<", mktime(0, 0, 0, date("n", $display_date)+1, 1, date("Y", $display_date)))
->find_all()
->count();
switch ($block_id) {
case "calendarview_photo":
if ( ($display_date != "") && (($day_count > 0) || ($month_count > 0)) ) {
$block = new Block();
$block->css_id = "g-calendarview-sidebar";
$block->title = t("Calendar");
$block->content = new View("calendarview_sidebar.html");
$block->content->date = $display_date;
$block->content->day_count = $day_count;
$block->content->month_count = $month_count;
}
break;
}
return $block;
}
}

View File

@ -0,0 +1,72 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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 calendarview_event_Core {
static function photo_menu($menu, $theme) {
$menu->append(Menu::factory("link")
->id("calendarview")
->label(t("View Calendar"))
->url(url::site("calendarview/calendar/"))
->css_id("g-calendarview-link"));
}
static function movie_menu($menu, $theme) {
$menu->append(Menu::factory("link")
->id("calendarview")
->label(t("View Calendar"))
->url(url::site("calendarview/calendar/"))
->css_id("g-calendarview-link"));
}
static function album_menu($menu, $theme) {
$menu->append(Menu::factory("link")
->id("calendarview")
->label(t("View Calendar"))
->url(url::site("calendarview/calendar/"))
->css_id("g-calendarview-link"));
}
static function tag_menu($menu, $theme) {
$menu->append(Menu::factory("link")
->id("calendarview")
->label(t("View Calendar"))
->url(url::site("calendarview/calendar/"))
->css_id("g-calendarview-link"));
}
static function pre_deactivate($data) {
// If the admin is about to deactivate EXIF, warn them that this module requires it.
if ($data->module == "exif") {
$data->messages["warn"][] = t("The CalendarView module requires the EXIF module.");
}
}
static function module_change($changes) {
// If EXIF is deactivated, display a warning that it is required for this module to function properly.
if (!module::is_active("exif") || in_array("exif", $changes->deactivate)) {
site_status::warning(
t("The CalendarView module requires the EXIF module. " .
"<a href=\"%url\">Activate the EXIF module now</a>",
array("url" => html::mark_clean(url::site("admin/modules")))),
"calendarview_needs_exif");
} else {
site_status::clear("calendarview_needs_exif");
}
}
}

View File

@ -17,13 +17,16 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class google_analytics_installer {
class calendarview_installer {
static function install() {
module::set_var("google_analytics", "code", "");
module::set_version("google_analytics", 2);
module::set_version("calendarview", 1);
}
static function deactivate() {
site_status::clear("calendarview_needs_exif");
}
static function uninstall() {
module::clear_var("google_analytics", "code");
module::delete("calendarview");
}
}

View File

@ -0,0 +1,25 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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 calendarview_theme_Core {
static function head($theme) {
$theme->css("calendarview_menu.css");
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -0,0 +1,31 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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 Calendar_Breadcrumb_Core {
// Creates a class to maintain a single breadcrumb.
// Multiple breadcrumbs can be achieved by createing an array of this class type.
public $title = "";
public $id = 1;
public $url = "";
public function __construct($new_title, $new_url) {
$this->title = $new_title;
$this->url = $new_url;
}
}

View File

@ -0,0 +1,87 @@
<?php defined('SYSPATH') OR die('No direct access allowed.');
class PHPCalendar_Core {
// Month and year to use for calendaring
protected $month;
protected $year;
protected $month_url;
// First Day of the Week (0 = Sunday or 1 = Monday).
protected $week_start = 0;
// Events for the current month.
protected $event_data = Array();
public function __construct($month = NULL, $year = NULL, $url = NULL)
{
empty($month) and $month = date('n'); // Current month
empty($year) and $year = date('Y'); // Current year
// Set the month and year
$this->month = (int) $month;
$this->year = (int) $year;
$this->month_url = $url;
}
public function event($day_of_the_week, $event_url = NULL, $css_id = NULL, $custom_text = NULL)
{
$this->event_data += Array($day_of_the_week => Array($event_url, $css_id, $custom_text));
}
public function render()
{
return $this->generate_calendar($this->year, $this->month, $this->event_data, 2, $this->month_url, $this->week_start, NULL);
}
# PHP Calendar (version 2.3), written by Keith Devens
# http://keithdevens.com/software/php_calendar
# see example at http://keithdevens.com/weblog
# License: http://keithdevens.com/software/license
function generate_calendar($year, $month, $days = array(), $day_name_length = 3, $month_href = NULL, $first_day = 0, $pn = array())
{
$first_of_month = gmmktime(0,0,0,$month,1,$year);
#remember that mktime will automatically correct if invalid dates are entered
# for instance, mktime(0,0,0,12,32,1997) will be the date for Jan 1, 1998
# this provides a built in "rounding" feature to generate_calendar()
if ($first_day == 0) $day_names = array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
if ($first_day == 1) $day_names = array("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday");
list($month, $year, $month_name, $weekday) = explode(',',gmstrftime('%m,%Y,%B,%w',$first_of_month));
$weekday = ($weekday + 7 - $first_day) % 7; #adjust for $first_day
$title = t(date("F", mktime(0, 0, 0, $month, 1, $year))) . '&nbsp;' . $year;
#Begin calendar. Uses a real <caption>. See http://diveintomark.org/archives/2002/07/03
@list($p, $pl) = each($pn); @list($n, $nl) = each($pn); #previous and next links, if applicable
if($p) $p = '<span class="calendar-prev">'.($pl ? '<a href="'.htmlspecialchars($pl).'">'.$p.'</a>' : $p).'</span>&nbsp;';
if($n) $n = '&nbsp;<span class="calendar-next">'.($nl ? '<a href="'.htmlspecialchars($nl).'">'.$n.'</a>' : $n).'</span>';
$calendar = '<table class="calendar" id="g-calendar-month">'."\n".
'<td class="title" colspan="7" align="center">'.$p.($month_href ? '<a href="'. ($month_href) .'">'.$title.'</a>' : $title).$n."</td></tr>\n<tr>";
if($day_name_length){ #if the day names should be shown ($day_name_length > 0)
#if day_name_length is >3, the full name of the day will be printed
foreach($day_names as $d)
$calendar .= '<th abbr="' . $d .'">'.t($day_name_length < 4 ? substr($d,0,$day_name_length) : $d) . '</th>';
$calendar .= "</tr>\n<tr>";
}
if($weekday > 0) $calendar .= '<td colspan="'.$weekday.'">&nbsp;</td>'; #initial 'empty' days
for($day=1,$days_in_month=gmdate('t',$first_of_month); $day<=$days_in_month; $day++,$weekday++){
if($weekday == 7){
$weekday = 0; #start a new week
$calendar .= "</tr>\n<tr>";
}
if(isset($days[$day]) and is_array($days[$day])){
@list($link, $classes, $content) = $days[$day];
if(is_null($content)) $content = $day;
$calendar .= '<td'.($classes ? ' class="'.htmlspecialchars($classes).'">' : '>').
($link ? '<a href="'.htmlspecialchars($link).'">'.$content.'</a>' : $content).'</td>';
}
else $calendar .= "<td class=\"day\">$day</td>";
}
if($weekday != 7) $calendar .= '<td colspan="'.(7-$weekday).'">&nbsp;</td>'; #remaining "empty" days
return $calendar."</tr>\n</table>\n";
}
}
?>

View File

@ -0,0 +1,3 @@
name = "CalendarView"
description = "View your photos by the date they were taken."
version = 1

View File

@ -0,0 +1,9 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<ul>
<? if ($day_count > 0): ?>
<li><a href="<?=url::site("calendarview/day/" . date("Y", $date) . "/-1/" . date("n", $date) . "/" . date("j", $date)); ?>"><?=t("More from"); ?> <?=date("F", $date); ?> <?=date("j", $date); ?><?=date("S", $date); ?></a></li>
<? endif ?>
<? if ($month_count > 0): ?>
<li><a href="<?=url::site("calendarview/month/" . date("Y", $date) . "/-1/" . date("n", $date)); ?>"><?=t("More from"); ?> <?=date("F", $date); ?></a></li>
<? endif ?>
</ul>

View File

@ -0,0 +1,178 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<div id="g-album-header">
<div id="g-album-header-buttons">
<?= $theme->dynamic_top() ?>
</div>
<h1><?= html::clean($title) ?></h1>
</div>
<br/><?= $calendar_user_year_form ?><br /><br />
<?
$counter_months = 1;
// Loop through January to November in the current year.
while ($counter_months <12) {
print "<div id=\"g-calendar-grid\">";
// Figure out if any photos were taken for the current month.
if ($calendar_user == "-1") {
$month_count = ORM::factory("item")
->viewable()
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $counter_months, 1, $calendar_year))
->where("captured", "<", mktime(0, 0, 0, $counter_months+1, 1, $calendar_year))
->find_all()
->count();
} else {
$month_count = ORM::factory("item")
->viewable()
->where("owner_id", "=", $calendar_user)
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $counter_months, 1, $calendar_year))
->where("captured", "<", mktime(0, 0, 0, $counter_months+1, 1, $calendar_year))
->find_all()
->count();
}
if ($month_count > 0) {
$month_url = url::site("calendarview/month/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/");
} else {
$month_url = "";
}
$calendar = new PHPCalendar($counter_months, $calendar_year, $month_url);
// If there are photos, loop through each day in the month and display links on the correct dates.
if ($month_count > 0) {
$curr_day = 1;
$MAX_DAYS = date('t', mktime(00, 00, 00, $counter_months, 1, $calendar_year));
while ($curr_day < $MAX_DAYS) {
if ($calendar_user == "-1") {
$day_count = ORM::factory("item")
->viewable()
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $counter_months, $curr_day, $calendar_year))
->where("captured", "<", mktime(0, 0, 0, $counter_months, ($curr_day + 1), $calendar_year))
->find_all()
->count();
} else {
$day_count = ORM::factory("item")
->viewable()
->where("owner_id", "=", $calendar_user)
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $counter_months, $curr_day, $calendar_year))
->where("captured", "<", mktime(0, 0, 0, $counter_months, ($curr_day + 1), $calendar_year))
->find_all()
->count();
}
if ($day_count > 0) {
$calendar->event($curr_day, url::site("calendarview/day/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/" . $curr_day));
}
$curr_day++;
}
// Do the last day of the month seperately, because the mktime code is different.
if ($calendar_user == "-1") {
$day_count = ORM::factory("item")
->viewable()
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $counter_months, $MAX_DAYS, $calendar_year))
->where("captured", "<",mktime(0, 0, 0, ($counter_months + 1), 1, $calendar_year))
->find_all()
->count();
} else {
$day_count = ORM::factory("item")
->viewable()
->where("owner_id", "=", $calendar_user)
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $counter_months, $MAX_DAYS, $calendar_year))
->where("captured", "<", mktime(0, 0, 0, ($counter_months + 1), 1, $calendar_year))
->find_all()
->count();
}
if ($day_count > 0) {
$calendar->event($MAX_DAYS, url::site("calendarview/day/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/" . $MAX_DAYS));
}
}
echo $calendar->render();
print "</div>";
$counter_months++;
}
// Do December seperately, because the mktime code is different.
print "<div id=\"g-calendar-grid\">";
if ($calendar_user == "-1") {
$month_count = ORM::factory("item")
->viewable()
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $counter_months, 1, $calendar_year))
->where("captured", "<", mktime(0, 0, 0, 1, 1, ($calendar_year + 1)))
->find_all()
->count();
} else {
$month_count = ORM::factory("item")
->viewable()
->where("owner_id", "=", $calendar_user)
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $counter_months, 1, $calendar_year))
->where("captured", "<", mktime(0, 0, 0, 1, 1, ($calendar_year + 1)))
->find_all()
->count();
}
if ($month_count > 0) {
$month_url = url::site("calendarview/month/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/");
} else {
$month_url = "";
}
$calendar = new PHPCalendar($counter_months, $calendar_year, $month_url);
if ($month_count > 0) {
$curr_day = 1;
$MAX_DAYS = date('t', mktime(00, 00, 00, $counter_months, 1, $calendar_year));
while ($curr_day < $MAX_DAYS) {
if ($calendar_user == "-1") {
$day_count = ORM::factory("item")
->viewable()
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $counter_months, $curr_day, $calendar_year))
->where("captured", "<", mktime(0, 0, 0, $counter_months, ($curr_day + 1), $calendar_year))
->find_all()
->count();
} else {
$day_count = ORM::factory("item")
->viewable()
->where("owner_id", "=", $calendar_user)
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $counter_months, $curr_day, $calendar_year))
->where("captured", "<", mktime(0, 0, 0, $counter_months, ($curr_day + 1), $calendar_year))
->find_all()
->count();
}
if ($day_count > 0) {
$calendar->event($curr_day, url::site("calendarview/day/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/" . $curr_day));
}
$curr_day++;
}
if ($calendar_user == "-1") {
$day_count = ORM::factory("item")
->viewable()
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $counter_months, $MAX_DAYS, $calendar_year))
->where("captured", "<", mktime(0, 0, 0, 1, 1, $calendar_year+1))
->find_all()
->count();
} else {
$day_count = ORM::factory("item")
->viewable()
->where("owner_id", "=", $calendar_user)
->where("type", "!=", "album")
->where("captured", ">=", mktime(0, 0, 0, $counter_months, $MAX_DAYS, $calendar_year))
->where("captured", "<", mktime(0, 0, 0, 1, 1, $calendar_year+1))
->find_all()
->count();
}
if ($day_count > 0) {
$calendar->event($MAX_DAYS, url::site("calendarview/day/" . $calendar_year . "/" . $calendar_user . "/" . $counter_months . "/" . $MAX_DAYS));
}
}
$counter_months++;
echo $calendar->render();
print "</div>";
?>

View File

@ -0,0 +1,154 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>
<? if ($page_title): ?>
<?= $page_title ?>
<? else: ?>
<? if ($theme->item()): ?>
<? if ($theme->item()->is_album()): ?>
<?= t("Browse Album :: %album_title", array("album_title" => $theme->item()->title)) ?>
<? elseif ($theme->item()->is_photo()): ?>
<?= t("Photo :: %photo_title", array("photo_title" => $theme->item()->title)) ?>
<? else: ?>
<?= t("Movie :: %movie_title", array("movie_title" => $theme->item()->title)) ?>
<? endif ?>
<? elseif ($theme->tag()): ?>
<?= t("Browse Tag :: %tag_title", array("tag_title" => $theme->tag()->name)) ?>
<? else: /* Not an item, not a tag, no page_title specified. Help! */ ?>
<?= t("Gallery") ?>
<? endif ?>
<? endif ?>
</title>
<link rel="shortcut icon" href="<?= url::file("lib/images/favicon.ico") ?>" type="image/x-icon" />
<?= $theme->css("yui/reset-fonts-grids.css") ?>
<?= $theme->css("superfish/css/superfish.css") ?>
<?= $theme->css("themeroller/ui.base.css") ?>
<?= $theme->css("gallery.common.css") ?>
<?= $theme->css("screen.css") ?>
<!--[if lt IE 8]>
<link rel="stylesheet" type="text/css" href="<?= $theme->url("css/fix-ie.css") ?>"
media="screen,print,projection" />
<![endif]-->
<? if ($theme->page_type == "collection"): ?>
<? if ($thumb_proportion != 1): ?>
<? $new_width = $thumb_proportion * 213 ?>
<? $new_height = $thumb_proportion * 240 ?>
<style type="text/css">
#g-content #g-album-grid .g-item {
width: <?= $new_width ?>px;
height: <?= $new_height ?>px;
/* <?= $thumb_proportion ?> */
}
</style>
<? endif ?>
<? endif ?>
<?= $theme->script("jquery.js") ?>
<?= $theme->script("jquery.form.js") ?>
<?= $theme->script("jquery-ui.js") ?>
<?= $theme->script("gallery.common.js") ?>
<? /* MSG_CANCEL is required by gallery.dialog.js */ ?>
<script type="text/javascript">
var MSG_CANCEL = <?= t('Cancel')->for_js() ?>;
</script>
<?= $theme->script("gallery.ajax.js") ?>
<?= $theme->script("gallery.dialog.js") ?>
<?= $theme->script("superfish/js/superfish.js") ?>
<?= $theme->script("jquery.localscroll.js") ?>
<?= $theme->script("ui.init.js") ?>
<? /* These are page specific, but if we put them before $theme->head() they get combined */ ?>
<? if ($theme->page_subtype == "photo"): ?>
<?= $theme->script("jquery.scrollTo.js") ?>
<?= $theme->script("gallery.show_full_size.js") ?>
<? elseif ($theme->page_subtype == "movie"): ?>
<?= $theme->script("flowplayer.js") ?>
<? endif ?>
<?= $theme->head() ?>
</head>
<body <?= $theme->body_attributes() ?>>
<?= $theme->page_top() ?>
<div id="doc4" class="yui-t5 g-view">
<?= $theme->site_status() ?>
<div id="g-header" class="ui-helper-clearfix">
<div id="g-banner">
<? if ($header_text = module::get_var("gallery", "header_text")): ?>
<?= $header_text ?>
<? else: ?>
<a id="g-logo" class="g-left" href="<?= item::root()->url() ?>" title="<?= t("go back to the Gallery home")->for_html_attr() ?>">
<img width="107" height="48" alt="<?= t("Gallery logo: Your photos on your web site")->for_html_attr() ?>" src="<?= url::file("lib/images/logo.png") ?>" />
</a>
<? endif ?>
<?= $theme->user_menu() ?>
<?= $theme->header_top() ?>
<!-- hide the menu and make it visible after the page has loaded, to minimize menu flicker -->
<div id="g-site-menu" style="visibility: hidden">
<?= $theme->site_menu() ?>
</div>
<script type="text/javascript"> $(document).ready(function() { $("#g-site-menu").css("visibility", "visible"); }) </script>
<?= $theme->header_bottom() ?>
</div>
<? // The following code was modifed to allow module-defined breadcrumbs.
// Everything else in this file is a copy of the default page.html.php file.
?>
<? if (!empty($breadcrumbs)): ?>
<ul class="g-breadcrumbs">
<? $i = 0 ?>
<? foreach ($breadcrumbs as $breadcrumb): ?>
<li<? if ($i == 0) print " class=\"g-first\"" ?>>
<!-- Adding ?show=<id> causes Gallery3 to display the page
containing that photo. For now, we just do it for
the immediate parent so that when you go back up a
level you're on the right page. -->
<? if ($breadcrumb->url) : ?>
<a href="<?= $breadcrumb->url ?>"><?= html::purify($breadcrumb->title) ?></a>
<? else : ?>
<?= html::purify($breadcrumb->title) ?>
<? endif ?>
</li>
<? $i++ ?>
<? endforeach ?>
</ul>
<? endif ?>
<? // End modified code ?>
</div>
<div id="bd">
<div id="yui-main">
<div class="yui-b">
<div id="g-content" class="yui-g">
<?= $theme->messages() ?>
<?= $content ?>
</div>
</div>
</div>
<div id="g-sidebar" class="yui-b">
<? if ($theme->page_subtype != "login"): ?>
<?= new View("sidebar.html") ?>
<? endif ?>
</div>
</div>
<div id="g-footer" class="ui-helper-clearfix">
<?= $theme->footer() ?>
<? if ($footer_text = module::get_var("gallery", "footer_text")): ?>
<?= $footer_text ?>
<? endif ?>
<? if (module::get_var("gallery", "show_credits")): ?>
<ul id="g-credits" class="g-inline">
<?= $theme->credits() ?>
</ul>
<? endif ?>
</div>
</div>
<?= $theme->page_bottom() ?>
</body>
</html>

View File

@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -48,13 +48,15 @@ class Admin_ContactOwner_Controller extends Admin_Controller {
$str_contactbutton = Input::instance()->post("owner_button_text");
$str_contactemail = Input::instance()->post("owner_email");
$str_contactname = Input::instance()->post("owner_name");
$str_messageheader = Input::instance()->post("message_header");
// Save Settings.
module::set_var("contactowner", "contact_owner_link", $ownerLink);
module::set_var("contactowner", "contact_user_link", $userLink);
module::set_var("contactowner", "contact_button_text", $str_contactbutton);
module::set_var("contactowner", "contact_owner_email", $str_contactemail );
module::set_var("contactowner", "contact_owner_name", $str_contactname );
module::set_var("contactowner", "contact_owner_email", $str_contactemail);
module::set_var("contactowner", "contact_owner_name", $str_contactname);
module::set_var("contactowner", "contact_owner_header", $str_messageheader);
message::success(t("Your Settings Have Been Saved."));
// Load Admin page.
@ -67,7 +69,7 @@ class Admin_ContactOwner_Controller extends Admin_Controller {
private function _get_admin_form() {
// Make a new Form.
$form = new Forge("admin/contactowner/saveprefs", "", "post",
array("id" => "gContactOwnerAdminForm"));
array("id" => "g-contact-owner-adminForm"));
// Make an array for the different types of link codes.
$add_contactlinks = $form->group("contactOwnerLinks");
@ -86,9 +88,12 @@ class Admin_ContactOwner_Controller extends Admin_Controller {
$add_contacts->input("owner_button_text")->label(t("Contact Owner Link Text"))->value(module::get_var("contactowner", "contact_button_text"));
$add_contacts->input("owner_email")->label(t("Owner Email Address"))->value(module::get_var("contactowner", "contact_owner_email"));
$add_contacts->input("owner_name")->label(t("Owner Name"))->value(module::get_var("contactowner", "contact_owner_name"));
$message_prefs = $form->group("messagePrefs");
$message_prefs->input("message_header")->label(t("Email Message Header"))->value(module::get_var("contactowner", "contact_owner_header"));
// Add a save button to the form.
$add_contacts->submit("SaveSettings")->value(t("Save"));
$form->submit("SaveSettings")->value(t("Save"));
// Return the newly generated form.
return $form;

View File

@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -20,18 +20,19 @@
class ContactOwner_Controller extends Controller {
public function emailowner() {
// Display a form that a vistor can use to contact the site owner.
// If this page is disabled, show a 404 error.
if (module::get_var("contactowner", "contact_owner_link") != true) {
kohana::show_404();
throw new Kohana_404_Exception();
}
// Make a new form with a couple of text boxes.
$form = new Forge("contactowner/sendemail", "", "post",
array("id" => "gContactOwnerSendForm"));
array("id" => "g-contact-owner-send-form"));
$sendmail_fields = $form->group("contactOwner");
$sendmail_fields->input("email_to")->label(t("To:"))->value(module::get_var("contactowner", "contact_owner_name"));
$sendmail_fields->input("email_from")->label(t("From:"))->value(user::active()->email);
$sendmail_fields->input("email_from")->label(t("From:"))->value(identity::active_user()->email);
$sendmail_fields->input("email_subject")->label(t("Subject:"))->value("");
$sendmail_fields->textarea("email_body")->label(t("Message:"))->value("");
$sendmail_fields->hidden("email_to_id")->value("-1");
@ -40,7 +41,7 @@ class ContactOwner_Controller extends Controller {
$sendmail_fields->submit("SendMessage")->value(t("Send"));
// Set up and display the actual page.
$template = new Theme_View("page.html", "Contact");
$template = new Theme_View("page.html", "other", "Contact");
$template->content = new View("contactowner_emailform.html");
$template->content->sendmail_form = $form;
print $template;
@ -48,24 +49,24 @@ class ContactOwner_Controller extends Controller {
public function emailid($user_id) {
// Display a form that a vistor can use to contact a registered user.
// If this page is disabled, show a 404 error.
if (module::get_var("contactowner", "contact_user_link") != true) {
kohana::show_404();
throw new Kohana_404_Exception();
}
// Locate the record for the user specified by $user_id,
// use this to determine the user's name.
$userDetails = ORM::factory("user")
->where("id", $user_id)
->where("id", "=", $user_id)
->find_all();
// Make a new form with a couple of text boxes.
$form = new Forge("contactowner/sendemail", "", "post",
array("id" => "gContactOwnerSendForm"));
array("id" => "g-contact-owner-send-form"));
$sendmail_fields = $form->group("contactOwner");
$sendmail_fields->input("email_to")->label(t("To:"))->value($userDetails[0]->name);
$sendmail_fields->input("email_from")->label(t("From:"))->value(user::active()->email);
$sendmail_fields->input("email_from")->label(t("From:"))->value(identity::active_user()->email);
$sendmail_fields->input("email_subject")->label(t("Subject:"))->value("");
$sendmail_fields->textarea("email_body")->label(t("Message:"))->value("");
$sendmail_fields->hidden("email_to_id")->value($user_id);
@ -74,7 +75,7 @@ class ContactOwner_Controller extends Controller {
$sendmail_fields->submit("SendMessage")->value(t("Send"));
// Set up and display the actual page.
$template = new Theme_View("page.html", "Contact");
$template = new Theme_View("page.html", "other", "Contact");
$template->content = new View("contactowner_emailform.html");
$template->content->sendmail_form = $form;
print $template;
@ -83,47 +84,71 @@ class ContactOwner_Controller extends Controller {
public function sendemail() {
// Process the data from the form into an email,
// then send the email.
// Copy the data from the email from into a couple of variables.
$str_emailsubject = Input::instance()->post("email_subject");
$str_emailtoid = Input::instance()->post("email_to_id");
$str_emailfrom = Input::instance()->post("email_from");
$str_emailbody = Input::instance()->post("email_body");
// Add in some <br> tags to the message body where ever there are line breaks.
$str_emailbody = str_replace("\n", "\n<br/>", $str_emailbody);
// Gallery's Sendmail library doesn't allow for custom from addresses,
// so add the from email to the beginning of the message body instead.
$str_emailbody = "Message Sent From " . $str_emailfrom . "\r\n\r\n<br/><br/>" . $str_emailbody;
// Figure out where the email is going to.
$str_emailto = "";
if ($str_emailtoid == -1) {
// If the email id is "-1" send the message to a pre-determined
// owner email address.
$str_emailto = module::get_var("contactowner", "contact_owner_email");
} else {
// or else grab the email from the user table.
$userDetails = ORM::factory("user")
->where("id", $str_emailtoid)
->find_all();
$str_emailto = $userDetails[0]->email;
// Make sure the form was submitted.
if ($_POST) {
// Set up some rules to validate the form against.
$post = new Validation($_POST);
$post->add_rules('email_from', 'required', 'valid::email');
$post->add_rules('email_subject', 'required');
$post->add_rules('email_body', 'required');
// If the form was filled out properly then...
if ($post->validate()) {
// Copy the data from the email form into a couple of variables.
$str_emailsubject = Input::instance()->post("email_subject");
$str_emailtoid = Input::instance()->post("email_to_id");
$str_emailfrom = Input::instance()->post("email_from");
$str_emailbody = Input::instance()->post("email_body");
// Add in some <br> tags to the message body where ever there are line breaks.
$str_emailbody = str_replace("\n", "\n<br/>", $str_emailbody);
// Gallery's Sendmail library doesn't allow for custom from addresses,
// so add the from email to the beginning of the message body instead.
// Also add in the admin-defined message header.
$str_emailbody = module::get_var("contactowner", "contact_owner_header") . "<br/>\r\n" . "Message Sent From " . $str_emailfrom . "<br/>\r\n<br/>\r\n" . $str_emailbody;
// Figure out where the email is going to.
$str_emailto = "";
if ($str_emailtoid == -1) {
// If the email id is "-1" send the message to a pre-determined
// owner email address.
$str_emailto = module::get_var("contactowner", "contact_owner_email");
} else {
// or else grab the email from the user table.
$userDetails = ORM::factory("user")
->where("id", "=", $str_emailtoid)
->find_all();
$str_emailto = $userDetails[0]->email;
}
// Send the email message.
Sendmail::factory()
->to($str_emailto)
->subject($str_emailsubject)
->header("Mime-Version", "1.0")
->header("Content-type", "text/html; charset=utf-8")
->message($str_emailbody)
->send();
// Display a message telling the visitor that their email has been sent.
$template = new Theme_View("page.html", "other", "Contact");
$template->content = new View("contactowner_emailform.html");
$template->content->sendmail_form = t("Your Message Has Been Sent.");
print $template;
} else {
// Display a message telling the visitor that their email has been not been sent,
// along with the reason(s) why.
$template = new Theme_View("page.html", "other", "Contact");
$template->content = new View("contactowner_emailform.html");
$template->content->sendmail_form = t("Your Message Has Not Been Sent.");
$template->content->sendmail_form = $template->content->sendmail_form . "<br/><br/>" . t("Reason(s):") . "<br/>";
foreach($post->errors('form_error_messages') as $error) {
$template->content->sendmail_form = $template->content->sendmail_form . " - " . t($error) . "<br/>";
}
print $template;
}
}
// Send the email message.
Sendmail::factory()
->to($str_emailto)
->subject($str_emailsubject)
->header("Mime-Version", "1.0")
->header("Content-type", "text/html; charset=utf-8")
->message($str_emailbody)
->send();
// Display a message telling the visitor that their email has been sent.
$template = new Theme_View("page.html", "Contact");
$template->content = new View("contactowner_emailform.html");
$template->content->sendmail_form = t("Your Message Has Been Sent.");
print $template;
}
}
}

View File

@ -0,0 +1,78 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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 contactowner_block_Core {
static function get_site_list() {
return array("contact_owner" => t("Contact Owner"));
}
static function get($block_id, $theme) {
$block = "";
switch ($block_id) {
case "contact_owner":
// Create a new block to display the links in.
$block = new Block();
$block->css_id = "g-contact-owner";
$block->title = t("Contact");
$block->content = new View("contactowner_block.html");
// if $displayBlock is true, this block will be displayed,
// if there aren't any links to put in the block for whatever reason
// then $displayBlock will rename set to false and the
// block will not be displayed.
$displayBlock = false;
if ($theme->item()) {
// Locate the record for the user that created the current item.
// Their name will be displayed as part of the contact link.
$userDetails = ORM::factory("user")
->where("id", "=", $theme->item->owner_id)
->find_all();
// Figure out if the contact item owner email link should be displayed.
// only display it if the current owner has an email address and
// the option for allowing item owners to be contacted is set to true.
if ((count($userDetails) > 0) && ($userDetails[0]->email != "") &&
(module::get_var("contactowner", "contact_user_link") == true)) {
$block->content->userLink = "<a href=\"" . url::site("contactowner/emailid/" .
$theme->item->owner_id) . "\">" . t("Contact") . " " .
$userDetails[0]->name . "</a>";
$displayBlock = true;
}
}
// Figure out if the contact site owner link should be displayed.
if (module::get_var("contactowner", "contact_owner_link")) {
$block->content->ownerLink = "<a href=\"" . url::site("contactowner/emailowner") .
"\">" . t(module::get_var("contactowner", "contact_button_text")) . "</a>";
$displayBlock = true;
}
break;
}
if ($displayBlock) {
return $block;
} else {
return "";
}
}
}

View File

@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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

View File

@ -1,6 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");/**
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -18,6 +19,17 @@
*/
class contactowner_installer {
static function install() {
module::set_version("contactowner", 1);
// Set some default values
module::set_var("contactowner", "contact_owner_link", false);
module::set_var("contactowner", "contact_user_link", true);
module::set_var("contactowner", "contact_button_text", "Email The Webmaster");
module::set_var("contactowner", "contact_owner_name", "Webmaster");
module::set_var("contactowner", "contact_owner_header", "You have received a message through your website:");
module::set_version("contactowner", 2);
}
static function uninstall() {
module::delete("contactowner");
}
}

View File

@ -1,70 +0,0 @@
<?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 contactowner_theme_Core {
static function sidebar_blocks($theme) {
// Display links in the Gallery sidebar to allow a
// visitor to send an email.
// Make sure the current page belongs to an item.
if (!$theme->item()) {
return;
}
// Locate the record for the user that created the current item.
// Their name will be displayed as part of the contact link.
$userDetails = ORM::factory("user")
->where("id", $theme->item->owner_id)
->find_all();
// Create a new block to display the links in.
$block = new Block();
$block->css_id = "gContactOwner";
$block->title = t("Contact:");
$block->content = new View("contactowner_block.html");
// if $displayBlock is true, this block will be displayed,
// if there aren't any links to put in the block for whatever reason
// then $displayBlock will rename set to false and the
// block will not be displayed.
$displayBlock = false;
// Figure out if the contact item owner email link should be displayed.
// only display it if the current owner has an email address and
// the option for allowing item owners to be contacted is set to true.
if ((count($userDetails) > 0) && ($userDetails[0]->email != "") &&
(module::get_var("contactowner", "contact_user_link") == true)) {
$block->content->userLink = "<a href=\"" . url::site("contactowner/emailid/" .
$theme->item->owner_id) . "\">" . t("Contact") . " " . $userDetails[0]->name . "</a>";
$displayBlock = true;
}
// Figure out if the contact site owner link should be displayed.
if (module::get_var("contactowner", "contact_owner_link")) {
$block->content->ownerLink = "<a href=\"" . url::site("contactowner/emailowner") .
"\">" . t(module::get_var("contactowner", "contact_button_text")) . "</a>";
$displayBlock = true;
}
if ($displayBlock) {
return $block;
}
}
}

View File

@ -1,3 +1,3 @@
name = ContactOwner
description = Allows visitors to send the website owner an email.
version = 1
name = "ContactOwner"
description = "Allows visitors to send the website owner an email."
version = 2

View File

@ -1,5 +1,5 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<div id="gContactOwnerAdmin">
<div id="g-contact-owner-admin">
<h2> <?= t("Contact Owner Settings") ?> </h2>
<?= $contactowner_form ?>
</div>

View File

@ -1,15 +1,15 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<ul id="gContactOwner">
<? if ($ownerLink != "") { ?>
<li style="clear: both;">
<? print ($ownerLink); ?>
<ul id="g-contact-owner">
<? if (!empty($ownerLink)): ?>
<li style="clear: both">
<?= $ownerLink ?>
</li>
<? } ?>
<? if ($userLink != "") { ?>
<li style="clear: both;">
<? print ($userLink); ?>
</li>
<? } ?>
<? endif ?>
<? if (!empty($userLink)): ?>
<li style="clear: both">
<?= ($userLink); ?>
</li>
<? endif ?>
</ul>

View File

@ -0,0 +1,36 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2010 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_info_block_Core {
static function get_admin_list() {
return array("database_info" => t("Database info"));
}
static function get($block_id) {
$block = new Block();
switch ($block_id) {
case "database_info":
$block->css_id = "g-database-info";
$block->title = t("Database information");
$block->content = new View("admin_block_db.html");
break;
}
return $block;
}
}

View File

@ -0,0 +1,3 @@
name = "Database Info"
description = "View information about your Gallery 3 database on the admin dashboard."
version = 1

View File

@ -0,0 +1,18 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<?
$db = Database::instance();
$tables = $db->query("SHOW TABLE STATUS");
$database_size = 0;
foreach($tables as $table) {
$database_size += ($table->Data_length + $table->Index_length);
}
$database_size = $database_size / 1024 / 1024;
?>
<ul>
<li>
<?= t("Database size: %dbsize MB", array("dbsize" => number_format($database_size, 2))) ?>
</li>
<li>
<?= t("Number of tables: %dbtables", array("dbtables" => count($tables))) ?>
</li>
</ul>

View File

@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -32,6 +32,7 @@ $config["methods"] = array(
"admin_page_bottom" => t("Bottom of administration page"),
"admin_page_top" => t("Top of administration page"),
"admin_head" => t("Adminstration page head"),
"body_attributes" => t("Body Attributes"),
"credits" => t("Album or photo page credits"),
"dynamic_bottom" => t("Bottom of dynamic page content"),
"dynamic_top" => t("Top of dynamic page content"),
@ -44,26 +45,10 @@ $config["methods"] = array(
"photo_blocks" => t("Photo block"),
"photo_bottom" => t("Bottom of photo content"),
"photo_top" => t("Top of photo content"),
"resize_bottom" => t("Bottom of the resize view"),
"resize_top" => t("Top of the resize view"),
"sidebar_bottom" => t("Bottom of sidebar"),
"sidebar_top" => t("Top of sidebar"),
"thumb_bottom" => t("Bottom of thumbnail"),
"thumb_info" => t("Thumbnail information"),
"thumb_top" => t("Top of thumbnail display")),
"menu" => array("album" => t("Add an album menu element"),
"photo" => t("Add an photo menu element")),
"event" => array("batch_complete" => t("Batch completion"),
"comment_add_form" => t("Comment add form creation"),
"comment_created" => t("Comment created"),
"comment_updated" => t("Comment updated"),
"group_before_delete" => t("Before delete group"),
"group_created" => t("Group created"),
"item_before_delete" => t("Before album or photo deletion"),
"item_created" => t("Album or photo created"),
"item_related_update" => t("Photo meta data update"),
"item_related_update_batch" => t("Photo meta data update"),
"item_updated" => t("Album or photo update"),
"user_before_delete" => t("Before user deletion"),
"user_created" => t("User created"),
"user_login" => t("User login"),
"user_logout" => t("User logout")));
"thumb_top" => t("Top of thumbnail display")));

View File

@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class Admin_Developer_Controller extends Admin_Controller {
static $event_list = array();
public function module() {
$view = new Admin_View("admin.html");
$view->content = new View("admin_developer.html");
@ -49,7 +51,10 @@ class Admin_Developer_Controller extends Admin_Controller {
$post = new Validation($_POST);
$post->add_rules("name", "required");
$post->add_rules("display_name", "required");
$post->add_rules("description", "required");
$post->add_callbacks("theme", array($this, "_noop_validation"));
$post->add_callbacks("event", array($this, "_noop_validation"));
$post->add_callbacks("name", array($this, "_is_module_defined"));
if ($post->validate()) {
@ -57,25 +62,27 @@ class Admin_Developer_Controller extends Admin_Controller {
->callback("developer_task::create_module")
->description(t("Create a new module"))
->name(t("Create Module"));
$task = task::create($task_def, array_merge(array("step" => 0), $post->as_array()));
$success_msg = t("Generation of %module completed successfully",
array("module" => $post->name));
$error_msg = t("Generation of %module failed.", array("module" => $post->name));
print json_encode(array("result" => "started",
"max_iterations" => 15,
"success_msg" => $success_msg, "error_msg" => $error_msg,
"url" => url::site("admin/developer/run_task/{$task->id}?csrf=" .
access::csrf_token()),
"task" => $task->as_array()));
$task_context = array("step" => 0, "success_msg" => $success_msg, "error_msg" => $error_msg);
$task = task::create($task_def, array_merge($task_context, $post->as_array()));
json::reply(array("result" => "started",
"max_iterations" => 15,
"url" => url::site("admin/developer/run_task/{$task->id}?csrf=" .
access::csrf_token()),
"task" => $task->as_array()));
} else {
$v = $this->_get_module_create_content(arr::overwrite($form, $post->as_array()),
arr::overwrite($errors, $post->errors()));
print json_encode(array("result" => "error",
"form" => $v->__toString()));
json::reply(array("result" => "error", "html" => (string)$v));
}
}
public function _noop_validation(Validation $array, $field) {
}
public function session($key) {
access::verify_csrf();
$input = Input::instance();
@ -84,8 +91,6 @@ class Admin_Developer_Controller extends Admin_Controller {
}
public function test_data_create() {
access::verify_csrf();
list ($form, $errors) = $this->_get_test_data_form();
$post = new Validation($_POST);
@ -113,22 +118,19 @@ class Admin_Developer_Controller extends Admin_Controller {
"comments" => $post->comments, "tags" => $post->tags));
batch::start();
print json_encode(array("result" => "started",
"max_iterations" => $total + 5,
"url" => url::site("admin/developer/run_task/{$task->id}?csrf=" .
access::csrf_token()),
"task" => $task->as_array()));
json::reply(array("result" => "started",
"max_iterations" => $total + 5,
"url" => url::site("admin/developer/run_task/{$task->id}?csrf=" .
access::csrf_token()),
"task" => $task->as_array()));
} else {
$v = $this->_get_test_data_view(arr::overwrite($form, $post->as_array()),
arr::overwrite($errors, $post->errors()));
print json_encode(array("result" => "error",
"form" => $v->__toString()));
arr::overwrite($errors, $post->errors()));
json::reply(array("result" => "error", "html" => (string)$v));
}
}
public function run_task($task_id) {
access::verify_csrf();
try {
$task = task::run($task_id);
} catch (Exception $e) {
@ -148,12 +150,10 @@ class Admin_Developer_Controller extends Admin_Controller {
message::success(empty($error_msg) ? $context["error_msg"] : $error_msg);
break;
}
print json_encode(array("result" => "success",
"task" => $task->as_array()));
json::reply(array("result" => "success", "task" => $task->as_array()));
} else {
print json_encode(array("result" => "in_progress",
"task" => $task->as_array()));
json::reply(array("result" => "in_progress", "task" => $task->as_array()));
}
}
@ -173,7 +173,7 @@ class Admin_Developer_Controller extends Admin_Controller {
}
function mptt_graph() {
$items = ORM::factory("item")->orderby("id")->find_all();
$items = ORM::factory("item")->order_by("id")->find_all();
$data = $this->_build_tree();
$proc = proc_open("/usr/bin/dot -Tsvg",
@ -191,11 +191,12 @@ class Admin_Developer_Controller extends Admin_Controller {
}
private function _build_tree() {
$items = ORM::factory("item")->orderby("id")->find_all();
$items = ORM::factory("item")->order_by("id")->find_all();
$data = "digraph G {\n";
foreach ($items as $item) {
$data .= " $item->parent_id -> $item->id\n";
$data .= " $item->id [label=\"$item->id [$item->level] <$item->left, $item->right>\"]\n";
$data .=
" $item->id [label=\"$item->id [$item->level] <$item->left_ptr, $item->right_ptr>\"]\n";
}
$data .= "}\n";
return $data;
@ -215,7 +216,7 @@ class Admin_Developer_Controller extends Admin_Controller {
}
private function _get_module_form() {
$form = array("name" => "", "description" => "", "theme[]" => array(), "menu[]" => array(),
$form = array("name" => "", "display_name" => "", "description" => "", "theme[]" => array(),
"event[]" => array());
$errors = array_fill_keys(array_keys($form), "");
@ -227,15 +228,53 @@ class Admin_Developer_Controller extends Admin_Controller {
$v = new View("developer_module.html");
$v->action = "admin/developer/module_create";
$v->hidden = array("csrf" => access::csrf_token());
$v->theme = $config["theme"];
$v->event = $config["event"];
$v->menu = $config["menu"];
$v->event = $this->_get_events();
$v->form = $form;
$v->errors = $errors;
$submit_attributes = array(
"id" => "g-generate-module",
"name" => "generate",
"class" => "ui-state-default ui-corner-all",
"style" => "clear:both!important");
if (!is_writable(MODPATH)) {
$submit_attributes["class"] .= " ui-state-disabled";
$submit_attributes["disabled"] = "disabled";
}
$v->submit_attributes = $submit_attributes;
return $v;
}
private function _get_events() {
if (empty(self::$event_list)) {
$dir = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(MODPATH));
foreach ($dir as $file) {
$file_as_string = file_get_contents($file);
if (preg_match_all('#module::event\("(.*?)"(.*)\);#mU', $file_as_string, $matches, PREG_SET_ORDER) > 0) {
foreach ($matches as $match) {
$event_name = $match[1];
$display_name = ucwords(str_replace("_", " ", $event_name));
if (!in_array($display_name, self::$event_list)) {
$parameters = array();
if (!empty($match[2]) &&
preg_match_all('#\$[a-zA-Z_]*#', $match[2], $param_names)) {
foreach ($param_names[0] as $name) {
$parameters[] = $name != '$this' ? $name : '$' . $event_name;
}
}
self::$event_list["static function $event_name(" . implode(", ", $parameters) . ")"] = $display_name;
}
}
ksort(self::$event_list);
}
}
}
return self::$event_list;
}
private function _get_test_data_form() {
$form = array("albums" => "10", "photos" => "10", "comments" => "10", "tags" => "10",
"generate_albums" => "");
@ -247,9 +286,8 @@ class Admin_Developer_Controller extends Admin_Controller {
private function _get_test_data_view($form, $errors) {
$v = new View("admin_developer_test_data.html");
$v->action = "admin/developer/test_data_create";
$v->hidden = array("csrf" => access::csrf_token());
$album_count = ORM::factory("item")->where("type", "album")->count_all();
$photo_count = ORM::factory("item")->where("type", "photo")->count_all();
$album_count = ORM::factory("item")->where("type", "=", "album")->count_all();
$photo_count = ORM::factory("item")->where("type", "=", "photo")->count_all();
$v->comment_installed = module::is_active("comment");
$comment_count = empty($v->comment_installed) ? 0 : ORM::factory("comment")->count_all();

View File

@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -21,21 +21,21 @@ class developer_event_Core {
static function admin_menu($menu, $theme) {
$developer_menu = Menu::factory("submenu")
->id("developer_menu")
->label(t("Developer Tools"));
->label(t("Developer tools"));
$menu->append($developer_menu);
$developer_menu
->append(Menu::factory("link")
->id("generate_menu")
->label(t("Generate Module"))
->label(t("Generate module"))
->url(url::site("admin/developer/module")))
->append(Menu::factory("link")
->id("generate_data")
->label(t("Generate Test Data"))
->label(t("Generate test data"))
->url(url::site("admin/developer/test_data")))
->append(Menu::factory("link")
->id("mptt_tree_menu")
->label(t("MPTT Tree"))
->label(t("MPTT tree"))
->url(url::site("admin/developer/mptt")));
$csrf = access::csrf_token();
@ -43,13 +43,13 @@ class developer_event_Core {
$developer_menu->append(
Menu::factory("link")
->id("scaffold_profiler")
->label("Profiling off")
->label(t("Profiling off"))
->url(url::site("admin/developer/session/profiler?value=0&csrf=$csrf")));
} else {
$developer_menu->append(
Menu::factory("link")
->id("scaffold_profiler")
->label("Profiling on")
->label(t("Profiling on"))
->url(url::site("admin/developer/session/profiler?value=1&csrf=$csrf")));
}
@ -57,13 +57,13 @@ class developer_event_Core {
$developer_menu->append(
Menu::factory("link")
->id("scaffold_debugger")
->label("Debugging off")
->label(t("Debugging off"))
->url(url::site("admin/developer/session/debug?value=0&csrf=$csrf")));
} else {
$developer_menu->append(
Menu::factory("link")
->id("scaffold_debugger")
->label("Debugging on")
->label(t("Debugging on"))
->url(url::site("admin/developer/session/debug?value=1&csrf=$csrf")));
}
}

View File

@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.");
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -34,11 +34,11 @@ class developer_task_Core {
switch ($context["step"]) {
case 0: // Create directory tree
foreach (array("", "controllers", "helpers", "js", "views") as $dir) {
foreach (array("", "controllers", "helpers", "views") as $dir) {
$path = "{$context['module_path']}/$dir";
if (!file_exists($path)) {
mkdir($path);
chmod($path, 0777);
chmod($path, 0755);
}
}
break;
@ -54,14 +54,10 @@ class developer_task_Core {
$context["block"] = array();
self::_render_helper_file($context, "block");
break;
case 4: // Generate menu helper
$context["menu"] = !isset($context["menu"]) ? array() : $context["menu"];
self::_render_helper_file($context, "menu");
break;
case 5: // Generate event helper
case 4: // Generate event helper
self::_render_helper_file($context, "event");
break;
case 6: // Generate admin controller
case 5: // Generate admin controller
$file = "{$context['module_path']}/controllers/admin_{$context['module']}.php";
ob_start();
$v = new View("admin_controller.txt");
@ -72,7 +68,7 @@ class developer_task_Core {
file_put_contents($file, ob_get_contents());
ob_end_clean();
break;
case 7: // Generate admin form
case 6: // Generate admin form
$file = "{$context['module_path']}/views/admin_{$context['module']}.html.php";
ob_start();
$v = new View("admin_html.txt");
@ -83,7 +79,7 @@ class developer_task_Core {
file_put_contents($file, ob_get_contents());
ob_end_clean();
break;
case 8: // Generate controller
case 7: // Generate controller
$file = "{$context['module_path']}/controllers/{$context['module']}.php";
ob_start();
$v = new View("controller.txt");
@ -95,7 +91,7 @@ class developer_task_Core {
file_put_contents($file, ob_get_contents());
ob_end_clean();
break;
case 9: // Generate sidebar block view
case 8: // Generate sidebar block view
$file = "{$context['module_path']}/views/{$context['module']}_block.html.php";
ob_start();
$v = new View("block_html.txt");
@ -107,11 +103,23 @@ class developer_task_Core {
file_put_contents($file, ob_get_contents());
ob_end_clean();
break;
case 9: // Generate dashboard block view
$file = "{$context['module_path']}/views/admin_{$context['module']}_block.html.php";
ob_start();
$v = new View("dashboard_block_html.txt");
$v->name = $context["name"];
$v->module = $context["module"];
$v->class_name = $context["class_name"];
$v->css_id = preg_replace("#\s+#", "", $context["name"]);
print $v->render();
file_put_contents($file, ob_get_contents());
ob_end_clean();
break;
case 10: // Generate module.info (do last)
$file = "{$context["module_path"]}/module.info";
ob_start();
$v = new View("module_info.txt");
$v->module_name = $context["name"];
$v->module_name = $context["display_name"];
$v->module_description = $context["description"];
print $v->render();
file_put_contents($file, ob_get_contents());
@ -119,7 +127,7 @@ class developer_task_Core {
break;
}
if (isset($file)) {
chmod($file, 0666);
chmod($file, 0765);
}
$task->done = (++$context["step"]) >= 11;
$task->context = serialize($context);
@ -132,7 +140,6 @@ class developer_task_Core {
$config = Kohana::config("developer.methods");
$file = "{$context["module_path"]}/helpers/{$context["module"]}_{$helper}.php";
touch($file);
chmod($file, 0666);
ob_start();
$v = new View("$helper.txt");
$v->helper = $helper;
@ -187,8 +194,8 @@ class developer_task_Core {
private static function _add_album_or_photo($desired_type=null) {
srand(time());
$parents = ORM::factory("item")->where("type", "album")->find_all()->as_array();
$owner_id = user::active()->id;
$parents = ORM::factory("item")->where("type", "=", "album")->find_all()->as_array();
$owner_id = identity::active_user()->id;
$test_images = glob(dirname(dirname(__FILE__)) . "/data/*.[Jj][Pp][Gg]");
@ -201,19 +208,31 @@ class developer_task_Core {
if ($type == "album") {
$thumb_size = module::get_var("core", "thumb_size");
$rand = rand();
$parents[] = album::create(
$parent, "rnd_$rand", "Rnd $rand", "random album $rand", $owner_id)
->save();
$item = ORM::factory("item");
$item->type = "album";
$item->parent_id = $parent->id;
$item->name = "rnd_$rand";
$item->title = "Rnd $rand";
$item->description = "random album $rand";
$item->owner_id = $owner_id;
$parents[] = $item->save();
} else {
$photo_index = rand(0, count($test_images) - 1);
photo::create($parent, $test_images[$photo_index], basename($test_images[$photo_index]),
"rnd_" . rand(), "sample thumb", $owner_id);
$item = ORM::factory("item");
$item->type = "photo";
$item->parent_id = $parent->id;
$item->set_data_file($test_images[$photo_index]);
$item->name = basename($test_images[$photo_index]);
$item->title = "rnd_" . rand();
$item->description = "sample thumb";
$item->owner_id = $owner_id;
$item->save();
}
}
private static function _add_comment() {
srand(time());
$photos = ORM::factory("item")->where("type", "photo")->find_all()->as_array();
$photos = ORM::factory("item")->where("type", "=", "photo")->find_all()->as_array();
$users = ORM::factory("user")->find_all()->as_array();
if (empty($photos)) {
@ -229,8 +248,15 @@ class developer_task_Core {
$guest_name = ucfirst(self::_random_phrase(rand(1, 3)));
$guest_email = sprintf("%s@%s.com", self::_random_phrase(1), self::_random_phrase(1));
$guest_url = sprintf("http://www.%s.com", self::_random_phrase(1));
comment::create($photo, $author, self::_random_phrase(rand(8, 500)),
$guest_name, $guest_email, $guest_url);
$comment = ORM::factory("comment");
$comment->author_id = $author->id;
$comment->item_id = $photo->id;
$comment->text = self::_random_phrase(rand(8, 500));
$comment->guest_name = $guest_name;
$comment->guest_email = $guest_email;
$comment->guest_url = $guest_url;
$comment->save();
}
private static function _add_tag() {

View File

@ -1,6 +1,6 @@
var module_success = function(data) {
$("#gDeveloperAdmin").append('<div id="gModuleProgress" style="margin-top: 1em;"></div>');
$("#gModuleProgress").progressbar();
$("#g-developer-admin").append('<div id="g-module-progress" style="margin-top: 1em;"></div>');
$("#g-module-progress").progressbar();
var task = data.task;
var url = data.url;
@ -10,7 +10,7 @@ var module_success = function(data) {
while (!done) {
$.ajax({async: false,
success: function(data, textStatus) {
$("#gModuleProgress").progressbar("value", data.task.percent_complete);
$("#g-module-progress").progressbar("value", data.task.percent_complete);
done = data.task.done;
},
error: function(XMLHttpRequest, textStatus, errorThrown) {

View File

@ -2,7 +2,7 @@
<?= "<?php defined(\"SYSPATH\") or die(\"No direct script access.\");" ?>
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -47,7 +47,7 @@ class Admin_<?= $class_name ?>_Controller extends Admin_Controller {
private function _get_form() {
$form = new Forge("admin/<?= $module ?>/handler", "", "post",
array("id" => "gAdminForm"));
array("id" => "g-adminForm"));
$group = $form->group("group");
$group->input("text")->label(t("Text"))->rules("required");
$group->submit("submit")->value(t("Submit"));

View File

@ -1,14 +1,13 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<?= html::script("modules/developer/js/developer.js") ?>
<script>
$("#gDeveloperForm").ready(function() {
ajaxify_developer_form("#gDeveloperForm form", module_success);
<script type="text/javascript">
$("#g-developer-form").ready(function() {
ajaxify_developer_form("#g-developer-form form", module_success);
});
</script>
<div id="gDeveloperAdmin">
<div id="g-developer-admin">
<h2><?= $title ?></h2>
<div id="gDeveloperForm" >
<div id="g-developer-form" >
<?= $developer_content ?>
</div>
</div>

View File

@ -1,92 +1,93 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<script>
$("#gGenerateTestData").ready(function() {
$(".gGenerateCheckbox").click(function() {
<script type="text/javascript">
$("#g-generate-test-data").ready(function() {
$(".g-generate-checkbox").click(function() {
var buttons = $(this).val();
$(buttons).attr("disabled", !this.checked);
});
<? if (!empty($form["generate_albums"])): ?>
$("#gGenerateAlbums").click();
$("#g-generate-albums").click();
<? endif ?>
<? if (!empty($form["generate_photos"])): ?>
$("#gGeneratePhotos").click();
$("#g-generate-photos").click();
<? endif ?>
<? if (!empty($form["generate_comments"])): ?>
$("#gGenerateCommentss").click();
$("#g-generate-comments").click();
<? endif ?>
<? if (!empty($form["generate_tags"])): ?>
$("#gGenerateTags").click();
$("#g-generate-tags").click();
<? endif ?>
});
</script>
<?= form::open($action, array("method" => "post", "id" => "gGenerateTestData"), $hidden) ?>
<?= form::open($action, array("method" => "post", "id" => "g-generate-test-data")) ?>
<? if (!empty($album_count)): ?>
<p><?= t("Currently:") ?><br />
<i>(<?= $album_count ?>, <?= $photo_count ?>, <?= $comment_count ?>, <?= $tag_count ?>)</i>
</p>
<? endif ?>
<fieldset>
<ul>
<li <? if (!empty($errors["albums"])): ?> class="gError"<? endif ?>>
<li><?= access::csrf_form_field() ?></li>
<li <? if (!empty($errors["albums"])): ?> class="g-error"<? endif ?>>
<fieldset>
<?= form::label("gGenerateAlbums", t("Generate Albums")) ?>
<?= form::checkbox(array("id" => "gGenerateAlbums", "name" => "generate_albums", "class" => "gGenerateCheckbox", "style" => "display:inline", "checked" => !empty($form["generate_albums"])), ".gRadioAlbum") ?>
<?= form::label("g-generate-albums", t("Generate Albums")) ?>
<?= form::checkbox(array("id" => "g-generate-albums", "name" => "generate_albums", "class" => "g-generate-checkbox", "style" => "display:inline", "checked" => !empty($form["generate_albums"])), ".g-radio-album") ?>
<? foreach (array(1, 10, 50, 100, 500, 1000) as $number): ?>
<span style="float:left;padding-right: .5em;"><?= form::label("album_$number", "$number") ?>
<?= form::radio(array("id" => "album_$number", "name" => "albums", "style" => "display:inline", "checked" => $number == 10, "disabled" => true, "class" => "gRadioAlbum"), $number) ?></span>
<?= form::radio(array("id" => "album_$number", "name" => "albums", "style" => "display:inline", "checked" => $number == 10, "disabled" => true, "class" => "g-radio-album"), $number) ?></span>
<? endforeach ?>
</fieldset>
<? if (!empty($errors["albums"]) && $errors["albums"] == "numeric"): ?>
<p class="gError"><?= t("Number to create must be numeric") ?></p>
<p class="g-error"><?= t("Number to create must be numeric") ?></p>
<? endif ?>
</li>
<li <? if (!empty($errors["photos"])): ?> class="gError"<? endif ?>>
<li <? if (!empty($errors["photos"])): ?> class="g-error"<? endif ?>>
<fieldset>
<?= form::label("gGeneratePhotos", t("Generate Photos and Albums")) ?>
<?= form::checkbox(array("id" => "gGeneratePhotos", "name" => "generate_photos", "class" => "gGenerateCheckbox", "style" => "display:inline", "checked" => !empty($form["generate_photos"])), ".gRadioPhoto") ?>
<?= form::label("g-generate-photos", t("Generate Photos and Albums")) ?>
<?= form::checkbox(array("id" => "g-generate-photos", "name" => "generate_photos", "class" => "g-generate-checkbox", "style" => "display:inline", "checked" => !empty($form["generate_photos"])), ".g-radio-photo") ?>
<? foreach (array(1, 10, 50, 100, 500, 1000) as $number): ?>
<span style="float:left;padding-right: .5em;"><?= form::label("photo_$number", "$number") ?>
<?= form::radio(array("id" => "photo_$number", "name" => "photos", "style" => "display:inline", "checked" => $number == 10, "disabled" => true, "class" => "gRadioPhoto"), $number) ?></span>
<?= form::radio(array("id" => "photo_$number", "name" => "photos", "style" => "display:inline", "checked" => $number == 10, "disabled" => true, "class" => "g-radio-photo"), $number) ?></span>
<? endforeach ?>
</fieldset>
<? if (!empty($errors["photos"]) && $errors["photos"] == "numeric"): ?>
<p class="gError"><?= t("Number to create must be numeric") ?></p>
<p class="g-error"><?= t("Number to create must be numeric") ?></p>
<? endif ?>
</li
</li>
<? if(!empty($comment_installed)): ?>
<li <? if (!empty($errors["comments"])): ?> class="gError"<? endif ?>>
<li <? if (!empty($errors["comments"])): ?> class="g-error"<? endif ?>>
<fieldset>
<?= form::label("gGenerateComments", t("Generate Comments")) ?>
<?= form::checkbox(array("id" => "gGenerateComments", "name" => "generate_comments", "class" => "gGenerateCheckbox", "style" => "display:inline", "checked" => !empty($form["generate_comments"])), ".gRadioComment") ?>
<?= form::label("g-generate-comments", t("Generate Comments")) ?>
<?= form::checkbox(array("id" => "g-generate-comments", "name" => "generate_comments", "class" => "g-generate-checkbox", "style" => "display:inline", "checked" => !empty($form["generate_comments"])), ".g-radio-comment") ?>
<? foreach (array(1, 10, 50, 100, 500, 1000) as $number): ?>
<span style="float:left;padding-right: .5em;"><?= form::label("comment_$number", "$number") ?>
<?= form::radio(array("id" => "comment_$number", "name" => "comments", "style" => "display:inline", "checked" => $number == 10, "disabled" => true, "class" => "gRadioComment"), $number) ?></span>
<?= form::radio(array("id" => "comment_$number", "name" => "comments", "style" => "display:inline", "checked" => $number == 10, "disabled" => true, "class" => "g-radio-comment"), $number) ?></span>
<? endforeach ?>
</fieldset>
<? if (!empty($errors["comments"]) && $errors["comments"] == "numeric"): ?>
<p class="gError"><?= t("Number to create must be numeric") ?></p>
<p class="g-error"><?= t("Number to create must be numeric") ?></p>
<? endif ?>
</li>
<? endif ?>
<? if(!empty($tag_installed)): ?>
<li <? if (!empty($errors["tags"])): ?> class="gError"<? endif ?>>
<li <? if (!empty($errors["tags"])): ?> class="g-error"<? endif ?>>
<fieldset>
<?= form::label("gGenerateTags", t("Generate Tags")) ?>
<?= form::checkbox(array("id" => "gGenerateTags", "name" => "generate_tags", "class" => "gGenerateCheckbox", "style" => "display:inline", "checked" => !empty($form["generate_tags"])), ".gRadioTag") ?>
<?= form::label("g-generate-tags", t("Generate Tags")) ?>
<?= form::checkbox(array("id" => "g-generate-tags", "name" => "generate_tags", "class" => "g-generate-checkbox", "style" => "display:inline", "checked" => !empty($form["generate_tags"])), ".g-radio-tag") ?>
<? foreach (array(1, 10, 50, 100, 500, 1000) as $number): ?>
<span style="float:left;padding-right: .5em;"><?= form::label("tag_$number", "$number") ?>
<?= form::radio(array("id" => "tag_$number", "name" => "tags", "style" => "display:inline", "checked" => $number == 10, "disabled" => true, "class" => "gRadioTag"), $number) ?></span>
<?= form::radio(array("id" => "tag_$number", "name" => "tags", "style" => "display:inline", "checked" => $number == 10, "disabled" => true, "class" => "g-radio-tag"), $number) ?></span>
<? endforeach ?>
</fieldset>
<? if (!empty($errors["tags"]) && $errors["tags"] == "numeric"): ?>
<p class="gError"><?= t("Number to create must be numeric") ?></p>
<p class="g-error"><?= t("Number to create must be numeric") ?></p>
<? endif ?>
</li>
<? endif ?>
<li>
<?= form::submit(array("id" => "gGenerateData", "name" => "generate", "class" => "submit", "style" => "clear:both!important"), t("Generate")) ?>
<?= form::submit(array("id" => "g-generate-data", "name" => "generate", "class" => "submit", "style" => "clear:both!important"), t("Generate")) ?>
</li>
</ul>
</fieldset>

View File

@ -1,7 +1,7 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<?= "<?php defined(\"SYSPATH\") or die(\"No direct script access.\") ?>" ?>
<div id="gAdmin<?= $css_id ?>">
<div id="g-admin-<?= $css_id ?>">
<h2>
<?= "<?= t(\"$name Adminstration\") ?>" ?>
</h2>

View File

@ -1,8 +1,9 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<?= "<?php defined(\"SYSPATH\") or die(\"No direct script access.\");" ?>
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -19,20 +20,34 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class <?= $module ?>_block {
static function get($block_id) {
static function get_site_list() {
return array(
"<?= "{$module}_site" ?>" => t("<?= $name ?> Sidebar Block"));
}
static function get_admin_list() {
return array(
"<?= "{$module}_admin" ?>" => t("<?= $name ?> Dashboard Block"));
}
static function get($block_id, $theme) {
$block = new Block();
if ($block_id == "<?= $module ?>") {
$block->css_id = "g<?= $css_id ?>Admin";
switch ($block_id) {
case "<?= "{$module}_admin" ?>":
$block->css_id = "g-<?= $css_id ?>-admin";
$block->title = t("<?= $module ?> Dashboard Block");
$block->content = new View("<?= $module ?>block.html");
$block->content = new View("admin_<?= $module ?>_block.html");
$block->content->item = ORM::factory("item", 1);
break;
case "<?= "{$module}_site" ?>":
$block->css_id = "g-<?= $css_id ?>-site";
$block->title = t("<?= $module ?> Sidebar Block");
$block->content = new View("<?= $module ?>_block.html");
$block->content->item = ORM::factory("item", 1);
break;
}
return $block;
}
static function get_list() {
return array(
"<?= $module ?>" => t("<?= $name ?> Dashboard Block"));
}
}

View File

@ -1,10 +1,10 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<?= "<?php defined(\"SYSPATH\") or die(\"No direct script access.\") ?>" ?>
<div class="g<?= $css_id ?>Block">
<div class="g-<?= $css_id ?>-block">
<?= "<a href=\"<?= \$item->url() ?>\">" ?>
<?= "<?= \$item->thumb_tag(array(\"class\" => \"gThumbnail\")) ?>" ?>
<?= "<?= \$item->thumb_tag(array(\"class\" => \"g-thumbnail\")) ?>" ?>
</a>
</div>

View File

@ -2,7 +2,7 @@
<?= "<?php defined(\"SYSPATH\") or die(\"No direct script access.\");" ?>
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -32,22 +32,19 @@ class <?= $class_name ?>_Controller extends Controller {
message::success(t("<?= $name ?> Processing Successfully"));
print json_encode(
array("result" => "success"));
json::reply(array("result" => "success"));
} else {
print json_encode(
array("result" => "error",
"form" => $form->__toString()));
json::reply(array("result" => "error", "html" => (string)$form));
}
}
private function _get_form() {
$form = new Forge("<?= $module ?>/handler", "", "post",
array("id" => "g<?= $css_id ?>Form"));
array("id" => "g-<?= $css_id ?>-form"));
$group = $form->group("group")->label(t("<?= $name ?> Handler"));
$group->input("text")->label(t("Text"))->rules("required");
$group->submit("submit")->value(t("Submit"));
return $form;
}
}
}

View File

@ -0,0 +1,10 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<?= "<?php defined(\"SYSPATH\") or die(\"No direct script access.\") ?>" ?>
<div class="g-<?= $css_id ?>-block">
<?= "<a href=\"<?= \$item->url() ?>\">" ?>
<?= "<?= \$item->thumb_tag(array(\"class\" => \"g-thumbnail\")) ?>" ?>
</a>
</div>

View File

@ -1,44 +1,49 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<?= form::open($action, array("method" => "post"), $hidden) ?>
<?= form::open($action, array("method" => "post")) ?>
<fieldset>
<ul>
<li <? if (!empty($errors["name"])): ?> class="gError"<? endif ?>>
<li><?= access::csrf_form_field() ?></li>
<li <? if (!empty($errors["name"])): ?> class="g-error"<? endif ?>>
<?= form::label("name", t("Name")) ?>
<?= form::input("name", $form["name"]) ?>
<? if (!empty($errors["name"]) && $errors["name"] == "required"): ?>
<p class="gError"><?= t("Module name is required") ?></p>
<p class="g-error"><?= t("Module name is required") ?></p>
<? endif ?>
<? if (!empty($errors["name"]) && $errors["name"] == "module_exists"): ?>
<p class="gError"><?= t("Module is already implemented") ?></p>
<p class="g-error"><?= t("Module is already implemented") ?></p>
<? endif ?>
</li>
<li <? if (!empty($errors["description"])): ?> class="gError"<? endif ?>>
<li <? if (!empty($errors["display_name"])): ?> class="g-error"<? endif ?>>
<?= form::label("display_name", t("Display name")) ?>
<?= form::input("display_name", $form["display_name"]) ?>
<? if (!empty($errors["display_name"]) && $errors["display_name"] == "required"): ?>
<p class="g-error"><?= t("Module display_name is required")?></p>
<? endif ?>
</li>
<li <? if (!empty($errors["description"])): ?> class="g-error"<? endif ?>>
<?= form::label("description", t("Description")) ?>
<?= form::input("description", $form["description"]) ?>
<? if (!empty($errors["description"]) && $errors["description"] == "required"): ?>
<p class="gError"><?= t("Module description is required")?></p>
<p class="g-error"><?= t("Module description is required")?></p>
<? endif ?>
</li>
<li>
<ul>
<li>
<?= form::label("theme[]", t("Theme Callbacks")) ?>
<?= form::label("theme[]", t("Theme callbacks")) ?>
<?= form::dropdown(array("name" => "theme[]", "multiple" => true, "size" => 6), $theme, $form["theme[]"]) ?>
</li>
<li>
<?= form::label("menu[]", t("Menu Callback")) ?>
<?= form::dropdown(array("name" => "menu[]", "multiple" => true, "size" => 6), $menu, $form["menu[]"]) ?>
</li>
<li>
<?= form::label("event[]", t("Gallery Event Handlers")) ?>
<li style="padding-left: 1em" >
<?= form::label("event[]", t("Gallery event handlers")) ?>
<?= form::dropdown(array("name" => "event[]", "multiple" => true, "size" => 6), $event, $form["event[]"]) ?>
</li>
</ul>
</li>
<li>
<?= form::submit(array("id" => "gGenerateModule", "name" => "generate", "class" => "submit", "style" => "clear:both!important"), t("Generate")) ?>
<?= form::submit($submit_attributes, t("Generate")) ?>
</li>
</ul>
</fieldset>
<?= form::close() ?>
</form>

View File

@ -2,7 +2,7 @@
<?= "<?php defined(\"SYSPATH\") or die(\"No direct script access.\");" ?>
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -19,78 +19,9 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class <?= $module ?>_event {
<? if (!empty($callbacks["batch_complete"])): ?>
static function batch_complete() {
<? foreach ($callbacks as $callback => $unused): ?>
<?= $callback ?> {
}
<? endif ?>
<? if (!empty($callbacks["comment_add_form"])): ?>
static function comment_add_form($form) {
}
<? endif ?>
<? if (!empty($callbacks["comment_created"])): ?>
static function comment_created($theme, $args) {
}
<? endif ?>
<? if (!empty($callbacks["comment_updated"])): ?>
static function comment_updated($old, $new) {
}
<? endif ?>
<? if (!empty($callbacks["group_before_delete"])): ?>
static function group_before_delete($group) {
}
<? endif ?>
<? if (!empty($callbacks["group_created"])): ?>
static function group_created($group) {
}
<? endif ?>
<? if (!empty($callbacks["item_before_delete"])): ?>
static function item_before_delete($item) {
}
<? endif ?>
<? if (!empty($callbacks["item_created"])): ?>
static function item_created($item) {
}
<? endif ?>
<? if (!empty($callbacks["item_related_update"])): ?>
static function item_related_update($item) {
}
<? endif ?>
<? if (!empty($callbacks["item_related_update_batch"])): ?>
static function item_related_update_batch($sql) {
}
<? endif ?>
<? if (!empty($callbacks["item_updated"])): ?>
static function item_updated($old, $new) {
}
<? endif ?>
<? if (!empty($callbacks["user_before_delete"])): ?>
static function user_before_delete($user) {
}
<? endif ?>
<? if (!empty($callbacks["user_created"])): ?>
static function user_created($user) {
}
<? endif ?>
<? if (!empty($callbacks["user_login"])): ?>
static function user_login($user) {
}
<? endif ?>
<? if (!empty($callbacks["user_logout"])): ?>
static function user_logout($user) {
}
<? endif ?>
<? endforeach ?>
}

View File

@ -2,7 +2,7 @@
<?= "<?php defined(\"SYSPATH\") or die(\"No direct script access.\");" ?>
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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

View File

@ -1,51 +0,0 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<?= "<?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 <?= $module ?>_menu {
static function admin($menu, $theme) {
$menu->get("settings_menu")
->append(Menu::factory("link")
->id("<?= $module ?>_menu")
->label(t("<?= $module_name ?> Administration"))
->url(url::site("admin/<?= $module ?>")));
}
<? if (!empty($callbacks["album"])): ?>
static function album($menu, $theme) {
}
<? endif ?>
<? if (!empty($callbacks["photo"])): ?>
static function photo($menu, $theme) {
}
<? endif ?>
static function site($menu, $theme) {
$item = $theme->item();
if ($item && access::can("edit", $item)) {
$options_menu = $menu->get("options_menu")
->append(Menu::factory("dialog")
->id("<?= $module ?>")
->label(t("Peform <?= $module_name ?> Processing"))
->url(url::site("<?= $module ?>/index/$item->id")));
}
}
}

View File

@ -1,9 +1,9 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
<div id="gMPTTTree">
<div id="g-mptt-tree">
<h2>
<?= t("MPTT Tree Visualizer") ?>
</h2>
<div id="gMPTT">
<div id="g-mptt">
<? if (empty($url)): ?>
<pre><?= $tree ?></pre>
<? else: ?>

View File

@ -2,7 +2,7 @@
<?= "<?php defined(\"SYSPATH\") or die(\"No direct script access.\");" ?>
/**
* Gallery - a web based photo album viewer and editor
* Copyright (C) 2000-2009 Bharat Mediratta
* Copyright (C) 2000-2010 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
@ -19,150 +19,139 @@
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
class <?= $module ?>_theme {
static function sidebar_blocks($theme) {
$block = new Block();
$block->css_id = "g<?= $css_id ?>";
$block->title = t("<?= $name ?>");
$block->content = new View("<?= $module ?>_block.html");
$block->content->item = ORM::factory("item", 1);
return $block;
}
<? if (!empty($callbacks["album_blocks"])): ?>
static function album_blocks($theme) {
}
<? endif ?>
<? if (!empty($callbacks["album_bottom"])): ?>
static function album_bottom($theme) {
}
<? endif ?>
<? if (!empty($callbacks["album_top"])): ?>
static function album_top($theme) {
}
<? endif ?>
<? if (!empty($callbacks["admin_credits"])): ?>
static function admin_credits($theme) {
}
<? endif ?>
<? if (!empty($callbacks["photo"])): ?>
static function admin_footer($theme) {
}
<? endif ?>
<? if (!empty($callbacks["admin_header_top"])): ?>
static function admin_header_top($theme) {
}
<? endif ?>
<? if (!empty($callbacks["admin_header_bottom"])): ?>
static function admin_header_bottom($theme) {
}
<? endif ?>
<? if (!empty($callbacks["admin_page_bottom"])): ?>
static function admin_page_bottom($theme) {
}
<? endif ?>
<? if (!empty($callbacks["admin_page_top"])): ?>
static function admin_page_top($theme) {
}
<? endif ?>
<? if (!empty($callbacks["admin_head"])): ?>
static function admin_head($theme) {
}
<? endif ?>
<? if (!empty($callbacks["credits"])): ?>
static function credits($theme) {
}
<? endif ?>
<? if (!empty($callbacks["dynamic_bottom"])): ?>
static function dynamic_bottom($theme) {
}
<? endif ?>
<? if (!empty($callbacks["dynamic_top"])): ?>
static function dynamic_top($theme) {
}
<? endif ?>
<? if (!empty($callbacks["footer"])): ?>
static function footer($theme) {
}
<? endif ?>
<? if (!empty($callbacks["head"])): ?>
static function head($theme) {
}
<? endif ?>
<? if (!empty($callbacks["header_bottom"])): ?>
static function header_bottom($theme) {
}
<? endif ?>
<? if (!empty($callbacks["header_top"])): ?>
static function header_top($theme) {
}
<? endif ?>
<? if (!empty($callbacks["page_bottom"])): ?>
static function page_bottom($theme) {
}
<? endif ?>
<? if (!empty($callbacks["pae_top"])): ?>
static function page_top($theme) {
}
<? endif ?>
<? if (!empty($callbacks["photo_blocks"])): ?>
static function photo_blocks($theme) {
}
<? endif ?>
<? if (!empty($callbacks["photo_bottom"])): ?>
static function photo_bottom($theme) {
}
<? endif ?>
<? if (!empty($callbacks["photo_top"])): ?>
static function photo_top($theme) {
}
<? endif ?>
<? if (!empty($callbacks["sidebar_bottom"])): ?>
static function sidebar_bottom($theme) {
}
<? endif ?>
<? if (!empty($callbacks["sidebar_top"])): ?>
static function sidebar_top($theme) {
}
<? endif ?>
<? if (!empty($callbacks["thumb_bottom"])): ?>
static function thumb_bottom($theme, $child) {
}
<? endif ?>
<? if (!empty($callbacks["thumb_info"])): ?>
static function thumb_info($theme, $child) {
}
<? endif ?>
<? if (!empty($callbacks["thumb_top"])): ?>
static function thumb_top($theme, $child) {
}
<? endif ?>
}

Some files were not shown because too many files have changed in this diff Show More