public static function update_locked($userid) { if (empty($userid)) { return; } $submitted = get_column_sql(' SELECT a.id FROM {artefact} a JOIN {view_artefact} va ON a.id = va.artefact JOIN {view} v ON va.view = v.id WHERE a.owner = ? AND v.owner = ? AND (v.submittedgroup IS NOT NULL OR v.submittedhost IS NOT NULL)', array($userid, $userid)); if ($submitted) { $submitted = artefact_get_descendants($submitted); if ($attachments = get_column_sql(' SELECT attachment FROM {artefact_attachment} WHERE artefact IN (' . join(',', $submitted) . ')', array())) { $submitted = array_merge($submitted, $attachments); } } db_begin(); if (!empty($submitted)) { $idstr = '(' . join(',', $submitted) . ')'; set_field_select('artefact', 'locked', 1, "locked = 0 AND id IN {$idstr}", array()); } // Unlock $select = 'locked = 1 AND "owner" = ?'; if (isset($idstr)) { $select .= " AND NOT id IN {$idstr}"; } set_field_select('artefact', 'locked', 0, $select, array($userid)); db_commit(); }
public static function render_instance(BlockInstance $instance, $editing = false) { $configdata = $instance->get('configdata'); // this will make sure to unserialize it for us $configdata['viewid'] = $instance->get('view'); $style = isset($configdata['style']) ? intval($configdata['style']) : 2; $copyright = null; // Needed to set Panoramio copyright later... $width = !empty($configdata['width']) ? $configdata['width'] : 75; switch ($style) { case 0: // thumbnails $template = 'thumbnails'; break; case 1: // slideshow $template = 'slideshow'; $width = !empty($configdata['width']) ? $configdata['width'] : 400; break; case 2: // square thumbnails $template = 'squarethumbs'; break; } $images = array(); $slimbox2 = get_config_plugin('blocktype', 'gallery', 'useslimbox2'); if ($slimbox2) { $slimbox2attr = 'lightbox_' . $instance->get('id'); } else { $slimbox2attr = null; } // if we're trying to embed external gallery (thumbnails or slideshow) if (isset($configdata['select']) && $configdata['select'] == 2) { $gallery = self::make_gallery_url($configdata['external']); if (empty($gallery)) { return get_string('externalnotsupported', 'blocktype.file/gallery'); } $url = isset($gallery['url']) ? hsc($gallery['url']) : null; $type = isset($gallery['type']) ? hsc($gallery['type']) : null; $var1 = isset($gallery['var1']) ? hsc($gallery['var1']) : null; $var2 = isset($gallery['var2']) ? hsc($gallery['var2']) : null; switch ($type) { case 'widget': /***************************** Roy Tanck's FLICKR WIDGET for Flickr RSS & Picasa RSS http://www.roytanck.com/get-my-flickr-widget/ *****************************/ $widget_sizes = array(100, 200, 300); $width = self::find_nearest($widget_sizes, $width); $images = urlencode(str_replace('&', '&', $url)); $template = 'imagecloud'; break; case 'picasa': // Slideshow if ($style == 1) { $picasa_show_sizes = array(144, 288, 400, 600, 800); $width = self::find_nearest($picasa_show_sizes, $width); $height = round($width * 0.75); $images = array('user' => $var1, 'gallery' => $var2); $template = 'picasashow'; } else { $picasa_thumbnails = array(32, 48, 64, 72, 104, 144, 150, 160); $width = self::find_nearest($picasa_thumbnails, $width); // If the Thumbnails should be Square... if ($style == 2) { $small = 's' . $width . '-c'; $URL = 'http://picasaweb.google.com/data/feed/api/user/' . $var1 . '/album/' . $var2 . '?kind=photo&thumbsize=' . $width . 'c'; } else { $small = 's' . $width; $URL = 'http://picasaweb.google.com/data/feed/api/user/' . $var1 . '/album/' . $var2 . '?kind=photo&thumbsize=' . $width; } $big = 's' . get_config_plugin('blocktype', 'gallery', 'previewwidth'); $xmlDoc = new DOMDocument('1.0', 'UTF-8'); $config = array(CURLOPT_URL => $URL, CURLOPT_RETURNTRANSFER => true); $result = mahara_http_request($config); $xmlDoc->loadXML($result->data); $photos = $xmlDoc->getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'group'); foreach ($photos as $photo) { $children = $photo->cloneNode(true); $thumb = $children->getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'thumbnail')->item(0)->getAttribute('url'); $description = null; if (isset($children->getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'description')->item(0)->firstChild->nodeValue)) { $description = $children->getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'description')->item(0)->firstChild->nodeValue; } $images[] = array('link' => str_replace($small, $big, $thumb), 'source' => $thumb, 'title' => $description, 'slimbox2' => $slimbox2attr); } } break; case 'flickr': // Slideshow if ($style == 1) { $flickr_show_sizes = array(400, 500, 700, 800); $width = self::find_nearest($flickr_show_sizes, $width); $height = round($width * 0.75); $images = array('user' => $var1, 'gallery' => $var2); $template = 'flickrshow'; } else { $width = 75; // Currently only thumbnail size, that Flickr supports $api_key = get_config_plugin('blocktype', 'gallery', 'flickrapikey'); $URL = 'http://api.flickr.com/services/rest/?method=flickr.photosets.getPhotos&extras=url_sq,url_t&photoset_id=' . $var2 . '&api_key=' . $api_key; $xmlDoc = new DOMDocument('1.0', 'UTF-8'); $config = array(CURLOPT_URL => $URL, CURLOPT_RETURNTRANSFER => true); $result = mahara_http_request($config); $xmlDoc->loadXML($result->data); $photos = $xmlDoc->getElementsByTagName('photo'); foreach ($photos as $photo) { // If the Thumbnails should be Square... if ($style == 2) { $thumb = $photo->getAttribute('url_sq'); $link = str_replace('_s.jpg', '_b.jpg', $thumb); } else { $thumb = $photo->getAttribute('url_t'); $link = str_replace('_t.jpg', '_b.jpg', $thumb); } $description = $photo->getAttribute('title'); $images[] = array('link' => $link, 'source' => $thumb, 'title' => $description, 'slimbox2' => $slimbox2attr); } } break; case 'panoramio': // Slideshow if ($style == 1) { $height = round($width * 0.75); $images = array('user' => $var1); $template = 'panoramioshow'; } else { $copyright = get_string('panoramiocopyright', 'blocktype.file/gallery'); $URL = 'http://www.panoramio.com/map/get_panoramas.php?set=' . $var1 . '&from=0&to=50&size=original&mapfilter=true'; $config = array(CURLOPT_URL => $URL, CURLOPT_RETURNTRANSFER => true); $result = mahara_http_request($config); $data = json_decode($result->data, true); foreach ($data['photos'] as $photo) { $link = str_replace('/original/', '/large/', $photo['photo_file_url']); // If the Thumbnails should be Square... if ($style == 2) { $thumb = str_replace('/original/', '/square/', $photo['photo_file_url']); $width = 60; // Currently only square thumbnail size, that Panoramio supports } else { $thumb = str_replace('/original/', '/thumbnail/', $photo['photo_file_url']); } $title = !empty($photo['photo_title']) ? $photo['photo_title'] : get_string('Photo', 'blocktype.file/gallery'); $description = '<a href="' . $photo['photo_url'] . '" target="_blank">' . $title . '</a>' . ' ' . get_string('by', 'blocktype.file/gallery') . ' ' . '<a href="' . $photo['owner_url'] . '" target="_blank">' . $photo['owner_name'] . '</a>'; $images[] = array('link' => $link, 'source' => $thumb, 'title' => $description, 'slimbox2' => $slimbox2attr); } } break; case 'photobucket': // Slideshow if ($style == 1) { $height = round($width * 0.75); $images = array('url' => $url, 'user' => $var1, 'album' => $var2); $template = 'photobucketshow'; } else { $consumer_key = get_config_plugin('blocktype', 'gallery', 'pbapikey'); // PhotoBucket API key $consumer_secret = get_config_plugin('blocktype', 'gallery', 'pbapiprivatekey'); //PhotoBucket API private key $oauth_signature_method = 'HMAC-SHA1'; $oauth_version = '1.0'; $oauth_timestamp = time(); $mt = microtime(); $rand = mt_rand(); $oauth_nonce = md5($mt . $rand); $method = 'GET'; $albumname = $var1 . '/' . $var2; $api_url = 'http://api.photobucket.com/album/' . urlencode($albumname); $params = null; $paramstring = 'oauth_consumer_key=' . $consumer_key . '&oauth_nonce=' . $oauth_nonce . '&oauth_signature_method=' . $oauth_signature_method . '&oauth_timestamp=' . $oauth_timestamp . '&oauth_version=' . $oauth_version; $base = urlencode($method) . '&' . urlencode($api_url) . '&' . urlencode($paramstring); $oauth_signature = base64_encode(hash_hmac('sha1', $base, $consumer_secret . '&', true)); $URL = $api_url . '?' . $paramstring . '&oauth_signature=' . urlencode($oauth_signature); $xmlDoc = new DOMDocument('1.0', 'UTF-8'); $config = array(CURLOPT_URL => $URL, CURLOPT_HEADER => false, CURLOPT_RETURNTRANSFER => true); $result = mahara_http_request($config); $xmlDoc->loadXML($result->data); $xmlDoc2 = new DOMDocument('1.0', 'UTF-8'); $config2 = array(CURLOPT_URL => $xmlDoc->getElementsByTagName('url')->item(0)->firstChild->nodeValue, CURLOPT_HEADER => false, CURLOPT_RETURNTRANSFER => true); $result2 = mahara_http_request($config2); $xmlDoc2->loadXML($result->data); $photos = $xmlDoc2->getElementsByTagName('media'); foreach ($photos as $photo) { $children = $photo->cloneNode(true); $link = $children->getElementsByTagName('url')->item(0)->firstChild->nodeValue; $thumb = $children->getElementsByTagName('thumb')->item(0)->firstChild->nodeValue; $description = null; if (isset($children->getElementsByTagName('description')->item(0)->firstChild->nodeValue)) { $description = $children->getElementsByTagName('description')->item(0)->firstChild->nodeValue; } $images[] = array('link' => $link, 'source' => $thumb, 'title' => $description, 'slimbox2' => $slimbox2attr); } } break; case 'windowslive': // Slideshow if ($style == 1) { $images = array('url' => $url, 'user' => $var1, 'album' => $var2); $template = 'windowsliveshow'; } else { $config = array(CURLOPT_URL => str_replace(' ', '%20', $url), CURLOPT_HEADER => false, CURLOPT_RETURNTRANSFER => true); $result = mahara_http_request($config); $data = $result->data; // Extract data about images and thumbs from HTML source - hack! preg_match_all("#previewImageUrl: '([a-zA-Z0-9\\_\\-\\.\\\\/]+)'#", $data, $photos); preg_match_all("#thumbnailImageUrl: '([a-zA-Z0-9\\_\\-\\.\\\\/]+)'#", $data, $thumbs); for ($i = 0; $i < sizeof($photos[1]); $i++) { $images[] = array('link' => str_replace(array('\\x3a', '\\x2f', '\\x25', '\\x3fpsid\\x3d1'), array(':', '/', '%', ''), $photos[1][$i]), 'source' => str_replace(array('\\x3a', '\\x2f', '\\x25', '\\x3fpsid\\x3d1'), array(':', '/', '%', ''), $thumbs[1][$i]), 'title' => null, 'slimbox2' => $slimbox2attr); } } break; } } else { safe_require('artefact', 'file'); $artefactids = array(); if (isset($configdata['select']) && $configdata['select'] == 1 && is_array($configdata['artefactids'])) { $artefactids = $configdata['artefactids']; } else { if (!empty($configdata['artefactid'])) { // Get descendents of this folder. $artefactids = artefact_get_descendants(array(intval($configdata['artefactid']))); } } // This can be either an image or profileicon. They both implement // render_self foreach ($artefactids as $artefactid) { $image = $instance->get_artefact_instance($artefactid); if ($image instanceof ArtefactTypeProfileIcon) { $src = get_config('wwwroot') . 'thumb.php?type=profileiconbyid&id=' . $artefactid; $description = $image->get('title'); } else { if ($image instanceof ArtefactTypeImage) { $src = get_config('wwwroot') . 'artefact/file/download.php?file=' . $artefactid; $src .= '&view=' . $instance->get('view'); $description = $image->get('description'); } else { continue; } } if ($slimbox2) { $link = $src . '&maxwidth=' . get_config_plugin('blocktype', 'gallery', 'previewwidth'); } else { $link = get_config('wwwroot') . 'artefact/artefact.php?artefact=' . $artefactid . '&view=' . $instance->get('view'); } // If the Thumbnails are Square or not... if ($style == 2) { $src .= '&size=' . $width . 'x' . $width; $height = $width; } else { $src .= '&maxwidth=' . $width; $imgwidth = $image->get('width'); $imgheight = $image->get('height'); $height = $imgwidth > $width ? intval($width / $imgwidth * $imgheight) : $imgheight; } $images[] = array('link' => $link, 'source' => $src, 'height' => $height, 'title' => $image->get('description'), 'slimbox2' => $slimbox2attr); } } $smarty = smarty_core(); $smarty->assign('instanceid', $instance->get('id')); $smarty->assign('count', count($images)); $smarty->assign('images', $images); $smarty->assign('showdescription', !empty($configdata['showdescription']) ? $configdata['showdescription'] : false); $smarty->assign('width', $width); $smarty->assign('captionwidth', get_config_plugin('blocktype', 'gallery', 'photoframe') ? $width + 8 : $width); if (isset($height)) { $smarty->assign('height', $height); } if (isset($needsapikey)) { $smarty->assign('needsapikey', $needsapikey); } $smarty->assign('frame', get_config_plugin('blocktype', 'gallery', 'photoframe')); $smarty->assign('copyright', $copyright); return $smarty->fetch('blocktype:gallery:' . $template . '.tpl'); }
public function delete() { // ArtefactType::delete() deletes all the child artefacts one by one. // If the folder contains a lot of artefacts, it's too slow to do this // but for very small directories it seems to be slightly faster. $descendants = artefact_get_descendants(array($this->id)); if (count($descendants) < 10) { parent::delete(); } else { ArtefactType::delete_by_artefacttype($descendants); } }
/** * Builds a new block instance as a copy of this one, taking into account * the Views being copied from and to. * * Blocktypes can decide whether they want to be copied to the new View. The * return value of this method should indicate whether the blocktype was * copied or not. * * @param View $view The view that this new blockinstance is being created for * @param View $template The view that this (the old) blockinstance comes from * @param array $artefactcopies Correspondence between original artefact IDs and IDs of copies * @return boolean Whether a new blockinstance was made or not. */ public function copy(View $view, View $template, &$artefactcopies) { $blocktypeclass = generate_class_name('blocktype', $this->get('blocktype')); $configdata = $this->get('configdata'); if (isset($configdata['copytype'])) { $copytype = $configdata['copytype']; } else { $copytype = call_static_method($blocktypeclass, 'default_copy_type'); } $viewowner = $view->ownership(); $templateowner = $template->ownership(); $sameowner = $viewowner['type'] == $templateowner['type'] && $viewowner['id'] == $templateowner['id']; // Check to see if the block is allowed to be copied into the new View // // Note for later: this is Blockinstance->allowed_in_view. This // determines whether this blockinstance should be copied into a view. // This could be a different question from BlockType::allowed_in_view! // But for now they use the same method. if (!call_static_method($blocktypeclass, 'allowed_in_view', $view)) { return false; } if ($copytype == 'nocopy' && !$sameowner) { return false; } $newblock = new BlockInstance(0, array('blocktype' => $this->get('blocktype'), 'title' => $this->get('title'), 'view' => $view->get('id'), 'view_obj' => $view, 'row' => $this->get('row'), 'column' => $this->get('column'), 'order' => $this->get('order'))); if ($sameowner || $copytype == 'reference') { $newblock->set('configdata', $configdata); $newblock->commit(); return true; } $artefactids = get_column('view_artefact', 'artefact', 'block', $this->get('id')); if (!empty($artefactids) && $copytype == 'full') { // Copy artefacts & put the new artefact ids into the new block. // Artefacts may have children (defined using the parent column of the artefact table) and attachments (currently // only for blogposts). If we copy an artefact we must copy all its descendents & attachments too. $descendants = artefact_get_descendants($artefactids); // We need the artefact instance before we can get its attachments $tocopy = array(); $attachmentlists = array(); $embedlists = array(); foreach ($descendants as $d) { if (!isset($artefactcopies[$d])) { $tocopy[$d] = artefact_instance_from_id($d); // Get attachments. $attachmentlists[$d] = $tocopy[$d]->attachment_id_list(); foreach ($attachmentlists[$d] as $a) { if (!isset($artefactcopies[$a]) && !isset($tocopy[$a])) { $tocopy[$a] = artefact_instance_from_id($a); } } // Get embedded file artefacts $embedlists[$d] = $tocopy[$d]->embed_id_list(); foreach ($embedlists[$d] as $a) { if (!isset($artefactcopies[$a]) && !isset($tocopy[$a])) { $tocopy[$a] = artefact_instance_from_id($a); } } } } // Copy all the artefacts we haven't copied yet foreach ($tocopy as $aid => $a) { // Save the id of the original artefact's parent $artefactcopies[$aid] = (object) array('oldid' => $aid, 'oldparent' => $a->get('parent')); if (!empty($attachmentlists[$aid])) { $artefactcopies[$aid]->oldattachments = $attachmentlists[$aid]; } if (!empty($embedlists[$aid])) { $artefactcopies[$aid]->oldembeds = $embedlists[$aid]; } $artefactcopies[$aid]->newid = $a->copy_for_new_owner($view->get('owner'), $view->get('group'), $view->get('institution')); } // Record new artefact ids in the new block if (isset($configdata['artefactid'])) { $configdata['artefactid'] = $artefactcopies[$configdata['artefactid']]->newid; } if (isset($configdata['artefactids'])) { foreach ($configdata['artefactids'] as &$oldid) { $oldid = $artefactcopies[$oldid]->newid; } } } else { $configdata = call_static_method($blocktypeclass, 'rewrite_blockinstance_config', $view, $configdata); } // Rewrite the extra configuration of block $configdata = call_static_method($blocktypeclass, 'rewrite_blockinstance_extra_config', $view, $newblock, $configdata, $artefactcopies); $newblock->set('configdata', $configdata); $newblock->commit(); return true; }
/** * Establishes exactly what views and artefacts are to be exported, and * sets up temporary export directories * * Subclasses can override this if they need to do anything else, but * they must call parent::__construct. * * @param User $user The user to export data for * @param mixed $views can be: * - PluginExport::EXPORT_ALL_VIEWS * - array, containing: * - int - view ids * - stdclass objects - db rows * - View objects * @param mixed $artefacts can be: * - PluginExport::EXPORT_ALL_ARTEFACTS * - PluginExport::EXPORT_ARTEFACTS_FOR_VIEWS * - PluginExport::EXPORT_COLLECTIONS * - array, containing: * - int - artefact ids * - stdclass objects - db rows * - ArtefactType subclasses */ public function __construct(User $user, $views, $artefacts, $progresscallback = null) { if (!is_null($progresscallback)) { if (is_callable($progresscallback)) { $this->progresscallback = $progresscallback; } else { throw new SystemException("The specified progress callback isn't callable"); } } $this->notify_progress_callback(0, 'Starting'); $this->exporttime = time(); $this->user = $user; $userid = $this->user->get('id'); $tmpviews = array(); $tmpartefacts = array(); // Get the list of views to export if ($views == self::EXPORT_ALL_VIEWS) { $tmpviews = get_column_sql('SELECT id FROM {view} WHERE owner = ? ORDER BY id', array($userid)); $this->viewexportmode = $views; } else { if (is_array($views) && $artefacts == self::EXPORT_COLLECTIONS) { $tmpviews = $views; $this->viewexportmode = self::EXPORT_COLLECTIONS; } else { if (is_array($views)) { $tmpviews = $views; $this->viewexportmode = self::EXPORT_LIST_OF_VIEWS; } } } foreach ($tmpviews as $v) { $view = null; if ($v instanceof View) { $view = $v; } else { if (is_object($v)) { $view = new View($v->id, $v); } else { if (is_numeric($v)) { $view = new View($v); } } } if (is_null($view)) { throw new ParamOutOfRangeException("Invalid view {$v}"); } if ($view->get('owner') != $userid) { throw new UserException("User {$userid} does not own view " . $view->get('id')); } $this->views[$view->get('id')] = $view; } // Get the list of artefacts to export if ($artefacts == self::EXPORT_ALL_ARTEFACTS) { $query = 'SELECT id FROM {artefact} WHERE "owner" = ?'; $args = array($userid); if (sizeof($tmpviews)) { $query .= 'UNION SELECT artefact FROM {view_artefact} WHERE "view" IN (SELECT id FROM {view} WHERE "owner" = ?) ORDER BY id'; $args[] = $userid; $this->artefactexportmode = $tmpartefacts = get_column_sql($query, $args); } } else { if ($tmpviews) { $sql = "SELECT DISTINCT va.artefact\n FROM {view_artefact} va\n LEFT JOIN {view} v ON v.id = va.view\n WHERE v.owner = ?\n AND va.view IN ( " . implode(',', array_keys($this->views)) . ")\n ORDER BY va.artefact"; $tmpartefacts = (array) get_column_sql($sql, array($userid)); // Some artefacts are not inside the view, but still need to be exported with it $tmpartefacts = array_unique(array_merge($tmpartefacts, $this->get_view_extra_artefacts())); $tmpartefacts = artefact_get_descendants($tmpartefacts); $tmpartefacts = array_unique(array_merge($tmpartefacts, $this->get_artefact_extra_artefacts($tmpartefacts))); } if ($artefacts == self::EXPORT_ARTEFACTS_FOR_VIEWS) { $this->artefactexportmode = $artefacts; } else { if ($artefacts == self::EXPORT_COLLECTIONS) { $this->artefactexportmode = self::EXPORT_ARTEFACTS_FOR_VIEWS; } else { $tmpartefacts = array_unique(array_merge($tmpartefacts, $artefacts)); $this->artefactexportmode = self::EXPORT_LIST_OF_ARTEFACTS; } } } $typestoplugins = get_records_assoc('artefact_installed_type'); $ids_to_get = array(); foreach ($tmpartefacts as $a) { if ($a instanceof ArtefactType) { continue; } else { if (is_object($a) && isset($a->id)) { $ids_to_get[] = $a->id; } else { if (is_numeric($a)) { $ids_to_get[] = $a; } } } } $artefacts = artefact_instances_from_ids($ids_to_get); foreach ($tmpartefacts as $a) { $artefact = null; if ($a instanceof ArtefactType) { $artefact = $a; } else { if (is_object($a) && isset($a->id)) { $artefact = $artefacts[$a->id]; } else { if (is_numeric($a)) { $artefact = $artefacts[$a]; } } } if (is_null($artefact)) { throw new ParamOutOfRangeException("Invalid artefact {$a}"); } // This check won't work, at the _least_ because at the time of // writing, can_view_artefact does not support normal users viewing // site files. This check is also pretty damn slow. So think twice // before uncommenting it. I presume if you _are_ uncommenting it, // it's because you're trying to isloate a security vulnerability // where a user can export another user's files or something. In // which case you'll be being careful anyway, I hope. //if (!$this->user->can_view_artefact($artefact)) { // throw new SystemException("User $userid does not own artefact " . $artefact->get('id')); //} if ($artefact->exportable()) { $this->artefacts[$artefact->get('id')] = $artefact; } } $this->collections = array(); if ($views === -1) { $collections = FALSE; } else { $collections = get_records_sql_assoc(' SELECT * FROM {collection} WHERE id IN ( SELECT collection FROM {collection_view} WHERE view IN (' . join(',', array_keys($this->views)) . ') )', array()); } if ($collections) { require_once 'collection.php'; foreach ($collections as &$c) { $this->collections[$c->id] = new Collection(0, $c); } } // Now set up the temporary export directories $this->exportdir = get_config('dataroot') . 'export/' . $this->user->get('id') . '/' . $this->exporttime . '/'; if (!check_dir_exists($this->exportdir)) { throw new SystemException("Couldn't create the temporary export directory {$this->exportdir}"); } $this->messages = array(); $this->notify_progress_callback(10, 'Setup'); }