array(), 'parts' => array(), ); $orderfields = serendipity_getImageFields(); if (empty($order) || !isset($orderfields[$order])) { $order = 'i.date'; } if (!is_array($filter)) { $filter = array(); } if (empty($ordermode) || ($ordermode != 'DESC' && $ordermode != 'ASC')) { $ordermode = 'DESC'; } if ($order == 'name') { $order = 'realname ' . $ordermode . ', name'; } if ($limit != 0) { $limitsql = serendipity_db_limit_sql(serendipity_db_limit($start, $limit)); } if ($strict_directory) { $cond['parts']['directory'] = " AND i.path = '" . serendipity_db_escape_string($directory) . "'\n"; } elseif (!empty($directory)) { $cond['parts']['directory'] = " AND i.path LIKE '" . serendipity_db_escape_string($directory) . "%'\n"; } if (!empty($filename)) { $cond['parts']['filename'] = " AND (i.name like '%" . serendipity_db_escape_string($filename) . "%' OR i.realname like '%" . serendipity_db_escape_string($filename) . "%')\n"; } if (!is_array($keywords)) { if (!empty($keywords)) { $keywords = explode(';', $keywords); } else { $keywords = array(); } } if (count($keywords) > 0) { $cond['parts']['keywords'] = " AND (mk.property IN ('" . serendipity_db_implode("', '", $keywords, 'string') . "'))\n"; $cond['joinparts']['keywords'] = true; } foreach($filter AS $f => $fval) { if (! (isset($orderfields[$f]) || $f == "fileCategory") || empty($fval)) { continue; } if (is_array($fval)) { if (empty($fval['from']) || empty($fval['to'])) { continue; } if ($orderfields[$f]['type'] == 'date') { $fval['from'] = serendipity_convertToTimestamp(trim($fval['from'])); $fval['to'] = serendipity_convertToTimestamp(trim($fval['to'])); } if (substr($f, 0, 3) === 'bp.') { $realf = substr($f, 3); $cond['parts']['filter'] .= " AND (bp2.property = '$realf' AND bp2.value >= " . (int)$fval['from'] . " AND bp2.value <= " . (int)$fval['to'] . ")\n"; } else { $cond['parts']['filter'] .= " AND ($f >= " . (int)$fval['from'] . " AND $f <= " . (int)$fval['to'] . ")\n"; } } elseif ($f == 'i.authorid') { $cond['parts']['filter'] .= " AND ( (hp.property = 'authorid' AND hp.value = " . (int)$fval . ") OR (i.authorid = " . (int)$fval . ") )\n"; $cond['joinparts']['hiddenproperties'] = true; } elseif ($orderfields[$f]['type'] == 'int') { if (substr($f, 0, 3) === 'bp.') { $realf = substr($f, 3); $cond['parts']['filter'] .= " AND (bp2.property = '$realf' AND bp2.value = '" . serendipity_db_escape_string(trim($fval)) . "')\n"; } else { $cond['parts']['filter'] .= " AND ($f = '" . serendipity_db_escape_string(trim($fval)) . "')\n"; } } elseif ($f == 'fileCategory') { switch ($fval) { case 'image': $cond['parts']['filter'] .= " AND (i.mime LIKE 'image/%')\n"; break; case 'video': $cond['parts']['filter'] .= " AND (i.mime LIKE 'video/%')\n"; break; } } else { if (substr($f, 0, 3) === 'bp.') { $realf = substr($f, 3); $cond['parts']['filter'] .= " AND (bp2.property = '$realf' AND bp2.value LIKE '%" . serendipity_db_escape_string(trim($fval)) . "%')\n"; } else { $cond['parts']['filter'] .= " AND ($f LIKE '%" . serendipity_db_escape_string(trim($fval)) . "%')\n"; } } $cond['joinparts']['filterproperties'] = true; } if (isset($serendipity['authorid']) && !serendipity_checkPermission('adminImagesViewOthers')) { $cond['parts']['authorid'] .= " AND (i.authorid = 0 OR i.authorid = " . (int)$serendipity['authorid'] . ")\n"; } $cond['and'] = 'WHERE 1=1 ' . implode("\n", $cond['parts']); $cond['args'] = func_get_args(); serendipity_plugin_api::hook_event('fetch_images_sql', $cond); serendipity_ACL_SQL($cond, false, 'directory'); if ($cond['joinparts']['keywords']) { $cond['joins'] .= "\n LEFT OUTER JOIN {$serendipity['dbPrefix']}mediaproperties AS mk ON (mk.mediaid = i.id AND mk.property_group = 'base_keyword')\n"; } if (substr($order, 0, 3) === 'bp.') { $cond['orderproperty'] = substr($order, 3); $cond['orderkey'] = 'bp.value'; $order = 'bp.value'; $cond['joinparts']['properties'] = true; } else { $cond['orderkey'] = "''"; } if ($cond['joinparts']['properties']) { $cond['joins'] .= "\n LEFT OUTER JOIN {$serendipity['dbPrefix']}mediaproperties AS bp ON (bp.mediaid = i.id AND bp.property_group = 'base_property' AND bp.property = '{$cond['orderproperty']}')\n"; } if ($cond['joinparts']['filterproperties']) { $cond['joins'] .= "\n LEFT OUTER JOIN {$serendipity['dbPrefix']}mediaproperties AS bp2 ON (bp2.mediaid = i.id AND bp2.property_group = 'base_property')\n"; } if ($cond['joinparts']['hiddenproperties']) { $cond['joins'] .= "\n LEFT OUTER JOIN {$serendipity['dbPrefix']}mediaproperties AS hp ON (hp.mediaid = i.id AND hp.property_group = 'base_hidden')\n"; } if ($serendipity['dbType'] == 'postgres' || $serendipity['dbType'] == 'pdo-postgres') { $cond['group'] = ''; $cond['distinct'] = 'DISTINCT'; } else { $cond['group'] = 'GROUP BY i.id'; $cond['distinct'] = ''; } $basequery = "FROM {$serendipity['dbPrefix']}images AS i LEFT OUTER JOIN {$serendipity['dbPrefix']}authors AS a ON i.authorid = a.authorid {$cond['joins']} {$cond['and']}"; $query = "SELECT {$cond['distinct']} i.id, {$cond[orderkey]} AS orderkey, i.name, i.extension, i.mime, i.size, i.dimensions_width, i.dimensions_height, i.date, i.thumbnail_name, i.authorid, i.path, i.hotlink, i.realname, a.realname AS authorname $basequery {$cond['group']} ORDER BY $order $ordermode $limitsql"; $rs = serendipity_db_query($query, false, 'assoc'); if (!is_array($rs) && $rs !== true && $rs !== 1) { echo '
' . $rs . '
'; return array(); } elseif (!is_array($rs)) { return array(); } $total_query = "SELECT count(i.id) $basequery GROUP BY i.id"; $total_rs = serendipity_db_query($total_query, false, 'num'); if (is_array($total_rs)) { $total = count($total_rs); } return $rs; } /** * Fetch a specific media item from the mediadatabase * * @access public * @param int The ID of an media item * @return array The media info data */ function serendipity_fetchImageFromDatabase($id, $mode = 'read') { global $serendipity; if (is_array($id)) { $cond = array( 'and' => "WHERE i.id IN (" . serendipity_db_implode(',', $id) . ")" ); $single = false; $assocKey = 'id'; $assocVal = false; } else { $cond = array( 'and' => "WHERE i.id = " . (int)$id ); $single = true; $assocKey = false; $assocVal = false; } if ($serendipity['dbType'] == 'postgres' || $serendipity['dbType'] == 'pdo-postgres') { $cond['group'] = ''; $cond['distinct'] = 'DISTINCT'; } else { $cond['group'] = 'GROUP BY i.id'; $cond['distinct'] = ''; } if ($mode != 'discard') { serendipity_ACL_SQL($cond, false, 'directory', $mode); } $rs = serendipity_db_query("SELECT {$cond['distinct']} i.id, i.name, i.extension, i.mime, i.size, i.dimensions_width, i.dimensions_height, i.date, i.thumbnail_name, i.authorid, i.path, i.hotlink, i.realname FROM {$serendipity['dbPrefix']}images AS i {$cond['joins']} {$cond['and']} {$cond['group']}", $single, 'assoc', false, $assocKey, $assocVal); return $rs; } /** * Update a media item * * @access public * @param array An array of columns to update * @param int The ID of an media item to update * @return boolean */ function serendipity_updateImageInDatabase($updates, $id) { global $serendipity; $admin = ''; if (!serendipity_checkPermission('adminImagesAdd')) { $admin = ' AND (authorid = ' . $serendipity['authorid'] . ' OR authorid = 0)'; } $i=0; if (sizeof($updates) > 0) { foreach ($updates AS $k => $v) { $q[] = $k ." = '" . serendipity_db_escape_string($v) . "'"; } serendipity_db_query("UPDATE {$serendipity['dbPrefix']}images SET ". implode($q, ',') ." WHERE id = " . (int)$id . " $admin"); $i++; } return $i; } /** * Delete a media item * * @access public * @param int The ID of a media item to delete * @return */ function serendipity_deleteImage($id) { global $serendipity; $dThumb = array(); $messages = ''; $file = serendipity_fetchImageFromDatabase($id); if (!is_array($file)) { $messages .= sprintf(FILE_NOT_FOUND . '
', $id); //return false; } else { $dFile = $file['path'] . $file['name'] . (empty($file['extension']) ? '' : '.' . $file['extension']); $dThumb = array(array( 'fthumb' => $file['thumbnail_name'] )); if (!serendipity_checkPermission('adminImagesDelete')) { return; } if (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid']) { // A non-admin user may not delete private files from other users. return; } if (!$file['hotlink']) { if (file_exists($serendipity['serendipityPath'] . $serendipity['uploadPath'] . $dFile)) { if (@unlink($serendipity['serendipityPath'] . $serendipity['uploadPath'] . $dFile)) { $messages .= sprintf(DELETE_FILE . '
', $dFile); } else { $messages .= sprintf(DELETE_FILE_FAIL . '
', $dFile); } serendipity_plugin_api::hook_event('backend_media_delete', $dThumb); foreach($dThumb AS $thumb) { $dfnThumb = $file['path'] . $file['name'] . (!empty($thumb['fthumb']) ? '.' . $thumb['fthumb'] : '') . (empty($file['extension']) ? '' : '.' . $file['extension']); $dfThumb = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $dfnThumb; if (@unlink($dfThumb)) { $messages .= sprintf(DELETE_THUMBNAIL . '
', $dfnThumb); } } } else { $messages .= sprintf(FILE_NOT_FOUND . '
', $dFile); } } else { $messages .= sprintf(DELETE_HOTLINK_FILE . '
', $file['name']); } serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}images WHERE id = ". (int)$id); serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}mediaproperties WHERE mediaid = ". (int)$id); } return $messages; } /** * Open a directory and fetch all existing media items * * @access public * @param boolean deprecated * @param int deprecated * @param int deprecated * @param array Array list of found items * @param string sub-directory to investigate [recursive use] * @return array List of media items */ function serendipity_fetchImages($group = false, $start = 0, $end = 20, $images = '', $odir = '') { global $serendipity; // Open directory $basedir = $serendipity['serendipityPath'] . $serendipity['uploadPath']; $images = array(); if ($dir = @opendir($basedir . $odir)) { $aTempArray = array(); while (($file = @readdir($dir)) !== false) { if ($file == '.svn' || $file == 'CVS' || $file == '.htaccess' || $file == '.' || $file == '..') { continue; // 2013/06/05 added exclude .htaccess for ckeditor/kcfinder usage } array_push($aTempArray, $file); } @closedir($dir); sort($aTempArray); foreach($aTempArray AS $f) { if (strpos($f, $serendipity['thumbSuffix']) !== false) { // This is a s9y thumbnail, skip it. continue; } $cdir = ($odir != '' ? $odir . '/' : ''); if (is_dir($basedir . $odir . '/' . $f)) { $temp = serendipity_fetchImages($group, $start, $end, $images, $cdir . $f); foreach($temp AS $tkey => $tval) { array_push($images, $tval); } } else { array_push($images, $cdir . $f); } } } natsort($images); /* BC */ $serendipity['imageList'] = $images; return $images; } /** * Inserts a hotlinked media file * * hotlinks are files that are only linked in your database, and not really stored on your server * * @access public * @param string The filename to hotlink * @param string The URL to hotlink with * @param int The owner of the hotlinked media item * @param int The timestamp of insertion (unix second) * @param string A temporary filename for fetching the file to investigate it * @return int The ID of the inserted media item */ function serendipity_insertHotlinkedImageInDatabase($filename, $url, $authorid = 0, $time = NULL, $tempfile = NULL) { global $serendipity; if (is_null($time)) { $time = time(); } list($filebase, $extension) = serendipity_parseFileName($filename); if ($tempfile && file_exists($tempfile)) { $filesize = @filesize($tempfile); $fdim = @serendipity_getimagesize($tempfile, '', $extension); $width = $fdim[0]; $height = $fdim[1]; $mime = $fdim['mime']; @unlink($tempfile); } $query = sprintf( "INSERT INTO {$serendipity['dbPrefix']}images ( name, date, authorid, extension, mime, size, dimensions_width, dimensions_height, path, hotlink, realname ) VALUES ( '%s', %s, %s, '%s', '%s', %s, %s, %s, '%s', 1, '%s' )", serendipity_db_escape_string($filebase), (int)$time, (int)$authorid, serendipity_db_escape_string($extension), serendipity_db_escape_string($mime), (int)$filesize, (int)$width, (int)$height, serendipity_db_escape_string($url), serendipity_db_escape_string($filename) ); $sql = serendipity_db_query($query); if (is_string($sql)) { echo '' . $query . ''; echo '' . $sql . ''; } $image_id = serendipity_db_insert_id('images', 'id'); if ($image_id > 0) { return $image_id; } return 0; } /** * Insert a media item in the database * * @access public * @param string The filename of the media item * @param string The path to the media item * @param int The owner author of the item * @param int The timestamp of when the media item was inserted * @return int The new media ID */ function serendipity_insertImageInDatabase($filename, $directory, $authorid = 0, $time = NULL, $realname = NULL) { global $serendipity; if (is_null($time)) { $time = time(); } if (is_null($realname)) { $realname = $filename; } $filepath = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $directory . $filename; $filesize = @filesize($filepath); list($filebase, $extension) = serendipity_parseFileName($filename); $thumbpath = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $directory . $filebase . '.'. $serendipity['thumbSuffix'] . (empty($extension) ? '' : '.' . $extension); $thumbnail = (file_exists($thumbpath) ? $serendipity['thumbSuffix'] : ''); $fdim = @serendipity_getimagesize($filepath, '', $extension); $width = $fdim[0]; $height = $fdim[1]; $mime = $fdim['mime']; $query = sprintf( "INSERT INTO {$serendipity['dbPrefix']}images ( name, extension, mime, size, dimensions_width, dimensions_height, thumbnail_name, date, authorid, path, realname ) VALUES ( '%s', '%s', '%s', %s, %s, %s, '%s', %s, %s, '%s', '%s' )", serendipity_db_escape_string($filebase), serendipity_db_escape_string($extension), serendipity_db_escape_string($mime), (int)$filesize, (int)$width, (int)$height, serendipity_db_escape_string($thumbnail), (int)$time, (int)$authorid, serendipity_db_escape_string($directory), serendipity_db_escape_string($realname) ); $sql = serendipity_db_query($query); if (is_string($sql)) { echo '' . $query . ''; echo '' . $sql . ''; } $image_id = serendipity_db_insert_id('images', 'id'); if ($image_id > 0) { return $image_id; } return 0; } /** * Create a thumbnail for an image * * LONG * * @access public * @param string The input image filename * @param string The directory to the image file * @param string The target size of the thumbnail (2-dimensional array width,height) * @param string Name of the thumbnail * @param bool Store thumbnail in temporary place? * @param bool Force enlarging of small images? * @return array The result size of the thumbnail */ function serendipity_makeThumbnail($file, $directory = '', $size = false, $thumbname = false, $is_temporary = false, $force_resize = false) { global $serendipity; if ($size === false) { $size = $serendipity['thumbSize']; } if ($size < 1) { return array(0,0); } if ($thumbname === false) { $thumbname = $serendipity['thumbSuffix']; } $t = serendipity_parseFileName($file); $f = $t[0]; $suf = $t[1]; $infile = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $directory . $file; # echo 'From: ' . $infile . '
'; if ($is_temporary) { $temppath = dirname($thumbname); if (!is_dir($temppath)) { @mkdir($temppath); } $outfile = $thumbname; } else { $outfile = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $directory . $f . '.' . $thumbname . '.' . $suf; } $serendipity['last_outfile'] = $outfile; # echo 'To: ' . $outfile . '
'; $fdim = @serendipity_getimagesize($infile, '', $suf); if (isset($fdim['noimage'])) { $r = array(0, 0); } else { if ($serendipity['magick'] !== true) { if (is_array($size)) { // The caller wants a thumbnail with a specific size $r = serendipity_resize_image_gd($infile, $outfile, $size['width'], $size['height']); } else { // The caller wants a thumbnail constrained in the dimension set by config $calc = serendipity_calculate_aspect_size($fdim[0], $fdim[1], $size, $serendipity['thumbConstraint']); $r = serendipity_resize_image_gd($infile, $outfile, $calc[0], $calc[1]); } } else { if (is_array($size)) { $r = $size; } else { $calc = serendipity_calculate_aspect_size($fdim[0], $fdim[1], $size, $serendipity['thumbConstraint']); $r = array('width' => $calc[0], 'height' => $calc[1]); } $newSize = $r['width'] . 'x' . $r['height']; if ($fdim['mime'] == 'application/pdf') { $cmd = escapeshellcmd($serendipity['convert']) . ' -antialias -flatten -scale '. serendipity_escapeshellarg($newSize) .' '. serendipity_escapeshellarg($infile . '[0]') . ' ' . serendipity_escapeshellarg($outfile . '.png'); } else { if (!$force_resize && serendipity_ini_bool(ini_get('safe_mode')) === false) { $newSize .= '>'; // Tell imagemagick to not enlarge small images, only works if safe_mode is off (safe_mode turns > in to \>) } $cmd = escapeshellcmd($serendipity['convert']) . ' -antialias -resize '. serendipity_escapeshellarg($newSize) .'\! '. serendipity_escapeshellarg($infile) .' '. serendipity_escapeshellarg($outfile); } exec($cmd, $output, $result); if ($result != 0) { echo '
' . sprintf(IMAGICK_EXEC_ERROR, $cmd, $output[0], $result) .'
'; $r = false; // return failure } else { touch($outfile); } unset($output, $result); } } return $r; } /** * Scale an image * * LONG * * @access public * @param int The ID of an image * @param int The target width * @param int The target height * @return true */ function serendipity_scaleImg($id, $width, $height) { global $serendipity; $file = serendipity_fetchImageFromDatabase($id); if (!is_array($file)) { return false; } $admin = ''; if (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid']) { return; } $infile = $outfile = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $file['path'] . $file['name'] . (empty($file['extension']) ? '' : '.' . $file['extension']); if ($serendipity['magick'] !== true) { serendipity_resize_image_gd($infile, $outfile, $width, $height); } else { $cmd = escapeshellcmd($serendipity['convert']) . ' -scale ' . serendipity_escapeshellarg($width . 'x' . $height) . ' ' . serendipity_escapeshellarg($infile) . ' ' . serendipity_escapeshellarg($outfile); exec($cmd, $output, $result); if ( $result != 0 ) { echo '
' . sprintf(IMAGICK_EXEC_ERROR, $cmd, $output[0], $result) .'
'; } unset($output, $result); } serendipity_updateImageInDatabase(array('dimensions_width' => $width, 'dimensions_height' => $height, 'size' => @filesize($outfile)), $id); return true; } /** * Rotate an image * * LONG * * @access public * @param int The ID of an image * @param int Number of degrees to rotate * @return boolean */ function serendipity_rotateImg($id, $degrees) { global $serendipity; $file = serendipity_fetchImageFromDatabase($id); if (!is_array($file)) { return false; } $admin = ''; if (!serendipity_checkPermission('adminImagesMaintainOthers') && $file['authorid'] != '0' && $file['authorid'] != $serendipity['authorid']) { // A non-admin user may not delete private files from other users. return false; } $infile = $outfile = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $file['path'] . $file['name'] . (empty($file['extension']) ? '' : '.' . $file['extension']); $infileThumb = $outfileThumb = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $file['path'] . $file['name'] . (!empty($file['thumbnail_name']) ? '.' . $file['thumbnail_name'] : '') . (empty($file['extension']) ? '' : '.' . $file['extension']); if ($serendipity['magick'] !== true) { serendipity_rotate_image_gd($infile, $outfile, $degrees); serendipity_rotate_image_gd($infileThumb, $outfileThumb, $degrees); } else { /* Why can't we just all agree on the rotation direction? */ $degrees = (360 - $degrees); /* Resize main image */ $cmd = escapeshellcmd($serendipity['convert']) . ' -rotate ' . serendipity_escapeshellarg($degrees) . ' ' . serendipity_escapeshellarg($infile) . ' ' . serendipity_escapeshellarg($outfile); exec($cmd, $output, $result); if ( $result != 0 ) { echo '
' . sprintf(IMAGICK_EXEC_ERROR, $cmd, $output[0], $result) .'
'; } unset($output, $result); /* Resize thumbnail */ $cmd = escapeshellcmd($serendipity['convert']) . ' -rotate ' . serendipity_escapeshellarg($degrees) . ' ' . serendipity_escapeshellarg($infileThumb) . ' ' . serendipity_escapeshellarg($outfileThumb); exec($cmd, $output, $result); if ( $result != 0 ) { echo '
'. sprintf(IMAGICK_EXEC_ERROR, $cmd, $output[0], $result) .'
'; } unset($output, $result); } $fdim = @getimagesize($outfile); serendipity_updateImageInDatabase(array('dimensions_width' => $fdim[0], 'dimensions_height' => $fdim[1]), $id); return true; } /** * Creates thumbnails for all images in the upload dir * * @access public * @return int Number of created thumbnails */ function serendipity_generateThumbs() { global $serendipity; $i=0; $serendipity['imageList'] = serendipity_fetchImagesFromDatabase(0, 0, $total); $msg_printed = false; foreach ($serendipity['imageList'] AS $k => $file) { $is_image = serendipity_isImage($file); if ($is_image && !$file['hotlink']) { $update = false; $filename = $file['path'] . $file['name'] . (empty($file['extension']) ? '' : '.' . $file['extension']); $ffull = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $filename; if (!file_exists($ffull)) { serendipity_deleteImage($file['id']); continue; } if (empty($file['thumbnail_name'])) { $file['thumbnail_name'] = $serendipity['thumbSuffix']; } $oldThumb = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $file['path'] . $file['name'] . '.' . $file['thumbnail_name'] . (empty($file['extension']) ? '' : '.' . $file['extension']); $newThumb = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $file['path'] . $file['name'] . '.' . $serendipity['thumbSuffix'] . (empty($file['extension']) ? '' : '.' . $file['extension']); $sThumb = $file['path'] . $file['name'] . '.' . $serendipity['thumbSuffix'] . (empty($file['extension']) ? '' : '.' . $file['extension']); $fdim = @getimagesize($ffull); if (!file_exists($oldThumb) && !file_exists($newThumb) && ($fdim[0] > $serendipity['thumbSize'] || $fdim[1] > $serendipity['thumbSize'])) { $returnsize = serendipity_makeThumbnail($file['name'] . (empty($file['extension']) ? '' : '.' . $file['extension']), $file['path']); if ($returnsize !== false ) { // Only print the resize message the first time if (!$msg_printed) { printf(RESIZE_BLAHBLAH, THUMBNAIL_SHORT); echo "\n" . '