Overview

Packages

  • CONTENIDO
  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentRssCreator
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
    • ScriptCookieDirective
  • mpAutoloaderClassMap
  • None
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SearchSolr
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • cAjaxRequest
  • cAutoload
  • cBackend
  • cEffectiveSetting
  • cGuiScrollListAlltranslations
  • cHTMLValidator
  • cMailer
  • cModuleFileTranslation
  • cModuleHandler
  • cModuleSearch
  • cModuleSynchronizer
  • cModuleTemplateHandler
  • CodeMirror
  • cPasswordRequest
  • cPermission
  • cRegistry
  • cSystemPurge
  • cSystemtest
  • cTinymce4Configuration
  • cTinyMCE4Editor
  • cTinyMCEEditor
  • cWYSIWYGEditor
  • FrontendList
  • HtmlParser
  • TODOBackendList
  • TreeItem
  • UploadList
  • UploadSearchResultList

Functions

  • addArtspec
  • addSortImages
  • backToMainArea
  • buildArticleSelect
  • buildCategorySelect
  • buildCategorySelectRights
  • buildHeapTable
  • buildStackString
  • buildTree
  • buildUserOrGroupPermsFromRequest
  • callPluginStore
  • cApiCatGetLevelNode
  • cApiImageCheckCachedImageValidity
  • cApiImageCheckImageEditingPosibility
  • cApiImageGetCacheFileName
  • cApiImageGetTargetDimensions
  • cApiImageIsAnimGif
  • cApiImgScale
  • cApiImgScaleGetMD5CacheFile
  • cApiImgScaleHQ
  • cApiImgScaleImageMagick
  • cApiImgScaleLQ
  • cApiIsImageMagickAvailable
  • cApiStrCleanURLCharacters
  • cApiStrNormalizeLineEndings
  • cApiStrRecodeString
  • cApiStrReplaceDiacritics
  • cApiStrTrimAfterWord
  • cApiStrTrimHard
  • cApiStrTrimSentence
  • cDeprecated
  • cDie
  • cError
  • checkLangInClients
  • checkPathInformation
  • cInclude
  • compareUrlStrings
  • conChangeTemplateForCat
  • conCopyArticle
  • conCopyArtLang
  • conCopyContainerConf
  • conCopyContent
  • conCopyMetaTags
  • conCopyTemplateConfiguration
  • conCreateLocationString
  • conDeeperCategoriesArray
  • conDeleteart
  • conEditArt
  • conEditFirstTime
  • conFetchCategoryTree
  • conFlagOnOffline
  • conGenerateCode
  • conGenerateCodeForAllArts
  • conGenerateCodeForAllArtsInCategory
  • conGenerateCodeForAllartsUsingLayout
  • conGenerateCodeForAllartsUsingMod
  • conGenerateCodeForAllArtsUsingTemplate
  • conGenerateCodeForArtInAllCategories
  • conGenerateCodeForClient
  • conGenerateKeywords
  • conGetAvailableMetaTagTypes
  • conGetCategoryArticleId
  • conGetCategoryAssignments
  • conGetContainerConfiguration
  • conGetContentFromArticle
  • conGetHtmlTranslationTable
  • conGetMetaValue
  • conGetTemplateConfigurationIdForArticle
  • conGetTemplateConfigurationIdForCategory
  • conGetTopmostCat
  • conGetUsedModules
  • conHtmlentities
  • conHtmlEntityDecode
  • conHtmlSpecialChars
  • conIsLocked
  • conLock
  • conLockBulkEditing
  • conMakeArticleIndex
  • conMakeCatOnline
  • conMakeInlineScript
  • conMakeOnline
  • conMakeOnlineBulkEditing
  • conMakePublic
  • conMakeStart
  • conMoveArticles
  • conPhp54Check
  • conRemoveOldCategoryArticle
  • conSaveContentEntry
  • conSetCodeFlag
  • conSetCodeFlagBulkEditing
  • conSetMetaValue
  • conSyncArticle
  • copyRightsForElement
  • createBulkEditingFunction
  • createRandomName
  • createRightsForElement
  • cWarning
  • dbGetColumns
  • dbGetIndexes
  • dbGetPrimaryKeyName
  • dbTableExists
  • dbUpgradeTable
  • defineIfNotDefined
  • deleteArtspec
  • deleteRightsForElement
  • deleteSystemProperty
  • displayDatetime
  • emptyLogFile
  • endAndLogTiming
  • extractNumber
  • generateDisplayFilePath
  • generateJs
  • getAllClientsAndLanguages
  • getArtLang
  • getArtspec
  • getAvailableContentTypes
  • getCanonicalDay
  • getCanonicalMonth
  • getDirectorySize
  • getEffectiveSetting
  • getEffectiveSettingsByType
  • getEncodingByLanguage
  • getFileContents
  • getFileInformation
  • getFileType
  • getGroupOrUserName
  • getIDForArea
  • getJsHelpContext
  • getLanguageNamesByClient
  • getLanguagesByClient
  • getmicrotime
  • getNamedFrame
  • getParam
  • getParentAreaId
  • getSearchResults
  • getStrExpandCollapseButton
  • getSystemProperties
  • getSystemPropertiesByType
  • getSystemProperty
  • getTemplateSelect
  • getUplExpandCollapseButton
  • htmldecode
  • htmlentities_iso88592
  • humanReadableSize
  • includePlugins
  • insertEmptyStrRow
  • ipMatch
  • isAlphanumeric
  • isArchive
  • isArtInMultipleUse
  • isFunctionDisabled
  • isGroup
  • isIPv4
  • isRunningFromWeb
  • isStartArticle
  • isUtf8
  • isValidMail
  • langActivateDeactivateLanguage
  • langDeleteLanguage
  • langEditLanguage
  • langGetTextDirection
  • langNewLanguage
  • langRenameLanguage
  • layDeleteLayout
  • layEditLayout
  • machineReadableSize
  • mailLogBulkEditingFunctions
  • mailLogDecodeAddresses
  • markSubMenuItem
  • mask
  • modDeleteModule
  • modEditModule
  • phpInfoToHtml
  • plugin_include
  • prCreateURLNameLocationString
  • prDeleteCacheFileContent
  • prGetCacheFileContent
  • prResolvePathViaCategoryNames
  • prResolvePathViaURLNames
  • prWriteCacheFileContent
  • putFileContents
  • recursiveCopy
  • removeFileInformation
  • renderBackendBreadcrumb
  • renderLabel
  • renderSelectProperty
  • renderTextProperty
  • saveGroupRights
  • saveRights
  • scanDirectory
  • scanPlugins
  • sendEncodingHeader
  • set_magic_quotes_gpc
  • setArtspecDefault
  • setArtspecOnline
  • setSystemProperty
  • showTree
  • startTiming
  • statCreateLocationString
  • statDisplayTopChooser
  • statDisplayYearlyTopChooser
  • statGetAvailableMonths
  • statGetAvailableYears
  • statResetStatistic
  • statsArchive
  • statsDisplayInfo
  • statsOverviewAll
  • statsOverviewTop
  • statsOverviewTopYear
  • statsOverviewYear
  • strAssignTemplate
  • strBuildSqlValues
  • strCheckTreeForErrors
  • strCopyCategory
  • strCopyTree
  • strDeeperCategoriesArray
  • strDeleteCategory
  • strHasArticles
  • strHasStartArticle
  • strMakePublic
  • strMakeVisible
  • strMoveCatTargetallowed
  • strMoveDownCategory
  • strMoveSubtree
  • strMoveUpCategory
  • strNewCategory
  • strNewTree
  • strNextBackwards
  • strNextDeeper
  • strNextDeeperAll
  • strNextPost
  • strOrderedPostTreeList
  • strRemakeTreeTable
  • strRenameCategory
  • strRenameCategoryAlias
  • strSortPrePost
  • strSyncCategory
  • systemHavePerm
  • tplAutoFillModules
  • tplBrowseLayoutForContainers
  • tplcfgDuplicate
  • tplDeleteTemplate
  • tplDuplicateTemplate
  • tplEditTemplate
  • tplGetContainerDefault
  • tplGetContainerMode
  • tplGetContainerName
  • tplGetContainerNumbersInLayout
  • tplGetContainerTypes
  • tplGetInUsedData
  • tplIsTemplateInUse
  • tplPreparseLayout
  • tplProcessSendContainerConfiguration
  • updateClientCache
  • updateFileInformation
  • uplCreateFriendlyName
  • uplDirectoryListRecursive
  • uplGetDirectoriesToExclude
  • uplGetFileExtension
  • uplGetFileIcon
  • uplGetFileTypeDescription
  • uplGetThumbnail
  • uplHasFiles
  • uplHasSubdirs
  • uplmkdir
  • uplRecursiveDBDirectoryList
  • uplRecursiveDirectoryList
  • uplRenameDirectory
  • uplSearch
  • uplSyncDirectory
  • uplSyncDirectoryDBFS
  • Overview
  • Package
  • Function
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: 
  3: /**
  4:  * This file contains CONTENIDO Image API functions.
  5:  *
  6:  * If you are planning to add a function, please make sure that:
  7:  * 1.) The function is in the correct place
  8:  * 2.) The function is documented
  9:  * 3.) The function makes sense and is generically usable
 10:  *
 11:  * @package Core
 12:  * @subpackage Backend
 13:  * @version SVN Revision $Rev:$
 14:  *
 15:  * @author Timo Hummel
 16:  * @copyright four for business AG <www.4fb.de>
 17:  * @license http://www.contenido.org/license/LIZENZ.txt
 18:  * @link http://www.4fb.de
 19:  * @link http://www.contenido.org
 20:  */
 21: 
 22: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 23: 
 24: /**
 25:  * Returns the MD5 filename used for caching.
 26:  *
 27:  * @param string $sImg
 28:  *         Path to upload image
 29:  * @param int $iMaxX
 30:  *         Maximum image x size
 31:  * @param int $iMaxY
 32:  *         Maximum image y size
 33:  * @param bool $bCrop
 34:  *         Flag to crop image
 35:  * @param bool $bExpand
 36:  *         Flag to expand image
 37:  * @return string
 38:  *         Path to the resulting image
 39:  */
 40: function cApiImgScaleGetMD5CacheFile($sImg, $iMaxX, $iMaxY, $bCrop, $bExpand) {
 41:     if (!cFileHandler::exists($sImg)) {
 42:         return false;
 43:     }
 44: 
 45:     $iFilesize = filesize($sImg);
 46: 
 47:     if (function_exists('md5_file')) {
 48:         $sMD5 = md5(implode('', array(
 49:             $sImg,
 50:             md5_file($sImg),
 51:             $iFilesize,
 52:             $iMaxX,
 53:             $iMaxY,
 54:             $bCrop,
 55:             $bExpand
 56:         )));
 57:     } else {
 58:         $sMD5 = md5(implode('', array(
 59:             $sImg,
 60:             $iFilesize,
 61:             $iMaxX,
 62:             $iMaxY,
 63:             $bCrop,
 64:             $bExpand
 65:         )));
 66:     }
 67: 
 68:     return $sMD5;
 69: }
 70: 
 71: /**
 72:  * Scales (or crops) an image.
 73:  * If scaling, the aspect ratio is maintained.
 74:  *
 75:  * Returns the path to the scaled temporary image.
 76:  *
 77:  * Note that this function does some very poor caching;
 78:  * it calculates an md5 hash out of the image plus the
 79:  * maximum X and Y sizes, and uses that as the file name.
 80:  * If the file is older than 10 minutes, regenerate it.
 81:  *
 82:  * @param string $img
 83:  *         The path to the image (relative to the frontend)
 84:  * @param int $maxX
 85:  *         The maximum size in x-direction
 86:  * @param int $maxY
 87:  *         The maximum size in y-direction
 88:  * @param bool $crop
 89:  *         If true, the image is cropped and not scaled.
 90:  * @param bool $expand
 91:  *         If true, the image is expanded (e.g. really scaled).
 92:  *         If false, the image will only be made smaller.
 93:  * @param int $cacheTime
 94:  *         The number of minutes to cache the image, use 0 for unlimited
 95:  * @param int $quality
 96:  *         The quality of the output file
 97:  * @param bool $keepType
 98:  *         If true and a png file is source, output file is also png
 99:  * @return string
100:  *         url to the resulting image (http://...
101:  */
102: function cApiImgScaleLQ($img, $maxX, $maxY, $crop = false, $expand = false, $cacheTime = 10, $quality = 0, $keepType = false) {
103:     global $cfgClient, $client, $cfg;
104: 
105:     if (!cFileHandler::exists($img)) {
106:         return false;
107:     }
108: 
109:     if ($quality == 0 && isset($cfg['images']['image_quality']['compression_rate'])) {
110:         $quality = (int) $cfg['images']['image_quality']['compression_rate'];
111:     }
112: 
113:     if ($quality == 0) {
114:         $quality = 75;
115:     }
116: 
117:     $filename = $img;
118:     $maxX = (int) $maxX;
119:     $maxY = (int) $maxY;
120:     $cacheTime = (int) $cacheTime;
121:     $quality = (int) $quality;
122: 
123:     if ($quality <= 0 || $quality > 100) {
124:         $quality = 75;
125:     }
126: 
127:     $frontendURL = cRegistry::getFrontendUrl();
128:     $filetype = cFileHandler::getExtension($filename);
129:     $md5 = cApiImgScaleGetMD5CacheFile($img, $maxX, $maxY, $crop, $expand);
130:     $cfileName = cApiImageGetCacheFileName($md5, $filetype, $keepType);
131:     $cacheFile = $cfgClient[$client]['cache']['path'] . $cfileName;
132:     $webFile = $frontendURL . 'cache/' . $cfileName;
133: 
134:     if (cApiImageCheckCachedImageValidity($cacheFile, $cacheTime)) {
135:         return $webFile;
136:     }
137: 
138:     // Get out which file we have
139:     switch (strtolower($filetype)) {
140:         case 'gif':
141:             $function = 'imagecreatefromgif';
142:             break;
143:         case 'png':
144:             $function = 'imagecreatefrompng';
145:             break;
146:         case 'jpg':
147:             $function = 'imagecreatefromjpeg';
148:             break;
149:         case 'jpeg':
150:             $function = 'imagecreatefromjpeg';
151:             break;
152:         default:
153:             return false;
154:     }
155: 
156:     if (function_exists($function)) {
157:         $imageHandle = @$function($filename);
158:     }
159: 
160:     // If we can't open the image, return false
161:     if (!$imageHandle) {
162:         return false;
163:     }
164: 
165:     $x = imagesx($imageHandle);
166:     $y = imagesy($imageHandle);
167: 
168:     list($targetX, $targetY) = cApiImageGetTargetDimensions($x, $y, $maxX, $maxY, $expand);
169: 
170:     // Create the target image with the target size, resize it afterwards.
171:     if ($crop) {
172:         // Create the target image with the max size, crop it afterwards.
173:         $targetImage = imagecreate($maxX, $maxY);
174:         imagecopy($targetImage, $imageHandle, 0, 0, 0, 0, $maxX, $maxY);
175:     } else {
176:         // Create the target image with the target size, resize it afterwards.
177:         $targetImage = imagecreate($targetX, $targetY);
178:         imagecopyresized($targetImage, $imageHandle, 0, 0, 0, 0, $targetX, $targetY, $x, $y);
179:     }
180: 
181:     // Output the file
182:     if ($keepType) {
183:         switch (strtolower($filetype)) {
184:             case 'png':
185:                 imagepng($targetImage, $cacheFile); // no quality option
186:                                                     // available
187:                 break;
188:             case 'gif':
189:                 imagegif($targetImage, $cacheFile); // no quality option
190:                                                     // available
191:                 break;
192:             default:
193:                 imagejpeg($targetImage, $cacheFile, $quality);
194:         }
195:     } else {
196:         imagejpeg($targetImage, $cacheFile, $quality);
197:     }
198: 
199:     return ($webFile);
200: }
201: 
202: /**
203:  * Scales (or crops) an image in high quality.
204:  * If scaling, the aspect ratio is maintained.
205:  *
206:  * Note: GDLib 2.x is required!
207:  * Note: Image cropping calculates center of the image!
208:  *
209:  * Returns the path to the scaled temporary image.
210:  *
211:  * Note that this function does some very poor caching;
212:  * it calculates an md5 hash out of the image plus the
213:  * maximum X and Y sizes, and uses that as the file name.
214:  * If the file is older than the specified cache time, regenerate it.
215:  *
216:  * @param string $img
217:  *         The path to the image (relative to the frontend)
218:  * @param int $maxX
219:  *         The maximum size in x-direction
220:  * @param int $maxY
221:  *         The maximum size in y-direction
222:  * @param bool $crop
223:  *         If true, the image is cropped and not scaled.
224:  * @param bool $expand
225:  *         If true, the image is expanded (e.g. really scaled).
226:  *         If false, the image will only be made smaller.
227:  * @param int $cacheTime
228:  *         The number of minutes to cache the image, use 0 for unlimited
229:  * @param int $quality
230:  *         The quality of the output file
231:  * @param bool $keepType
232:  *         If true and a png file is source, output file is also png
233:  * @return string
234:  *         Url to the resulting image (http://...)
235:  */
236: function cApiImgScaleHQ($img, $maxX, $maxY, $crop = false, $expand = false, $cacheTime = 10, $quality = 0, $keepType = true) {
237:     global $cfgClient, $client, $cfg;
238: 
239:     if (!cFileHandler::exists($img)) {
240:         return false;
241:     }
242: 
243:     if ($quality == 0 && isset($cfg['images']['image_quality']['compression_rate'])) {
244:         $quality = (int) $cfg['images']['image_quality']['compression_rate'];
245:     }
246: 
247:     if ($quality == 0) {
248:         $quality = 75;
249:     }
250: 
251:     $filename = $img;
252:     $maxX = (int) $maxX;
253:     $maxY = (int) $maxY;
254:     $cacheTime = (int) $cacheTime;
255:     $quality = (int) $quality;
256: 
257:     if ($quality <= 0 || $quality > 100) {
258:         $quality = 75;
259:     }
260: 
261:     $frontendURL = cRegistry::getFrontendUrl();
262:     $filetype = cFileHandler::getExtension($filename);
263:     $md5 = cApiImgScaleGetMD5CacheFile($img, $maxX, $maxY, $crop, $expand);
264:     $cfileName = cApiImageGetCacheFileName($md5, $filetype, $keepType);
265:     $cacheFile = $cfgClient[$client]['cache']['path'] . $cfileName;
266:     $webFile = $frontendURL . 'cache/' . $cfileName;
267: 
268:     if (cApiImageCheckCachedImageValidity($cacheFile, $cacheTime)) {
269:         return $webFile;
270:     }
271: 
272:     // Get out which file we have
273:     switch (strtolower($filetype)) {
274:         case 'gif':
275:             $function = 'imagecreatefromgif';
276:             break;
277:         case 'png':
278:             $function = 'imagecreatefrompng';
279:             break;
280:         case 'jpg':
281:             $function = 'imagecreatefromjpeg';
282:             break;
283:         case 'jpeg':
284:             $function = 'imagecreatefromjpeg';
285:             break;
286:         default:
287:             return false;
288:     }
289: 
290:     if (function_exists($function)) {
291:         $imageHandle = @$function($filename);
292:     }
293: 
294:     // If we can't open the image, return false
295:     if (!$imageHandle) {
296:         return false;
297:     }
298: 
299:     $x = imagesx($imageHandle);
300:     $y = imagesy($imageHandle);
301: 
302:     list($targetX, $targetY) = cApiImageGetTargetDimensions($x, $y, $maxX, $maxY, $expand);
303: 
304:     // Create the target image with the target size, resize it afterwards.
305:     if ($crop) {
306:         // Create the target image with the max size, crop it afterwards.
307:         $targetImage = imagecreatetruecolor($maxX, $maxY);
308:         // calculate canter of the image
309:         $srcX = ($x - $maxX) / 2;
310:         $srcY = ($y - $maxY) / 2;
311:         // crop image from center
312:         imagecopy($targetImage, $imageHandle, 0, 0, $srcX, $srcY, $maxX, $maxY);
313:     } else {
314:         // Create the target image with the target size, resize it afterwards.
315:         $targetImage = imagecreatetruecolor($targetX, $targetY);
316: 
317:         // Preserve transparency
318:         if (strtolower($filetype) == 'gif' or strtolower($filetype) == 'png') {
319:             imagecolortransparent($targetImage, imagecolorallocatealpha($targetImage, 0, 0, 0, 127));
320:             imagealphablending($targetImage, false);
321:             imagesavealpha($targetImage, true);
322:         }
323: 
324:         imagecopyresampled($targetImage, $imageHandle, 0, 0, 0, 0, $targetX, $targetY, $x, $y);
325:     }
326: 
327:     // Output the file
328:     if ($keepType) {
329:         switch (strtolower($filetype)) {
330:             case 'png':
331:                 imagepng($targetImage, $cacheFile); // no quality option
332:                                                     // available
333:                 break;
334:             case 'gif':
335:                 imagegif($targetImage, $cacheFile);
336:                 break;
337:             default:
338:                 imagejpeg($targetImage, $cacheFile, $quality);
339:         }
340:     } else {
341:         imagejpeg($targetImage, $cacheFile, $quality);
342:     }
343: 
344:     return $webFile;
345: }
346: 
347: /**
348:  * Scales (or crops) an image using ImageMagick.
349:  * If scaling, the aspect ratio is maintained.
350:  *
351:  * Note: ImageMagick is required!
352:  *
353:  * Returns the path to the scaled temporary image.
354:  *
355:  * Note that this function does some very poor caching;
356:  * it calculates an md5 hash out of the image plus the
357:  * maximum X and Y sizes, and uses that as the file name.
358:  * If the file is older than the specified cache time, regenerate it.
359:  *
360:  * @param string $img
361:  *         The path to the image (relative to the frontend)
362:  * @param int $maxX
363:  *         The maximum size in x-direction
364:  * @param int $maxY
365:  *         The maximum size in y-direction
366:  * @param bool $crop
367:  *         If true, the image is cropped and not scaled.
368:  * @param bool $expand
369:  *         If true, the image is expanded (e.g. really scaled).
370:  *         If false, the image will only be made smaller.
371:  * @param int $cacheTime
372:  *         The number of minutes to cache the image, use 0 for unlimited
373:  * @param int $quality
374:  *         The quality of the output file
375:  * @param bool $keepType
376:  *         If true and a png file is source, output file is also png
377:  * @return string
378:  *         Url to the resulting image (http://...)
379:  */
380: function cApiImgScaleImageMagick($img, $maxX, $maxY, $crop = false, $expand = false, $cacheTime = 10, $quality = 0, $keepType = false) {
381:     global $cfg, $cfgClient, $client;
382: 
383:     if (!cFileHandler::exists($img)) {
384:         return false;
385:     } elseif (isFunctionDisabled('escapeshellarg') || isFunctionDisabled('exec')) {
386:         return false;
387:     }
388: 
389:     if ($quality == 0 && isset($cfg['images']['image_quality']['compression_rate'])) {
390:         $quality = (int) $cfg['images']['image_quality']['compression_rate'];
391:     }
392: 
393:     if ($quality == 0) {
394:         $quality = 75;
395:     }
396: 
397:     $filename = $img;
398:     $maxX = (int) $maxX;
399:     $maxY = (int) $maxY;
400:     $cacheTime = (int) $cacheTime;
401:     $quality = (int) $quality;
402: 
403:     if ($quality <= 0 || $quality > 100) {
404:         $quality = 75;
405:     }
406: 
407:     $frontendURL = cRegistry::getFrontendUrl();
408:     $filetype = cFileHandler::getExtension($filename);
409:     $md5 = cApiImgScaleGetMD5CacheFile($img, $maxX, $maxY, $crop, $expand);
410:     $cfileName = cApiImageGetCacheFileName($md5, $filetype, $keepType);
411:     $cacheFile = $cfgClient[$client]['cache']['path'] . $cfileName;
412:     $webFile = $frontendURL . 'cache/' . $cfileName;
413: 
414:     if (cApiImageCheckCachedImageValidity($cacheFile, $cacheTime)) {
415:         return $webFile;
416:     }
417: 
418:     list($x, $y) = @getimagesize($filename);
419:     if ($x == 0 || $y == 0) {
420:         return false;
421:     }
422: 
423:     list($targetX, $targetY) = cApiImageGetTargetDimensions($x, $y, $maxX, $maxY, $expand);
424: 
425:     // If is animated gif resize first frame
426:     if ($filetype == 'gif') {
427:         if (cApiImageIsAnimGif($filename)) {
428:             $filename .= '[0]';
429:         }
430:     }
431: 
432:     // Try to execute convert
433:     $output = array();
434:     $retVal = 0;
435:     $program = escapeshellarg($cfg['images']['image_magick']['path'] . 'convert');
436:     $source = escapeshellarg($filename);
437:     $destination = escapeshellarg($cacheFile);
438:     if ($crop) {
439:         $cmd = "'{$program}' -gravity center -quality {$quality} -crop {$maxX}x{$maxY}+1+1 '{$source}' '{$destination}'";
440:     } else {
441:         $cmd = "'{$program}' -quality {$quality} -geometry {$targetX}x{$targetY} '{$source}' '{$destination}'";
442:     }
443: 
444:     exec($cmd, $output, $retVal);
445: 
446:     if (!cFileHandler::exists($cacheFile)) {
447:         return false;
448:     } else {
449:         return $webFile;
450:     }
451: }
452: 
453: /**
454:  * Check if gif is animated, uses "identify" of ImageMagick.
455:  *
456:  * @param string $sFile
457:  *         file path
458:  * @return bool
459:  *         True (gif is animated)/ false (single frame gif)
460:  */
461: function cApiImageIsAnimGif($sFile) {
462:     global $cfg;
463: 
464:     if (isFunctionDisabled('escapeshellarg') || isFunctionDisabled('exec')) {
465:         // Function escapeshellarg or exec is disabled
466:         return false;
467:     } elseif ('im' != cApiImageCheckImageEditingPosibility()) {
468:         // ImageMagick ist not available
469:         return false;
470:     }
471: 
472:     $output = array();
473:     $retval = 0;
474:     $program = escapeshellarg($cfg['images']['image_magick']['path'] . 'identify');
475:     $source = escapeshellarg($sFile);
476: 
477:     exec("'{$program}' '{$source}'", $output, $retval);
478: 
479:     if (count($output) == 1) {
480:         return false;
481:     }
482: 
483:     return true;
484: }
485: 
486: /**
487:  * Scales (or crops) an image.
488:  * If scaling, the aspect ratio is maintained.
489:  *
490:  * This function chooses the best method to scale, depending on the system
491:  * environment and/or the parameters.
492:  *
493:  * Returns the path to the scaled temporary image.
494:  *
495:  * Note that this function does some very poor caching;
496:  * it calculates an md5 hash out of the image plus the
497:  * maximum X and Y sizes, and uses that as the file name.
498:  * If the file is older than 10 minutes, regenerate it.
499:  *
500:  * @param string $img
501:  *         The path to the image (relative to the frontend)
502:  * @param int $maxX
503:  *         The maximum size in x-direction
504:  * @param int $maxY
505:  *         The maximum size in y-direction
506:  * @param bool $crop
507:  *         If true, the image is cropped and not scaled.
508:  * @param bool $expand
509:  *         If true, the image is expanded (e.g. really scaled).
510:  *         If false, the image will only be made smaller.
511:  * @param int $cacheTime
512:  *         The number of minutes to cache the image, use 0 for unlimited
513:  * @param bool $wantHQ
514:  *         If true, try to force high quality mode
515:  * @param int $quality
516:  *         The quality of the output file
517:  * @param bool $keepType
518:  *         If true and a png file is source, output file is also png
519:  * @return string
520:  *         Path to the resulting image
521:  */
522: function cApiImgScale($img, $maxX, $maxY, $crop = false, $expand = false, $cacheTime = 10, $wantHQ = false, $quality = 0, $keepType = true) {
523:     global $client, $cfgClient, $cfg;
524: 
525:     $deleteAfter = false;
526: 
527:     if ($quality == 0 && isset($cfg['images']['image_quality']['compression_rate'])) {
528:         $quality = (int) $cfg['images']['image_quality']['compression_rate'];
529:     }
530: 
531:     if ($quality == 0) {
532:         $quality = 75;
533:     }
534: 
535:     $sRelativeImg = str_replace($cfgClient[$client]['upl']['path'], '', $img);
536:     if (cApiDbfs::isDbfs($sRelativeImg)) {
537:         // This check should be faster than a file existance check
538:         $dbfs = new cApiDbfsCollection();
539: 
540:         $file = basename($sRelativeImg);
541: 
542:         $dbfs->writeToFile($sRelativeImg, $cfgClient[$client]['cache']['path'] . $file);
543: 
544:         $img = $cfgClient[$client]['cache']['path'] . $file;
545:         $deleteAfter = true;
546:     } else if (!cFileHandler::exists($img)) {
547:         // Try with upload string
548:         if (cFileHandler::exists($cfgClient[$client]['upl']['path'] . $img) && !is_dir($cfgClient[$client]['upl']['path'] . $img)) {
549:             $img = $cfgClient[$client]['upl']['path'] . $img;
550:         } else {
551:             // No, it's neither in the upload directory nor in the dbfs. return.
552:             return false;
553:         }
554:     }
555: 
556:     $filename = $img;
557:     $filetype = substr($filename, strlen($filename) - 4, 4);
558: 
559:     $mxdAvImgEditingPosibility = cApiImageCheckImageEditingPosibility();
560:     switch ($mxdAvImgEditingPosibility) {
561:         case '1': // gd1
562:             $method = 'gd1';
563:             if (!function_exists('imagecreatefromgif') && $filetype == '.gif') {
564:                 $method = 'failure';
565:             }
566:             break;
567:         case '2': // gd2
568:             $method = 'gd2';
569:             if (!function_exists('imagecreatefromgif') && $filetype == '.gif') {
570:                 $method = 'failure';
571:             }
572:             break;
573:         case 'im': // imagemagick
574:             $method = 'im';
575:             break;
576:         case '0':
577:             $method = 'failure';
578:             break;
579:         default:
580:             $method = 'failure';
581:             break;
582:     }
583: 
584:     switch ($method) {
585:         case 'gd1':
586:             $return = cApiImgScaleLQ($img, $maxX, $maxY, $crop, $expand, $cacheTime, $quality, $keepType);
587:             break;
588:         case 'gd2':
589:             $return = cApiImgScaleHQ($img, $maxX, $maxY, $crop, $expand, $cacheTime, $quality, $keepType);
590:             break;
591:         case 'im':
592:             $return = cApiImgScaleImageMagick($img, $maxX, $maxY, $crop, $expand, $cacheTime, $quality, $keepType);
593:             break;
594:         case 'failure':
595:             $frontendURL = cRegistry::getFrontendUrl();
596:             $return = str_replace(cRegistry::getFrontendPath(), $frontendURL, $img);
597:             break;
598:     }
599: 
600:     if ($deleteAfter == true) {
601:         unlink($img);
602:     }
603: 
604:     return $return;
605: }
606: 
607: /**
608:  * Check possible image editing functionality
609:  *
610:  * @return mixed
611:  *         Information about installed image editing extensions/tools
612:  *         <pre>
613:  *         - 'im' ImageMagick is available and usage is enabled
614:  *         - '2' GD library version 2 is available
615:  *         - '1' GD library version 1 is available
616:  *         - '0' Nothing could detected
617:  *         </pre>
618:  */
619: function cApiImageCheckImageEditingPosibility() {
620:     global $cfg;
621: 
622:     if ($cfg['images']['image_magick']['use']) {
623:         if (cApiIsImageMagickAvailable()) {
624:             return 'im';
625:         }
626:     }
627: 
628:     if (!extension_loaded('gd')) {
629:         return '0';
630:     }
631: 
632:     if (function_exists('gd_info')) {
633:         $sGDVersion = '';
634:         $aGDInformations = gd_info();
635:         if (preg_match('#([0-9\.])+#', $aGDInformations['GD Version'], $sGDVersion)) {
636:             if ($sGDVersion[0] >= '2') {
637:                 return '2';
638:             }
639:             return '1';
640:         }
641:         return '1';
642:     }
643:     return '1';
644: }
645: 
646: /**
647:  * Returns new calculated dimensions of a target image.
648:  *
649:  * @param int $x
650:  * @param int $y
651:  * @param int $maxX
652:  * @param int $maxY
653:  * @param bool $expand
654:  * @return array
655:  *         Index 0 is target X and index 1 is target Y
656:  */
657: function cApiImageGetTargetDimensions($x, $y, $maxX, $maxY, $expand) {
658:     if (($maxX / $x) < ($maxY / $y)) {
659:         $targetY = $y * ($maxX / $x);
660:         $targetX = round($maxX);
661: 
662:         // Force wished height
663:         if ($targetY < $maxY) {
664:             $targetY = ceil($targetY);
665:         } else {
666:             $targetY = floor($targetY);
667:         }
668:     } else {
669:         $targetX = $x * ($maxY / $y);
670:         $targetY = round($maxY);
671: 
672:         // Force wished width
673:         if ($targetX < $maxX) {
674:             $targetX = ceil($targetX);
675:         } else {
676:             $targetX = floor($targetX);
677:         }
678:     }
679: 
680:     if ($expand == false && (($targetX > $x) || ($targetY > $y))) {
681:         $targetX = $x;
682:         $targetY = $y;
683:     }
684: 
685:     $targetX = ($targetX != 0) ? $targetX : 1;
686:     $targetY = ($targetY != 0) ? $targetY : 1;
687: 
688:     return array(
689:         $targetX,
690:         $targetY
691:     );
692: }
693: 
694: /**
695:  * Returns cache file name.
696:  *
697:  * @param string $md5
698:  * @param string $filetype
699:  * @param bool $keepType
700:  * @return string
701:  */
702: function cApiImageGetCacheFileName($md5, $filetype, $keepType) {
703:     // Create the target file names for web and server
704:     if ($keepType) {
705:         // Should we keep the file type?
706:         // Just using switch if someone likes to add other types
707:         switch (strtolower($filetype)) {
708:             case 'png':
709:                 $fileName = $md5 . '.png';
710:                 break;
711:             case 'gif':
712:                 $fileName = $md5 . '.gif';
713:                 break;
714:             default:
715:                 $fileName = $md5 . '.jpg';
716:         }
717:     } else { // No... use .jpg
718:         $fileName = $md5 . '.jpg';
719:     }
720:     return $fileName;
721: }
722: 
723: /**
724:  * Validates cache version of a image.
725:  *
726:  * @param string $cacheFile
727:  * @param int $cacheTime
728:  * @return bool
729:  *         Returns true, if cache file exists and7or is still valid or false
730:  */
731: function cApiImageCheckCachedImageValidity($cacheFile, $cacheTime) {
732:     // Check if the file exists. If it does, check if the file is valid.
733:     if (cFileHandler::exists($cacheFile)) {
734:         if ($cacheTime == 0) {
735:             // Do not check expiration date
736:             return true;
737:         } else if (!function_exists('md5_file')) {
738:             // TODO: Explain why this is still needed ... or remove it
739:             if ((filemtime($cacheFile) + (60 * $cacheTime)) < time()) {
740:                 // Cache time expired, unlink the file
741:                 unlink($cacheFile);
742:             } else {
743:                 // Return the web file name
744:                 return true;
745:             }
746:         } else {
747:             return true;
748:         }
749:     }
750: 
751:     return false;
752: }
753: 
754: /**
755:  * Checks if ImageMagick is available
756:  *
757:  * @return bool
758:  *         true if ImageMagick is available
759:  */
760: function cApiIsImageMagickAvailable() {
761:     global $cfg;
762:     static $imagemagickAvailable = NULL;
763: 
764:     // if the check has already been executed, just return the result
765:     if (is_bool($imagemagickAvailable)) {
766:         return $imagemagickAvailable;
767:     }
768: 
769:     // check, if escapeshellarg or exec function is disabled, we need both
770:     if (isFunctionDisabled('escapeshellarg') || isFunctionDisabled('exec')) {
771:         $imagemagickAvailable = false;
772:         return $imagemagickAvailable;
773:     }
774: 
775:     // otherwise execute the IM check
776:     $output = array();
777:     $retval = 0;
778:     $imPath = $cfg['images']['image_magick']['path'];
779:     $program = escapeshellarg($cfg['images']['image_magick']['path'] . 'convert');
780:     @exec("'{$program}' -version", $output, $retval);
781: 
782:     if (!is_array($output) || count($output) == 0) {
783:         // exec is probably disabled, so we assume IM to be unavailable
784:         $imagemagickAvailable = false;
785:     } else {
786:         // otherwise output contains the output of the command "convert version"
787:         // if IM is available, it contains the string "ImageMagick"
788:         if (strpos($output[0], 'ImageMagick') !== false) {
789:             $imagemagickAvailable = true;
790:         } else {
791:             $imagemagickAvailable = false;
792:         }
793:     }
794: 
795:     return $imagemagickAvailable;
796: }
797: 
CMS CONTENIDO 4.9.8 API documentation generated by ApiGen 2.8.0