/** * Handle image upload * * Returns array with uploaded files details or error details */ public function uploadImage($uploadFieldName = self::DEFAULT_FILE_FIELD_NAME, $destFileName = null, $forceOverwrite = false) { global $IP, $wgRequest, $wgUser; wfProfileIn(__METHOD__); $ret = false; // check whether upload is enabled (RT #53714) if (!WikiaPhotoGalleryHelper::isUploadAllowed()) { $ret = array('error' => true, 'message' => wfMsg('uploaddisabled')); wfProfileOut(__METHOD__); return $ret; } $imageName = stripslashes(!empty($destFileName) ? $destFileName : $wgRequest->getFileName($uploadFieldName)); // validate name and content of uploaded photo $nameValidation = $this->checkImageName($imageName, $uploadFieldName); if ($nameValidation == UploadBase::SUCCESS) { // get path to uploaded image $imagePath = $wgRequest->getFileTempName($uploadFieldName); // check if image with this name is already uploaded if ($this->imageExists($imageName) && !$forceOverwrite) { // upload as temporary file $this->log(__METHOD__, "image '{$imageName}' already exists!"); $tempName = $this->tempFileName($wgUser); $title = Title::makeTitle(NS_FILE, $tempName); $localRepo = RepoGroup::singleton()->getLocalRepo(); $file = new FakeLocalFile($title, $localRepo); $file->upload($wgRequest->getFileTempName($uploadFieldName), '', ''); // store uploaded image in GarbageCollector (image will be removed if not used) $tempId = $this->tempFileStoreInfo($tempName); // generate thumbnail (to fit 200x200 box) of temporary file $width = min(WikiaPhotoGalleryHelper::thumbnailMaxWidth, $file->width); $height = min(WikiaPhotoGalleryHelper::thumbnailMaxHeight, $file->height); $thumbnail = $file->transform(array('height' => $height, 'width' => $width)); // split uploaded file name into name + extension (foo-bar.png => foo-bar + png) list($fileName, $extensionsName) = UploadBase::splitExtensions($imageName); $extensionName = !empty($extensionsName) ? end($extensionsName) : ''; $this->log(__METHOD__, 'upload successful'); $ret = array('conflict' => true, 'name' => $imageName, 'nameParts' => array($fileName, $extensionName), 'tempId' => $tempId, 'size' => array('height' => $file->height, 'width' => $file->width), 'thumbnail' => array('height' => $thumbnail->height, 'url' => $thumbnail->url, 'width' => $thumbnail->width)); } else { // use regular MW upload $this->log(__METHOD__, "image '{$imageName}' is new one - uploading as MW file"); $this->log(__METHOD__, "uploading '{$imagePath}' as File:{$imageName}"); // create title and file objects for MW image to create $imageTitle = Title::newFromText($imageName, NS_FILE); $imageFile = new LocalFile($imageTitle, RepoGroup::singleton()->getLocalRepo()); // perform upload $result = $imageFile->upload($imagePath, '', ''); $this->log(__METHOD__, !empty($result->ok) ? 'upload successful' : 'upload failed'); $ret = array('success' => !empty($result->ok), 'name' => $imageName, 'size' => array('height' => !empty($result->ok) ? $imageFile->getHeight() : 0, 'width' => !empty($result->ok) ? $imageFile->getWidth() : 0)); } } else { $reason = $nameValidation; $this->log(__METHOD__, "upload failed - file name is not valid (error #{$reason})"); $ret = array('error' => true, 'reason' => $reason, 'message' => $this->translateError($reason)); } wfProfileOut(__METHOD__); return $ret; }
</p> </div> </div> <!-- Slider preview --> <div class="WikiaPhotoGalleryEditorPage"> <div class="WikiaPhotoGalleryEditorPageInner"> <h1><?php echo wfMsg('wikiaPhotoGallery-sliderpreview-optionstitle'); ?> </h1> <div class="clearfix"> <!-- type radio buttons --> <?php echo WikiaPhotoGalleryHelper::renderImageOptionWidget('WikiaPhotoGallerySliderType', 'wikiaPhotoGallery-sliderpreview-choosetype', array('bottom', 'right'), 103); ?> </div> <h1><?php echo wfMsg('wikiaPhotoGallery-sliderpreview-photostitle'); ?> </h1> <p> <button id="WikiaPhotoGallerySliderAddImage" class="wikia-button"><?php echo wfMsg('wikiaPhotoGallery-sliderpreview-addphoto'); ?> </button> </p> <div id="WikiaPhotoGallerySliderEditorPreview" class="preview"></div>
/** * replacing gallery in wikitext (saving changes) * @author Marooned */ public static function saveGalleryData() { global $wgRequest; wfProfileIn(__METHOD__); $hash = $wgRequest->getVal('hash'); $wikitext = $wgRequest->getVal('wikitext'); $starttime = $wgRequest->getVal('starttime'); $result = WikiaPhotoGalleryHelper::saveGalleryDataByHash($hash, $wikitext, $starttime); wfProfileOut(__METHOD__); // return JSON as HTML - decode it JS-side return json_encode($result); }
/** * Hook handler * @author Marooned * * @param $parser Parser * @param $ig WikiaPhotoGallery */ public static function beforeParserrenderImageGallery($parser, $ig) { wfProfileIn(__METHOD__); // parse each gallery / slideshow and get its data $ig->parse(); $data = $ig->getData(); // get data of gallery / slideshow we're interested in if ($data['hash'] == self::$mGalleryHash) { self::$mGalleryData = $data; } self::$lastGalleryData = $data; wfProfileOut(__METHOD__); // by returning false we're telling MW parser to return gallery's HTML immediatelly return false; }
/** * Return a HTML representation of the image slideshow */ private function renderSlideshow() { global $wgStylePath; wfProfileIn(__METHOD__); // don't render empty slideshows if (empty($this->mFiles)) { wfProfileOut(__METHOD__); return ''; } // If we can, render this as a media gallery if ($this->canRenderMediaGallery()) { $html = $this->renderMediaGallery(); wfProfileOut(__METHOD__); return trim(preg_replace('/\\n+/', ' ', $html)); } /** @var Skin|Linker $sk The Skin object falls back to Linker methods */ $sk = RequestContext::getMain()->getSkin(); // slideshow wrapper CSS class $class = 'wikia-slideshow clearfix'; $id = "slideshow-{$this->mData['id']}"; // do not add button for galleries from templates if (isset($this->mData['params']['source']) && $this->mData['params']['source'] == "template") { $class .= ' template'; } // support "position" attribute (slideshow alignment) switch ($this->getParam('position')) { case 'left': $class .= ' floatleft'; break; case 'center': $class .= ' slideshow-center'; break; case 'right': $class .= ' floatright'; break; } // wrap image slideshow inside div.slideshow $attribs = Sanitizer::mergeAttributes(array('class' => $class, 'data-hash' => $this->mData['hash'], 'data-crop' => $this->mCrop, 'id' => $id), $this->mAttribs); //renderSlideshow for WikiaMobile if (F::app()->checkSkin('wikiamobile')) { $slideshowHtml = $this->renderWikiaMobileMediaGroup(); } else { $slideshowHtml = Xml::openElement('div', $attribs); // render slideshow caption if ($this->mCaption) { $slideshowHtml .= '<div class="wikia-slideshow-caption">' . $this->mCaption . '</div>'; } // fit images inside width:height = 4:3 box $this->mHeights = round($this->mWidths * 3 / 4); $params = array('width' => $this->mWidths, 'height' => $this->mHeights); wfDebug(__METHOD__ . ": slideshow {$params['width']}x{$params['height']}\n"); $slideshowHtml .= Xml::openElement('div', array('class' => 'wikia-slideshow-wrapper', 'style' => 'width: ' . ($this->mWidths + 10) . 'px')); // wrap images inside <div> and <ul> $slideshowHtml .= Xml::openElement('div', array('class' => 'wikia-slideshow-images-wrapper accent')); $slideshowHtml .= Xml::openElement('ul', array('class' => 'wikia-slideshow-images neutral', 'style' => "height: {$params['height']}px; width: {$params['width']}px")); $index = 0; foreach ($this->mFiles as $p => $pair) { /** * @var $nt Title */ $nt = $pair[0]; $text = $pair[1]; $link = $pair[2]; # Give extensions a chance to select the file revision for us $time = $descQuery = false; wfRunHooks('BeforeGalleryFindFile', array(&$this, &$nt, &$time, &$descQuery)); $img = wfFindFile($nt, $time); if (WikiaFileHelper::isFileTypeVideo($img)) { continue; } $thumb = null; // let's properly scale image (don't make it bigger than original size) and handle "crop" attribute if (is_object($img) && $nt->getNamespace() == NS_FILE) { $thumbParams = WikiaPhotoGalleryHelper::getThumbnailDimensions($img, $params['width'], $params['height'], $this->mCrop); } $caption = $linkOverlay = ''; // render caption overlay if ($text != '') { $caption = Xml::openElement('span', array('class' => 'wikia-slideshow-image-caption')) . Xml::openElement('span', array('class' => 'wikia-slideshow-image-caption-inner')) . $text . Xml::closeElement('span') . Xml::closeElement('span'); } // parse link $linkAttribs = $this->parseLink($nt->getLocalUrl(), $nt->getText(), $link); // extra link tag attributes $linkAttribs['id'] = "{$id}-{$index}"; $linkAttribs['style'] = 'width: ' . ($params['width'] - 80) . 'px'; if ($link == '') { // tooltip to be used for not-linked images $linkAttribs['title'] = wfMessage('wikiaPhotoGallery-slideshow-view-popout-tooltip')->text(); $linkAttribs['class'] = 'wikia-slideshow-image'; unset($linkAttribs['href']); } else { // linked images $linkAttribs['class'] .= ' wikia-slideshow-image'; // support |linktext= syntax if ($this->mData['images'][$p]['linktext'] != '') { $linkText = $this->mData['images'][$p]['linktext']; } else { $linkText = $link; } // add link overlay $linkOverlay = Xml::openElement('span', array('class' => 'wikia-slideshow-link-overlay')) . wfMessage('wikiaPhotoGallery-slideshow-view-link-overlay', Sanitizer::removeHTMLtags($linkText))->text() . Xml::closeElement('span'); } // generate HTML for a single slideshow image $thumbHtml = null; $liAttribs = array('title' => null); if ($nt->getNamespace() != NS_FILE || !$img) { # We're dealing with a non-image, spit out the name and be done with it. $thumbHtml = '<a class="image broken-image new" style="line-height: ' . $this->mHeights . 'px;">' . $nt->getText() . '</a>'; } elseif ($this->mHideBadImages && wfIsBadImage($nt->getDBkey(), $this->getContextTitle())) { # The image is blacklisted, just show it as a text link. $thumbHtml = '<div style="height: ' . ($this->mHeights * 1.25 + 2) . 'px;">' . $sk->makeKnownLinkObj($nt, $nt->getText()) . '</div>'; } elseif (!($thumb = $img->transform($thumbParams))) { # Error generating thumbnail. $thumbHtml = '<div style="height: ' . ($this->mHeights * 1.25 + 2) . 'px;">' . htmlspecialchars($img->getLastError()) . '</div>'; } else { $thumbAttribs = array('data-src' => $thumb->url, 'class' => 'thumbimage', 'width' => $thumb->width, 'height' => $thumb->height, 'style' => 'border: 0px;', 'data-image-name' => $img->getTitle()->getText(), 'data-image-key' => $img->getTitle()->getDBKey()); if (!empty($this->mData['images'][$p]['data-caption'])) { $thumbAttribs['data-caption'] = $this->mData['images'][$p]['data-caption']; } $thumbHtml = Xml::element('img', $thumbAttribs); } // add CSS class so we can show first slideshow image before JS is loaded if ($index == 0) { $liAttribs['class'] = 'wikia-slideshow-first-image'; } $slideshowHtml .= Xml::openElement('li', $liAttribs) . $thumbHtml . Xml::element('a', $linkAttribs, ' ') . $caption . $linkOverlay . '</li>'; $index++; // Call parser transform hook if ($this->mParser && is_object($img) && $img->getHandler()) { $img->getHandler()->parserTransformHook($this->mParser, $img); } if (is_object($thumb)) { wfDebug(__METHOD__ . ": image '" . $nt->getText() . "' {$thumb->width}x{$thumb->height}\n"); } } $slideshowHtml .= Xml::closeElement('ul'); $slideshowHtml .= Xml::closeElement('div'); // render prev/next buttons global $wgBlankImgUrl; $top = ($params['height'] >> 1) - 30 + 5; $slideshowHtml .= Xml::openElement('div', array('class' => 'wikia-slideshow-prev-next')); // prev $slideshowHtml .= Xml::openElement('a', array('class' => 'wikia-slideshow-sprite wikia-slideshow-prev', 'style' => "top: {$top}px", 'title' => wfMessage('wikiaPhotoGallery-slideshow-view-prev-tooltip')->text())); $slideshowHtml .= Xml::openElement('span'); $slideshowHtml .= Xml::element('img', array('class' => 'chevron', 'src' => $wgBlankImgUrl)); $slideshowHtml .= Xml::closeElement('span'); $slideshowHtml .= Xml::closeElement('a'); // next $slideshowHtml .= Xml::openElement('a', array('class' => 'wikia-slideshow-sprite wikia-slideshow-next', 'style' => "top: {$top}px", 'title' => wfMessage('wikiaPhotoGallery-slideshow-view-next-tooltip')->text())); $slideshowHtml .= Xml::openElement('span'); $slideshowHtml .= Xml::element('img', array('class' => 'chevron', 'src' => $wgBlankImgUrl)); $slideshowHtml .= Xml::closeElement('span'); $slideshowHtml .= Xml::closeElement('a'); $slideshowHtml .= Xml::closeElement('div'); // render slideshow toolbar $slideshowHtml .= Xml::openElement('div', array('class' => 'wikia-slideshow-toolbar clearfix', 'style' => 'display: none')); // Pop-out icon, "X of X" counter $counterValue = wfMessage('wikiaPhotoGallery-slideshow-view-number', '$1', $index)->text(); $slideshowHtml .= Xml::openElement('div', array('style' => 'float: left')); $slideshowHtml .= Xml::element('img', array('class' => 'wikia-slideshow-popout lightbox', 'height' => 11, 'src' => "{$wgStylePath}/common/images/magnify-clip.png", 'title' => wfMessage('wikiaPhotoGallery-slideshow-view-popout-tooltip')->text(), 'width' => 15)); $slideshowHtml .= Xml::element('span', array('class' => 'wikia-slideshow-toolbar-counter', 'data-counter' => $counterValue), str_replace('$1', '1', $counterValue)); $slideshowHtml .= Xml::closeElement('div'); // "Add Image" if (!empty($this->mShowAddButton)) { $slideshowHtml .= Xml::element('a', array('class' => 'wikia-slideshow-addimage wikia-button secondary', 'style' => 'float: right'), wfMessage('wikiaPhotoGallery-slideshow-view-addphoto')->inContentLanguage()->text()); } $slideshowHtml .= Xml::closeElement('div'); // close slideshow wrapper $slideshowHtml .= Xml::closeElement('div'); $slideshowHtml .= Xml::closeElement('div'); // output JS to init slideshow $width = "{$params['width']}px"; $height = "{$params['height']}px"; $slideshowHtml .= JSSnippets::addToStack(array('wikia_photo_gallery_slideshow_js', 'wikia_photo_gallery_slideshow_scss'), array(), 'WikiaPhotoGallerySlideshow.init', array('id' => $id, 'width' => $width, 'height' => $height)); } wfProfileOut(__METHOD__); return $slideshowHtml; }