From 085d7cff74113dae96d4892d601921b98e0bd71e Mon Sep 17 00:00:00 2001 From: John Bowles Date: Wed, 25 Aug 2010 21:39:57 -0700 Subject: [PATCH 01/16] Inital commit. Not yet in a working state, please do not pull. In the process of refactoring. --- .../controllers/embedded_videos.php | 176 +++ modules/embed_videos/helpers/embed_video.php | 107 ++ .../helpers/embed_video_event.php | 37 + .../helpers/embed_video_installer.php | 13 + .../embed_videos/images/embed_video_icon.png | Bin 0 -> 3772 bytes .../embed_videos/models/embedded_video.php | 7 + modules/embed_videos/models/item.php | 1033 +++++++++++++++++ modules/embed_videos/module.info | 3 + .../embed_videos/views/embed_video.html.php | 19 + .../views/embed_videoplayer.html.php | 3 + 10 files changed, 1398 insertions(+) create mode 100644 modules/embed_videos/controllers/embedded_videos.php create mode 100644 modules/embed_videos/helpers/embed_video.php create mode 100644 modules/embed_videos/helpers/embed_video_event.php create mode 100644 modules/embed_videos/helpers/embed_video_installer.php create mode 100644 modules/embed_videos/images/embed_video_icon.png create mode 100644 modules/embed_videos/models/embedded_video.php create mode 100644 modules/embed_videos/models/item.php create mode 100644 modules/embed_videos/module.info create mode 100644 modules/embed_videos/views/embed_video.html.php create mode 100644 modules/embed_videos/views/embed_videoplayer.html.php diff --git a/modules/embed_videos/controllers/embedded_videos.php b/modules/embed_videos/controllers/embedded_videos.php new file mode 100644 index 00000000..becab73a --- /dev/null +++ b/modules/embed_videos/controllers/embedded_videos.php @@ -0,0 +1,176 @@ +parent()->get_position($movie, $where); + if ($position > 1) { + list($previous_item, $ignore, $next_item) = $movie->parent()->children(3, $position - 2, $where); + } else { + $previous_item = null; + list($next_item) = $movie->parent()->viewable()->children(1, $position, $where); + } + $template = new Theme_View("page.html", "item", "embed"); + $template->set_global("item", $movie); + $template->set_global("children", array()); + $template->set_global("children_count", 0); + $template->set_global("parents", $movie->parents()); + $template->set_global("next_item", $next_item); + $template->set_global("previous_item", $previous_item); + $template->set_global("sibling_count", $movie->parent()->viewable()->children_count($where)); + $template->set_global("position", $position); + $template->content = new View("embed.html"); + $movie->view_count++; + $movie->save(); + print $template; + } + public function update($movie_id) { + access::verify_csrf(); + $movie = ORM::factory("item", $movie_id); + access::required("view", $movie); + access::required("edit", $movie); + $form = embed::get_edit_form($movie); + try { + $valid = $form->validate(); + $movie->title = $form->edit_item->title->value; + $movie->description = $form->edit_item->description->value; + $movie->slug = $form->edit_item->slug->value; + //$movie->name = $form->edit_item->inputs["name"]->value; + $movie->validate(); + } + catch(ORM_Validation_Exception $e) { + // Translate ORM validation errors into form error messages + foreach($e->validation->errors() as $key => $error) { + $form->edit_item->inputs[$key]->add_error($error, 1); + } + $valid = false; + } + if ($valid) { + $movie->save(); + module::event("item_edit_form_completed", $movie, $form); + log::success("content", "Updated embed", "url() }\">view"); + message::success(t("Saved embed %movie_title", array("movie_title" => $movie->title))); + if ($form->from_id->value == $movie->id) { + // Use the new url; it might have changed. + print json_encode(array("result" => "success", "location" => $movie->url())); + } else { + // Stay on the same page + print json_encode(array("result" => "success")); + } + } else { + print json_encode(array("result" => "error", "form" => (string)$form)); + } + } + public function create($id) { + $album = ORM::factory("item", $id); + access::required("view", $album); + access::required("add", $album); + access::verify_csrf(); + $form = embed::get_add_form($album); + //$form->add_rules('youtubeid', array('required', 'length[11]')); + //$form->add_callback('youtubeid', 'valid_youtubeid'); + batch::start(); + try { + $valid = $form->validate(); + if (preg_match('/^[a-zA-Z0-9_-]{11}$/', $form->add_embed->inputs['name']->value)) { + $temp_filename = VARPATH . "tmp/" . $form->add_embed->inputs['name']->value . ".jpg"; + $item = ORM::factory("item"); + $item->type = "photo"; + $item->name = basename($form->add_embed->inputs['name']->value . ".jpg"); + //$item->youtubeid = $form->add_embed->youtubeid->value; + $item->title = $form->add_embed->title->value; + $item->parent_id = $album->id; + $item->description = $form->add_embed->description->value; + $item->slug = $form->add_embed->slug->value; + //$item->validate(); + $content = file_get_contents("http://img.youtube.com/vi/" . $form->add_embed->inputs['name']->value . "/0.jpg"); + if ($content) { + $file = fopen($temp_filename, "wb"); + fwrite($file, $content); + fclose($file); + gallery_graphics::composite($temp_filename, $temp_filename, array("file" => "modules/embed/images/icon.png", "position" => "center", "transparency" => 95)); + $item->set_data_file($temp_filename); + $path_info = @pathinfo($temp_filename); + $item->save(); + $embedded_video = ORM::factory("embedded_video"); + $embedded_video->video = true; + $embedded_video->embed_code = "test"; + $embedded_video->source = "YouTube"; + $embedded_video->item_id = $item->id; + $embedded_video->validate(); + $embedded_video->save(); + log::success("content", t("Added a embedded video"), html::anchor("embeds/$item->id", t("view video"))); + module::event("add_event_form_completed", $item, $form); + } else { + $form->add_embed->inputs['name']->add_error('invalid_id', 1); + $valid = false; + } + } else { + $form->add_embed->inputs['name']->add_error('invalid_id', 1); + $valid = false; + } + } + catch(Exception $e) { + // Lame error handling for now. Just record the exception and move on + Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); + // Ugh. I hate to use instanceof, But this beats catching the exception separately since + // we mostly want to treat it the same way as all other exceptions + if ($e instanceof ORM_Validation_Exception) { + Kohana_Log::add("error", "Validation errors: " . print_r($e->validation->errors(), 1)); + foreach($e->validation->errors() as $key => $error) { + $form->add_embed->inputs[$key]->add_error($error, 1); + } + $valid = false; + } + if (file_exists($temp_filename)) { + unlink($temp_filename); + } + } + if (file_exists($temp_filename)) { + unlink($temp_filename); + } + batch::stop(); + if ($valid) { + //print json_encode(array("result" => "success")); + json::reply(array("result" => "success", "location" => $item->url())); + } else { + //json::reply(array("result" => "error", "form" => (string)$form)); + print $form; + } + } + public function form_add($album_id) { + $album = ORM::factory("item", $album_id); + access::required("view", $album); + access::required("add", $album); + print embed::get_add_form($album); + } + public function form_edit($id) { + $embed = ORM::factory("item", $id); + access::required("view", $embed); + access::required("edit", $embed); + print embed::get_edit_form($embed); + } +} diff --git a/modules/embed_videos/helpers/embed_video.php b/modules/embed_videos/helpers/embed_video.php new file mode 100644 index 00000000..7a60107d --- /dev/null +++ b/modules/embed_videos/helpers/embed_video.php @@ -0,0 +1,107 @@ +id}", "", "post", array("id" => "g-add-embed-form")); + $group = $form->group("add_embed") + ->label(t("Add embedded video to %album_title", array("album_title" => $album->title))); + $group->input("title")->label(t("Title")) + ->error_messages("required", t("You must provide a title")) + ->error_messages("length", t("Your title is too long")); + $group->input("name")->label(t("Youtube ID")) + ->error_messages( + "conflict", t("There is already a movie with this ID")) + ->error_messages("required", t("You must provide a Youtube ID")) + ->error_messages("length", t("Invalid Youtube ID")) + ->error_messages("invalid_id", t("Invalid Youtube ID")); + $group->textarea("description")->label(t("Description")); + $group->input("slug")->label(t("Internet Address")) + ->error_messages( + "conflict", t("There is already a movie, photo or album with this internet address")) + ->error_messages( + "not_url_safe", + t("The internet address should contain only letters, numbers, hyphens and underscores")) + ->error_messages("required", t("You must provide an internet address")) + ->error_messages("length", t("Your internet address is too long")); + $group->hidden("type")->value("embed"); + + module::event("embed_add_form", $album, $form); + + $group = $form->group("buttons")->label(""); + $group->submit("")->value(t("Add")); + + return $form; + } + + static function get_edit_form($photo) { + $form = new Forge("embeds/update/$photo->id", "", "post", array("id" => "g-edit-embed-form")); + $form->hidden("from_id")->value($photo->id); + $group = $form->group("edit_item")->label(t("Edit Embedded Video")); + $group->input("title")->label(t("Title"))->value($photo->title) + ->error_messages("required", t("You must provide a title")) + ->error_messages("length", t("Your title is too long")); + $group->textarea("description")->label(t("Description"))->value($photo->description); + $group->input("slug")->label(t("Internet Address"))->value($photo->slug) + ->error_messages( + "conflict", t("There is already a movie, photo or album with this internet address")) + ->error_messages( + "not_url_safe", + t("The internet address should contain only letters, numbers, hyphens and underscores")) + ->error_messages("required", t("You must provide an internet address")) + ->error_messages("length", t("Your internet address is too long")); + + module::event("item_edit_form", $photo, $form); + + $group = $form->group("buttons")->label(""); + $group->submit("")->value(t("Modify")); + return $form; + } + + /** + * Return scaled width and height. + * + * @param integer $width + * @param integer $height + * @param integer $max the target size for the largest dimension + * @param string $format the output format using %d placeholders for width and height + */ + static function img_dimensions($width, $height, $max, $format="width=\"%d\" height=\"%d\"") { + if (!$width || !$height) { + return ""; + } + + if ($width > $height) { + $new_width = $max; + $new_height = (int)$max * ($height / $width); + } else { + $new_height = $max; + $new_width = (int)$max * ($width / $height); + } + return sprintf($format, $new_width, $new_height); + } + +} diff --git a/modules/embed_videos/helpers/embed_video_event.php b/modules/embed_videos/helpers/embed_video_event.php new file mode 100644 index 00000000..6224bfb8 --- /dev/null +++ b/modules/embed_videos/helpers/embed_video_event.php @@ -0,0 +1,37 @@ +is_embed()) { + // Build our thumbnail/resizes. + try { + graphics::generate($item); + } catch (Exception $e) { + log::error("graphics", t("Couldn't create a thumbnail or resize for %item_title", + array("item_title" => $item->title)), + html::anchor($item->abs_url(), t("details"))); + Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); + } + + // If the parent has no cover item, make this it. + $parent = $item->parent(); + if (access::can("edit", $parent) && $parent->album_cover_item_id == null) { + item::make_album_cover($item); + } + } + } + static function site_menu($menu, $theme) { + $item = $theme->item(); + + if ($can_add = $item && access::can("add", $item)) { + $menu->get("add_menu") + ->append(Menu::factory("dialog") + ->id("embed_add") + ->label(t("Embed Video")) + ->url(url::site("form/add/embeds/$item->id"))); + } + } +} diff --git a/modules/embed_videos/helpers/embed_video_installer.php b/modules/embed_videos/helpers/embed_video_installer.php new file mode 100644 index 00000000..1837abfd --- /dev/null +++ b/modules/embed_videos/helpers/embed_video_installer.php @@ -0,0 +1,13 @@ +l~$J)6BCmqxH?{*j9_i2Sy(_O^J>nojooV6BA>4GBW(!G18gi zrl-$_mCV_wi;2m36Pz6bwyVu{1q((d;y?aeo}dM{p8IQfbPUn``7UB|*Zo`f-8A@-J{1$M~JvV<=_BG#zBarT#LW*qLt2qhWTSROgQ z!L1)34PoC{nA(%D+*3|LKOEJ6+MT$q==XY#spAv5HJFC-$|vjj(lvw9F$0B8uN9kf zHx<_~KTZ-W*alBlzRf>bvr#fV5;xKbHI2%0Tlv~{Y5r^ZF;0rd$odxIodO;Lt++&2 zw)_s6EY9W_t0)kw>!soB06Za)klwJ%7r13sAD~ODE^tOs@?em<>vZrXI;jvqJFo}` zjihlN4LdGtG1F%sI(#_K>Bw>57cUU`h=%mX{la@&pWesvI{MWeS%jSyJIw3f`=&fb zQS)yz6-fC^1+v#ebp|om=r+C2yifeeAowSATBDLKYtMCqmOtYB! z5Ll(YhjGV&cOeBUP9_>%<`qW+mCBSl^%SHYx^)NP@6udD#y0sU86=&_p~`s@M=2|K z&fEL@W_>=iqo?jba%JUjjn2C?aC z{I1A}p3+gnr3;JF-(-)B^!Ur$F4$kTAC+4?g%{jAm4fgTYsR|^>#+fR7Sko~K|}ER zzS9Z6rDLYAyUJPhxfZ=g-&Um%AkIc^LR5){I`%e(La5-))|K*xkXqWsm0IjL0Qn72 zp-BZa2g%lA-TACjPNw};2g9??>JLFB|8bz^@Qwnv5o~5Uwi)wS${1HK)d$-RA4D}D zM7w($srWZzfmks|YZrPzr%D`5L1N^r?=X&Ok(3ZD)S|xlF$h(8=yrcJ}En(IE z$qy;a+M6s}kyV}t%9pQt|IC3rt9^EHQ|9F&jzQ6nWS@jDT!7`?h{>ZYT@pgtB#GGtGP5C z&y6cSyfIe(ci6rJoM))WJmK5qpy*6RTcvr} z>m#?93kGP*D<a}nM6_}B5sw|s7Qd&a}}zBsQ_H|WQ*g?D`c`o(G|Fgp*AOW^7)9NrAUNf{R& z{nypGzO(Zev{xjQ|J`78+U{P$d#7SzGPf&qeVQ!!&pSjRH zh)hGn=o+Zj6DXOdmL7bPR~#azi2*~j3{(hb1}KJuEJE8We+Y`y`hvUJ?q(5m^xcg0 zePMKy7Fp;_Q-EfFl>z3hhu?;ZlJdr##52hp)xF{ptq=apS%<8xpAKHt@r<3XEVvmX zD2}Fy#eEIg$Vk}8@LU-v7p-RL2Rk`Za>?wllKO*<@r(ANkD?_H&y}h2f9G~~e{S_Y zYF*9cLg(HOE{gH**-6xLSh!oTzNZY6mRC2msOCNTRzt&+I%CtB)$kvYPPT!gEe$?3~b4i>XW`DgPL})BxKIW56-kV@gJ^z~(Kjl6d3`bw;(=6q&v)VA5on1c_xh}q?kdcuJJ?qdimK=1Z81Z zs8rGZXt&i?s5Ot2ucb+>9>fUPuXGUPjG3nY1#vr%UO<4Nw@t_9_4%O}ZQ?&RM%!`*XAMz0y~y*)AF(1&qQX|%)q z$^BI{G3g9gUy^a_b4%KVz?X92eXbJefy`^1LX($fwALUj$c1qQj-EJ{ny0lrw4{2b z3G*LUH(x_mx%Ii+|98lB2*j9ua-igDx-w(Nnr`@aJ0Bdde%p9#ju}}}?R28jY!KDH z^w~i4MYOLqXj;$(4e8MsS(_iK$VknK+P3&lHUkf-lyIXS5VBwS=YVl_No;b43&zJ6G~)ccthG(EYplJw;J+wK94*$D6SM|Fb|JiW_Z4h$3ZrL^xKvu@tw`hU#K zG}RmKJv#CjVlX^vI!%DDQaSdN*9PskWt(`ad`hpSYj?Nk@3pqh-yWXrE2FFBX|IYG zNc&g%C+vQYHJW|yO%Qc&NSrxY<*-THiNbMkJJM)e-v}%E@g{jV+lenL;1u|L_&F%16RZ^JP-Y}y^93wlMB7G z*TDhmLA@TaL>`x+@R4BG?(J2Dmd_HC{4aA=_YUo*Uf~*tjnW6PPg3H`tn-GmcjD>{ zt{^FB7pOp%l$+DEO@mB1UML*uj}n!2EWT8k%a)UuZ=d$?oNg7z^;o)@NjOpc5KE;B z-_W7pf&03yfOXwh9BIr387f0He-_%$AP9;VgjSvzufzf%8Q>AC*YZN)arsSejwPlC zX+!JaNrfivpz8=QnL%N>c_z6iFY(wRUAl=o1UjQ&9$`g4KgCT(Uy*dWstPaJjE5B| zKSJ;@I^YPR}Q|?geiNUkiK%Na7m3Xs(D_( z`m-fc?WdB{i0PDkq1l)L{jP#Gd@nZ`wQ5~?w&UD}?Vhx~t6t$9y!3^(qoS8Ji9SC? z-C+;#@*$V5Ozt`R^+Th%BUqQ1Xmhi5UR5NHmTAW4Tr-?|RHL%|-@Ej`b0_)n%lF2f z&<;h7*fzA!-y{yj_!xno&u_TRnof>=4$W*YC|#gM|NN0?ec#%SkQP*Ck9~c<*p%}V zPhsdYWm^XQ9==ws)8bkjnBAwA)is)VKJxi_W|5R=+p)L^a>sEm8SwX0jDYuczUvg4 F^nd)r_*wt} literal 0 HcmV?d00001 diff --git a/modules/embed_videos/models/embedded_video.php b/modules/embed_videos/models/embedded_video.php new file mode 100644 index 00000000..6c849d72 --- /dev/null +++ b/modules/embed_videos/models/embedded_video.php @@ -0,0 +1,7 @@ +loaded()) { + // Set reasonable defaults + $this->created = time(); + $this->rand_key = ((float)mt_rand()) / (float)mt_getrandmax(); + $this->thumb_dirty = 1; + $this->resize_dirty = 1; + $this->sort_column = "created"; + $this->sort_order = "ASC"; + $this->owner_id = identity::active_user()->id; + } + } + + /** + * Add a set of restrictions to any following queries to restrict access only to items + * viewable by the active user. + * @chainable + */ + public function viewable() { + return item::viewable($this); + } + + /** + * Is this item an album? + * @return true if it's an album + */ + public function is_album() { + return $this->type == 'album'; + } + + /** + * Is this item a photo? + * @return true if it's a photo + */ + public function is_photo() { + return $this->type == 'photo'; + } + + /** + * Is this item a movie? + * @return true if it's a movie + */ + public function is_movie() { + return $this->type == 'movie'; + } + + public function is_embed() { + return $this->type == 'embed'; + } + + public function delete($ignored_id=null) { + if ($this->id == 1) { + $v = new Validation(array("id")); + $v->add_error("id", "cant_delete_root_album"); + ORM_Validation_Exception::handle_validation($this->table_name, $v); + } + + $old = clone $this; + module::event("item_before_delete", $this); + + $parent = $this->parent(); + if ($parent->album_cover_item_id == $this->id) { + item::remove_album_cover($parent); + } + + $path = $this->file_path(); + $resize_path = $this->resize_path(); + $thumb_path = $this->thumb_path(); + + parent::delete(); + if (is_dir($path)) { + // Take some precautions against accidentally deleting way too much + $delete_resize_path = dirname($resize_path); + $delete_thumb_path = dirname($thumb_path); + if ($delete_resize_path == VARPATH . "resizes" || + $delete_thumb_path == VARPATH . "thumbs" || + $path == VARPATH . "albums") { + throw new Exception( + "@todo DELETING_TOO_MUCH ($delete_resize_path, $delete_thumb_path, $path)"); + } + @dir::unlink($path); + @dir::unlink($delete_resize_path); + @dir::unlink($delete_thumb_path); + } else { + @unlink($path); + @unlink($resize_path); + @unlink($thumb_path); + } + + module::event("item_deleted", $old); + } + + /** + * Specify the path to the data file associated with this item. To actually associate it, + * you still have to call save(). + * @chainable + */ + public function set_data_file($data_file) { + $this->data_file = $data_file; + return $this; + } + + /** + * Return the server-relative url to this item, eg: + * /gallery3/index.php/BobsWedding?page=2 + * /gallery3/index.php/BobsWedding/Eating-Cake.jpg + * + * @param string $query the query string (eg "show=3") + */ + public function url($query=null) { + $url = url::site($this->relative_url()); + if ($query) { + $url .= "?$query"; + } + return $url; + } + + /** + * Return the full url to this item, eg: + * http://example.com/gallery3/index.php/BobsWedding?page=2 + * http://example.com/gallery3/index.php/BobsWedding/Eating-Cake.jpg + * + * @param string $query the query string (eg "show=3") + */ + public function abs_url($query=null) { + $url = url::abs_site($this->relative_url()); + if ($query) { + $url .= "?$query"; + } + return $url; + } + + /** + * album: /var/albums/album1/album2 + * photo: /var/albums/album1/album2/photo.jpg + */ + public function file_path() { + return VARPATH . "albums/" . urldecode($this->relative_path()); + } + + /** + * album: http://example.com/gallery3/var/resizes/album1/ + * photo: http://example.com/gallery3/var/albums/album1/photo.jpg + */ + public function file_url($full_uri=false) { + $relative_path = "var/albums/" . $this->relative_path(); + return ($full_uri ? url::abs_file($relative_path) : url::file($relative_path)) + . "?m={$this->updated}"; + } + + /** + * album: /var/resizes/album1/.thumb.jpg + * photo: /var/albums/album1/photo.thumb.jpg + */ + public function thumb_path() { + $base = VARPATH . "thumbs/" . urldecode($this->relative_path()); + if ($this->is_photo() || $this->is_embed()) { + return $base; + } else if ($this->is_album()) { + return $base . "/.album.jpg"; + } else if ($this->is_movie()) { + // Replace the extension with jpg + return preg_replace("/...$/", "jpg", $base); + } + } + + /** + * Return true if there is a thumbnail for this item. + */ + public function has_thumb() { + return $this->thumb_width && $this->thumb_height; + } + + /** + * album: http://example.com/gallery3/var/resizes/album1/.thumb.jpg + * photo: http://example.com/gallery3/var/albums/album1/photo.thumb.jpg + */ + public function thumb_url($full_uri=false) { + $cache_buster = "?m={$this->updated}"; + $relative_path = "var/thumbs/" . $this->relative_path(); + $base = ($full_uri ? url::abs_file($relative_path) : url::file($relative_path)); + if ($this->is_photo() || $this->is_embed()) { + return $base . $cache_buster; + } else if ($this->is_album()) { + return $base . "/.album.jpg" . $cache_buster; + } else if ($this->is_movie()) { + // Replace the extension with jpg + $base = preg_replace("/...$/", "jpg", $base); + return $base . $cache_buster; + } + } + + /** + * album: /var/resizes/album1/.resize.jpg + * photo: /var/albums/album1/photo.resize.jpg + */ + public function resize_path() { + return VARPATH . "resizes/" . urldecode($this->relative_path()) . + ($this->is_album() ? "/.album.jpg" : ""); + } + + /** + * album: http://example.com/gallery3/var/resizes/album1/.resize.jpg + * photo: http://example.com/gallery3/var/albums/album1/photo.resize.jpg + */ + public function resize_url($full_uri=false) { + $relative_path = "var/resizes/" . $this->relative_path(); + return ($full_uri ? url::abs_file($relative_path) : url::file($relative_path)) . + ($this->is_album() ? "/.album.jpg" : "") + . "?m={$this->updated}"; + } + + /** + * Rebuild the relative_path_cache and relative_url_cache. + */ + private function _build_relative_caches() { + $names = array(); + $slugs = array(); + foreach (db::build() + ->select(array("name", "slug")) + ->from("items") + ->where("left_ptr", "<=", $this->left_ptr) + ->where("right_ptr", ">=", $this->right_ptr) + ->where("id", "<>", 1) + ->order_by("left_ptr", "ASC") + ->execute() as $row) { + // Don't encode the names segment + $names[] = rawurlencode($row->name); + $slugs[] = rawurlencode($row->slug); + } + $this->relative_path_cache = implode($names, "/"); + $this->relative_url_cache = implode($slugs, "/"); + return $this; + } + + /** + * Return the relative path to this item's file. Note that the components of the path are + * urlencoded so if you want to use this as a filesystem path, you need to call urldecode + * on it. + * @return string + */ + public function relative_path() { + if (!$this->loaded()) { + return; + } + + if (!isset($this->relative_path_cache)) { + $this->_build_relative_caches()->save(); + } + return $this->relative_path_cache; + } + + /** + * Return the relative url to this item's file. + * @return string + */ + public function relative_url() { + if (!$this->loaded()) { + return; + } + + if (!isset($this->relative_url_cache)) { + $this->_build_relative_caches()->save(); + } + return $this->relative_url_cache; + } + + /** + * @see ORM::__get() + */ + public function __get($column) { + if ($column == "owner") { + // This relationship depends on an outside module, which may not be present so handle + // failures gracefully. + try { + return identity::lookup_user($this->owner_id); + } catch (Exception $e) { + return null; + } + } else { + return parent::__get($column); + } + } + + /** + * Handle any business logic necessary to create or modify an item. + * @see ORM::save() + * + * @return ORM Item_Model + */ + public function save() { + $significant_changes = $this->changed; + unset($significant_changes["view_count"]); + unset($significant_changes["relative_url_cache"]); + unset($significant_changes["relative_path_cache"]); + + if ((!empty($this->changed) && $significant_changes) || isset($this->data_file)) { + $this->updated = time(); + if (!$this->loaded()) { + // Create a new item. + + // Set a weight if it's missing. We don't do this in the constructor because it's not a + // simple assignment. + if (empty($this->weight)) { + $this->weight = item::get_max_weight(); + } + + // Make an url friendly slug from the name, if necessary + if (empty($this->slug)) { + $tmp = pathinfo($this->name, PATHINFO_FILENAME); + $tmp = preg_replace("/[^A-Za-z0-9-_]+/", "-", $tmp); + $this->slug = trim($tmp, "-"); + + // If the filename is all invalid characters, then the slug may be empty here. Pick a + // random value. + if (empty($this->slug)) { + $this->slug = (string)rand(1000, 9999); + } + } + + // Get the width, height and mime type from our data file for photos and movies. + if ($this->is_photo() || $this->is_movie() || $this->is_embed()) { + if ($this->is_photo() || $this->is_embed()) { + list ($this->width, $this->height, $this->mime_type, $extension) = + photo::get_file_metadata($this->data_file); + } else if ($this->is_movie()) { + list ($this->width, $this->height, $this->mime_type, $extension) = + movie::get_file_metadata($this->data_file); + } + + // Force an extension onto the name if necessary + $pi = pathinfo($this->data_file); + if (empty($pi["extension"])) { + $this->name = "{$this->name}.$extension"; + } + } + + // Randomize the name or slug if there's a conflict. Preserve the extension. + // @todo Improve this. Random numbers are not user friendly + $base_name = pathinfo($this->name, PATHINFO_FILENAME); + $base_ext = pathinfo($this->name, PATHINFO_EXTENSION); + $base_slug = $this->slug; + while (ORM::factory("item") + ->where("parent_id", "=", $this->parent_id) + ->and_open() + ->where("name", "=", $this->name) + ->or_where("slug", "=", $this->slug) + ->close() + ->find()->id) { + $rand = rand(); + if ($base_ext) { + $this->name = "$base_name-$rand.$base_ext"; + } else { + $this->name = "$base_name-$rand"; + } + $this->slug = "$base_slug-$rand"; + } + + parent::save(); + + // Build our url caches, then save again. We have to do this after it's already been + // saved once because we use only information from the database to build the paths. If we + // could depend on a save happening later we could defer this 2nd save. + $this->_build_relative_caches(); + parent::save(); + + // Take any actions that we can only do once all our paths are set correctly after saving. + switch ($this->type) { + case "album": + mkdir($this->file_path()); + mkdir(dirname($this->thumb_path())); + mkdir(dirname($this->resize_path())); + break; + + case "photo": + case "movie": + case "embed": + // The thumb or resize may already exist in the case where a movie and a photo generate + // a thumbnail of the same name (eg, foo.flv movie and foo.jpg photo will generate + // foo.jpg thumbnail). If that happens, randomize and save again. + if (file_exists($this->resize_path()) || + file_exists($this->thumb_path())) { + $pi = pathinfo($this->name); + $this->name = $pi["filename"] . "-" . rand() . "." . $pi["extension"]; + parent::save(); + } + + copy($this->data_file, $this->file_path()); + break; + } + + // This will almost definitely trigger another save, so put it at the end so that we're + // tail recursive. + module::event("item_created", $this); + } else { + // Update an existing item + + // If any significant fields have changed, load up a copy of the original item and + // keep it around. + $original = ORM::factory("item", $this->id); + if (array_intersect($this->changed, array("parent_id", "name", "slug"))) { + $original->_build_relative_caches(); + $this->relative_path_cache = null; + $this->relative_url_cache = null; + } + + parent::save(); + + // Now update the filesystem and any database caches if there were significant value + // changes. If anything past this point fails, then we'll have an inconsistent database + // so this code should be as robust as we can make it. + + // Update the MPTT pointers, if necessary. We have to do this before we generate any + // cached paths! + if ($original->parent_id != $this->parent_id) { + parent::move_to($this->parent()); + } + + if ($original->parent_id != $this->parent_id || $original->name != $this->name) { + // Move all of the items associated data files + @rename($original->file_path(), $this->file_path()); + if ($this->is_album()) { + @rename(dirname($original->resize_path()), dirname($this->resize_path())); + @rename(dirname($original->thumb_path()), dirname($this->thumb_path())); + } else { + @rename($original->resize_path(), $this->resize_path()); + @rename($original->thumb_path(), $this->thumb_path()); + } + + if ($original->parent_id != $this->parent_id) { + // This will result in 2 events since we'll still fire the item_updated event below + module::event("item_moved", $this, $original->parent()); + } + } + + // Changing the name, slug or parent ripples downwards + if ($this->is_album() && + ($original->name != $this->name || + $original->slug != $this->slug || + $original->parent_id != $this->parent_id)) { + db::build() + ->update("items") + ->set("relative_url_cache", null) + ->set("relative_path_cache", null) + ->where("left_ptr", ">", $this->left_ptr) + ->where("right_ptr", "<", $this->right_ptr) + ->execute(); + } + + // Replace the data file, if requested. + // @todo: we don't handle the case where you swap in a file of a different mime type + // should we prevent that in validation? or in set_data_file() + if ($this->data_file && ($this->is_photo() || $this->is_movie())) { + copy($this->data_file, $this->file_path()); + + // Get the width, height and mime type from our data file for photos and movies. + if ($this->is_photo() || $this->is_embed()) { + list ($this->width, $this->height) = photo::get_file_metadata($this->file_path()); + } else if ($this->is_movie()) { + list ($this->width, $this->height) = movie::get_file_metadata($this->file_path()); + } + $this->thumb_dirty = 1; + $this->resize_dirty = 1; + } + + module::event("item_updated", $original, $this); + + if ($this->data_file) { + // Null out the data file variable here, otherwise this event will trigger another + // save() which will think that we're doing another file move. + $this->data_file = null; + module::event("item_updated_data_file", $this); + } + } + } else if (!empty($this->changed)) { + // Insignificant changes only. Don't fire events or do any special checking to try to keep + // this lightweight. + parent::save(); + } + + return $this; + } + + /** + * Return the Item_Model representing the cover for this album. + * @return Item_Model or null if there's no cover + */ + public function album_cover() { + if (!$this->is_album()) { + return null; + } + + if (empty($this->album_cover_item_id)) { + return null; + } + + try { + return model_cache::get("item", $this->album_cover_item_id); + } catch (Exception $e) { + // It's possible (unlikely) that the item was deleted, if so keep going. + return null; + } + } + + /** + * Find the position of the given child id in this album. The resulting value is 1-indexed, so + * the first child in the album is at position 1. + */ + public function get_position($child, $where=array()) { + if ($this->sort_order == "DESC") { + $comp = ">"; + } else { + $comp = "<"; + } + $db = db::build(); + + // If the comparison column has NULLs in it, we can't use comparators on it and will have to + // deal with it the hard way. + $count = $db->from("items") + ->where("parent_id", "=", $this->id) + ->where($this->sort_column, "IS", null) + ->merge_where($where) + ->count_records(); + + if (empty($count)) { + // There are no NULLs in the sort column, so we can just use it directly. + $sort_column = $this->sort_column; + + $position = $db->from("items") + ->where("parent_id", "=", $this->id) + ->where($sort_column, $comp, $child->$sort_column) + ->merge_where($where) + ->count_records(); + + // We stopped short of our target value in the sort (notice that we're using a < comparator + // above) because it's possible that we have duplicate values in the sort column. An + // equality check would just arbitrarily pick one of those multiple possible equivalent + // columns, which would mean that if you choose a sort order that has duplicates, it'd pick + // any one of them as the child's "position". + // + // Fix this by doing a 2nd query where we iterate over the equivalent columns and add them to + // our base value. + foreach ($db + ->select("id") + ->from("items") + ->where("parent_id", "=", $this->id) + ->where($sort_column, "=", $child->$sort_column) + ->merge_where($where) + ->order_by(array("id" => "ASC")) + ->execute() as $row) { + $position++; + if ($row->id == $child->id) { + break; + } + } + } else { + // There are NULLs in the sort column, so we can't use MySQL comparators. Fall back to + // iterating over every child row to get to the current one. This can be wildly inefficient + // for really large albums, but it should be a rare case that the user is sorting an album + // with null values in the sort column. + // + // Reproduce the children() functionality here using Database directly to avoid loading the + // whole ORM for each row. + $order_by = array($this->sort_column => $this->sort_order); + // Use id as a tie breaker + if ($this->sort_column != "id") { + $order_by["id"] = "ASC"; + } + + $position = 0; + foreach ($db->select("id") + ->from("items") + ->where("parent_id", "=", $this->id) + ->merge_where($where) + ->order_by($order_by) + ->execute() as $row) { + $position++; + if ($row->id == $child->id) { + break; + } + } + } + + return $position; + } + + /** + * Return an tag for the thumbnail. + * @param array $extra_attrs Extra attributes to add to the img tag + * @param int (optional) $max Maximum size of the thumbnail (default: null) + * @param boolean (optional) $center_vertically Center vertically (default: false) + * @return string + */ + public function thumb_img($extra_attrs=array(), $max=null, $center_vertically=false) { + list ($height, $width) = $this->scale_dimensions($max); + if ($center_vertically && $max) { + // The constant is divide by 2 to calculate the file and 10 to convert to em + $margin_top = ($max - $height) / 20; + $extra_attrs["style"] = "margin-top: {$margin_top}em"; + $extra_attrs["title"] = $this->title; + } + $attrs = array_merge($extra_attrs, + array( + "src" => $this->thumb_url(), + "alt" => $this->title, + "width" => $width, + "height" => $height) + ); + // html::image forces an absolute url which we don't want + return ""; + } + + /** + * Calculate the largest width/height that fits inside the given maximum, while preserving the + * aspect ratio. + * @param int $max Maximum size of the largest dimension + * @return array + */ + public function scale_dimensions($max) { + $width = $this->thumb_width; + $height = $this->thumb_height; + + if ($height) { + if (isset($max)) { + if ($width > $height) { + $height = (int)($max * ($height / $width)); + $width = $max; + } else { + $width = (int)($max * ($width / $height)); + $height = $max; + } + } + } else { + // Missing thumbnail, can happen on albums with no photos yet. + // @todo we should enforce a placeholder for those albums. + $width = 0; + $height = 0; + } + return array($height, $width); + } + + /** + * Return an tag for the resize. + * @param array $extra_attrs Extra attributes to add to the img tag + * @return string + */ + public function resize_img($extra_attrs) { + $attrs = array_merge($extra_attrs, + array("src" => $this->resize_url(), + "alt" => $this->title, + "width" => $this->resize_width, + "height" => $this->resize_height) + ); + // html::image forces an absolute url which we don't want + return ""; + } + + /** + * Return a flowplayer + \ No newline at end of file From 30f8f02a56965863d1debd757471720f18ceb4db Mon Sep 17 00:00:00 2001 From: John Bowles Date: Thu, 26 Aug 2010 22:12:18 -0700 Subject: [PATCH 12/16] Fixed controller. --- .../controllers/embedded_videos.php | 197 +++--------------- 1 file changed, 31 insertions(+), 166 deletions(-) diff --git a/modules/embed_videos/controllers/embedded_videos.php b/modules/embed_videos/controllers/embedded_videos.php index 5b3a25b1..fdb7b5e1 100644 --- a/modules/embed_videos/controllers/embedded_videos.php +++ b/modules/embed_videos/controllers/embedded_videos.php @@ -18,144 +18,6 @@ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ class Embedded_videos_Controller extends Controller { -<<<<<<< HEAD - public function show($movie) { - if (!is_object($movie)) { - // show() must be public because we route to it in url::parse_url(), so make - // sure that we're actually receiving an object - throw new Kohana_404_Exception(); - } - access::required("view", $movie); - $where = array(array("type", "!=", "album")); - $position = $movie->parent()->get_position($movie, $where); - if ($position > 1) { - list($previous_item, $ignore, $next_item) = $movie->parent()->children(3, $position - 2, $where); - } else { - $previous_item = null; - list($next_item) = $movie->parent()->viewable()->children(1, $position, $where); - } - $embedded_video = ORM::factory("embedded_video")->where("item_id", "=", $movie->id)->find(); - //$db = Database::instance(); - //$result = $db->from('embedded_videos')->select('embed_code')->where('item_id',$movie->id)->get(); - $template = new Theme_View("page.html", "item", "embedded_video"); - $template->set_global("item", $movie); - $template->set_global("embedded_video", $embedded_video->embed_code); - $template->set_global("children", array()); - $template->set_global("children_count", 0); - $template->set_global("parents", $movie->parents()); - $template->set_global("next_item", $next_item); - $template->set_global("previous_item", $previous_item); - $template->set_global("sibling_count", $movie->parent()->viewable()->children_count($where)); - $template->set_global("position", $position); - $template->content = new View("embedded_video.html"); - db::query("UPDATE {items} SET `view_count` = `view_count` + 1 WHERE `id` = $movie->id")->execute(); - //$movie->view_count++; - //$movie->save(); - print $template; - } - public function update($movie_id) { - access::verify_csrf(); - $movie = ORM::factory("item", $movie_id); - access::required("view", $movie); - access::required("edit", $movie); - $form = embed_videos::get_edit_form($movie); - try { - $valid = $form->validate(); - $movie->title = $form->edit_item->title->value; - $movie->description = $form->edit_item->description->value; - $movie->slug = $form->edit_item->slug->value; - //$movie->name = $form->edit_item->inputs["name"]->value; - $movie->validate(); - } - catch(ORM_Validation_Exception $e) { - // Translate ORM validation errors into form error messages - foreach($e->validation->errors() as $key => $error) { - $form->edit_item->inputs[$key]->add_error($error, 1); - } - $valid = false; - } - if ($valid) { - $movie->save(); - module::event("item_edit_form_completed", $movie, $form); - log::success("content", "Updated embed", "url() }\">view"); - message::success(t("Saved embed %movie_title", array("movie_title" => $movie->title))); - if ($form->from_id->value == $movie->id) { - // Use the new url; it might have changed. - print json_encode(array("result" => "success", "location" => $movie->url())); - } else { - // Stay on the same page - print json_encode(array("result" => "success")); - } - } else { - print json_encode(array("result" => "error", "form" => (string)$form)); - } - } - - public function create($id) { - $album = ORM::factory("item", $id); - access::required("view", $album); - access::required("add", $album); - access::verify_csrf(); - $form = embed_videos::get_add_form($album); - $temp_filename = ""; - //$form->add_rules('youtubeid', array('required', 'length[11]')); - //$form->add_callback('youtubeid', 'valid_youtubeid'); - batch::start(); - try { - $valid = $form->validate(); - if ($form->add_embedded_video->inputs['video_url']->value != "") { - $youtubeUrlPattern="youtube"; - $youtubeApiUrl="http://gdata.youtube.com/feeds/api/"; - $youtubeThumbnailUrl="http://img.youtube.com/vi/"; - $valid_url=false; - $embedded_video = ORM::factory("embedded_video"); - $item = ORM::factory("item"); - $item->type = "photo"; - $url = $form->add_embedded_video->inputs['video_url']->value; - if(preg_match("/$youtubeUrlPattern/",$url)) { - if(preg_match("/watch\?v=(.*?)(&\S+=\S+)/",$url,$matches)) { - $video_id = $matches[1]; - $embedded_video->embed_code = ''; - $embedded_video->source = "YouTube"; - $content = file_get_contents("http://img.youtube.com/vi/" . $video_id . "/0.jpg"); - $itemname = "youtube_" . $video_id . ".jpg"; - $temp_filename = VARPATH . "tmp/$itemname"; - if ($content) { - $valid_url = true; - } - } - } - //$item->validate(); - //$content = file_get_contents("http://img.youtube.com/vi/" . $form->add_embedded_video->inputs['name']->value . "/0.jpg"); - if ($valid_url) { - $file = fopen($temp_filename, "wb"); - fwrite($file, $content); - fclose($file); - gallery_graphics::composite($temp_filename, $temp_filename, array("file" => "modules/embed_videos/images/embed_video_icon.png", "position" => "center", "transparency" => 95)); - $item->name = basename($itemname); - $item->title = $form->add_embedded_video->title->value; - $item->parent_id = $album->id; - $item->description = $form->add_embedded_video->description->value; - $item->slug = $form->add_embedded_video->slug->value; - $item->set_data_file($temp_filename); - $path_info = @pathinfo($temp_filename); - $item->save(); - //module::event("item_created", $item); - db::query("UPDATE {items} SET `type` = 'embedded_video' WHERE `id` = $item->id")->execute(); - $embedded_video->item_id = $item->id; - $embedded_video->validate(); - $embedded_video->save(); - log::success("content", t("Added a embedded video"), html::anchor("embeds/$item->id", t("view video"))); - module::event("add_event_form_completed", $item, $form); - - } else { - $form->add_embedded_video->inputs['video_url']->add_error('invalid_id', 1); - $valid = false; - } - } else { - $form->add_embedded_video->inputs['video_url']->add_error('invalid_id', 1); - $valid = false; -======= public function create($id) { $album = ORM::factory("item", $id); access::required("view", $album); @@ -187,26 +49,9 @@ class Embedded_videos_Controller extends Controller { $temp_filename = VARPATH . "tmp/$itemname"; if ($content) { $valid_url = true; ->>>>>>> js-solution } + } } -<<<<<<< HEAD - catch(Exception $e) { - // Lame error handling for now. Just record the exception and move on - Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); - // Ugh. I hate to use instanceof, But this beats catching the exception separately since - // we mostly want to treat it the same way as all other exceptions - if ($e instanceof ORM_Validation_Exception) { - Kohana_Log::add("error", "Validation errors: " . print_r($e->validation->errors(), 1)); - foreach($e->validation->errors() as $key => $error) { - $form->add_embed->inputs[$key]->add_error($error, 1); - } - $valid = false; - } - if (file_exists($temp_filename)) { - unlink($temp_filename); - } -======= //$item->validate(); //$content = file_get_contents("http://img.youtube.com/vi/" . $form->add_embedded_video->inputs['name']->value . "/0.jpg"); if ($valid_url) { @@ -231,18 +76,38 @@ class Embedded_videos_Controller extends Controller { } else { $form->add_embedded_video->inputs['video_url']->add_error('invalid_id', 1); $valid = false; ->>>>>>> js-solution } - if (file_exists($temp_filename)) { - unlink($temp_filename); + } else { + $form->add_embedded_video->inputs['video_url']->add_error('invalid_id', 1); + $valid = false; + } + } + catch(Exception $e) { + // Lame error handling for now. Just record the exception and move on + Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); + // Ugh. I hate to use instanceof, But this beats catching the exception separately since + // we mostly want to treat it the same way as all other exceptions + if ($e instanceof ORM_Validation_Exception) { + Kohana_Log::add("error", "Validation errors: " . print_r($e->validation->errors(), 1)); + foreach($e->validation->errors() as $key => $error) { + $form->add_embed->inputs[$key]->add_error($error, 1); } - batch::stop(); - if ($valid) { - //print json_encode(array("result" => "success")); - json::reply(array("result" => "success", "location" => $item->url())); - } else { - //json::reply(array("result" => "error", "form" => (string)$form)); - print $form; + $valid = false; + } + if (file_exists($temp_filename)) { + unlink($temp_filename); + } + } + if (file_exists($temp_filename)) { + unlink($temp_filename); + } + batch::stop(); + if ($valid) { + //print json_encode(array("result" => "success")); + json::reply(array("result" => "success", "location" => $item->url())); + } else { + //json::reply(array("result" => "error", "form" => (string)$form)); + print $form; } } public function form_add($album_id) { From 95b357636c7f4b6a7bd5aeedb3d6dc416d7a4c10 Mon Sep 17 00:00:00 2001 From: John Bowles Date: Thu, 26 Aug 2010 22:44:54 -0700 Subject: [PATCH 13/16] Fetch title and description from Youtube API if none is provided. --- .../embed_videos/controllers/embedded_videos.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/embed_videos/controllers/embedded_videos.php b/modules/embed_videos/controllers/embedded_videos.php index fdb7b5e1..83077e59 100644 --- a/modules/embed_videos/controllers/embedded_videos.php +++ b/modules/embed_videos/controllers/embedded_videos.php @@ -31,6 +31,8 @@ class Embedded_videos_Controller extends Controller { try { $valid = $form->validate(); if ($form->add_embedded_video->inputs['video_url']->value != "") { + $title = $form->add_embedded_video->inputs['title']->value; + $description = $form->add_embedded_video->inputs['description']->value; $youtubeUrlPattern="youtube"; $youtubeApiUrl="http://gdata.youtube.com/feeds/api/"; $youtubeThumbnailUrl="http://img.youtube.com/vi/"; @@ -49,6 +51,13 @@ class Embedded_videos_Controller extends Controller { $temp_filename = VARPATH . "tmp/$itemname"; if ($content) { $valid_url = true; + $sxml = simplexml_load_file("http://gdata.youtube.com/feeds/api/videos/$video_id"); + if ($title == '') { + $title = (string)$sxml->title; + } + if ($description == '') { + $description = (string)$sxml->content; + } } } } @@ -61,10 +70,10 @@ class Embedded_videos_Controller extends Controller { gallery_graphics::composite($temp_filename, $temp_filename, array("file" => "modules/embed_videos/images/embed_video_icon.png", "position" => "center", "transparency" => 95)); $item->set_data_file($temp_filename); $item->name = basename($itemname); - $item->title = $form->add_embedded_video->title->value; + $item->title = $title; $item->parent_id = $album->id; - $item->description = $form->add_embedded_video->description->value; - $item->slug = $form->add_embedded_video->slug->value; + $item->description = $description; + $item->slug = $form->add_embedded_video->inputs['slug']->value; $path_info = @pathinfo($temp_filename); $item->save(); //db::query("UPDATE {items} SET `type` = 'embedded_video' WHERE `id` = $item->id")->execute(); From d0447f020a056f5c4ee205152e0d79529ac36820 Mon Sep 17 00:00:00 2001 From: John Bowles Date: Thu, 26 Aug 2010 22:57:20 -0700 Subject: [PATCH 14/16] Clean up a few things --- .../embed_videos/controllers/embedded_videos.php | 13 +++++++------ modules/embed_videos/helpers/embed_videos.php | 5 ++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/embed_videos/controllers/embedded_videos.php b/modules/embed_videos/controllers/embedded_videos.php index 83077e59..256ad7c2 100644 --- a/modules/embed_videos/controllers/embedded_videos.php +++ b/modules/embed_videos/controllers/embedded_videos.php @@ -52,11 +52,13 @@ class Embedded_videos_Controller extends Controller { if ($content) { $valid_url = true; $sxml = simplexml_load_file("http://gdata.youtube.com/feeds/api/videos/$video_id"); - if ($title == '') { - $title = (string)$sxml->title; - } - if ($description == '') { - $description = (string)$sxml->content; + if ($sxml) { + if ($title == '') { + $title = (string)$sxml->title; + } + if ($description == '') { + $description = (string)$sxml->content; + } } } } @@ -76,7 +78,6 @@ class Embedded_videos_Controller extends Controller { $item->slug = $form->add_embedded_video->inputs['slug']->value; $path_info = @pathinfo($temp_filename); $item->save(); - //db::query("UPDATE {items} SET `type` = 'embedded_video' WHERE `id` = $item->id")->execute(); $embedded_video->item_id = $item->id; $embedded_video->validate(); $embedded_video->save(); diff --git a/modules/embed_videos/helpers/embed_videos.php b/modules/embed_videos/helpers/embed_videos.php index 49182407..75b47ec2 100644 --- a/modules/embed_videos/helpers/embed_videos.php +++ b/modules/embed_videos/helpers/embed_videos.php @@ -35,9 +35,8 @@ class embed_videos_Core { $group->input("video_url")->label(t("Video URL")) ->error_messages( "conflict", t("There is already a movie with this ID")) - ->error_messages("required", t("You must provide a Youtube ID")) - ->error_messages("length", t("Invalid Youtube ID")) - ->error_messages("invalid_id", t("Invalid Youtube ID")); + ->error_messages("required", t("You must provide a URL")) + ->error_messages("invalid_id", t("Invalid URL")); $group->textarea("description")->label(t("Description")); $group->input("slug")->label(t("Internet Address")) ->error_messages( From 78a4fbacea52a3a1c0395375cc113426e12c429e Mon Sep 17 00:00:00 2001 From: John Bowles Date: Thu, 26 Aug 2010 23:35:22 -0700 Subject: [PATCH 15/16] Embed Videos: Oops. Left out some of the regexes for youtube. --- .../controllers/embedded_videos.php | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/modules/embed_videos/controllers/embedded_videos.php b/modules/embed_videos/controllers/embedded_videos.php index 256ad7c2..205377fe 100644 --- a/modules/embed_videos/controllers/embedded_videos.php +++ b/modules/embed_videos/controllers/embedded_videos.php @@ -25,24 +25,33 @@ class Embedded_videos_Controller extends Controller { access::verify_csrf(); $form = embed_videos::get_add_form($album); $temp_filename = ""; - //$form->add_rules('youtubeid', array('required', 'length[11]')); - //$form->add_callback('youtubeid', 'valid_youtubeid'); + + // Yes, this is a mess. + $youtubeUrlPattern="youtube"; + $youtubeThumbnailUrl="http://img.youtube.com/vi/"; + // End mess + batch::start(); try { $valid = $form->validate(); if ($form->add_embedded_video->inputs['video_url']->value != "") { $title = $form->add_embedded_video->inputs['title']->value; $description = $form->add_embedded_video->inputs['description']->value; - $youtubeUrlPattern="youtube"; - $youtubeApiUrl="http://gdata.youtube.com/feeds/api/"; - $youtubeThumbnailUrl="http://img.youtube.com/vi/"; $valid_url=false; $embedded_video = ORM::factory("embedded_video"); $item = ORM::factory("item"); $item->type = "photo"; $url = $form->add_embedded_video->inputs['video_url']->value; if(preg_match("/$youtubeUrlPattern/",$url)) { - if(preg_match("/watch\?v=(.*?)(&\S+=\S+)/",$url,$matches)) { + $video_id = 0; + if (preg_match("/watch\?v=(.*?)(&\S+=\S+)/",$url,$matches)) { + $video_id = $matches[1]; + } else if (preg_match("/watch\?v=(.*)/",$url,$matches)) { + $video_id = $matches[1]; + } else if (preg_match("/v\/(.*)/",$url,$matches)) { + $video_id = $matches[1]; + } + if ($video_id) { $video_id = $matches[1]; $embedded_video->embed_code = ''; $embedded_video->source = "YouTube"; From 329799db33b04d09b9ce3bef4f26ffab6e2fcebc Mon Sep 17 00:00:00 2001 From: John Bowles Date: Fri, 27 Aug 2010 17:00:18 -0700 Subject: [PATCH 16/16] Embed_videos: Moved JS to header, added DIV. Removed unused view. --- .../helpers/embed_videos_theme.php | 2 +- .../views/embed_video_js.html.php | 6 +++--- .../views/embedded_video.html.php | 19 ------------------- 3 files changed, 4 insertions(+), 23 deletions(-) delete mode 100644 modules/embed_videos/views/embedded_video.html.php diff --git a/modules/embed_videos/helpers/embed_videos_theme.php b/modules/embed_videos/helpers/embed_videos_theme.php index 5d51204f..b7464478 100644 --- a/modules/embed_videos/helpers/embed_videos_theme.php +++ b/modules/embed_videos/helpers/embed_videos_theme.php @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ class embed_videos_theme_Core { - static function photo_bottom($theme) { + static function head($theme) { $item = $theme->item(); if ($item && $item->is_photo()) { $embedded_video = ORM::factory("embedded_video") diff --git a/modules/embed_videos/views/embed_video_js.html.php b/modules/embed_videos/views/embed_video_js.html.php index 7f3201c8..ea2aa721 100644 --- a/modules/embed_videos/views/embed_video_js.html.php +++ b/modules/embed_videos/views/embed_video_js.html.php @@ -20,8 +20,8 @@ ?> \ No newline at end of file diff --git a/modules/embed_videos/views/embedded_video.html.php b/modules/embed_videos/views/embedded_video.html.php deleted file mode 100644 index efdd7f1c..00000000 --- a/modules/embed_videos/views/embedded_video.html.php +++ /dev/null @@ -1,19 +0,0 @@ - -
- photo_top() ?> - - paginator() ?> - -
- resize_top($item) ?> - - resize_bottom($item) ?> -
- -
-

title) ?>

-
description)) ?>
-
- - photo_bottom() ?> -