protected function onDetail() { if (empty($this->post['directory']) || empty($this->post['file'])) { return; } $file = realpath($this->path . '/' . $this->post['directory'] . '/' . $this->post['file']); if (!$this->checkFile($file)) { return; } require_once $this->options['id3Path']; // Xinha: The URL is weird in the standard distribution of filemanager, it seems to expect // that the files directory (where you are selecting/uploading) is always within the filemanager // directory itself somewhere. // // Also the 'baseURL' seems to be wanted as the parent of the 'basedir' ("directory" option) // Xinha is supplying both the same (eg url = /foo/test and dir = /home/bar/public_html/foo/test ) // so we will rip off the first part of directory, below. $url = $this->options['baseURL'] . '/' . preg_replace('/^[^\\/]*\\//', '', $this->post['directory'] . '/' . $this->post['file']); $mime = $this->getMimeType($file); $content = null; // Xinha: We want to get some more information about what has been selected in a way // we can use it. Effectively what gets put in here will be passed into the // 'onDetails' event handler of your FileManager object (if any). $extra_return_detail = array('url' => $url, 'mime' => $mime); if (FileManagerUtility::startsWith($mime, 'image/')) { $size = getimagesize($file); $content = '<img src="' . $url . '" class="preview" alt="" /> <h2>${more}</h2> <dl> <dt>${width}</dt><dd>' . $size[0] . 'px</dd> <dt>${height}</dt><dd>' . $size[1] . 'px</dd> </dl>'; // Xinha: Return some information about the image which can be access // from the onDetails event handler in FileManager $extra_return_detail['width'] = $size[0]; $extra_return_detail['height'] = $size[1]; } elseif (FileManagerUtility::startsWith($mime, 'text/') || $mime == 'application/x-javascript') { $filecontent = file_get_contents($file, null, null, 0, 300); if (!FileManagerUtility::isBinary($filecontent)) { $content = '<div class="textpreview">' . nl2br(str_replace(array('$', "\t"), array('$', ' '), htmlentities($filecontent))) . '</div>'; } } elseif ($mime == 'application/zip') { $out = array(array(), array()); $getid3 = new getID3(); $getid3->Analyze($file); foreach ($getid3->info['zip']['files'] as $name => $size) { $icon = is_array($size) ? 'dir' : $this->getIcon($name); $out[$icon == 'dir' ? 0 : 1][$name] = '<li><a><img src="' . $this->options['assetBasePath'] . '/Icons/' . $icon . '.png" alt="" /> ' . $name . '</a></li>'; } natcasesort($out[0]); natcasesort($out[1]); $content = '<ul>' . implode(array_merge($out[0], $out[1])) . '</ul>'; } elseif (FileManagerUtility::startsWith($mime, 'audio/')) { $getid3 = new getID3(); $getid3->Analyze($file); $content = '<div class="object"> <object type="application/x-shockwave-flash" data="' . $this->options['assetBasePath'] . '/dewplayer.swf?mp3=' . rawurlencode($url) . '&volume=30" width="200" height="20"> <param name="movie" value="' . $this->options['assetBasePath'] . '/dewplayer.swf?mp3=' . rawurlencode($url) . '&volume=30" /> </object> </div> <h2>${more}</h2> <dl> <dt>${title}</dt><dd>' . $getid3->info['comments']['title'][0] . '</dd> <dt>${artist}</dt><dd>' . $getid3->info['comments']['artist'][0] . '</dd> <dt>${album}</dt><dd>' . $getid3->info['comments']['album'][0] . '</dd> <dt>${length}</dt><dd>' . $getid3->info['playtime_string'] . '</dd> <dt>${bitrate}</dt><dd>' . round($getid3->info['bitrate'] / 1000) . 'kbps</dd> </dl>'; } echo json_encode(array_merge(array('content' => $content ? $content : '<div class="margin"> ${nopreview}<br/><button value="' . $url . '">${download}</button> </div>'), $extra_return_detail)); }
/** * Produce a HTML snippet detailing the given file in the JSON 'content' element; place additional info * in the JSON elements 'thumbnail', 'thumb48', 'thumb250', 'width', 'height', ... * * Return an augmented JSON array. * * Throw an exception on error. */ public function extractDetailInfo($json_in, $legal_url, &$meta, $mime_filter, $mime_filters, $mode) { $auto_thumb_gen_mode = !in_array('direct', $mode, true); $metaHTML_mode = in_array('metaHTML', $mode, true); $metaJSON_mode = in_array('metaJSON', $mode, true); $url = $this->legal2abs_url_path($legal_url); $filename = basename($url); log_message('error', '$url : ' . $url); // must transform here so alias/etc. expansions inside url_path2file_path() get a chance: $file = $this->url_path2file_path($url); $isdir = !is_file($file); $bad_ext = false; $mime = null; // only perform the (costly) getID3 scan when it hasn't been done before, i.e. can we re-use previously obtained data or not? if (!is_object($meta)) { $meta = $this->getFileInfo($file, $legal_url); } if (!$isdir) { $mime = $meta->getMimeType(); $mime2 = $this->getMimeFromExt($file); $meta->store('mime_type from file extension', $mime2); $bad_ext = $mime2 != $mime; if ($bad_ext) { $iconspec = 'is.' + $this->getExtFromMime($mime); } else { $iconspec = $filename; } if (!$this->IsAllowedMimeType($mime, $mime_filters)) { throw new FileManagerException('extension'); } } else { if (is_dir($file)) { $mime = $meta->getMimeType(); // $mime = 'text/directory'; $iconspec = 'is.directory'; } else { // simply do NOT list anything that we cannot cope with. // That includes clearly inaccessible files (and paths) with non-ASCII characters: // PHP5 and below are a real mess when it comes to handling Unicode filesystems // (see the php.net site too: readdir / glob / etc. user comments and the official // notice that PHP will support filesystem UTF-8/Unicode only when PHP6 is released. // // Big, fat bummer! throw new FileManagerException('nofile'); } } // as all the work below is quite costly, we check whether the already loaded cache entry got our number: // several chunks of work below may have been cached and when they have been, use the cached data. // it's an internal error when this entry do not exist in the cache store by now! $fi = $meta->fetch('analysis'); //assert(!empty($fi)); $icon48 = $this->getIcon($iconspec, false); $icon = $this->getIcon($iconspec, true); $thumb250 = $meta->fetch('thumb250_direct'); $thumb48 = $meta->fetch('thumb48_direct'); $thumb250_e = false; $thumb48_e = false; $tstamp_str = date($this->options['dateFormat'], @filemtime($file)); $fsize = @filesize($file); $json = array_merge(array('content' => self::compressHTML('<div class="margin"> ${nopreview} </div>')), array('path' => $legal_url, 'name' => $filename, 'date' => $tstamp_str, 'mime' => $mime, 'size' => $fsize)); if (empty($fsize)) { $fsize_str = '-'; } else { // convert to T/G/M/K-bytes: $fsize_str = $this->format_bytes($fsize); } $content = '<dl> <dt>${modified}</dt> <dd class="filemanager-modified">' . $tstamp_str . '</dd> <dt>${type}</dt> <dd class="filemanager-type">' . $mime . '</dd> <dt>${size}</dt> <dd class="filemanager-size">' . $fsize_str . '</dd>'; $content_dl_term = false; $preview_HTML = null; $postdiag_err_HTML = ''; $postdiag_dump_HTML = ''; $thumbnails_done_or_deferred = false; // TRUE: mark our thumbnail work as 'done'; any NULL thumbnails represent deferred generation entries! $check_for_embedded_img = false; $mime_els = explode('/', $mime); for (;;) { switch ($mime_els[0]) { case 'image': /* * thumbnail_gen_mode === 'auto': * * offload the thumbnailing process to another event ('event=thumbnail') to be fired by the client * when it's time to render the thumbnail: * WE simply assume the thumbnail will be there, and when it doesn't, that's * for the event=thumbnail handler to worry about (creating the thumbnail on demand or serving * a generic icon image instead). Meanwhile, we are able to speed up the response process here quite * a bit (rendering thumbnails from very large images can take a lot of time!) * * To further improve matters, we first generate the 250px thumbnail and then generate the 48px * thumbnail from that one (if it doesn't already exist). That saves us one more time processing * the (possibly huge) original image; downscaling the 250px file is quite fast, relatively speaking. * * That bit of code ASSUMES that the thumbnail will be generated from the file argument, while * the url argument is used to determine the thumbnail name/path. */ $emsg = null; try { if (empty($thumb250)) { $thumb250 = $this->getThumb($meta, $file, $this->options['thumbBigSize'], $this->options['thumbBigSize'], $auto_thumb_gen_mode); } if (!empty($thumb250)) { $thumb250_e = FileManagerUtility::rawurlencode_path($thumb250); } if (empty($thumb48)) { $thumb48 = $this->getThumb($meta, !empty($thumb250) ? $this->url_path2file_path($thumb250) : $file, $this->options['thumbSmallSize'], $this->options['thumbSmallSize'], $auto_thumb_gen_mode); } if (!empty($thumb48)) { $thumb48_e = FileManagerUtility::rawurlencode_path($thumb48); } if (empty($thumb48) || empty($thumb250)) { /* * do NOT generate the thumbnail itself yet (it takes too much time!) but do check whether it CAN be generated * at all: THAT is a (relatively speaking) fast operation! */ $imginfo = Image::checkFileForProcessing($file); } $thumbnails_done_or_deferred = true; } catch (Exception $e) { $emsg = $e->getMessage(); $icon48 = $this->getIconForError($emsg, $legal_url, false); $icon = $this->getIconForError($emsg, $legal_url, true); // even cache the fail: that means next time around we don't suffer the failure but immediately serve the error icon instead. } $width = round($this->getID3infoItem($fi, 0, 'video', 'resolution_x')); $height = round($this->getID3infoItem($fi, 0, 'video', 'resolution_y')); $json['width'] = $width; $json['height'] = $height; $content .= ' <dt>${width}</dt><dd>' . $width . 'px</dd> <dt>${height}</dt><dd>' . $height . 'px</dd> </dl>'; $content_dl_term = true; $sw_make = $this->mkSafeUTF8($this->getID3infoItem($fi, null, 'jpg', 'exif', 'IFD0', 'Software')); $time_make = $this->mkSafeUTF8($this->getID3infoItem($fi, null, 'jpg', 'exif', 'IFD0', 'DateTime')); if (!empty($sw_make) || !empty($time_make)) { $content .= '<p>Made with ' . (empty($sw_make) ? '???' : $sw_make) . ' @ ' . (empty($time_make) ? '???' : $time_make) . '</p>'; } // are we delaying the thumbnail generation? When yes, then we need to infer the thumbnail dimensions *anyway*! if (empty($thumb48) && $thumbnails_done_or_deferred) { $dims = $this->predictThumbDimensions($width, $height, $this->options['thumbSmallSize'], $this->options['thumbSmallSize']); $json['thumb48_width'] = $dims['width']; $json['thumb48_height'] = $dims['height']; } if (empty($thumb250)) { if ($thumbnails_done_or_deferred) { // to show the loader.gif in the preview <img> tag, we MUST set a width+height there, so we guestimate the thumbnail250 size as accurately as possible // // derive size from original: $dims = $this->predictThumbDimensions($width, $height, $this->options['thumbBigSize'], $this->options['thumbBigSize']); $preview_HTML = '<a href="' . FileManagerUtility::rawurlencode_path($url) . '" data-milkbox="single" title="' . htmlentities($filename, ENT_QUOTES, 'UTF-8') . '"> <img src="' . $this->options['URLpath4assets'] . 'Images/transparent.gif" class="preview" alt="preview" style="width: ' . $dims['width'] . 'px; height: ' . $dims['height'] . 'px;" /> </a>'; $json['thumb250_width'] = $dims['width']; $json['thumb250_height'] = $dims['height']; } else { // when we get here, a failure occurred before, so we only will have the icons. So we use those: $preview_HTML = '<a href="' . FileManagerUtility::rawurlencode_path($url) . '" data-milkbox="single" title="' . htmlentities($filename, ENT_QUOTES, 'UTF-8') . '"> <img src="' . FileManagerUtility::rawurlencode_path($icon48) . '" class="preview" alt="preview" /> </a>'; } } // else: defer the $preview_HTML production until we're at the end of this and have fetched the actual thumbnail dimensions if (!empty($emsg)) { // use the abilities of modify_json4exception() to munge/format the exception message: $jsa = array('error' => ''); $this->modify_json4exception($jsa, $emsg, 'path = ' . $url); $postdiag_err_HTML .= "\n" . '<p class="err_info">' . $jsa['error'] . '</p>'; if (strpos($emsg, 'img_will_not_fit') !== false) { $earr = explode(':', $emsg, 2); $postdiag_err_HTML .= "\n" . '<p class="tech_info">Estimated minimum memory requirements to create thumbnails for this image: ' . $earr[1] . '</p>'; } } break; case 'text': switch ($mime_els[1]) { case 'directory': $content = '<dl>'; $preview_HTML = ''; break; default: // text preview: $filecontent = @file_get_contents($file, false, null, 0); if ($filecontent === false) { throw new FileManagerException('nofile'); } if (!FileManagerUtility::isBinary($filecontent)) { $preview_HTML = '<pre>' . str_replace(array('$', "\t"), array('$', ' '), htmlentities($filecontent, ENT_NOQUOTES, 'UTF-8')) . '</pre>'; } else { // else: fall back to 'no preview available' (if getID3 didn't deliver instead...) $mime_els[0] = 'unknown'; // remap! continue 3; } break; } break; case 'application': switch ($mime_els[1]) { case 'x-javascript': $mime_els[0] = 'text'; // remap! continue 3; case 'zip': $out = array(array(), array()); $info = $this->getID3infoItem($fi, null, 'zip', 'files'); if (is_array($info)) { foreach ($info as $name => $size) { $name = $this->mkSafeUTF8($name); $isdir = is_array($size); $out[$isdir ? 0 : 1][$name] = '<li><a><img src="' . FileManagerUtility::rawurlencode_path($this->getIcon($name, true)) . '" alt="" /> ' . $name . '</a></li>'; } natcasesort($out[0]); natcasesort($out[1]); $preview_HTML = '<ul>' . implode(array_merge($out[0], $out[1])) . '</ul>'; } break; case 'x-shockwave-flash': $check_for_embedded_img = true; $info = $this->getID3infoItem($fi, null, 'swf', 'header'); if (is_array($info)) { $width = round($this->getID3infoItem($fi, 0, 'swf', 'header', 'frame_width') / 10); $height = round($this->getID3infoItem($fi, 0, 'swf', 'header', 'frame_height') / 10); $json['width'] = $width; $json['height'] = $height; $content .= ' <dt>${width}</dt><dd>' . $width . 'px</dd> <dt>${height}</dt><dd>' . $height . 'px</dd> <dt>${length}</dt><dd>' . round($this->getID3infoItem($fi, 0, 'swf', 'header', 'length') / $this->getID3infoItem($fi, 25, 'swf', 'header', 'frame_count')) . 's</dd> </dl>'; $content_dl_term = true; } break; default: // else: fall back to 'no preview available' (if getID3 didn't deliver instead...) $mime_els[0] = 'unknown'; // remap! continue 3; } break; case 'audio': $check_for_embedded_img = true; $title = $this->mkSafeUTF8($this->getID3infoItem($fi, $this->getID3infoItem($fi, '???', 'tags', 'id3v1', 'title', 0), 'tags', 'id3v2', 'title', 0)); $artist = $this->mkSafeUTF8($this->getID3infoItem($fi, $this->getID3infoItem($fi, '???', 'tags', 'id3v1', 'artist', 0), 'tags', 'id3v2', 'artist', 0)); $album = $this->mkSafeUTF8($this->getID3infoItem($fi, $this->getID3infoItem($fi, '???', 'tags', 'id3v1', 'album', 0), 'tags', 'id3v2', 'album', 0)); $content .= ' <dt>${title}</dt><dd>' . $title . '</dd> <dt>${artist}</dt><dd>' . $artist . '</dd> <dt>${album}</dt><dd>' . $album . '</dd> <dt>${length}</dt><dd>' . $this->mkSafeUTF8($this->getID3infoItem($fi, '???', 'playtime_string')) . '</dd> <dt>${bitrate}</dt><dd>' . round($this->getID3infoItem($fi, 0, 'bitrate') / 1000) . 'kbps</dd> </dl>'; $content_dl_term = true; break; case 'video': $check_for_embedded_img = true; $a_fmt = $this->mkSafeUTF8($this->getID3infoItem($fi, '???', 'audio', 'dataformat')); $a_samplerate = round($this->getID3infoItem($fi, 0, 'audio', 'sample_rate') / 1000, 1); $a_bitrate = round($this->getID3infoItem($fi, 0, 'audio', 'bitrate') / 1000, 1); $a_bitrate_mode = $this->mkSafeUTF8($this->getID3infoItem($fi, '???', 'audio', 'bitrate_mode')); $a_channels = round($this->getID3infoItem($fi, 0, 'audio', 'channels')); $a_codec = $this->mkSafeUTF8($this->getID3infoItem($fi, '', 'audio', 'codec')); $a_streams = $this->getID3infoItem($fi, '???', 'audio', 'streams'); $a_streamcount = is_array($a_streams) ? count($a_streams) : 0; $v_fmt = $this->mkSafeUTF8($this->getID3infoItem($fi, '???', 'video', 'dataformat')); $v_bitrate = round($this->getID3infoItem($fi, 0, 'video', 'bitrate') / 1000, 1); $v_bitrate_mode = $this->mkSafeUTF8($this->getID3infoItem($fi, '???', 'video', 'bitrate_mode')); $v_framerate = round($this->getID3infoItem($fi, 0, 'video', 'frame_rate'), 5); $v_width = round($this->getID3infoItem($fi, '???', 'video', 'resolution_x')); $v_height = round($this->getID3infoItem($fi, '???', 'video', 'resolution_y')); $v_par = round($this->getID3infoItem($fi, 1.0, 'video', 'pixel_aspect_ratio'), 7); $v_codec = $this->mkSafeUTF8($this->getID3infoItem($fi, '', 'video', 'codec')); $g_bitrate = round($this->getID3infoItem($fi, 0, 'bitrate') / 1000, 1); $g_playtime_str = $this->mkSafeUTF8($this->getID3infoItem($fi, '???', 'playtime_string')); $content .= ' <dt>Audio</dt><dd>'; if ($a_fmt === '???' && $a_samplerate == 0 && $a_bitrate == 0 && $a_bitrate_mode === '???' && $a_channels == 0 && empty($a_codec) && $a_streams === '???' && $a_streamcount == 0) { $content .= '-'; } else { $content .= $a_fmt . (!empty($a_codec) ? ' (' . $a_codec . ')' : '') . (!empty($a_channels) ? $a_channels === 1 ? ' (mono)' : ($a_channels === 2 ? ' (stereo)' : ' (' . $a_channels . ' channels)') : '') . ': ' . $a_samplerate . ' kHz @ ' . $a_bitrate . ' kbps (' . strtoupper($a_bitrate_mode) . ')' . ($a_streamcount > 1 ? ' (' . $a_streamcount . ' streams)' : ''); } $content .= '</dd> <dt>Video</dt><dd>' . $v_fmt . (!empty($v_codec) ? ' (' . $v_codec . ')' : '') . ': ' . $v_framerate . ' fps @ ' . $v_bitrate . ' kbps (' . strtoupper($v_bitrate_mode) . ')' . ($v_par != 1.0 ? ', PAR: ' . $v_par : '') . '</dd> <dt>${width}</dt><dd>' . $v_width . 'px</dd> <dt>${height}</dt><dd>' . $v_height . 'px</dd> <dt>${length}</dt><dd>' . $g_playtime_str . '</dd> <dt>${bitrate}</dt><dd>' . $g_bitrate . 'kbps</dd> </dl>'; $content_dl_term = true; break; default: // fall back to 'no preview available' (if getID3 didn't deliver instead...) break; } break; } if (!$content_dl_term) { $content .= '</dl>'; } if (!empty($fi['error'])) { $postdiag_err_HTML .= '<p class="err_info">' . $this->mkSafeUTF8(implode(', ', $fi['error'])) . '</p>'; } $emsgX = null; if (empty($thumb250)) { if (!$thumbnails_done_or_deferred) { // check if we have stored a thumbnail for this file anyhow: $thumb250 = $this->getThumb($meta, $file, $this->options['thumbBigSize'], $this->options['thumbBigSize'], true); if (empty($thumb250)) { if (!empty($fi) && $check_for_embedded_img) { /* * No thumbnail available yet, so find me one! * * When we find a thumbnail during the 'cleanup' scan, we don't know up front if it's suitable to be used directly, * so we treat it as an alternative 'original' file and generate a 250px/48px thumbnail set from it. * * When the embedded thumbnail is small enough, the thumbnail creation process will be simply a copy action, so relatively * low cost. */ $embed = $this->extract_ID3info_embedded_image($fi); //@file_put_contents(dirname(__FILE__) . '/extract_embedded_img.log', print_r(array('html' => $preview_HTML, 'json' => $json, 'thumb250_e' => $thumb250_e, 'thumb250' => $thumb250, 'embed' => $embed, 'fileinfo' => $fi), true)); if (is_object($embed)) { $thumbX = $meta->getThumbURL('embed'); $tfi = pathinfo($thumbX); $tfi['extension'] = image_type_to_extension($embed->metadata[2]); $thumbX = $tfi['dirname'] . '/' . $tfi['filename'] . '.' . $tfi['extension']; $thumbX = $this->normalize($thumbX); $thumbX_f = $this->url_path2file_path($thumbX); // as we've spent some effort to dig out the embedded thumbnail, and 'knowing' (assuming) that generally // embedded thumbnails are not too large, we don't concern ourselves with delaying the thumbnail generation (the // source file mapping is not bidirectional, either!) and go straight ahead and produce the 250px thumbnail at least. $thumb250 = false; $thumb250_e = false; $thumb48 = false; $thumb48_e = false; $meta->mkCacheDir(); if (false === file_put_contents($thumbX_f, $embed->imagedata)) { @unlink($thumbX_f); $emsgX = 'Cannot save embedded image data to cache.'; $icon48 = $this->getIcon('is.default-error', false); $icon = $this->getIcon('is.default-error', true); } else { try { $thumb250 = $this->getThumb($meta, $thumbX_f, $this->options['thumbBigSize'], $this->options['thumbBigSize'], false); if (!empty($thumb250)) { $thumb250_e = FileManagerUtility::rawurlencode_path($thumb250); } $thumb48 = $this->getThumb($meta, !empty($thumb250) ? $this->url_path2file_path($thumb250) : $thumbX_f, $this->options['thumbSmallSize'], $this->options['thumbSmallSize'], false); if (!empty($thumb48)) { $thumb48_e = FileManagerUtility::rawurlencode_path($thumb48); } } catch (Exception $e) { $emsgX = $e->getMessage(); $icon48 = $this->getIconForError($emsgX, $legal_url, false); $icon = $this->getIconForError($emsgX, $legal_url, true); } } } } } else { // !empty($thumb250) $thumb250_e = FileManagerUtility::rawurlencode_path($thumb250); try { $thumb48 = $this->getThumb($meta, $this->url_path2file_path($thumb250), $this->options['thumbSmallSize'], $this->options['thumbSmallSize'], false); assert(!empty($thumb48)); $thumb48_e = FileManagerUtility::rawurlencode_path($thumb48); } catch (Exception $e) { $emsgX = $e->getMessage(); $icon48 = $this->getIconForError($emsgX, $legal_url, false); $icon = $this->getIconForError($emsgX, $legal_url, true); $thumb48 = false; $thumb48_e = false; } } } } else { if (empty($thumb250_e)) { $thumb250_e = FileManagerUtility::rawurlencode_path($thumb250); } if (empty($thumb48)) { try { $thumb48 = $this->getThumb($meta, $this->url_path2file_path($thumb250), $this->options['thumbSmallSize'], $this->options['thumbSmallSize'], false); assert(!empty($thumb48)); $thumb48_e = FileManagerUtility::rawurlencode_path($thumb48); } catch (Exception $e) { $emsgX = $e->getMessage(); $icon48 = $this->getIconForError($emsgX, $legal_url, false); $icon = $this->getIconForError($emsgX, $legal_url, true); $thumb48 = false; $thumb48_e = false; } } if (empty($thumb48_e)) { $thumb48_e = FileManagerUtility::rawurlencode_path($thumb48); } } // also provide X/Y size info with each direct-access thumbnail file: if (!empty($thumb250)) { $json['thumb250'] = $thumb250_e; $meta->store('thumb250_direct', $thumb250); $tnsize = $meta->fetch('thumb250_info'); if (empty($tnsize)) { $tnsize = getimagesize($this->url_path2file_path($thumb250)); $meta->store('thumb250_info', $tnsize); } if (is_array($tnsize)) { $json['thumb250_width'] = $tnsize[0]; $json['thumb250_height'] = $tnsize[1]; if (empty($preview_HTML)) { $preview_HTML = '<a href="' . FileManagerUtility::rawurlencode_path($url) . '" data-milkbox="single" title="' . htmlentities($filename, ENT_QUOTES, 'UTF-8') . '"> <img src="' . $thumb250_e . '" class="preview" alt="' . (!empty($emsgX) ? $this->mkSafe4HTMLattr($emsgX) : 'preview') . '" style="width: ' . $tnsize[0] . 'px; height: ' . $tnsize[1] . 'px;" /> </a>'; } } } if (!empty($thumb48)) { $json['thumb48'] = $thumb48_e; $meta->store('thumb48_direct', $thumb48); $tnsize = $meta->fetch('thumb48_info'); if (empty($tnsize)) { $tnsize = getimagesize($this->url_path2file_path($thumb48)); $meta->store('thumb48_info', $tnsize); } if (is_array($tnsize)) { $json['thumb48_width'] = $tnsize[0]; $json['thumb48_height'] = $tnsize[1]; } } if ($thumbnails_done_or_deferred && (empty($thumbs250) || empty($thumbs48))) { $json['thumbs_deferred'] = true; } else { $json['thumbs_deferred'] = false; } if (!empty($icon48)) { $icon48_e = FileManagerUtility::rawurlencode_path($icon48); $json['icon48'] = $icon48_e; } if (!empty($icon)) { $icon_e = FileManagerUtility::rawurlencode_path($icon); $json['icon'] = $icon_e; } $fi4dump = null; if (!empty($fi)) { try { $fi4dump = $meta->fetch('file_info_dump'); if (empty($fi4dump)) { $fi4dump = array_merge(array(), $fi); // clone $fi $this->clean_ID3info_results($fi4dump); $meta->store('file_info_dump', $fi4dump); } $dump = FileManagerUtility::table_var_dump($fi4dump, false); $postdiag_dump_HTML .= "\n" . $dump . "\n"; //@file_put_contents(dirname(__FILE__) . '/getid3.log', print_r(array('html' => $preview_HTML, 'json' => $json, 'thumb250_e' => $thumb250_e, 'thumb250' => $thumb250, 'embed' => $embed, 'fileinfo' => $fi), true)); } catch (Exception $e) { $postdiag_err_HTML .= '<p class="err_info">' . $e->getMessage() . '</p>'; } } if ($preview_HTML === null) { $preview_HTML = '${nopreview}'; } if (!empty($preview_HTML)) { //$content .= '<h3>${preview}</h3>'; $content .= '<div class="filemanager-preview-content">' . $preview_HTML . '</div>'; } if (!empty($postdiag_err_HTML)) { $content .= '<div class="filemanager-errors">' . $postdiag_err_HTML . '</div>'; } if (!empty($postdiag_dump_HTML) && $metaHTML_mode) { $content .= '<div class="filemanager-diag-dump">' . $postdiag_dump_HTML . '</div>'; } $json['content'] = self::compressHTML($content); $json['metadata'] = $metaJSON_mode ? $fi4dump : null; return array_merge(is_array($json_in) ? $json_in : array(), $json); }
protected function onDetail() { if (empty($this->post['file'])) { return; } $file = $this->basedir . $this->post['directory'] . $this->post['file']; if (!$this->checkFile($file)) { return; } $url = str_replace($_SERVER['DOCUMENT_ROOT'], '', $this->normalize($file)); $mime = $this->getMimeType($file); $content = null; // image if (FileManagerUtility::startsWith($mime, 'image/')) { // generates a random number to put on the end of the image, to prevent caching $randomImage = '?' . md5(uniqid(rand(), 1)); $size = getimagesize($file); $content = '<dl> <dt>${width}</dt><dd>' . $size[0] . 'px</dd> <dt>${height}</dt><dd>' . $size[1] . 'px</dd> </dl> <h2>${preview}</h2> <a href="' . $url . '" data-milkbox="preview" title="' . str_replace($_SERVER['DOCUMENT_ROOT'], '', $file) . '"><img src="' . $this->options['thumbnailPath'] . $this->getThumb($this->normalize($file)) . $randomImage . '" class="preview" alt="preview" /></a> '; // text preview } elseif (FileManagerUtility::startsWith($mime, 'text/') || $mime == 'application/x-javascript') { $filecontent = file_get_contents($file, false, null, 0); if (!FileManagerUtility::isBinary($filecontent)) { $content = '<div class="textpreview"><pre>' . str_replace(array('$', "\t"), array('$', ' '), htmlentities($filecontent, ENT_QUOTES, 'UTF-8')) . '</pre></div>'; } // zip } elseif ($mime == 'application/zip') { require_once dirname(__FILE__) . '/Assets/getid3/getid3.php'; $out = array(array(), array()); $getid3 = new getID3(); $getid3->Analyze($file); foreach ($getid3->info['zip']['files'] as $name => $size) { $dir = is_array($size) ? true : true; $out[$dir ? 0 : 1][$name] = '<li><a><img src="' . $this->getIcon($name, true) . '" alt="" /> ' . $name . '</a></li>'; } natcasesort($out[0]); natcasesort($out[1]); $content = '<ul>' . implode(array_merge($out[0], $out[1])) . '</ul>'; // swf } elseif ($mime == 'application/x-shockwave-flash') { require_once dirname(__FILE__) . '/Assets/getid3/getid3.php'; $getid3 = new getID3(); $getid3->Analyze($file); $content = '<dl> <dt>${width}</dt><dd>' . $getid3->info['swf']['header']['frame_width'] / 10 . 'px</dd> <dt>${height}</dt><dd>' . $getid3->info['swf']['header']['frame_height'] / 10 . 'px</dd> <dt>${length}</dt><dd>' . round($getid3->info['swf']['header']['length'] / $getid3->info['swf']['header']['frame_count']) . 's</dd> </dl> <h2>${preview}</h2> <div class="object"> <object type="application/x-shockwave-flash" data="' . str_replace($_SERVER['DOCUMENT_ROOT'], '', $file) . '" width="500" height="400"> <param name="scale" value="noscale" /> <param name="movie" value="' . str_replace($_SERVER['DOCUMENT_ROOT'], '', $file) . '" /> </object> </div>'; // audio } elseif (FileManagerUtility::startsWith($mime, 'audio/')) { require_once dirname(__FILE__) . '/Assets/getid3/getid3.php'; $getid3 = new getID3(); $getid3->encoding = "UTF-8"; $getid3->Analyze($file); $title = str_replace("\$", "$", !empty($getid3->info['tags']['id3v2']['title'][0]) ? $getid3->info['tags']['id3v2']['title'][0] : (!empty($getid3->info['tags']['id3v1']['title'][0]) ? $getid3->info['tags']['id3v1']['title'][0] : "-")); $artist = str_replace("\$", "$", !empty($getid3->info['tags']['id3v2']['artist'][0]) ? $getid3->info['tags']['id3v2']['artist'][0] : (!empty($getid3->info['tags']['id3v1']['artist'][0]) ? $getid3->info['tags']['id3v1']['artist'][0] : "-")); $album = str_replace("\$", "$", !empty($getid3->info['tags']['id3v2']['album'][0]) ? $getid3->info['tags']['id3v2']['album'][0] : (!empty($getid3->info['tags']['id3v1']['album'][0]) ? $getid3->info['tags']['id3v1']['album'][0] : "-")); $content = '<dl> <dt>${title}</dt><dd>' . $title . '</dd> <dt>${artist}</dt><dd>' . $artist . '</dd> <dt>${album}</dt><dd>' . $album . '</dd> <dt>${length}</dt><dd>' . (!empty($getid3->info['playtime_string']) ? $getid3->info['playtime_string'] : "-") . '</dd> <dt>${bitrate}</dt><dd>' . (!empty($getid3->info['bitrate']) ? round($getid3->info['bitrate'] / 1000) . "kbps" : "-") . '</dd> </dl> <h2>${preview}</h2> <div class="object"> <object type="application/x-shockwave-flash" data="' . $this->options['assetBasePath'] . '/dewplayer.swf" width="200" height="20" id="dewplayer" name="dewplayer"> <param name="wmode" value="transparent" /> <param name="movie" value="' . $this->options['assetBasePath'] . '/dewplayer.swf" /> <param name="flashvars" value="mp3=' . rawurlencode($url) . '&volume=50&showtime=1" /> </object> </div>'; } echo json_encode(array('content' => $content ? $content : '<div class="margin"> ${nopreview} </div>')); }
protected function onDetail() { if (empty($this->post['directory']) || empty($this->post['file'])) { return; } $file = realpath($this->path . '/' . $this->post['directory'] . '/' . $this->post['file']); if (!$this->checkFile($file)) { return; } require_once $this->options['id3Path']; $url = $this->options['baseURL'] . $this->normalize(substr($file, strlen($this->path) + 1)); $mime = $this->getMimeType($file); $content = null; if (FileManagerUtility::startsWith($mime, 'image/')) { $size = getimagesize($file); $content = '<img src="' . $url . '" class="preview" alt="" /> <h2>${more}</h2> <dl> <dt>${width}</dt><dd>' . $size[0] . 'px</dd> <dt>${height}</dt><dd>' . $size[1] . 'px</dd> </dl>'; } elseif (FileManagerUtility::startsWith($mime, 'text/') || $mime == 'application/x-javascript') { $filecontent = file_get_contents($file, null, null, 0, 300); if (!FileManagerUtility::isBinary($filecontent)) { $content = '<div class="textpreview">' . nl2br(str_replace(array('$', "\t"), array('$', ' '), htmlentities($filecontent))) . '</div>'; } } elseif ($mime == 'application/zip') { $out = array(array(), array()); $getid3 = new getID3(); $getid3->Analyze($file); foreach ($getid3->info['zip']['files'] as $name => $size) { $icon = is_array($size) ? 'dir' : $this->getIcon($name); $out[$icon == 'dir' ? 0 : 1][$name] = '<li><a><img src="' . $this->options['assetBasePath'] . '/Icons/' . $icon . '.png" alt="" /> ' . $name . '</a></li>'; } natcasesort($out[0]); natcasesort($out[1]); $content = '<ul>' . implode(array_merge($out[0], $out[1])) . '</ul>'; } elseif (FileManagerUtility::startsWith($mime, 'audio/')) { $getid3 = new getID3(); $getid3->Analyze($file); $content = '<div class="object"> <object type="application/x-shockwave-flash" data="' . $this->options['assetBasePath'] . '/dewplayer.swf?mp3=' . rawurlencode($url) . '&volume=30" width="200" height="20"> <param name="movie" value="' . $this->options['assetBasePath'] . '/dewplayer.swf?mp3=' . rawurlencode($url) . '&volume=30" /> </object> </div> <h2>${more}</h2> <dl> <dt>${title}</dt><dd>' . $getid3->info['comments']['title'][0] . '</dd> <dt>${artist}</dt><dd>' . $getid3->info['comments']['artist'][0] . '</dd> <dt>${album}</dt><dd>' . $getid3->info['comments']['album'][0] . '</dd> <dt>${length}</dt><dd>' . $getid3->info['playtime_string'] . '</dd> <dt>${bitrate}</dt><dd>' . round($getid3->info['bitrate'] / 1000) . 'kbps</dd> </dl>'; } echo json_encode(array('content' => $content ? $content : '<div class="margin"> ${nopreview}<br/><button value="' . $url . '">${download}</button> </div>')); }
protected static function clean_EXIF_results(&$arr) { // see http://nl2.php.net/manual/en/function.array-walk-recursive.php#81835 // --> we don't mind about it because we're not worried about the references occurring in here, now or later. // Indeed, that does assume we (as in 'we' being this particular function!) know about how the // data we process will be used. Risky, but fine with me. Hence the 'protected'. array_walk_recursive($arr, function (&$value, $key) { if (is_string($value)) { if (FileManagerUtility::isBinary($value)) { $value = '(binary data... length = ' . strlen($value) . ')'; } } }); }