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:  * @author Mischa Holz
   8:  * @copyright four for business AG <www.4fb.de>
   9:  * @license http://www.contenido.org/license/LIZENZ.txt
  10:  * @link http://www.4fb.de
  11:  * @link http://www.contenido.org
  12:  */
  13: 
  14: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
  15: 
  16: /**
  17:  * Provides functions to test the system integrity
  18:  *
  19:  * @package Core
  20:  * @subpackage Backend
  21:  */
  22: class cSystemtest {
  23: 
  24:     /**
  25:      * The minimal PHP version
  26:      *
  27:      * @var string
  28:      */
  29:     const CON_SETUP_MIN_PHP_VERSION = '5.3';
  30: 
  31:     /**
  32:      * Messages have no influence on the result of the system integrity
  33:      *
  34:      * @var int
  35:      */
  36:     const C_SEVERITY_NONE = 1;
  37: 
  38:     /**
  39:      * Messages are only to inform the user about something.
  40:      *
  41:      * @var int
  42:      */
  43:     const C_SEVERITY_INFO = 2;
  44: 
  45:     /**
  46:      * Messages about settings which aren't correct, but CONTENIDO might work
  47:      * anyway
  48:      *
  49:      * @var int
  50:      */
  51:     const C_SEVERITY_WARNING = 3;
  52: 
  53:     /**
  54:      * Messages about settings which aren't correct.
  55:      * CONTENIDO won't work
  56:      *
  57:      * @var int
  58:      */
  59:     const C_SEVERITY_ERROR = 4;
  60: 
  61:     /**
  62:      * Possible result of cSystemtest::predictCorrectFilePermissions()
  63:      * The filepermissions are okay
  64:      *
  65:      * @var int
  66:      */
  67:     const CON_PREDICT_SUFFICIENT = 1;
  68: 
  69:     /**
  70:      * Possible result of cSystemtest::predictCorrectFilePermissions()
  71:      * The filepermissions are not predictable (we can't figure the server UID)
  72:      *
  73:      * @var int
  74:      */
  75:     const CON_PREDICT_NOTPREDICTABLE = 2;
  76: 
  77:     /**
  78:      * Possible result of cSystemtest::predictCorrectFilePermissions()
  79:      * The filepermissions for the owner have to be changed
  80:      *
  81:      * @var int
  82:      */
  83:     const CON_PREDICT_CHANGEPERM_SAMEOWNER = 3;
  84: 
  85:     /**
  86:      * Possible result of cSystemtest::predictCorrectFilePermissions()
  87:      * The filepermissions for the group have to be changed
  88:      *
  89:      * @var int
  90:      */
  91:     const CON_PREDICT_CHANGEPERM_SAMEGROUP = 4;
  92: 
  93:     /**
  94:      * Possible result of cSystemtest::predictCorrectFilePermissions()
  95:      * The filepermissions for others should be changed
  96:      *
  97:      * @var int
  98:      */
  99:     const CON_PREDICT_CHANGEPERM_OTHERS = 5;
 100: 
 101:     /**
 102:      * Possible result of cSystemtest::predictCorrectFilePermissions()
 103:      * The owner of the file should be changed
 104:      *
 105:      * @var int
 106:      */
 107:     const CON_PREDICT_CHANGEUSER = 6;
 108: 
 109:     /**
 110:      * Possible result of cSystemtest::predictCorrectFilePermissions()
 111:      * The group of the file should be changed
 112:      *
 113:      * @var int
 114:      */
 115:     const CON_PREDICT_CHANGEGROUP = 7;
 116: 
 117:     /**
 118:      * Possible result of cSystemtest::predictCorrectFilePermissions()
 119:      * The filepermissions are unpredictable because Windows
 120:      *
 121:      * @var int
 122:      */
 123:     const CON_PREDICT_WINDOWS = 8;
 124: 
 125:     /**
 126:      * Possible result of cSystemtest::checkOpenBaseDir().
 127:      * No restrictions
 128:      *
 129:      * @var int
 130:      */
 131:     const CON_BASEDIR_NORESTRICTION = 1;
 132: 
 133:     /**
 134:      * Possible result of cSystemtest::checkOpenBaseDir().
 135:      * The Basedir is set to ".". CONTENIDO won't work
 136:      *
 137:      * @var int
 138:      */
 139:     const CON_BASEDIR_DOTRESTRICTION = 2;
 140: 
 141:     /**
 142:      * Possible result of cSystemtest::checkOpenBaseDir().
 143:      * Open basedir is in effect but CONTENIDO works anyway
 144:      *
 145:      * @var int
 146:      */
 147:     const CON_BASEDIR_RESTRICTIONSUFFICIENT = 3;
 148: 
 149:     /**
 150:      * Possible result of cSystemtest::checkOpenBaseDir().
 151:      * Open basedir is in effect and CONTENIDO doesn't work with it
 152:      *
 153:      * @var int
 154:      */
 155:     const CON_BASEDIR_INCOMPATIBLE = 4;
 156: 
 157:     /**
 158:      * Possible result of cSystemtest::isPHPExtensionLoaded()
 159:      * The extension is loaded
 160:      *
 161:      * @var int
 162:      */
 163:     const CON_EXTENSION_AVAILABLE = 1;
 164: 
 165:     /**
 166:      * Possible result of cSystemtest::isPHPExtensionLoaded()
 167:      * The extension is not loaded
 168:      *
 169:      * @var int
 170:      */
 171:     const CON_EXTENSION_UNAVAILABLE = 2;
 172: 
 173:     /**
 174:      * Possible result of cSystemtest::isPHPExtensionLoaded()
 175:      * It was unable to check wether the extension is loaded or not
 176:      *
 177:      * @var int
 178:      */
 179:     const CON_EXTENSION_CANTCHECK = 3;
 180: 
 181:     /**
 182:      * Possible result of cSystemtest::checkImageResizer()
 183:      * GD is available for image resizing
 184:      *
 185:      * @var int
 186:      */
 187:     const CON_IMAGERESIZE_GD = 1;
 188: 
 189:     /**
 190:      * Possible result of cSystemtest::checkImageResizer()
 191:      * ImageMagick is available for image resizing
 192:      *
 193:      * @var int
 194:      */
 195:     const CON_IMAGERESIZE_IMAGEMAGICK = 2;
 196: 
 197:     /**
 198:      * Possible result of cSystemtest::checkImageResizer()
 199:      * It was unable to check which extension is available for image resizing
 200:      *
 201:      * @var int
 202:      */
 203:     const CON_IMAGERESIZE_CANTCHECK = 3;
 204: 
 205:     /**
 206:      * Possible result of cSystemtest::checkImageResizer()
 207:      * No fitting extension is available
 208:      *
 209:      * @var int
 210:      */
 211:     const CON_IMAGERESIZE_NOTHINGAVAILABLE = 4;
 212: 
 213:     /**
 214:      * Possible result of cSystemtest::testMySQL()
 215:      * Everything works fine with the given settings
 216:      *
 217:      * @var int
 218:      */
 219:     const CON_MYSQL_OK = 1;
 220: 
 221:     /**
 222:      * Possible result of cSystemtest::testMySQL()
 223:      * Strict mode is activated.
 224:      * CONTENIDO won't work
 225:      *
 226:      * @var int
 227:      */
 228:     const CON_MYSQL_STRICT_MODE = 2;
 229: 
 230:     /**
 231:      * Possible result of cSystemtest::testMySQL()
 232:      * Strict mode is activated.
 233:      * CONTENIDO won't work
 234:      *
 235:      * @var int
 236:      */
 237:     const CON_MYSQL_CANT_CONNECT = 3;
 238: 
 239:     /**
 240:      * The test results which are stored for display.
 241:      * Every array element is an assoicative array like this:
 242:      * $_messages[$i] = array(
 243:      * "result" => $result, //true or false, success or no success
 244:      * "severity" => $severity, //one of the C_SEVERITY constants
 245:      * "headline" => $headline, //the headline of the message
 246:      * "message" => $message //the message
 247:      * );
 248:      *
 249:      * @var array
 250:      */
 251:     protected $_messages;
 252: 
 253:     /**
 254:      * The stored config array
 255:      *
 256:      * @var array
 257:      */
 258:     protected $_config;
 259: 
 260:     /**
 261:      * Constructor to create an instance of this class.
 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 (cFileHandler::exists($filename)) {
 500:             return cFileHandler::writeable($filename);
 501:         } else {
 502:             return cFileHandler::writeable(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 cDirHandler::exists($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 (cFileHandler::writeable($file) && cFileHandler::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:         } else {
 748:             return self::CON_EXTENSION_UNAVAILABLE;
 749:         }
 750:     }
 751: 
 752:     /**
 753:      * Returns true if the interpreter is run on Windows
 754:      *
 755:      * @return bool
 756:      */
 757:     public function isWindows() {
 758:         if (strtolower(substr(PHP_OS, 0, 3)) == "win") {
 759:             return true;
 760:         } else {
 761:             return false;
 762:         }
 763:     }
 764: 
 765:     /**
 766:      * Test PHP function
 767:      *
 768:      * @return bool
 769:      *         true if the test passed and false if not
 770:      */
 771:     public function testPHPVersion() {
 772:         if (version_compare(phpversion(), CON_SETUP_MIN_PHP_VERSION, '>=') == true) {
 773:             return true;
 774:         } else {
 775:             return false;
 776:         }
 777:     }
 778: 
 779:     /**
 780:      *
 781:      * @return bool
 782:      *         true if the test passed and false if not
 783:      */
 784:     public function getSafeModeStatus() {
 785:         if ($this->getPHPIniSetting("safe_mode") == "1") {
 786:             return true;
 787:         } else {
 788:             return false;
 789:         }
 790:     }
 791: 
 792:     /**
 793:      *
 794:      * @return bool
 795:      *         true if the test passed and false if not
 796:      */
 797:     public function getSafeModeGidStatus() {
 798:         if ($this->getPHPIniSetting("safe_mode_gid") == "1") {
 799:             return true;
 800:         } else {
 801:             return false;
 802:         }
 803:     }
 804: 
 805:     /**
 806:      *
 807:      * @return bool
 808:      *         true if the test passed and false if not
 809:      */
 810:     public function testXMLParserCreate() {
 811:         return function_exists("xml_parser_create");
 812:     }
 813: 
 814:     /**
 815:      *
 816:      * @return bool
 817:      *         true if the test passed and false if not
 818:      */
 819:     public function testFileUploadSetting() {
 820:         return $this->getPHPIniSetting('file_uploads');
 821:     }
 822: 
 823:     /**
 824:      *
 825:      * @return bool
 826:      *         true if the test passed and false if not
 827:      */
 828:     public function testMagicQuotesRuntimeSetting() {
 829:         return !$this->getPHPIniSetting('magic_quotes_runtime');
 830:     }
 831: 
 832:     /**
 833:      *
 834:      * @return bool
 835:      *         true if the test passed and false if not
 836:      */
 837:     public function testMagicQuotesSybaseSetting() {
 838:         return !$this->getPHPIniSetting('magic_quotes_sybase');
 839:     }
 840: 
 841:     /**
 842:      *
 843:      * @return bool
 844:      *         true if the test passed and false if not
 845:      */
 846:     public function testMaxExecutionTime() {
 847:         return (intval($this->getPHPIniSetting('max_execution_time') == 0) || (intval($this->getPHPIniSetting('max_execution_time')) >= 30));
 848:     }
 849: 
 850:     /**
 851:      *
 852:      * @return bool
 853:      *         true if the test passed and false if not
 854:      */
 855:     public function testZIPArchive() {
 856:         return class_exists("ZipArchive");
 857:     }
 858: 
 859:     /**
 860:      *
 861:      * @return bool
 862:      *         true if the test passed and false if not
 863:      */
 864:     public function testMemoryLimit() {
 865:         $memoryLimit = $this->getAsBytes($this->getPHPIniSetting("memory_limit"));
 866:         return ($memoryLimit > 1024 * 1024 * 32) || ($memoryLimit == 0) || ('-1' === $memoryLimit);
 867:     }
 868: 
 869:     /**
 870:      *
 871:      * @return bool
 872:      *         true if the test passed and false if not
 873:      */
 874:     public function testPHPSQLSafeMode() {
 875:         return !$this->getPHPIniSetting('sql.safe_mode');
 876:     }
 877: 
 878:     /**
 879:      *
 880:      * @return bool
 881:      *         true if the test passed and false if not
 882:      */
 883:     public function testDOMDocument() {
 884:         return class_exists("DOMDocument");
 885:     }
 886: 
 887:     /**
 888:      *
 889:      * @param string $ext
 890:      * @return bool
 891:      *         true if the test passed and false if not
 892:      */
 893:     public function testPHPExtension($ext) {
 894:         return $this->isPHPExtensionLoaded($ext) == CON_EXTENSION_AVAILABLE;
 895:     }
 896: 
 897:     /**
 898:      *
 899:      * @return bool
 900:      *         true if the test passed and false if not
 901:      */
 902:     public function testIconv() {
 903:         return function_exists("iconv");
 904:     }
 905: 
 906:     /**
 907:      *
 908:      * @return bool
 909:      *         true if the test passed and false if not
 910:      */
 911:     public function testGDGIFRead() {
 912:         if (($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_AVAILABLE) && ($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_CANTCHECK)) {
 913:             return false;
 914:         }
 915:         return function_exists("imagecreatefromgif");
 916:     }
 917: 
 918:     /**
 919:      *
 920:      * @return bool
 921:      *         true if the test passed and false if not
 922:      */
 923:     public function testGDGIFWrite() {
 924:         if (($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_AVAILABLE) && ($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_CANTCHECK)) {
 925:             return false;
 926:         }
 927:         return function_exists("imagegif");
 928:     }
 929: 
 930:     /**
 931:      *
 932:      * @return bool
 933:      *         true if the test passed and false if not
 934:      */
 935:     public function testGDJPEGRead() {
 936:         if (($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_AVAILABLE) && ($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_CANTCHECK)) {
 937:             return false;
 938:         }
 939:         return function_exists("imagecreatefromjpeg");
 940:     }
 941: 
 942:     /**
 943:      *
 944:      * @return bool
 945:      *         true if the test passed and false if not
 946:      */
 947:     public function testGDJPEGWrite() {
 948:         if (($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_AVAILABLE) && ($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_CANTCHECK)) {
 949:             return false;
 950:         }
 951:         return function_exists("imagejpeg");
 952:     }
 953: 
 954:     /**
 955:      *
 956:      * @return bool
 957:      *         true if the test passed and false if not
 958:      */
 959:     public function testGDPNGRead() {
 960:         if (($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_AVAILABLE) && ($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_CANTCHECK)) {
 961:             return false;
 962:         }
 963:         return function_exists("imagecreatefrompng");
 964:     }
 965: 
 966:     /**
 967:      *
 968:      * @return bool
 969:      *         true if the test passed and false if not
 970:      */
 971:     public function testGDPNGWrite() {
 972:         if (($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_AVAILABLE) && ($this->isPHPExtensionLoaded('gd') != self::CON_EXTENSION_CANTCHECK)) {
 973:             return false;
 974:         }
 975:         return function_exists("imagepng");
 976:     }
 977: 
 978:     /**
 979:      *
 980:      * @return bool
 981:      *         true if the test passed and false if not
 982:      */
 983:     public function testMySQLExtension() {
 984:         if ($this->isPHPExtensionLoaded("mysql") == self::CON_EXTENSION_AVAILABLE) {
 985:             return true;
 986:         } else {
 987:             return false;
 988:         }
 989:     }
 990: 
 991:     /**
 992:      *
 993:      * @return bool
 994:      *         true if the test passed and false if not
 995:      */
 996:     public function testMySQLiExtension() {
 997:         if ($this->isPHPExtensionLoaded("mysqli") == self::CON_EXTENSION_AVAILABLE) {
 998:             return true;
 999:         } else {
1000:             return false;
1001:         }
1002:     }
1003: 
1004:     /**
1005:      *
1006:      * @param string $host
1007:      * @param string $username
1008:      * @param string $password
1009:      * @return bool
1010:      *         true if the test passed and false if not
1011:      */
1012:     public function testMySQLModeStrict($host, $username, $password) {
1013:         // host, user and password
1014:         $dbCfg = array(
1015:             'connection' => array(
1016:                 'host' => $host,
1017:                 'user' => $username,
1018:                 'password' => $password
1019:             )
1020:         );
1021: 
1022:         $db = new cDb($dbCfg);
1023:         $db->query('SELECT LOWER(@@GLOBAL.sql_mode) AS sql_mode');
1024:         if ($db->nextRecord()) {
1025:             if (strpos($db->f('sql_mode'), 'strict_trans_tables') !== false || strpos($db->f('sql_mode'), 'strict_all_tables') !== false) {
1026:                 return false;
1027:             }
1028:         }
1029:         return true;
1030:     }
1031: 
1032:     /**
1033:      *
1034:      * @param string $host
1035:      * @param string $username
1036:      * @param string $password
1037:      * @return int
1038:      *         1 if the test passed and > 1 if not
1039:      */
1040:     public function testMySQL($host, $username, $password) {
1041:         list($handle, $status) = $this->doMySQLConnect($host, $username, $password);
1042: 
1043:         $errorMessage = "";
1044:         if ($this->testMySQLiExtension() && !$this->testMySQLExtension()) {
1045:             if (!empty($handle)) {
1046:                 $errorMessage = mysqli_error($handle->getLinkId());
1047:             } else {
1048:                 $errorMessage = mysqli_error();
1049:             }
1050:         } else {
1051:             $errorMessage = mysql_error();
1052:         }
1053:         if ($errorMessage != "") {
1054:             return $errorMessage;
1055:         }
1056: 
1057:         if (false === isset($handle) || $handle->getLinkId()->errno == 1045) {
1058:             return self::CON_MYSQL_CANT_CONNECT;
1059:         }
1060: 
1061:         if (!$this->testMySQLModeStrict($host, $username, $password)) {
1062:             return self::CON_MYSQL_STRICT_MODE;
1063:         }
1064: 
1065:         return self::CON_MYSQL_OK;
1066:     }
1067: 
1068:     /**
1069:      *
1070:      * @param bool $testConfig [optional]
1071:      * @param bool $testFrontend [optional]
1072:      * @return bool
1073:      *         true if the test passed and false if not
1074:      */
1075:     public function testFilesystem($testConfig = true, $testFrontend = true) {
1076:         global $cfgClient;
1077: 
1078:         $status = true;
1079: 
1080:         $files = array(
1081:             // check files
1082:             array(
1083:                 'filename' => $this->_config['path']['contenido_logs'] . "errorlog.txt",
1084:                 'severity' => self::C_SEVERITY_WARNING
1085:             ),
1086:             array(
1087:                 'filename' => $this->_config['path']['contenido_logs'] . "setuplog.txt",
1088:                 'severity' => self::C_SEVERITY_WARNING
1089:             ),
1090:             array(
1091:                 'filename' => $this->_config['path']['contenido_cronlog'] . "pseudo-cron.log",
1092:                 'severity' => self::C_SEVERITY_WARNING
1093:             ),
1094:             array(
1095:                 'filename' => $this->_config['path']['contenido_cronlog'] . "session_cleanup.php.job",
1096:                 'severity' => self::C_SEVERITY_WARNING
1097:             ),
1098:             array(
1099:                 'filename' => $this->_config['path']['contenido_cronlog'] . "send_reminder.php.job",
1100:                 'severity' => self::C_SEVERITY_WARNING
1101:             ),
1102:             array(
1103:                 'filename' => $this->_config['path']['contenido_cronlog'] . "optimize_database.php.job",
1104:                 'severity' => self::C_SEVERITY_WARNING
1105:             ),
1106:             array(
1107:                 'filename' => $this->_config['path']['contenido_cronlog'] . "move_old_stats.php.job",
1108:                 'severity' => self::C_SEVERITY_WARNING
1109:             ),
1110:             array(
1111:                 'filename' => $this->_config['path']['contenido_cronlog'] . "move_articles.php.job",
1112:                 'severity' => self::C_SEVERITY_WARNING
1113:             ),
1114:             array(
1115:                 'filename' => $this->_config['path']['contenido_cronlog'] . "linkchecker.php.job",
1116:                 'severity' => self::C_SEVERITY_WARNING
1117:             ),
1118:             array(
1119:                 'filename' => $this->_config['path']['contenido_cronlog'] . "run_newsletter_job.php.job",
1120:                 'severity' => self::C_SEVERITY_WARNING
1121:             ),
1122:             array(
1123:                 'filename' => $this->_config['path']['contenido_cronlog'] . "setfrontenduserstate.php.job",
1124:                 'severity' => self::C_SEVERITY_WARNING
1125:             ),
1126:             array(
1127:                 'filename' => $this->_config['path']['contenido_cronlog'] . "advance_workflow.php.job",
1128:                 'severity' => self::C_SEVERITY_WARNING
1129:             ),
1130:             array(
1131:                 'filename' => $this->_config['path']['contenido_cache'],
1132:                 'severity' => self::C_SEVERITY_WARNING,
1133:                 'dir' => true
1134:             ),
1135:             array(
1136:                 'filename' => $this->_config['path']['contenido_temp'],
1137:                 'severity' => self::C_SEVERITY_WARNING,
1138:                 'dir' => true
1139:             ),
1140:             array(
1141:                 'filename' => $this->_config['path']['contenido_config'] . "config.php",
1142:                 'severity' => self::C_SEVERITY_ERROR,
1143:                 'config' => $testConfig
1144:             )
1145:         );
1146: 
1147:         $frontendFiles = array(
1148:             "cache",
1149:             "cache/code",
1150:             "css",
1151:             "data",
1152:             "data/layouts",
1153:             "data/logs",
1154:             "data/modules",
1155:             "data/version",
1156:             "data/version/css",
1157:             "data/version/js",
1158:             "data/version/layout",
1159:             "data/version/module",
1160:             "data/version/templates",
1161:             "js",
1162:             "templates",
1163:             "upload"
1164:         );
1165: 
1166:         $ret = true;
1167:         foreach ($files as $key => $file) {
1168: 
1169:             $name = $file['filename'];
1170:             $severity = $file['severity'];
1171:             $frontend = $file['frontend'];
1172:             $config = $file['config'];
1173: 
1174:             if (array_key_exists('frontend', $file) && $frontend != false) {
1175:                 $ret = $this->testSingleFile($name, $severity, $frontend);
1176:             } else if (array_key_exists('config', $file) && $config != false) {
1177:                 $ret = $this->testSingleFile($name, $severity);
1178:             } else if (!array_key_exists('frontend', $file) && !array_key_exists('config', $file)) {
1179:                 $ret = $this->testSingleFile($name, $severity, $config);
1180:             }
1181:             if ($ret == false) {
1182:                 $status = false;
1183:             }
1184:         }
1185: 
1186:         if ($testFrontend) {
1187:             foreach ($cfgClient as $oneClient) {
1188:                 if (!is_array($oneClient)) {
1189:                     continue;
1190:                 }
1191:                 foreach ($frontendFiles as $file) {
1192: 
1193:                     // If data/layouts or data/modules not exist, do not display an error message
1194:                     // Cause: At CONTENIDO 4.8 both folders do not exist
1195:                     // Only for upgrade mode
1196: 
1197:                     if ($_SESSION['setuptype'] == 'upgrade' && ($file == "data/layouts" || $file == "data/modules") && !cDirHandler::exists($oneClient["path"]["frontend"] . $file)) {
1198:                         continue;
1199:                     } else {
1200:                         $ret = $this->testSingleFile($oneClient["path"]["frontend"] . $file, self::C_SEVERITY_WARNING, true);
1201:                     }
1202: 
1203:                     if ($ret == false) {
1204:                         $status = false;
1205:                     }
1206:                 }
1207:             }
1208:         }
1209: 
1210:         return $status;
1211:     }
1212: 
1213:     /**
1214:      * Checks a single file or directory wether it is writeable or not
1215:      *
1216:      * @param string $filename
1217:      *         The file
1218:      * @param int $severity
1219:      *         The resulting C_SEVERITY constant should the test fail
1220:      * @param bool $dir [optional]
1221:      *         True if the $filename is a directory
1222:      * @throws Exception
1223:      *         Throws a generic Exception in the event that the permissions are wrong
1224:      * @return bool
1225:      *         Returns true if everything is fine
1226:      */
1227:     protected function testSingleFile($filename, $severity, $dir = false) {
1228:         if (strpos($filename, $this->_config["path"]["frontend"]) === 0) {
1229:             $length = strlen($this->_config["path"]["frontend"]) + 1;
1230:             $shortFilename = substr($filename, $length);
1231:         } else { // for dirs
1232:             $shortFilename = $filename;
1233:         }
1234: 
1235:         if (!$dir) {
1236:             $status = $this->canWriteFile($filename);
1237:         } else {
1238:             $status = $this->canWriteDir($filename);
1239:         }
1240: 
1241:         $title = sprintf(i18n("Can't write %s"), $shortFilename);
1242:         $message = sprintf(i18n("Setup or CONTENIDO can't write to the file %s. Please change the file permissions to correct this problem."), $shortFilename);
1243: 
1244:         if ($status == false) {
1245:             if (cFileHandler::exists($filename)) {
1246:                 $perm = $this->predictCorrectFilepermissions($filename);
1247: 
1248:                 switch ($perm) {
1249:                     case self::CON_PREDICT_WINDOWS:
1250:                         $predictMessage = i18n("Your Server runs Windows. Due to that, Setup can't recommend any file permissions.");
1251:                         break;
1252:                     case self::CON_PREDICT_NOTPREDICTABLE:
1253:                         $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);
1254:                         break;
1255:                     case self::CON_PREDICT_CHANGEPERM_SAMEOWNER:
1256:                         $mfileperms = substr(sprintf("%o", fileperms($filename)), -3);
1257:                         $mfileperms{0} = intval($mfileperms{0}) | 0x6;
1258:                         $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);
1259:                         break;
1260:                     case self::CON_PREDICT_CHANGEPERM_SAMEGROUP:
1261:                         $mfileperms = substr(sprintf("%o", fileperms($filename)), -3);
1262:                         $mfileperms{1} = intval($mfileperms{1}) | 0x6;
1263:                         $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);
1264:                         break;
1265:                     case self::CON_PREDICT_CHANGEPERM_OTHERS:
1266:                         $mfileperms = substr(sprintf("%o", fileperms($filename)), -3);
1267:                         $mfileperms{2} = intval($mfileperms{2}) | 0x6;
1268:                         $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);
1269:                         break;
1270:                 }
1271:             } else {
1272:                 $target = dirname($filename);
1273: 
1274:                 $perm = $this->predictCorrectFilepermissions($target);
1275: 
1276:                 switch ($perm) {
1277:                     case self::CON_PREDICT_WINDOWS:
1278:                         $predictMessage = i18n("Your Server runs Windows. Due to that, Setup can't recommend any directory permissions.");
1279:                         break;
1280:                     case self::CON_PREDICT_NOTPREDICTABLE:
1281:                         $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));
1282:                         break;
1283:                     case self::CON_PREDICT_CHANGEPERM_SAMEOWNER:
1284:                         $mfileperms = substr(sprintf("%o", @fileperms($target)), -3);
1285:                         $mfileperms{0} = intval($mfileperms{0}) | 0x6;
1286:                         $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);
1287:                         break;
1288:                     case self::CON_PREDICT_CHANGEPERM_SAMEGROUP:
1289:                         $mfileperms = substr(sprintf("%o", @fileperms($target)), -3);
1290:                         $mfileperms{1} = intval($mfileperms{1}) | 0x6;
1291:                         $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);
1292:                         break;
1293:                     case self::CON_PREDICT_CHANGEPERM_OTHERS:
1294:                         $mfileperms = substr(sprintf("%o", @fileperms($target)), -3);
1295:                         $mfileperms{2} = intval($mfileperms{2}) | 0x6;
1296:                         $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);
1297:                         break;
1298:                 }
1299:             }
1300: 
1301:             $this->storeResult(false, $severity, $title, $message . "<br><br>" . $predictMessage);
1302:             if ($title && $message) {
1303:                 $status = false;
1304:             }
1305:         }
1306: 
1307:         return $status;
1308:     }
1309: 
1310:     /**
1311:      *
1312:      * @return bool
1313:      *         true if the test passed and false if not
1314:      */
1315:     public function testFrontendFolderCreation() {
1316:         $directories = array(
1317:             "cms/cache",
1318:             "cms/cache/code",
1319:             "cms/css",
1320:             "cms/data",
1321:             "cms/data/layouts",
1322:             "cms/data/modules",
1323:             "cms/data/version",
1324:             "cms/data/version/css",
1325:             "cms/data/version/js",
1326:             "cms/data/version/layout",
1327:             "cms/data/version/module",
1328:             "cms/data/version/templates",
1329:             "cms/js",
1330:             "cms/templates",
1331:             "cms/upload"
1332:         );
1333: 
1334:         $ret = true;
1335: 
1336:         foreach ($directories as $dir) {
1337:             if (!cFileHandler::exists("../" . $dir)) {
1338:                 if (!mkdir("../" . $dir)) {
1339:                     $ret = false;
1340:                     $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."));
1341:                 } else {
1342:                     if (!cFileHandler::chmod("../" . $dir, "777")) {
1343:                         $ret = false;
1344:                         $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."));
1345:                     }
1346:                 }
1347:             }
1348:         }
1349: 
1350:         return $ret;
1351:     }
1352: 
1353:     /**
1354:      * Checks for the open_basedir directive and returns one of the CON_BASEDIR
1355:      * constants
1356:      *
1357:      * @return int
1358:      */
1359:     public function checkOpenBasedirCompatibility() {
1360:         $value = $this->getPHPIniSetting("open_basedir");
1361: 
1362:         if ($this->isWindows()) {
1363:             $aBasedirEntries = explode(";", $value);
1364:         } else {
1365:             $aBasedirEntries = explode(":", $value);
1366:         }
1367: 
1368:         if (count($aBasedirEntries) == 1 && $aBasedirEntries[0] == $value) {
1369:             return self::CON_BASEDIR_NORESTRICTION;
1370:         }
1371: 
1372:         if (in_array(".", $aBasedirEntries) && count($aBasedirEntries) == 1) {
1373:             return self::CON_BASEDIR_DOTRESTRICTION;
1374:         }
1375: 
1376:         $sCurrentDirectory = getcwd();
1377: 
1378:         foreach ($aBasedirEntries as $entry) {
1379:             if (stristr($sCurrentDirectory, $entry)) {
1380:                 return self::CON_BASEDIR_RESTRICTIONSUFFICIENT;
1381:             }
1382:         }
1383: 
1384:         return self::CON_BASEDIR_INCOMPATIBLE;
1385:     }
1386: 
1387:     /**
1388:      * Checks the available image resizer classes and functions
1389:      *
1390:      * @return int
1391:      *         Returns one of the CON_IMAGERESIZE constants
1392:      */
1393:     public function checkImageResizer() {
1394:         $iGDStatus = $this->isPHPExtensionLoaded('gd');
1395: 
1396:         if ($iGDStatus == self::CON_EXTENSION_AVAILABLE) {
1397:             return self::CON_IMAGERESIZE_GD;
1398:         }
1399: 
1400:         if (function_exists('imagecreate')) {
1401:             return self::CON_IMAGERESIZE_GD;
1402:         }
1403: 
1404:         if(function_exists("checkAndInclude")) {
1405:             checkAndInclude($this->_config['path']['contenido'] . 'includes/functions.api.images.php');
1406:         } else {
1407:             cInclude('includes', 'functions.api.images.php');
1408:         }
1409:         if (cApiIsImageMagickAvailable()) {
1410:             return self::CON_IMAGERESIZE_IMAGEMAGICK;
1411:         }
1412: 
1413:         if ($iGDStatus === self::CON_EXTENSION_CANTCHECK) {
1414:             return self::CON_IMAGERESIZE_CANTCHECK;
1415:         } else {
1416:             return self::CON_IMAGERESIZE_NOTHINGAVAILABLE;
1417:         }
1418:     }
1419: 
1420:     /**
1421:      *
1422:      * @param string $setupType
1423:      * @param string $databaseName
1424:      * @param string $databasePrefix
1425:      * @param string $charset [optional]
1426:      * @param string $collation [optional]
1427:      */
1428:     public function checkSetupMysql($setupType, $databaseName, $databasePrefix, $charset = '', $collation = '') {
1429:         switch ($setupType) {
1430:             case "setup":
1431: 
1432:                 $db = getSetupMySQLDBConnection(false);
1433: 
1434:                 // Check if the database exists
1435:                 $status = checkMySQLDatabaseExists($db, $databaseName);
1436: 
1437:                 if ($status) {
1438:                     // Yes, database exists
1439:                     $db = getSetupMySQLDBConnection();
1440:                     $db->connect();
1441: 
1442:                     // Check if data already exists
1443:                     $db->query('SHOW TABLES LIKE "%s_actions"', $databasePrefix);
1444: 
1445:                     if ($db->nextRecord()) {
1446:                         $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)));
1447:                         return;
1448:                     }
1449: 
1450:                     // Check if data already exists
1451:                     $db->query('SHOW TABLES LIKE "%s_test"', $databasePrefix);
1452:                     if ($db->nextRecord()) {
1453:                         $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)));
1454:                         return;
1455:                     }
1456: 
1457:                     // Good, table doesn't exist. Check for database permisions
1458:                     $status = checkMySQLTableCreation($db, $databaseName, sprintf("%s_test", $databasePrefix));
1459:                     if (!$status) {
1460:                         $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));
1461:                         return;
1462:                     }
1463: 
1464:                     // Good, we could create a table. Now remove it again
1465:                     $status = checkMySQLDropTable($db, $databaseName, sprintf("%s_test", $databasePrefix));
1466:                     if (!$status) {
1467:                         $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)));
1468:                     }
1469:                 } else {
1470:                     $db->connect();
1471:                     // Check if database can be created
1472:                     $status = checkMySQLDatabaseCreation($db, $databaseName, $charset, $collation);
1473:                     if (!$status) {
1474:                         $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")));
1475:                         return;
1476:                     }
1477: 
1478:                     // Check for database permisions
1479:                     $status = checkMySQLTableCreation($db, $databaseName, sprintf("%s_test", $databasePrefix));
1480:                     if (!$status) {
1481:                         $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));
1482:                         return;
1483:                     }
1484: 
1485:                     // Good, we could create a table. Now remove it again
1486:                     $status = checkMySQLDropTable($db, $databaseName, sprintf("%s_test", $databasePrefix));
1487:                     if (!$status) {
1488:                         $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)));
1489:                     }
1490:                 }
1491:                 break;
1492:             case "upgrade":
1493:                 $db = getSetupMySQLDBConnection(false);
1494: 
1495:                 // Check if the database exists
1496:                 $status = checkMySQLDatabaseExists($db, $databaseName);
1497:                 if (!$status) {
1498:                     $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));
1499:                     return;
1500:                 }
1501: 
1502:                 $db = getSetupMySQLDBConnection();
1503: 
1504:                 // Check if data already exists
1505:                 $sql = 'SHOW TABLES LIKE "%s_actions"';
1506:                 $db->query(sprintf($sql, $databasePrefix));
1507:                 if (!$db->nextRecord()) {
1508:                     $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));
1509:                     return;
1510:                 }
1511: 
1512:                 break;
1513:         }
1514:     }
1515: 
1516: }
1517: 
CMS CONTENIDO 4.9.11 API documentation generated by ApiGen 2.8.0