PageRenderTime 41ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/gallery/helpers/movie.php

https://github.com/ShakeNBake/gallery3
PHP | 200 lines | 129 code | 26 blank | 45 comment | 20 complexity | 8164e9e971b77b308facb0c6375e178e MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php defined("SYSPATH") or die("No direct script access.");
  2. /**
  3. * Gallery - a web based photo album viewer and editor
  4. * Copyright (C) 2000-2009 Bharat Mediratta
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or (at
  9. * your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. /**
  21. * This is the API for handling movies.
  22. *
  23. * Note: by design, this class does not do any permission checking.
  24. */
  25. class movie_Core {
  26. /**
  27. * Create a new movie.
  28. * @param integer $parent_id id of parent album
  29. * @param string $filename path to the photo file on disk
  30. * @param string $name the filename to use for this photo in the album
  31. * @param integer $title the title of the new photo
  32. * @param string $description (optional) the longer description of this photo
  33. * @param string $slug (optional) the url component for this photo
  34. * @return Item_Model
  35. */
  36. static function create($parent, $filename, $name, $title,
  37. $description=null, $owner_id=null, $slug=null) {
  38. if (!$parent->loaded || !$parent->is_album()) {
  39. throw new Exception("@todo INVALID_PARENT");
  40. }
  41. if (!is_file($filename)) {
  42. throw new Exception("@todo MISSING_MOVIE_FILE");
  43. }
  44. if (strpos($name, "/")) {
  45. throw new Exception("@todo NAME_CANNOT_CONTAIN_SLASH");
  46. }
  47. // We don't allow trailing periods as a security measure
  48. // ref: http://dev.kohanaphp.com/issues/684
  49. if (rtrim($name, ".") != $name) {
  50. throw new Exception("@todo NAME_CANNOT_END_IN_PERIOD");
  51. }
  52. try {
  53. $movie_info = movie::getmoviesize($filename);
  54. } catch (Exception $e) {
  55. // Assuming this is MISSING_FFMPEG for now
  56. $movie_info = getimagesize(MODPATH . "gallery/images/missing_movie.png");
  57. }
  58. // Force an extension onto the name
  59. $pi = pathinfo($filename);
  60. if (empty($pi["extension"])) {
  61. $pi["extension"] = image_type_to_extension($movie_info[2], false);
  62. $name .= "." . $pi["extension"];
  63. }
  64. if (empty($slug)) {
  65. $slug = item::convert_filename_to_slug($name);
  66. }
  67. $movie = ORM::factory("item");
  68. $movie->type = "movie";
  69. $movie->title = $title;
  70. $movie->description = $description;
  71. $movie->name = $name;
  72. $movie->owner_id = $owner_id ? $owner_id : user::active();
  73. $movie->width = $movie_info[0];
  74. $movie->height = $movie_info[1];
  75. $movie->mime_type = strtolower($pi["extension"]) == "mp4" ? "video/mp4" : "video/x-flv";
  76. $movie->thumb_dirty = 1;
  77. $movie->resize_dirty = 1;
  78. $movie->sort_column = "weight";
  79. $movie->slug = $slug;
  80. $movie->rand_key = ((float)mt_rand()) / (float)mt_getrandmax();
  81. // Randomize the name if there's a conflict
  82. // @todo Improve this. Random numbers are not user friendly
  83. while (ORM::factory("item")
  84. ->where("parent_id", $parent->id)
  85. ->open_paren()
  86. ->where("name", $movie->name)
  87. ->orwhere("slug", $movie->slug)
  88. ->close_paren()
  89. ->find()->id) {
  90. $rand = rand();
  91. $movie->name = "{$name}.$rand.{$pi['extension']}";
  92. $movie->slug = "{$slug}-$rand";
  93. }
  94. // This saves the photo
  95. $movie->add_to_parent($parent);
  96. // If the thumb or resize already exists then rename it
  97. if (file_exists($movie->resize_path()) ||
  98. file_exists($movie->thumb_path())) {
  99. $movie->name = $pi["filename"] . "-" . rand() . "." . $pi["extension"];
  100. $movie->save();
  101. }
  102. copy($filename, $movie->file_path());
  103. // @todo: publish this from inside Item_Model::save() when we refactor to the point where
  104. // there's only one save() happening here.
  105. module::event("item_created", $movie);
  106. // Build our thumbnail
  107. graphics::generate($movie);
  108. // If the parent has no cover item, make this it.
  109. if (access::can("edit", $parent) && $parent->album_cover_item_id == null) {
  110. item::make_album_cover($movie);
  111. }
  112. return $movie;
  113. }
  114. static function get_edit_form($movie) {
  115. $form = new Forge("movies/$movie->id", "", "post", array("id" => "gEditMovieForm"));
  116. $form->hidden("_method")->value("put");
  117. $group = $form->group("edit_item")->label(t("Edit Movie"));
  118. $group->input("title")->label(t("Title"))->value($movie->title);
  119. $group->textarea("description")->label(t("Description"))->value($movie->description);
  120. $group->input("filename")->label(t("Filename"))->value($movie->name)
  121. ->error_messages(
  122. "name_conflict", t("There is already a movie, photo or album with this name"))
  123. ->callback("item::validate_no_slashes")
  124. ->error_messages("no_slashes", t("The movie name can't contain a \"/\""))
  125. ->callback("item::validate_no_trailing_period")
  126. ->error_messages("no_trailing_period", t("The movie name can't end in \".\""));
  127. $group->input("slug")->label(t("Internet Address"))->value($movie->slug)
  128. ->callback("item::validate_url_safe")
  129. ->error_messages(
  130. "slug_conflict", t("There is already a movie, photo or album with this internet address"))
  131. ->error_messages(
  132. "not_url_safe",
  133. t("The internet address should contain only letters, numbers, hyphens and underscores"));
  134. module::event("item_edit_form", $movie, $form);
  135. $group = $form->group("buttons")->label("");
  136. $group->submit("")->value(t("Modify"));
  137. $form->add_rules_from(ORM::factory("item"));
  138. return $form;
  139. }
  140. static function getmoviesize($filename) {
  141. $ffmpeg = self::find_ffmpeg();
  142. if (empty($ffmpeg)) {
  143. throw new Exception("@todo MISSING_FFMPEG");
  144. }
  145. $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($filename) . " 2>&1";
  146. $result = `$cmd`;
  147. if (preg_match("/Stream.*?Video:.*?(\d+)x(\d+)/", $result, $regs)) {
  148. list ($width, $height) = array($regs[1], $regs[2]);
  149. } else {
  150. list ($width, $height) = array(0, 0);
  151. }
  152. return array($width, $height);
  153. }
  154. static function extract_frame($input_file, $output_file) {
  155. $ffmpeg = self::find_ffmpeg();
  156. if (empty($ffmpeg)) {
  157. throw new Exception("@todo MISSING_FFMPEG");
  158. }
  159. $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($input_file) .
  160. " -an -ss 00:00:03 -an -r 1 -vframes 1" .
  161. " -y -f mjpeg " . escapeshellarg($output_file) . " 2>&1";
  162. exec($cmd);
  163. }
  164. static function find_ffmpeg() {
  165. if (!$ffmpeg_path = module::get_var("gallery", "ffmpeg_path")) {
  166. putenv("PATH=" . getenv("PATH") . ":/usr/local/bin:/opt/local/bin:/opt/bin");
  167. if (function_exists("exec")) {
  168. $ffmpeg_path = exec("which ffmpeg");
  169. }
  170. module::set_var("gallery", "ffmpeg_path", $ffmpeg_path);
  171. }
  172. return $ffmpeg_path;
  173. }
  174. }