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
  • Class
  • Tree
  • Deprecated
  • Todo
   1: <?php
   2: /**
   3:  * This file contains the the system test class.
   4:  *
   5:  * @package Core
   6:  * @subpackage Backend
   7:  * @version SVN Revision $Rev:$
   8:  *
   9:  * @author Mischa Holz
  10:  * @copyright four for business AG <www.4fb.de>
  11:  * @license http://www.contenido.org/license/LIZENZ.txt
  12:  * @link http://www.4fb.de
  13:  * @link http://www.contenido.org
  14:  */
  15: 
  16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
  17: 
  18: /**
  19:  * Provides functions to test the system integrity
  20:  *
  21:  * @package Core
  22:  * @subpackage Backend
  23:  */
  24: class cSystemtest {
  25: 
  26:     /**
  27:      * The minimal PHP version
  28:      *
  29:      * @var string
  30:      */
  31:     const CON_SETUP_MIN_PHP_VERSION = '5.3';
  32: 
  33:     /**
  34:      * Messages have no influence on the result of the system integrity
  35:      *
  36:      * @var int
  37:      */
  38:     const C_SEVERITY_NONE = 1;
  39: 
  40:     /**
  41:      * Messages are only to inform the user about something.
  42:      *
  43:      * @var int
  44:      */
  45:     const C_SEVERITY_INFO = 2;
  46: 
  47:     /**
  48:      * Messages about settings which aren't correct, but CONTENIDO might work
  49:      * anyway
  50:      *
  51:      * @var int
  52:      */
  53:     const C_SEVERITY_WARNING = 3;
  54: 
  55:     /**
  56:      * Messages about settings which aren't correct.
  57:      * CONTENIDO won't work
  58:      *
  59:      * @var int
  60:      */
  61:     const C_SEVERITY_ERROR = 4;
  62: 
  63:     /**
  64:      * Possible result of cSystemtest::predictCorrectFilePermissions()
  65:      * The filepermissions are okay
  66:      *
  67:      * @var int
  68:      */
  69:     const CON_PREDICT_SUFFICIENT = 1;
  70: 
  71:     /**
  72:      * Possible result of cSystemtest::predictCorrectFilePermissions()
  73:      * The filepermissions are not predictable (we can't figure the server UID)
  74:      *
  75:      * @var int
  76:      */
  77:     const CON_PREDICT_NOTPREDICTABLE = 2;
  78: 
  79:     /**
  80:      * Possible result of cSystemtest::predictCorrectFilePermissions()
  81:      * The filepermissions for the owner have to be changed
  82:      *
  83:      * @var int
  84:      */
  85:     const CON_PREDICT_CHANGEPERM_SAMEOWNER = 3;
  86: 
  87:     /**
  88:      * Possible result of cSystemtest::predictCorrectFilePermissions()
  89:      * The filepermissions for the group have to be changed
  90:      *
  91:      * @var int
  92:      */
  93:     const CON_PREDICT_CHANGEPERM_SAMEGROUP = 4;
  94: 
  95:     /**
  96:      * Possible result of cSystemtest::predictCorrectFilePermissions()
  97:      * The filepermissions for others should be changed
  98:      *
  99:      * @var int
 100:      */
 101:     const CON_PREDICT_CHANGEPERM_OTHERS = 5;
 102: 
 103:     /**
 104:      * Possible result of cSystemtest::predictCorrectFilePermissions()
 105:      * The owner of the file should be changed
 106:      *
 107:      * @var int
 108:      */
 109:     const CON_PREDICT_CHANGEUSER = 6;
 110: 
 111:     /**
 112:      * Possible result of cSystemtest::predictCorrectFilePermissions()
 113:      * The group of the file should be changed
 114:      *
 115:      * @var int
 116:      */
 117:     const CON_PREDICT_CHANGEGROUP = 7;
 118: 
 119:     /**
 120:      * Possible result of cSystemtest::predictCorrectFilePermissions()
 121:      * The filepermissions are unpredictable because Windows
 122:      *
 123:      * @var int
 124:      */
 125:     const CON_PREDICT_WINDOWS = 8;
 126: 
 127:     /**
 128:      * Possible result of cSystemtest::checkOpenBaseDir().
 129:      * No restrictions
 130:      *
 131:      * @var int
 132:      */
 133:     const CON_BASEDIR_NORESTRICTION = 1;
 134: 
 135:     /**
 136:      * Possible result of cSystemtest::checkOpenBaseDir().
 137:      * The Basedir is set to ".". CONTENIDO won't work
 138:      *
 139:      * @var int
 140:      */
 141:     const CON_BASEDIR_DOTRESTRICTION = 2;
 142: 
 143:     /**
 144:      * Possible result of cSystemtest::checkOpenBaseDir().
 145:      * Open basedir is in effect but CONTENIDO works anyway
 146:      *
 147:      * @var int
 148:      */
 149:     const CON_BASEDIR_RESTRICTIONSUFFICIENT = 3;
 150: 
 151:     /**
 152:      * Possible result of cSystemtest::checkOpenBaseDir().
 153:      * Open basedir is in effect and CONTENIDO doesn't work with it
 154:      *
 155:      * @var int
 156:      */
 157:     const CON_BASEDIR_INCOMPATIBLE = 4;
 158: 
 159:     /**
 160:      * Possible result of cSystemtest::isPHPExtensionLoaded()
 161:      * The extension is loaded
 162:      *
 163:      * @var int
 164:      */
 165:     const CON_EXTENSION_AVAILABLE = 1;
 166: 
 167:     /**
 168:      * Possible result of cSystemtest::isPHPExtensionLoaded()
 169:      * The extension is not loaded
 170:      *
 171:      * @var int
 172:      */
 173:     const CON_EXTENSION_UNAVAILABLE = 2;
 174: 
 175:     /**
 176:      * Possible result of cSystemtest::isPHPExtensionLoaded()
 177:      * It was unable to check wether the extension is loaded or not
 178:      *
 179:      * @var int
 180:      */
 181:     const CON_EXTENSION_CANTCHECK = 3;
 182: 
 183:     /**
 184:      * Possible result of cSystemtest::checkImageResizer()
 185:      * GD is available for image resizing
 186:      *
 187:      * @var int
 188:      */
 189:     const CON_IMAGERESIZE_GD = 1;
 190: 
 191:     /**
 192:      * Possible result of cSystemtest::checkImageResizer()
 193:      * ImageMagick is available for image resizing
 194:      *
 195:      * @var int
 196:      */
 197:     const CON_IMAGERESIZE_IMAGEMAGICK = 2;
 198: 
 199:     /**
 200:      * Possible result of cSystemtest::checkImageResizer()
 201:      * It was unable to check which extension is available for image resizing
 202:      *
 203:      * @var int
 204:      */
 205:     const CON_IMAGERESIZE_CANTCHECK = 3;
 206: 
 207:     /**
 208:      * Possible result of cSystemtest::checkImageResizer()
 209:      * No fitting extension is available
 210:      *
 211:      * @var int
 212:      */
 213:     const CON_IMAGERESIZE_NOTHINGAVAILABLE = 4;
 214: 
 215:     /**
 216:      * Possible result of cSystemtest::testMySQL()
 217:      * Everything works fine with the given settings
 218:      *
 219:      * @var int
 220:      */
 221:     const CON_MYSQL_OK = 1;
 222: 
 223:     /**
 224:      * Possible result of cSystemtest::testMySQL()
 225:      * Strict mode is activated.
 226:      * CONTENIDO won't work
 227:      *
 228:      * @var int
 229:      */
 230:     const CON_MYSQL_STRICT_MODE = 2;
 231: 
 232:     /**
 233:      * Possible result of cSystemtest::testMySQL()
 234:      * Strict mode is activated.
 235:      * CONTENIDO won't work
 236:      *
 237:      * @var int
 238:      */
 239:     const CON_MYSQL_CANT_CONNECT = 3;
 240: 
 241:     /**
 242:      * The test results which are stored for display.
 243:      * Every array element is an assoicative array like this:
 244:      * $_messages[$i] = array(
 245:      * "result" => $result, //true or false, success or no success
 246:      * "severity" => $severity, //one of the C_SEVERITY constants
 247:      * "headline" => $headline, //the headline of the message
 248:      * "message" => $message //the message
 249:      * );
 250:      *
 251:      * @var array
 252:      */
 253:     protected $_messages;
 254: 
 255:     /**
 256:      * The stored config array
 257:      *
 258:      * @var array
 259:      */
 260:     protected $_config;
 261: 
 262:     /**
 263:      * Caches the given config array for later use.
 264:      *
 265:      * @param array $config
 266:      *         A config array which should be similar to CONTENIDO's $cfg
 267:      */
 268:     public function __construct($config) {
 269:         $this->_config = $config;
 270:     }
 271: 
 272:     /**
 273:      * Runs all available tests and stores the resuls in the messages array
 274:      *
 275:      * @param bool $testFileSystem [optional]
 276:      *         If this is true the file system checks will be performed too
 277:      *         with standard settings.
 278:      */
 279:     public function runTests($testFileSystem = true) {
 280:         $this->storeResult($this->testPHPVersion(), self::C_SEVERITY_ERROR, sprintf(i18n("PHP Version lower than %s"), self::CON_SETUP_MIN_PHP_VERSION), sprintf(i18n("CONTENIDO requires PHP %s or higher as it uses functionality first introduced with this version. Please update your PHP version."), self::CON_SETUP_MIN_PHP_VERSION), i18n("The PHP version is higher than ") . self::CON_SETUP_MIN_PHP_VERSION);
 281:         $this->storeResult($this->testFileUploadSetting(), self::C_SEVERITY_WARNING, i18n("File uploads disabled"), sprintf(i18n("Your PHP version is not configured for file uploads. You can't upload files using CONTENIDO's file manager unless you configure PHP for file uploads. See %s for more information"), '<a target="_blank" href="http://www.php.net/manual/en/ini.core.php#ini.file-uploads">http://www.php.net/manual/en/ini.core.php#ini.file-uploads</a>'), i18n("PHP file upload is enabled"));
 282:         $this->storeResult($this->testMagicQuotesRuntimeSetting(), self::C_SEVERITY_ERROR, i18n("PHP setting 'magic_quotes_runtime' is turned on"), i18n("The PHP setting 'magic_quotes_runtime' is turned on. CONTENIDO has been developed to comply with magic_quotes_runtime=Off as this is the PHP default setting. You have to change this directive to make CONTENIDO work."), i18n("'magic_quotes_runtime' is turned off"));
 283:         $this->storeResult($this->testMagicQuotesSybaseSetting(), self::C_SEVERITY_ERROR, i18n("PHP Setting 'magic_quotes_sybase' is turned on"), i18n("The PHP Setting 'magic_quotes_sybase' is turned on. CONTENIDO has been developed to comply with magic_quotes_sybase=Off as this is the PHP default setting. You have to change this directive to make CONTENIDO work."), i18n("'magic_quotes_sybase' is turned off"));
 284:         $this->storeResult($this->testMaxExecutionTime(), self::C_SEVERITY_WARNING, i18n("PHP maximum execution time is less than 30 seconds"), i18n("PHP is configured for a maximum execution time of less than 30 seconds. This could cause problems with slow web servers and/or long operations in the backend. Our recommended execution time is 120 seconds on slow web servers, 60 seconds for medium ones and 30 seconds for fast web servers."), i18n("PHP allows execution times longer than 30 seconds"));
 285:         $this->storeResult($this->testZIPArchive(), self::C_SEVERITY_WARNING, i18n("The class ZipArchive could not be found"), i18n("This could cause some problems, but CONTENIDO is able to run without it. You should check your PHP installation."), i18n("The ZipArchive class is enabled"));
 286: 
 287:         $test = $this->checkOpenBasedirCompatibility();
 288:         switch ($test) {
 289:             case self::CON_BASEDIR_NORESTRICTION:
 290:                 $this->storeResult(true, self::C_SEVERITY_ERROR, "", "", i18n("open_basedir directive doesn't enforce any restrictions"));
 291:                 break;
 292:             case self::CON_BASEDIR_DOTRESTRICTION:
 293:                 $this->storeResult(false, self::C_SEVERITY_ERROR, i18n("open_basedir directive set to '.'"), i18n("The directive open_basedir is set to '.' (e.g. current directory). This means that CONTENIDO is unable to access files in a logical upper level in the filesystem. This will cause problems managing the CONTENIDO frontends. Either add the full path of this CONTENIDO installation to the open_basedir directive, or turn it off completely."));
 294:                 break;
 295:             case self::CON_BASEDIR_RESTRICTIONSUFFICIENT:
 296:                 $this->storeResult(false, self::C_SEVERITY_INFO, i18n("open_basedir setting might be insufficient"), i18n("Setup believes that the PHP directive open_basedir is configured sufficient, however, if you encounter errors like 'open_basedir restriction in effect. File <filename> is not within the allowed path(s): <path>', you have to adjust the open_basedir directive"));
 297:                 break;
 298:             case self::CON_BASEDIR_INCOMPATIBLE:
 299:                 $this->storeResult(false, self::C_SEVERITY_ERROR, i18n("open_basedir directive incompatible"), i18n("Setup has checked your PHP open_basedir directive and reckons that it is not sufficient. Please change the directive to include the CONTENIDO installation or turn it off completely."));
 300:                 break;
 301:         }
 302: 
 303:         $this->storeResult($this->testMemoryLimit(), self::C_SEVERITY_WARNING, i18n("PHP memory_limit directive too small"), i18n("The memory_limit directive is set to 32 MB or lower. This might be not enough for CONTENIDO to operate correctly. We recommend to disable this setting completely, as this can cause problems with large CONTENIDO projects."), i18n("Memory limit is either high enough or deactivated"));
 304:         $this->storeResult($this->testPHPSQLSafeMode(), self::C_SEVERITY_ERROR, i18n("PHP sql.safe_mode turned on"), i18n("The PHP directive sql.safe_mode is turned on. This causes problems with the SQL queries issued by CONTENIDO. Please turn that directive off."), i18n("sql.safe_mode is deactivated"));
 305:         $this->storeResult($this->isPHPExtensionLoaded("gd") == self::CON_EXTENSION_AVAILABLE, self::C_SEVERITY_WARNING, i18n("PHP GD-Extension is not loaded"), i18n("The PHP GD-Extension is not loaded. Some third-party modules rely on the GD functionality. If you don't enable the GD extension, you will encounter problems with modules like galleries."), i18n("GD extension loaded"));
 306:         if ($this->isPHPExtensionLoaded("gd") == self::CON_EXTENSION_AVAILABLE) {
 307:             $this->storeResult($this->testGDGIFRead(), self::C_SEVERITY_INFO, i18n("GD-Library GIF read support missing"), i18n("Your GD version doesn't support reading GIF files. This might cause problems with some modules."), i18n("GD is able to read GIFs"));
 308:             $this->storeResult($this->testGDGIFWrite(), self::C_SEVERITY_INFO, i18n("GD-Library GIF write support missing"), i18n("Your GD version doesn't support writing GIF files. This might cause problems with some modules."), i18n("GD is able to write GIFs"));
 309:             $this->storeResult($this->testGDJPEGRead(), self::C_SEVERITY_INFO, i18n("GD-Library JPEG read support missing"), i18n("Your GD version doesn't support reading JPEG files. This might cause problems with some modules."), i18n("GD is able to read JPEGs"));
 310:             $this->storeResult($this->testGDJPEGWrite(), self::C_SEVERITY_INFO, i18n("GD-Library JPEG write support missing"), i18n("Your GD version doesn't support writing JPEG files. This might cause problems with some modules."), i18n("GD is able to write JPEGs"));
 311:             $this->storeResult($this->testGDPNGRead(), self::C_SEVERITY_INFO, i18n("GD-Library PNG read support missing"), i18n("Your GD version doesn't support reading PNG files. This might cause problems with some modules."), i18n("GD is able to read PNGs"));
 312:             $this->storeResult($this->testGDPNGWrite(), self::C_SEVERITY_INFO, i18n("GD-Library PNG write support missing"), i18n("Your GD version doesn't support writing PNG files. This might cause problems with some modules."), i18n("GD is able to write PNGs"));
 313:         }
 314:         $this->storeResult($this->isPHPExtensionLoaded("pcre") == self::CON_EXTENSION_AVAILABLE, self::C_SEVERITY_ERROR, i18n("PHP PCRE Extension is not loaded"), i18n("The PHP PCRE Extension is not loaded. CONTENIDO uses PCRE-functions like preg_repace and preg_match and won't work without the PCRE Extension."), i18n("PCRE extension loaded"));
 315:         $this->storeResult($this->isPHPExtensionLoaded("xml") == self::CON_EXTENSION_AVAILABLE, self::C_SEVERITY_ERROR, i18n("PHP XML Extension is not loaded"), i18n("The PHP XML Extension is not loaded. CONTENIDO won't work without the XML Extension."), i18n("XML extension loaded"));
 316:         $this->storeResult($this->testDOMDocument(), self::C_SEVERITY_ERROR, i18n("Class 'DOMDocument' is not available"), i18n("The class DOMDocument could not be found. Please check your PHP installation and enable the XML extension if necessary. CONTENIDO won't work without it."), i18n("DOMDocument is available"));
 317:         $this->storeResult($this->testXMLParserCreate(), self::C_SEVERITY_ERROR, i18n("Function 'xml_parser_create' is not available"), i18n("The function xml_parser_create could not be found. Please check your PHP installation and enable the XML extension if necessary. CONTENIDO won't work without it."), i18n("xml_parser_create is available"));
 318:         $this->storeResult(class_exists("SimpleXMLElement") && function_exists("dom_import_simplexml"), self::C_SEVERITY_ERROR, i18n("The class SimpleXML is missing"), i18n("The SimpleXML class is missing. Make sure that the extension is installed and activated"), i18n("SimpleXML is available"));
 319:         $this->storeResult($this->isPHPExtensionLoaded("mbstring") == self::CON_EXTENSION_AVAILABLE, self::C_SEVERITY_ERROR, i18n("PHP mbstring extension is not loaded"), i18n("Since version 4.9.4 CONTENIDO requires the mbstring extension to be loaded and activated! Without it CONTENIDO won't work!"), i18n("mbstring extension is loaded"));
 320: 
 321:         $result = $this->checkImageResizer();
 322:         switch ($result) {
 323:             case self::CON_IMAGERESIZE_CANTCHECK:
 324:                 $this->storeResult(false, self::C_SEVERITY_WARNING, i18n("Unable to check for a suitable image resizer"), i18n("Setup has tried to check for a suitable image resizer (which is, for exampl, required for thumbnail creation), but was not able to clearly identify one. If thumbnails won't work, make sure you've got either the GD-extension or ImageMagick available."));
 325:                 break;
 326:             case self::CON_IMAGERESIZE_NOTHINGAVAILABLE:
 327:                 $this->storeResult(false, self::C_SEVERITY_ERROR, i18n("No suitable image resizer available"), i18n("Setup checked your image resizing support, however, it was unable to find a suitable image resizer. Thumbnails won't work correctly or won't be looking good. Install the GD-Extension or ImageMagick"));
 328:                 break;
 329:             case self::CON_IMAGERESIZE_GD:
 330:                 $this->storeResult(true, self::C_SEVERITY_WARNING, "", "", i18n("GD extension is available and usable to handle images"));
 331:                 break;
 332:             case self::CON_IMAGERESIZE_IMAGEMAGICK:
 333:                 $this->storeResult(true, self::C_SEVERITY_WARNING, "", "", i18n("ImageMagick extension is available and usable to handle images"));
 334:                 break;
 335:         }
 336: 
 337:         $this->storeResult($this->testIconv(), self::C_SEVERITY_ERROR, i18n("PHP iconv functions are not available."), i18n("PHP has been compiled with the --without-iconv directive. CONTENIDO won't work without the iconv functions."), i18n("iconv is available"));
 338: 
 339:         $result = $this->testMySQL($this->_config['db']['connection']['host'], $this->_config['db']['connection']['user'], $this->_config['db']['connection']['password']);
 340:         switch ($result) {
 341:             case self::CON_MYSQL_OK:
 342:                 $this->storeResult(true, self::C_SEVERITY_ERROR, "", "", i18n("Database connection works"));
 343:                 break;
 344:             case self::CON_MYSQL_STRICT_MODE:
 345:                 $this->storeResult(false, self::C_SEVERITY_ERROR, i18n('MySQL is running in strict mode'), i18n('MySQL is running in strict mode, CONTENIDO will not work with this mode. Please change your sql_mode!'));
 346:                 break;
 347:             default:
 348:                 $this->storeResult(false, self::C_SEVERITY_ERROR, i18n("MySQL database connect failed"), sprintf(i18n("Setup was unable to connect to the MySQL Server (Server %s, Username %s). Please correct the MySQL data and try again.<br><br>The error message given was: %s"), $this->_config['db']['connection']['host'], $this->_config['db']['connection']['user'], $result));
 349:         }
 350: 
 351:         if ($testFileSystem) {
 352:             $this->storeResult($this->testFilesystem(), self::C_SEVERITY_WARNING, i18n("Permission error"), i18n("CONTENIDO doesn't have the necessary permissions to write all the files it needs. Please check your filesystem permissions."), i18n("Filesystem checks"), i18n("CONTENIDO has all the necessary permissions to read and write files"));
 353:         }
 354:     }
 355: 
 356:     /**
 357:      * Stores a result in the messages array for later display
 358:      *
 359:      * @param bool $result
 360:      *         true for success, false otherwise
 361:      * @param int $severity
 362:      *         One one of the C_SEVERITY constants
 363:      * @param string $errorHeadline [optional]
 364:      *         The headline which will be stored in the case that $result is false
 365:      * @param string $errorMessage [optional]
 366:      *         The message which will be stored in the case that $result is false
 367:      * @param string $successHeadline [optional]
 368:      *         The headline which will be stored in the case that $result is true
 369:      * @param string $successMessage [optional]
 370:      *         The message which will be stored in the case that $result is true
 371:      */
 372:     public function storeResult($result, $severity, $errorHeadline = "", $errorMessage = "", $successHeadline = "", $successMessage = "") {
 373:         if ($result) {
 374:             $this->_messages[] = array(
 375:                 "result" => $result,
 376:                 "severity" => $severity,
 377:                 "headline" => $successHeadline,
 378:                 "message" => $successMessage
 379:             );
 380:         } else {
 381:             $this->_messages[] = array(
 382:                 "result" => $result,
 383:                 "severity" => $severity,
 384:                 "headline" => $errorHeadline,
 385:                 "message" => $errorMessage
 386:             );
 387:         }
 388:     }
 389: 
 390:     /**
 391:      * Returns the message array
 392:      *
 393:      * @see cSystemtest::$_messages
 394:      * @return array
 395:      */
 396:     public function getResults() {
 397:         return $this->_messages;
 398:     }
 399: 
 400:     /**
 401:      * Returns an array with information about the file, especially the file
 402:      * owner
 403:      *
 404:      * The return array looks like this:
 405:      * array(
 406:      * "info" => $info, //'s' for a socket, 'l' for a symbolic link, '-' for a
 407:      * regular file, 'b' "block special", 'd' for a directory, 'c' "character
 408:      * special", 'p' FIFO pipe, 'u' for unkown
 409:      * "type" => $type, //A more descriptive version of $info
 410:      * "owner" => array(
 411:      * "id" => $id, //the owner id
 412:      * "read" => $read, //true if the owner is allowed to read the file
 413:      * "write" => $write //true if the owner is allowed to write the file
 414:      * )
 415:      * "group" => array(
 416:      * "id" => $id, //the owner group
 417:      * "read" => $read, //true if the owner group is allowed to read the file
 418:      * "write" => $write //true if the owner group is allowed to write the file
 419:      * )
 420:      * "others" => array(
 421:      * "read" => $read, //true if others are allowed to read the file
 422:      * "write" => $write //true if others are allowed to write the file
 423:      * )
 424:      * )
 425:      *
 426:      * @param string $sFilename
 427:      *         The path to the file
 428:      * @return bool|array
 429:      *         if the file can't be accessed
 430:      */
 431:     protected function getFileInfo($sFilename) {
 432:         if (!cFileHandler::exists($sFilename)) {
 433:             return false;
 434:         }
 435: 
 436:         $oiFilePermissions = fileperms($sFilename);
 437:         if ($oiFilePermissions === false) {
 438:             return false;
 439:         }
 440: 
 441:         switch (true) {
 442:             case (($oiFilePermissions & 0xC000) == 0xC000):
 443:                 $info = 's';
 444:                 $type = "socket";
 445:                 break;
 446:             case (($oiFilePermissions & 0xA000) == 0xA000):
 447:                 $info = 'l';
 448:                 $type = "symbolic link";
 449:                 break;
 450:             case (($oiFilePermissions & 0x8000) == 0x8000):
 451:                 $info = '-';
 452:                 $type = "regular file";
 453:                 break;
 454:             case (($oiFilePermissions & 0x6000) == 0x6000):
 455:                 $info = 'b';
 456:                 $type = "block special";
 457:                 break;
 458:             case (($oiFilePermissions & 0x4000) == 0x4000):
 459:                 $info = 'd';
 460:                 $type = "directory";
 461:                 break;
 462:             case (($oiFilePermissions & 0x2000) == 0x2000):
 463:                 $info = 'c';
 464:                 $type = "character special";
 465:                 break;
 466:             case (($oiFilePermissions & 0x1000) == 0x1000):
 467:                 $info = 'p';
 468:                 $type = "FIFO pipe";
 469:                 break;
 470:             default:
 471:                 $info = "u";
 472:                 $type = "Unknown";
 473:                 break;
 474:         }
 475: 
 476:         $aFileinfo = array();
 477:         $aFileinfo["info"] = $info;
 478:         $aFileinfo["type"] = $type;
 479:         $aFileinfo["owner"]["read"] = ($oiFilePermissions & 0x0100) ? true : false;
 480:         $aFileinfo["owner"]["write"] = ($oiFilePermissions & 0x0080) ? true : false;
 481:         $aFileinfo["group"]["read"] = ($oiFilePermissions & 0x0020) ? true : false;
 482:         $aFileinfo["group"]["write"] = ($oiFilePermissions & 0x0010) ? true : false;
 483:         $aFileinfo["others"]["read"] = ($oiFilePermissions & 0x0004) ? true : false;
 484:         $aFileinfo["others"]["write"] = ($oiFilePermissions & 0x0002) ? true : false;
 485:         $aFileinfo["owner"]["id"] = fileowner($sFilename);
 486:         $aFileinfo["group"]["id"] = filegroup($sFilename);
 487:         return $aFileinfo;
 488:     }
 489: 
 490:     /**
 491:      * Returns true if the file is writeable
 492:      *
 493:      * @param string $filename
 494:      *         The path to the file
 495:      * @return bool
 496:      */
 497:     protected function canWriteFile($filename) {
 498:         clearstatcache();
 499:         if (is_file($filename)) {
 500:             return is_writable($filename);
 501:         } else {
 502:             return is_writable(dirname($filename));
 503:         }
 504:     }
 505: 
 506:     /**
 507:      * Returns true if the given file is a directory and if it is writeable
 508:      *
 509:      * @param string $dirname
 510:      *         The path to the directory
 511:      * @return bool
 512:      */
 513:     protected function canWriteDir($dirname) {
 514:         clearstatcache();
 515:         return is_dir($dirname) && is_writable($dirname);
 516:     }
 517: 
 518:     /**
 519:      * Returns the current user which runs the PHP interpreter
 520:      *
 521:      * @return number|bool
 522:      *         ID or false if unable to determine the user
 523:      */
 524:     protected function getServerUID() {
 525:         if (function_exists("posix_getuid")) {
 526:             return posix_getuid();
 527:         }
 528: 
 529:         $sFilename = md5(mt_rand()) . ".txt";
 530: 
 531:         if (is_writeable(".")) {
 532:             cFileHandler::create($sFilename, "test");
 533:             $iUserId = fileowner($sFilename);
 534:             cFileHandler::remove($sFilename);
 535: 
 536:             return $iUserId;
 537:         } else {
 538:             if (is_writeable("/tmp/")) {
 539:                 cFileHandler::create("/tmp/" . $sFilename, "w");
 540:                 $iUserId = fileowner("/tmp/" . $sFilename);
 541:                 cFileHandler::remove("/tmp/" . $sFilename);
 542: 
 543:                 return $iUserId;
 544:             }
 545:             return false;
 546:         }
 547:     }
 548: 
 549:     /**
 550:      * Returns the current group which runs the PHP interpreter
 551:      *
 552:      * @return number|bool
 553:      *         ID or false if unable to determine the group
 554:      */
 555:     protected function getServerGID() {
 556:         if (function_exists("posix_getgid")) {
 557:             return posix_getgid();
 558:         }
 559: 
 560:         $sFilename = md5(mt_rand()) . ".txt";
 561: 
 562:         if (is_writeable(".")) {
 563:             cFileHandler::create($sFilename, "test");
 564:             $iUserId = filegroup($sFilename);
 565:             cFileHandler::remove($sFilename);
 566: 
 567:             return $iUserId;
 568:         } else {
 569:             return false;
 570:         }
 571:     }
 572: 
 573:     /**
 574:      * Returns one of the CON_PREDICT suggestions depending on the permissions
 575:      * of the given file
 576:      *
 577:      * @param string $file
 578:      *         The path to the file
 579:      * @return int
 580:      *         CON_PREDICT_*
 581:      */
 582:     protected function predictCorrectFilepermissions($file) {
 583:         // Check if the system is a windows system. If yes, we can't predict
 584:         // anything.
 585:         if ($this->isWindows()) {
 586:             return self::CON_PREDICT_WINDOWS;
 587:         }
 588: 
 589:         // Check if the file is read- and writeable. If yes, we don't need to do
 590:         // any
 591:         // further checks.
 592:         if (is_writable($file) && is_readable($file)) {
 593:             return self::CON_PREDICT_SUFFICIENT;
 594:         }
 595: 
 596:         // If we can't find out the web server UID, we cannot predict the
 597:         // correct
 598:         // mask.
 599:         $iServerUID = $this->getServerUID();
 600:         if ($iServerUID === false) {
 601:             return self::CON_PREDICT_NOTPREDICTABLE;
 602:         }
 603: 
 604:         // If we can't find out the web server GID, we cannot predict the
 605:         // correct
 606:         // mask.
 607:         $iServerGID = $this->getServerGID();
 608:         if ($iServerGID === false) {
 609:             return self::CON_PREDICT_NOTPREDICTABLE;
 610:         }
 611: 
 612:         $aFilePermissions = $this->getFileInfo($file);
 613: 
 614:         if ($this->getSafeModeStatus()) {
 615:             // SAFE-Mode related checks
 616:             if ($iServerUID == $aFilePermissions["owner"]["id"]) {
 617:                 return self::CON_PREDICT_CHANGEPERM_SAMEOWNER;
 618:             }
 619: 
 620:             if ($this->getSafeModeGidStatus()) {
 621:                 // SAFE-Mode GID related checks
 622:                 if ($iServerGID == $aFilePermissions["group"]["id"]) {
 623:                     return self::CON_PREDICT_CHANGEPERM_SAMEGROUP;
 624:                 }
 625: 
 626:                 return self::CON_PREDICT_CHANGEGROUP;
 627:             }
 628:         } else {
 629:             // Regular checks
 630:             if ($iServerUID == $aFilePermissions["owner"]["id"]) {
 631:                 return self::CON_PREDICT_CHANGEPERM_SAMEOWNER;
 632:             }
 633: 
 634:             if ($iServerGID == $aFilePermissions["group"]["id"]) {
 635:                 return self::CON_PREDICT_CHANGEPERM_SAMEGROUP;
 636:             }
 637: 
 638:             return self::CON_PREDICT_CHANGEPERM_OTHERS;
 639:         }
 640:     }
 641: 
 642:     /**
 643:      * Gets a PHP setting with ini_get
 644:      *
 645:      * @param string $setting
 646:      *         A PHP setting
 647:      * @return mixed
 648:      *         The value of the PHP setting or NULL if ini_get is disabled
 649:      */
 650:     protected function getPHPIniSetting($setting) {
 651:         // Avoid errors if ini_get is in the disable_functions directive
 652:         $value = @ini_get($setting);
 653: 
 654:         return $value;
 655:     }
 656: 
 657:     /**
 658:      * Converts a string like "12M" to the correct number of bytes
 659:      *
 660:      * @param string $val
 661:      *         A string in the form of "12K", "12M" or "12G"
 662:      * @return number
 663:      */
 664:     protected function getAsBytes($val) {
 665:         if (strlen($val) == 0) {
 666:             return 0;
 667:         }
 668:         $val = trim($val);
 669:         $last = $val{strlen($val) - 1};
 670:         switch ($last) {
 671:             case 'k':
 672:             case 'K':
 673:                 return (int) $val * 1024;
 674:                 break;
 675:             case 'm':
 676:             case 'M':
 677:                 return (int) $val * 1048576;
 678:                 break;
 679:             case 'g':
 680:             case 'G':
 681:                 return (int) $val * 1048576 * 1024;
 682:                 break;
 683:             default:
 684:                 return $val;
 685:         }
 686:     }
 687: 
 688:     /**
 689:      * Connects to the database with the given settings
 690:      *
 691:      * @param string $host
 692:      *         The database host
 693:      * @param string $username
 694:      *         The database user
 695:      * @param string $password
 696:      *         The database user password
 697:      * @return array
 698:      *         with the cDB object on the first place and a bool on the second
 699:      */
 700:     protected function doMySQLConnect($host, $username, $password) {
 701:         $aOptions = array(
 702:             'connection' => array(
 703:                 'host' => $host,
 704:                 'user' => $username,
 705:                 'password' => $password
 706:             )
 707:         );
 708:         try {
 709:             $db = new cDb($aOptions);
 710:         } catch (cDbException $e) {
 711:             return array(
 712:                 $db,
 713:                 false
 714:             );
 715:         }
 716: 
 717:         if ($db->connect() == 0) {
 718:             return array(
 719:                 $db,
 720:                 false
 721:             );
 722:         } else {
 723:             return array(
 724:                 $db,
 725:                 true
 726:             );
 727:         }
 728:     }
 729: 
 730:     /**
 731:      * Checks if a given extension is loaded.
 732:      *
 733:      * @param string $extension
 734:      *         A PHP extension
 735:      * @return int
 736:      *         Returns one of the CON_EXTENSION constants
 737:      */
 738:     public function isPHPExtensionLoaded($extension) {
 739:         $value = extension_loaded($extension);
 740: 
 741:         if ($value === NULL) {
 742:             return self::CON_EXTENSION_CANTCHECK;
 743:         }
 744: 
 745:         if ($value === true) {
 746:             return self::CON_EXTENSION_AVAILABLE;
 747:         }
 748: 
 749:         if ($value === false) {
 750:             return self::CON_EXTENSION_UNAVAILABLE;
 751:         }
 752:     }
 753: 
 754:     /**
 755:      * Returns true if the interpreter is run on Windows
 756:      *
 757:      * @return bool
 758:      */
 759:     public function isWindows() {
 760:         if (strtolower(substr(PHP_OS, 0, 3)) == "win") {
 761:             return true;
 762:         } else {
 763:             return false;
 764:         }
 765:     }
 766: 
 767:     /**
 768:      * Test PHP function
 769:      *
 770:      * @return bool
 771:      *         true if the test passed and false if not
 772:      */
 773:     public function testPHPVersion() {
 774:         if (version_compare(phpversion(), CON_SETUP_MIN_PHP_VERSION, '>=') == true) {
 775:             return true;
 776:         } else {
 777:             return false;
 778:         }
 779:     }
 780: 
 781:     /**
 782:      *
 783:      * @return bool
 784:      *         true if the test passed and false if not
 785:      */
 786:     public function getSafeModeStatus() {
 787:         if ($this->getPHPIniSetting("safe_mode") == "1") {
 788:             return true;
 789:         } else {
 790:             return false;
 791:         }
 792:     }
 793: 
 794:     /**
 795:      *
 796:      * @return bool
 797:      *         true if the test passed and false if not
 798:      */
 799:     public function getSafeModeGidStatus() {
 800:         if ($this->getPHPIniSetting("safe_mode_gid") == "1") {
 801:             return true;
 802:         } else {
 803:             return false;
 804:         }
 805:     }
 806: 
 807:     /**
 808:      *
 809:      * @return bool
 810:      *         true if the test passed and false if not
 811:      */
 812:     public function testXMLParserCreate() {
 813:         return function_exists("xml_parser_create");
 814:     }
 815: 
 816:     /**
 817:      *
 818:      * @return bool
 819:      *         true if the test passed and false if not
 820:      */
 821:     public function testFileUploadSetting() {
 822:         return $this->getPHPIniSetting('file_uploads');
 823:     }
 824: 
 825:     /**
 826:      *
 827:      * @return bool
 828:      *         true if the test passed and false if not
 829:      */
 830:     public function testMagicQuotesRuntimeSetting() {
 831:         return !$this->getPHPIniSetting('magic_quotes_runtime');
 832:     }
 833: 
 834:     /**
 835:      *
 836:      * @return bool
 837:      *         true if the test passed and false if not
 838:      */
 839:     public function testMagicQuotesSybaseSetting() {
 840:         return !$this->getPHPIniSetting('magic_quotes_sybase');
 841:     }
 842: 
 843:     /**
 844:      *
 845:      * @return bool
 846:      *         true if the test passed and false if not
 847:      */
 848:     public function testMaxExecutionTime() {
 849:         return intval($this->getPHPIniSetting('max_execution_time')) >= 30;
 850:     }
 851: 
 852:     /**
 853:      *
 854:      * @return bool
 855:      *         true if the test passed and false if not
 856:      */
 857:     public function testZIPArchive() {
 858:         return class_exists("ZipArchive");
 859:     }
 860: 
 861:     /**
 862:      *
 863:      * @return bool
 864:      *         true if the test passed and false if not
 865:      */
 866:     public function testMemoryLimit() {
 867:         $memoryLimit = $this->getAsBytes($this->getPHPIniSetting("memory_limit"));
 868:         return ($memoryLimit > 1024 * 1024 * 32) || ($memoryLimit == 0) || ('-1' === $memoryLimit);
 869:     }
 870: 
 871:     /**
 872:      *
 873:      * @return bool
 874:      *         true if the test passed and false if not
 875:      */
 876:     public function testPHPSQLSafeMode() {
 877:         return !$this->getPHPIniSetting('sql.safe_mode');
 878:     }
 879: 
 880:     /**
 881:      *
 882:      * @return bool
 883:      *         true if the test passed and false if not
 884:      */
 885:     public function testDOMDocument() {
 886:         return class_exists("DOMDocument");
 887:     }
 888: 
 889:     /**
 890:      *
 891:      * @param string $ext
 892:      * @return bool
 893:      *         true if the test passed and false if not
 894:      */
 895:     public function testPHPExtension($ext) {
 896:         return $this->isPHPExtensionLoaded($ext) == CON_EXTENSION_AVAILABLE;
 897:     }
 898: 
 899:     /**
 900:      *
 901:      * @return bool
 902:      *         true if the test passed and false if not
 903:      */
 904:     public function testIconv() {
 905:         return function_exists("iconv");
 906:     }
 907: 
 908:     /**
 909:      *
 910:      * @return bool
 911:      *         true if the test passed and false if not
 912:      */
 913:     public function testGDGIFRead() {
 914:         if (($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_AVAILABLE) && ($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_CANTCHECK)) {
 915:             return false;
 916:         }
 917:         return function_exists("imagecreatefromgif");
 918:     }
 919: 
 920:     /**
 921:      *
 922:      * @return bool
 923:      *         true if the test passed and false if not
 924:      */
 925:     public function testGDGIFWrite() {
 926:         if (($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_AVAILABLE) && ($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_CANTCHECK)) {
 927:             return false;
 928:         }
 929:         return function_exists("imagegif");
 930:     }
 931: 
 932:     /**
 933:      *
 934:      * @return bool
 935:      *         true if the test passed and false if not
 936:      */
 937:     public function testGDJPEGRead() {
 938:         if (($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_AVAILABLE) && ($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_CANTCHECK)) {
 939:             return false;
 940:         }
 941:         return function_exists("imagecreatefromjpeg");
 942:     }
 943: 
 944:     /**
 945:      *
 946:      * @return bool
 947:      *         true if the test passed and false if not
 948:      */
 949:     public function testGDJPEGWrite() {
 950:         if (($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_AVAILABLE) && ($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_CANTCHECK)) {
 951:             return false;
 952:         }
 953:         return function_exists("imagejpeg");
 954:     }
 955: 
 956:     /**
 957:      *
 958:      * @return bool
 959:      *         true if the test passed and false if not
 960:      */
 961:     public function testGDPNGRead() {
 962:         if (($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_AVAILABLE) && ($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_CANTCHECK)) {
 963:             return false;
 964:         }
 965:         return function_exists("imagecreatefrompng");
 966:     }
 967: 
 968:     /**
 969:      *
 970:      * @return bool
 971:      *         true if the test passed and false if not
 972:      */
 973:     public function testGDPNGWrite() {
 974:         if (($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_AVAILABLE) && ($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_CANTCHECK)) {
 975:             return false;
 976:         }
 977:         return function_exists("imagepng");
 978:     }
 979: 
 980:     /**
 981:      *
 982:      * @return bool
 983:      *         true if the test passed and false if not
 984:      */
 985:     public function testMySQLExtension() {
 986:         if ($this->isPHPExtensionLoaded("mysql") == self::CON_EXTENSION_AVAILABLE) {
 987:             return true;
 988:         } else {
 989:             return false;
 990:         }
 991:     }
 992: 
 993:     /**
 994:      *
 995:      * @return bool
 996:      *         true if the test passed and false if not
 997:      */
 998:     public function testMySQLiExtension() {
 999:         if ($this->isPHPExtensionLoaded("mysqli") == self::CON_EXTENSION_AVAILABLE) {
1000:             return true;
1001:         } else {
1002:             return false;
1003:         }
1004:     }
1005: 
1006:     /**
1007:      *
1008:      * @param string $host
1009:      * @param string $username
1010:      * @param string $password
1011:      * @return bool
1012:      *         true if the test passed and false if not
1013:      */
1014:     public function testMySQLModeStrict($host, $username, $password) {
1015:         // host, user and password
1016:         $dbCfg = array(
1017:             'connection' => array(
1018:                 'host' => $host,
1019:                 'user' => $username,
1020:                 'password' => $password
1021:             )
1022:         );
1023: 
1024:         $db = new cDb($dbCfg);
1025:         $db->query('SELECT LOWER(@@GLOBAL.sql_mode) AS sql_mode');
1026:         if ($db->nextRecord()) {
1027:             if (strpos($db->f('sql_mode'), 'strict_trans_tables') !== false || strpos($db->f('sql_mode'), 'strict_all_tables') !== false) {
1028:                 return false;
1029:             }
1030:         }
1031:         return true;
1032:     }
1033: 
1034:     /**
1035:      *
1036:      * @param string $host
1037:      * @param string $username
1038:      * @param string $password
1039:      * @return int
1040:      *         1 if the test passed and > 1 if not
1041:      */
1042:     public function testMySQL($host, $username, $password) {
1043:         list($handle, $status) = $this->doMySQLConnect($host, $username, $password);
1044: 
1045:         $errorMessage = "";
1046:         if ($this->testMySQLiExtension() && !$this->testMySQLExtension()) {
1047:             $errorMessage = mysqli_error($handle->getLinkId());
1048:         } else {
1049:             $errorMessage = mysql_error();
1050:         }
1051:         if ($errorMessage != "") {
1052:             return $errorMessage;
1053:         }
1054: 
1055:         if (false === isset($handle) || $handle->getLinkId()->errno == 1045) {
1056:             return self::CON_MYSQL_CANT_CONNECT;
1057:         }
1058: 
1059:         if (!$this->testMySQLModeStrict($host, $username, $password)) {
1060:             return self::CON_MYSQL_STRICT_MODE;
1061:         }
1062: 
1063:         return self::CON_MYSQL_OK;
1064:     }
1065: 
1066:     /**
1067:      *
1068:      * @param bool $testConfig [optional]
1069:      * @param bool $testFrontend [optional]
1070:      * @return bool
1071:      *         true if the test passed and false if not
1072:      */
1073:     public function testFilesystem($testConfig = true, $testFrontend = true) {
1074:         global $cfgClient;
1075: 
1076:         $status = true;
1077: 
1078:         $files = array(
1079:             // check files
1080:             array(
1081:                 'filename' => $this->_config['path']['contenido_logs'] . "errorlog.txt",
1082:                 'severity' => self::C_SEVERITY_WARNING
1083:             ),
1084:             array(
1085:                 'filename' => $this->_config['path']['contenido_logs'] . "setuplog.txt",
1086:                 'severity' => self::C_SEVERITY_WARNING
1087:             ),
1088:             array(
1089:                 'filename' => $this->_config['path']['contenido_cronlog'] . "pseudo-cron.log",
1090:                 'severity' => self::C_SEVERITY_WARNING
1091:             ),
1092:             array(
1093:                 'filename' => $this->_config['path']['contenido_cronlog'] . "session_cleanup.php.job",
1094:                 'severity' => self::C_SEVERITY_WARNING
1095:             ),
1096:             array(
1097:                 'filename' => $this->_config['path']['contenido_cronlog'] . "send_reminder.php.job",
1098:                 'severity' => self::C_SEVERITY_WARNING
1099:             ),
1100:             array(
1101:                 'filename' => $this->_config['path']['contenido_cronlog'] . "optimize_database.php.job",
1102:                 'severity' => self::C_SEVERITY_WARNING
1103:             ),
1104:             array(
1105:                 'filename' => $this->_config['path']['contenido_cronlog'] . "move_old_stats.php.job",
1106:                 'severity' => self::C_SEVERITY_WARNING
1107:             ),
1108:             array(
1109:                 'filename' => $this->_config['path']['contenido_cronlog'] . "move_articles.php.job",
1110:                 'severity' => self::C_SEVERITY_WARNING
1111:             ),
1112:             array(
1113:                 'filename' => $this->_config['path']['contenido_cronlog'] . "linkchecker.php.job",
1114:                 'severity' => self::C_SEVERITY_WARNING
1115:             ),
1116:             array(
1117:                 'filename' => $this->_config['path']['contenido_cronlog'] . "run_newsletter_job.php.job",
1118:                 'severity' => self::C_SEVERITY_WARNING
1119:             ),
1120:             array(
1121:                 'filename' => $this->_config['path']['contenido_cronlog'] . "setfrontenduserstate.php.job",
1122:                 'severity' => self::C_SEVERITY_WARNING
1123:             ),
1124:             array(
1125:                 'filename' => $this->_config['path']['contenido_cronlog'] . "advance_workflow.php.job",
1126:                 'severity' => self::C_SEVERITY_WARNING
1127:             ),
1128:             array(
1129:                 'filename' => $this->_config['path']['contenido_cache'],
1130:                 'severity' => self::C_SEVERITY_WARNING,
1131:                 'dir' => true
1132:             ),
1133:             array(
1134:                 'filename' => $this->_config['path']['contenido_temp'],
1135:                 'severity' => self::C_SEVERITY_WARNING,
1136:                 'dir' => true
1137:             ),
1138:             array(
1139:                 'filename' => $this->_config['path']['contenido_config'] . "config.php",
1140:                 'severity' => self::C_SEVERITY_ERROR,
1141:                 'config' => $testConfig
1142:             )
1143:         );
1144: 
1145:         $frontendFiles = array(
1146:             "cache",
1147:             "cache/code",
1148:             "css",
1149:             "data",
1150:             "data/layouts",
1151:             "data/logs",
1152:             "data/modules",
1153:             "data/version",
1154:             "data/version/css",
1155:             "data/version/js",
1156:             "data/version/layout",
1157:             "data/version/module",
1158:             "data/version/templates",
1159:             "js",
1160:             "templates",
1161:             "upload"
1162:         );
1163: 
1164:         $ret = true;
1165:         foreach ($files as $key => $file) {
1166: 
1167:             $name = $file['filename'];
1168:             $severity = $file['severity'];
1169:             $dir = $file['dir'];
1170:             $frontend = $file['frontend'];
1171:             $config = $file['config'];
1172: 
1173:             if (array_key_exists('frontend', $file) && $frontend != false) {
1174:                 $ret = $this->testSingleFile($name, $severity, $frontend);
1175:             } else if (array_key_exists('config', $file) && $config != false) {
1176:                 $ret = $this->testSingleFile($name, $severity);
1177:             } else if (!array_key_exists('frontend', $file) && !array_key_exists('config', $file)) {
1178:                 $ret = $this->testSingleFile($name, $severity, $config);
1179:             }
1180:             if ($ret == false) {
1181:                 $status = false;
1182:             }
1183:         }
1184: 
1185:         if ($testFrontend) {
1186:             foreach ($cfgClient as $oneClient) {
1187:                 if (!is_array($oneClient)) {
1188:                     continue;
1189:                 }
1190:                 foreach ($frontendFiles as $file) {
1191: 
1192:                     // If data/layouts or data/modules not exist, do not display an error message
1193:                     // Cause: At CONTENIDO 4.8 both folders do not exist
1194:                     if (($file == "data/layouts" || $file == "data/modules") && !is_dir($oneClient["path"]["frontend"] . $file)) {
1195:                         continue;
1196:                     } else {
1197:                         $ret = $this->testSingleFile($oneClient["path"]["frontend"] . $file, self::C_SEVERITY_WARNING, true);
1198:                     }
1199: 
1200:                     if ($ret == false) {
1201:                         $status = false;
1202:                     }
1203:                 }
1204:             }
1205:         }
1206: 
1207:         return $status;
1208:     }
1209: 
1210:     /**
1211:      * Checks a single file or directory wether it is writeable or not
1212:      *
1213:      * @param string $filename
1214:      *         The file
1215:      * @param int $severity
1216:      *         The resulting C_SEVERITY constant should the test fail
1217:      * @param bool $dir [optional]
1218:      *         True if the $filename is a directory
1219:      * @throws Exception
1220:      *         Throws a generic Exception in the event that the permissions are wrong
1221:      * @return bool
1222:      *         Returns true if everything is fine
1223:      */
1224:     protected function testSingleFile($filename, $severity, $dir = false) {
1225:         if (strpos($filename, $this->_config["path"]["frontend"]) === 0) {
1226:             $length = strlen($this->_config["path"]["frontend"]) + 1;
1227:             $shortFilename = substr($filename, $length);
1228:         } else { // for dirs
1229:             $shortFilename = $filename;
1230:         }
1231: 
1232:         if (!$dir) {
1233:             $status = $this->canWriteFile($filename);
1234:         } else {
1235:             $status = $this->canWriteDir($filename);
1236:         }
1237: 
1238:         $title = sprintf(i18n("Can't write %s"), $shortFilename);
1239:         $message = sprintf(i18n("Setup or CONTENIDO can't write to the file %s. Please change the file permissions to correct this problem."), $shortFilename);
1240: 
1241:         if ($status == false) {
1242:             if (cFileHandler::exists($filename)) {
1243:                 $perm = $this->predictCorrectFilepermissions($filename);
1244: 
1245:                 switch ($perm) {
1246:                     case self::CON_PREDICT_WINDOWS:
1247:                         $predictMessage = i18n("Your Server runs Windows. Due to that, Setup can't recommend any file permissions.");
1248:                         break;
1249:                     case self::CON_PREDICT_NOTPREDICTABLE:
1250:                         $predictMessage = sprintf(i18n("Due to a very restrictive environment, an advise is not possible. Ask your system administrator to enable write access to the file %s, especially in environments where ACL (Access Control Lists) are used."), $shortFilename);
1251:                         break;
1252:                     case self::CON_PREDICT_CHANGEPERM_SAMEOWNER:
1253:                         $mfileperms = substr(sprintf("%o", fileperms($filename)), -3);
1254:                         $mfileperms{0} = intval($mfileperms{0}) | 0x6;
1255:                         $predictMessage = sprintf(i18n("Your web server and the owner of your files are identical. You need to enable write access for the owner, e.g. using chmod u+rw %s, setting the file mask to %s or set the owner to allow writing the file."), $shortFilename, $mfileperms);
1256:                         break;
1257:                     case self::CON_PREDICT_CHANGEPERM_SAMEGROUP:
1258:                         $mfileperms = substr(sprintf("%o", fileperms($filename)), -3);
1259:                         $mfileperms{1} = intval($mfileperms{1}) | 0x6;
1260:                         $predictMessage = sprintf(i18n("Your web server's group and the group of your files are identical. You need to enable write access for the group, e.g. using chmod g+rw %s, setting the file mask to %s or set the group to allow writing the file."), $shortFilename, $mfileperms);
1261:                         break;
1262:                     case self::CON_PREDICT_CHANGEPERM_OTHERS:
1263:                         $mfileperms = substr(sprintf("%o", fileperms($filename)), -3);
1264:                         $mfileperms{2} = intval($mfileperms{2}) | 0x6;
1265:                         $predictMessage = sprintf(i18n("Your web server is not equal to the file owner, and is not in the webserver's group. It would be highly insecure to allow world write acess to the files. If you want to install anyways, enable write access for all others, e.g. using chmod o+rw %s, setting the file mask to %s or set the others to allow writing the file."), $shortFilename, $mfileperms);
1266:                         break;
1267:                 }
1268:             } else {
1269:                 $target = dirname($filename);
1270: 
1271:                 $perm = $this->predictCorrectFilepermissions($target);
1272: 
1273:                 switch ($perm) {
1274:                     case self::CON_PREDICT_WINDOWS:
1275:                         $predictMessage = i18n("Your Server runs Windows. Due to that, Setup can't recommend any directory permissions.");
1276:                         break;
1277:                     case self::CON_PREDICT_NOTPREDICTABLE:
1278:                         $predictMessage = sprintf(i18n("Due to a very restrictive environment, an advise is not possible. Ask your system administrator to enable write access to the file or directory %s, especially in environments where ACL (Access Control Lists) are used."), dirname($shortFilename));
1279:                         break;
1280:                     case self::CON_PREDICT_CHANGEPERM_SAMEOWNER:
1281:                         $mfileperms = substr(sprintf("%o", @fileperms($target)), -3);
1282:                         $mfileperms{0} = intval($mfileperms{0}) | 0x6;
1283:                         $predictMessage = sprintf(i18n("Your web server and the owner of your directory are identical. You need to enable write access for the owner, e.g. using chmod u+rw %s, setting the directory mask to %s or set the owner to allow writing the directory."), dirname($shortFilename), $mfileperms);
1284:                         break;
1285:                     case self::CON_PREDICT_CHANGEPERM_SAMEGROUP:
1286:                         $mfileperms = substr(sprintf("%o", @fileperms($target)), -3);
1287:                         $mfileperms{1} = intval($mfileperms{1}) | 0x6;
1288:                         $predictMessage = sprintf(i18n("Your web server's group and the group of your directory are identical. You need to enable write access for the group, e.g. using chmod g+rw %s, setting the directory mask to %s or set the group to allow writing the directory."), dirname($shortFilename), $mfileperms);
1289:                         break;
1290:                     case self::CON_PREDICT_CHANGEPERM_OTHERS:
1291:                         $mfileperms = substr(sprintf("%o", @fileperms($target)), -3);
1292:                         $mfileperms{2} = intval($mfileperms{2}) | 0x6;
1293:                         $predictMessage = sprintf(i18n("Your web server is not equal to the directory owner, and is not in the webserver's group. It would be highly insecure to allow world write acess to the directory. If you want to install anyways, enable write access for all others, e.g. using chmod o+rw %s, setting the directory mask to %s or set the others to allow writing the directory."), dirname($shortFilename), $mfileperms);
1294:                         break;
1295:                 }
1296:             }
1297: 
1298:             $this->storeResult(false, $severity, $title, $message . "<br><br>" . $predictMessage);
1299:             if ($title && $message) {
1300:                 $status = false;
1301:             }
1302:         }
1303: 
1304:         return $status;
1305:     }
1306: 
1307:     /**
1308:      *
1309:      * @return bool
1310:      *         true if the test passed and false if not
1311:      */
1312:     public function testFrontendFolderCreation() {
1313:         $directories = array(
1314:             "cms/cache",
1315:             "cms/cache/code",
1316:             "cms/css",
1317:             "cms/data",
1318:             "cms/data/layouts",
1319:             "cms/data/modules",
1320:             "cms/data/version",
1321:             "cms/data/version/css",
1322:             "cms/data/version/js",
1323:             "cms/data/version/layout",
1324:             "cms/data/version/module",
1325:             "cms/data/version/templates",
1326:             "cms/js",
1327:             "cms/templates",
1328:             "cms/upload"
1329:         );
1330: 
1331:         $ret = true;
1332: 
1333:         foreach ($directories as $dir) {
1334:             if (!cFileHandler::exists("../" . $dir)) {
1335:                 if (!mkdir("../" . $dir)) {
1336:                     $ret = false;
1337:                     $this->storeResult(false, self::C_SEVERITY_WARNING, sprintf(i18n("Could not find or create directory %s"), $dir), i18n("The frontend expects certain directories to exist and it needs to be able to write to these directories."));
1338:                 } else {
1339:                     if (!cFileHandler::chmod("../" . $dir, "777")) {
1340:                         $ret = false;
1341:                         $this->storeResult(false, self::C_SEVERITY_WARNING, sprintf(i18n("Could not find or create directory %s"), $dir), i18n("The frontend expects certain directories to exist and it needs to be able to write to these directories."));
1342:                     }
1343:                 }
1344:             }
1345:         }
1346: 
1347:         return $ret;
1348:     }
1349: 
1350:     /**
1351:      * Checks for the open_basedir directive and returns one of the CON_BASEDIR
1352:      * constants
1353:      *
1354:      * @return int
1355:      */
1356:     public function checkOpenBasedirCompatibility() {
1357:         $value = $this->getPHPIniSetting("open_basedir");
1358: 
1359:         if ($this->isWindows()) {
1360:             $aBasedirEntries = explode(";", $value);
1361:         } else {
1362:             $aBasedirEntries = explode(":", $value);
1363:         }
1364: 
1365:         if (count($aBasedirEntries) == 1 && $aBasedirEntries[0] == $value) {
1366:             return self::CON_BASEDIR_NORESTRICTION;
1367:         }
1368: 
1369:         if (in_array(".", $aBasedirEntries) && count($aBasedirEntries) == 1) {
1370:             return self::CON_BASEDIR_DOTRESTRICTION;
1371:         }
1372: 
1373:         $sCurrentDirectory = getcwd();
1374: 
1375:         foreach ($aBasedirEntries as $entry) {
1376:             if (stristr($sCurrentDirectory, $entry)) {
1377:                 return self::CON_BASEDIR_RESTRICTIONSUFFICIENT;
1378:             }
1379:         }
1380: 
1381:         return self::CON_BASEDIR_INCOMPATIBLE;
1382:     }
1383: 
1384:     /**
1385:      * Checks the available image resizer classes and functions
1386:      *
1387:      * @return int
1388:      *         Returns one of the CON_IMAGERESIZE constants
1389:      */
1390:     public function checkImageResizer() {
1391:         $iGDStatus = $this->isPHPExtensionLoaded('gd');
1392: 
1393:         if ($iGDStatus == self::CON_EXTENSION_AVAILABLE) {
1394:             return self::CON_IMAGERESIZE_GD;
1395:         }
1396: 
1397:         if (function_exists('imagecreate')) {
1398:             return self::CON_IMAGERESIZE_GD;
1399:         }
1400: 
1401:         if(function_exists("checkAndInclude")) {
1402:             checkAndInclude($this->_config['path']['contenido'] . 'includes/functions.api.images.php');
1403:         } else {
1404:             cInclude('includes', 'functions.api.images.php');
1405:         }
1406:         if (capiIsImageMagickAvailable()) {
1407:             return self::CON_IMAGERESIZE_IMAGEMAGICK;
1408:         }
1409: 
1410:         if ($iGDStatus === self::CON_EXTENSION_CANTCHECK) {
1411:             return self::CON_IMAGERESIZE_CANTCHECK;
1412:         } else {
1413:             return self::CON_IMAGERESIZE_NOTHINGAVAILABLE;
1414:         }
1415:     }
1416: 
1417:     /**
1418:      *
1419:      * @param string $setupType
1420:      * @param string $databaseName
1421:      * @param string $databasePrefix
1422:      * @param string $charset [optional]
1423:      * @param string $collation [optional]
1424:      */
1425:     public function checkSetupMysql($setupType, $databaseName, $databasePrefix, $charset = '', $collation = '') {
1426:         switch ($setupType) {
1427:             case "setup":
1428: 
1429:                 $db = getSetupMySQLDBConnection(false);
1430: 
1431:                 // Check if the database exists
1432:                 $status = checkMySQLDatabaseExists($db, $databaseName);
1433: 
1434:                 if ($status) {
1435:                     // Yes, database exists
1436:                     $db = getSetupMySQLDBConnection();
1437:                     $db->connect();
1438: 
1439:                     // Check if data already exists
1440:                     $db->query('SHOW TABLES LIKE "%s_actions"', $databasePrefix);
1441: 
1442:                     if ($db->nextRecord()) {
1443:                         $this->storeResult(false, cSystemtest::C_SEVERITY_ERROR, i18n("MySQL database already exists and seems to be filled", "setup"), sprintf(i18n("Setup checked the database %s and found the table %s. It seems that you already have a CONTENIDO installation in this database. If you want to install anyways, change the database prefix. If you want to upgrade from a previous version, choose 'upgrade' as setup type.", "setup"), $databaseName, sprintf("%s_actions", $databasePrefix)));
1444:                         return;
1445:                     }
1446: 
1447:                     // Check if data already exists
1448:                     $db->query('SHOW TABLES LIKE "%s_test"', $databasePrefix);
1449:                     if ($db->nextRecord()) {
1450:                         $this->storeResult(false, cSystemtest::C_SEVERITY_ERROR, i18n("MySQL test table already exists in the database", "setup"), sprintf(i18n("Setup checked the database %s and found the test table %s. Please remove it before continuing.", "setup"), $databaseName, sprintf("%s_test", $databasePrefix)));
1451:                         return;
1452:                     }
1453: 
1454:                     // Good, table doesn't exist. Check for database permisions
1455:                     $status = checkMySQLTableCreation($db, $databaseName, sprintf("%s_test", $databasePrefix));
1456:                     if (!$status) {
1457:                         $this->storeResult(false, cSystemtest::C_SEVERITY_ERROR, i18n("Unable to create tables in the selected MySQL database", "setup"), sprintf(i18n("Setup tried to create a test table in the database %s and failed. Please assign table creation permissions to the database user you entered, or ask an administrator to do so.", "setup"), $databaseName));
1458:                         return;
1459:                     }
1460: 
1461:                     // Good, we could create a table. Now remove it again
1462:                     $status = checkMySQLDropTable($db, $databaseName, sprintf("%s_test", $databasePrefix));
1463:                     if (!$status) {
1464:                         $this->storeResult(false, cSystemtest::C_SEVERITY_WARNING, i18n("Unable to remove the test table", "setup"), sprintf(i18n("Setup tried to remove the test table %s in the database %s and failed due to insufficient permissions. Please remove the table %s manually.", "setup"), sprintf("%s_test", $databasePrefix), $databaseName, sprintf("%s_test", $databasePrefix)));
1465:                     }
1466:                 } else {
1467:                     $db->connect();
1468:                     // Check if database can be created
1469:                     $status = checkMySQLDatabaseCreation($db, $databaseName, $charset, $collation);
1470:                     if (!$status) {
1471:                         $this->storeResult(false, cSystemtest::C_SEVERITY_ERROR, i18n("Unable to create the database in the MySQL server", "setup"), sprintf(i18n("Setup tried to create a test database and failed. Please assign database creation permissions to the database user you entered, ask an administrator to do so, or create the database manually.", "setup")));
1472:                         return;
1473:                     }
1474: 
1475:                     // Check for database permisions
1476:                     $status = checkMySQLTableCreation($db, $databaseName, sprintf("%s_test", $databasePrefix));
1477:                     if (!$status) {
1478:                         $this->storeResult(false, cSystemtest::C_SEVERITY_ERROR, i18n("Unable to create tables in the selected MySQL database", "setup"), sprintf(i18n("Setup tried to create a test table in the database %s and failed. Please assign table creation permissions to the database user you entered, or ask an administrator to do so.", "setup"), $databaseName));
1479:                         return;
1480:                     }
1481: 
1482:                     // Good, we could create a table. Now remove it again
1483:                     $status = checkMySQLDropTable($db, $databaseName, sprintf("%s_test", $databasePrefix));
1484:                     if (!$status) {
1485:                         $this->storeResult(false, cSystemtest::C_SEVERITY_WARNING, i18n("Unable to remove the test table", "setup"), sprintf(i18n("Setup tried to remove the test table %s in the database %s and failed due to insufficient permissions. Please remove the table %s manually.", "setup"), sprintf("%s_test", $databasePrefix), $databaseName, sprintf("%s_test", $databasePrefix)));
1486:                     }
1487:                 }
1488:                 break;
1489:             case "upgrade":
1490:                 $db = getSetupMySQLDBConnection(false);
1491: 
1492:                 // Check if the database exists
1493:                 $status = checkMySQLDatabaseExists($db, $databaseName);
1494:                 if (!$status) {
1495:                     $this->storeResult(false, cSystemtest::C_SEVERITY_ERROR, i18n("No data found for the upgrade", "setup"), sprintf(i18n("Setup tried to locate the data for the upgrade, however, the database %s doesn't exist. You need to copy your database first before running setup.", "setup"), $databaseName));
1496:                     return;
1497:                 }
1498: 
1499:                 $db = getSetupMySQLDBConnection();
1500: 
1501:                 // Check if data already exists
1502:                 $sql = 'SHOW TABLES LIKE "%s_actions"';
1503:                 $db->query(sprintf($sql, $databasePrefix));
1504:                 if (!$db->nextRecord()) {
1505:                     $this->storeResult(false, cSystemtest::C_SEVERITY_ERROR, i18n("No data found for the upgrade", "setup"), sprintf(i18n("Setup tried to locate the data for the upgrade, however, the database %s contains no tables. You need to copy your database first before running setup.", "setup"), $databaseName));
1506:                     return;
1507:                 }
1508: 
1509:                 break;
1510:         }
1511:     }
1512: 
1513: }
1514: 
CMS CONTENIDO 4.9.8 API documentation generated by ApiGen 2.8.0