+
+// Activate given extension
+function ACTIVATE_EXTENSION ($ext_name) {
+ // Activate the extension
+ SQL_QUERY_ESC("UPDATE `{!_MYSQL_PREFIX!}_extensions` SET `ext_active`='Y' WHERE `ext_name`='%s' LIMIT 1",
+ array($ext_name), __FUNCTION__, __LINE__);
+
+ // Extension has been activated?
+ if (SQL_AFFECTEDROWS() == 1) {
+ // Then run all queries
+ EXTENSION_RUN_SQLS(GET_EXT_ID($ext_name), 'activate');
+ } // END - if
+}
+
+// Deactivate given extension
+function DEACTIVATE_EXTENSION($ext_name) {
+ // Activate the extension
+ SQL_QUERY_ESC("UPDATE `{!_MYSQL_PREFIX!}_extensions` SET `ext_active`='N' WHERE `ext_name`='%s' LIMIT 1",
+ array($ext_name), __FUNCTION__, __LINE__);
+
+ // Extension has been activated?
+ if (SQL_AFFECTEDROWS() == 1) {
+ // Then run all queries
+ EXTENSION_RUN_SQLS(GET_EXT_ID($ext_name), 'deactivate');
+
+ // Create new task
+ CREATE_EXTENSION_DEACTIVATION_TASK($ext_name);
+
+ // Notify the admin
+ sendAdminNotification(
+ getMessage('ADMIN_SUBJECT_EXTENSION_DEACTIVATED'),
+ 'admin_ext_deactivated',
+ array('ext_name' => $ext_name)
+ );
+ } // END - if
+}
+
+// Checks wether the extension is older than given
+function EXT_VERSION_IS_OLDER ($ext_name, $ext_ver) {
+ // Get current extension version
+ $currVersion = GET_EXT_VERSION($ext_name);
+
+ // Remove all dots from both versions
+ $currVersion = str_replace('.', '', $currVersion);
+ $ext_ver = str_replace('.', '', $ext_ver);
+
+ // Now compare both and return the result
+ return ($currVersion < $ext_ver);
+}
+
+// Creates a new task for updated extension
+function CREATE_EXTENSION_UPDATE_TASK ($admin_id, $ext_name, $ext_ver, $notes) {
+ // Create subject line
+ $subject = '[UPDATE-'.$ext_name.'-'.$ext_ver.':] {--ADMIN_UPDATE_EXT_SUBJ--}';
+
+ // Is the extension there?
+ if (GET_EXT_VERSION($ext_name) != '') {
+ // Check if task is not there
+ if (DETERMINE_TASK_ID_BY_SUBJECT($subject) == 0) {
+ // Task not created so it's a brand-new extension which we need to register and create a task for!
+ SQL_QUERY_ESC("INSERT INTO `{!_MYSQL_PREFIX!}_task_system` (assigned_admin, userid, status, task_type, subject, text, task_created) VALUES ('%s','0','NEW','EXTENSION_UPDATE','%s','%s', UNIX_TIMESTAMP())",
+ array($admin_id, $subject, $notes), __FUNCTION__, __LINE__);
+ } // END - if
+ } // END - if
+}
+
+// Creates a new task for newly installed extension
+function CREATE_NEW_EXTENSION_TASK ($admin_id, $subject, $ext) {
+ // Not installed and do we have created a task for the admin?
+ if ((DETERMINE_TASK_ID_BY_SUBJECT($subject) == 0) && (GET_EXT_VERSION($ext) == '')) {
+ // Template file
+ $tpl = sprintf("%stemplates/%s/html/ext/ext_%s.tpl",
+ constant('PATH'),
+ getLanguage(),
+ $ext
+ );
+
+ // Set default message if ext-foo is missing
+ $msg = sprintf(getMessage('ADMIN_EXT_TEXT_FILE_MISSING'), $ext);
+
+ // Load text for task if found
+ if (isFileReadable($tpl)) {
+ // Load extension's own text template (HTML!)
+ $msg = LOAD_TEMPLATE('ext_' . $ext, true);
+ } else {
+ // Write this in debug.log as well
+ DEBUG_LOG(__FUNCTION__, __LINE__, $msg);
+ }
+
+ // Task not created so it's a brand-new extension which we need to register and create a task for!
+ SQL_QUERY_ESC("INSERT INTO `{!_MYSQL_PREFIX!}_task_system` (assigned_admin, userid, status, task_type, subject, text, task_created)
+VALUES (%s, 0, 'NEW', 'EXTENSION', '%s', '%s', UNIX_TIMESTAMP())",
+ array(
+ $admin_id,
+ $subject,
+ smartAddSlashes($msg),
+ ), __FUNCTION__, __LINE__, true, false, false
+ );
+ } // END - if
+}
+
+// Creates a task for automatically deactivated (deprecated) extension
+function CREATE_EXTENSION_DEACTIVATION_TASK ($ext) {
+ // Create subject line
+ $subject = sprintf("[%s:] %s", $ext, getMessage('TASK_SUBJ_EXTENSION_DEACTIVATED'));
+
+ // Not installed and do we have created a task for the admin?
+ if ((DETERMINE_TASK_ID_BY_SUBJECT($subject) == 0) && (GET_EXT_VERSION($ext) != '')) {
+ // Task not created so add it
+ SQL_QUERY_ESC("INSERT INTO `{!_MYSQL_PREFIX!}_task_system` (assigned_admin, userid, status, task_type, subject, text, task_created)
+VALUES (0, 0, 'NEW', 'EXTENSION_DEACTIVATION', '%s', '%s', UNIX_TIMESTAMP())",
+ array(
+ $subject,
+ SQL_ESCAPE(LOAD_TEMPLATE('task_ext_deactivated', true, $ext)),
+ ), __FUNCTION__, __LINE__, true, false
+ );
+ } // END - if
+}
+
+// Checks if the module has a menu
+function MODULE_HAS_MENU ($mod, $forceDb = false) {
+ // All is false by default
+ $ret = false;
+
+ //* DEBUG: */ DEBUG_LOG(__FUNCTION__, __LINE__, "mod={$mod},cache=".GET_EXT_VERSION('cache'));
+ if (GET_EXT_VERSION('cache') >= '0.1.2') {
+ // Cache version is okay, so let's check the cache!
+ if (isset($GLOBALS['cache_array']['modules']['has_menu'][$mod])) {
+ // Check module cache and count hit
+ $ret = ($GLOBALS['cache_array']['modules']['has_menu'][$mod] == 'Y');
+ incrementConfigEntry('cache_hits');
+ } elseif (isset($GLOBALS['cache_array']['extensions']['ext_menu'][$mod])) {
+ // Check cache and count hit
+ $ret = ($GLOBALS['cache_array']['extensions']['ext_menu'][$mod] == 'Y');
+ incrementConfigEntry('cache_hits');
+ } elseif ((IS_ADMIN()) && ($mod == 'admin')) {
+ // Admin module has always a menu!
+ $ret = true;
+ }
+ } elseif ((GET_EXT_VERSION('sql_patches') >= '0.3.6') && ((!EXT_IS_ACTIVE('cache')) || ($forceDb === true))) {
+ // Check database for entry
+ $result = SQL_QUERY_ESC("SELECT has_menu FROM `{!_MYSQL_PREFIX!}_mod_reg` WHERE `module`='%s' LIMIT 1",
+ array($mod), __FUNCTION__, __LINE__);
+
+ // Entry found?
+ if (SQL_NUMROWS($result) == 1) {
+ // Load "has_menu" column
+ list($has_menu) = SQL_FETCHROW($result);
+
+ // Fake cache... ;-)
+ $GLOBALS['cache_array']['extensions']['ext_menu'][$mod] = $has_menu;
+
+ // Does it have a menu?
+ $ret = ($has_menu == 'Y');
+ } // END - if
+
+ // Free memory
+ SQL_FREERESULT($result);
+ } elseif (GET_EXT_VERSION('sql_patches') == '') {
+ // No sql_patches installed, so maybe in admin area or no admin registered?
+ $ret = (((IS_ADMIN()) || (!isAdminRegistered())) && ($mod == 'admin')); // Then there is a menu!
+ }
+
+ // Return status
+ //* DEBUG: */ print __FUNCTION__."[".__LINE__."]:currName=".EXT_GET_CURR_NAME().':'; var_dump($ret);
+ return $ret;
+}
+
+// Determines the task id for given extension
+function DETERMINE_EXTENSION_TASK_ID ($ext_name) {
+ // Default is not found
+ $task_id = 0;
+
+ // Search for extension task's id
+ $result = SQL_QUERY_ESC("SELECT `id` FROM `{!_MYSQL_PREFIX!}_task_system` WHERE task_type='EXTENSION' AND subject='[%s:]' LIMIT 1",
+ array($ext_name), __FUNCTION__, __LINE__);
+
+ // Entry found?
+ if (SQL_NUMROWS($result) == 1) {
+ // Task found so load task's ID and register extension...
+ list($task_id) = SQL_FETCHROW($result);
+ } // END - if
+
+ // Free result
+ SQL_FREERESULT($result);
+
+ // Return it
+ return $task_id;
+}
+
+// Determines the task id for given subject
+function DETERMINE_TASK_ID_BY_SUBJECT ($subject) {
+ // Default is not found
+ $task_id = 0;
+
+ // Search for task id
+ $result = SQL_QUERY_ESC("SELECT `id` FROM `{!_MYSQL_PREFIX!}_task_system` WHERE subject LIKE '%s%%' LIMIT 1",
+ array($subject), __FUNCTION__, __LINE__);
+
+ // Entry found?
+ if (SQL_NUMROWS($result) == 1) {
+ // Task found so load task's ID and register extension...
+ list($task_id) = SQL_FETCHROW($result);
+ } // END - if
+
+ // Free result
+ SQL_FREERESULT($result);
+
+ // Return it
+ return $task_id;
+}
+
+// Add updates notes for given version
+function ADD_EXTENSION_NOTES ($ver) {
+ // Init notes/content
+ $out = ''; $content = array();
+
+ // Is do we have verbose output enabled?
+ if ((getConfig('verbose_sql') == 'Y') || (!EXT_IS_ACTIVE('sql_patches'))) {
+
+ // Update notes found?
+ if (EXT_GET_UPDATE_NOTES() != '') {
+ // Update notes found
+ $content = array(
+ 'ver' => $ver,
+ 'notes' => EXT_GET_UPDATE_NOTES()
+ );
+
+ // Reset them
+ EXT_SET_UPDATE_NOTES('');
+ } elseif (($ver == '0.0') || ($ver == '0.0.0')) {
+ // Initial release
+ $content = array(
+ 'ver' => $ver,
+ 'notes' => getMessage('INITIAL_RELEASE')
+ );
+ } else {
+ // No update notes found!
+ $content = array(
+ 'ver' => $ver,
+ 'notes' => getMessage('NO_UPDATE_NOTES')
+ );
+ }
+
+ // Load template
+ $out = LOAD_TEMPLATE('admin_ext_notes', true, $content);
+ } // END - if
+
+ // Add the notes
+ EXT_APPEND_NOTES($out);
+}
+
+// Getter for CSS files array
+function EXT_GET_CSS_FILES () {
+ // By default no additional CSS files are found
+ $cssFiles = array();
+
+ // Is the array there?
+ if (isset($GLOBALS['css_files'])) {
+ // Then use it
+ $cssFiles = $GLOBALS['css_files'];
+ } // END - if
+
+ // Return array
+ return $cssFiles;
+}
+
+// Init CSS files array
+function EXT_INIT_CSS_FILES () {
+ // Simply init it
+ $GLOBALS['css_files'] = array();
+}
+
+// Add new entry
+function EXT_ADD_CSS_FILE ($file) {
+ // Is the array there?
+ if (!isset($GLOBALS['css_files'])) {
+ // Then auto-init them
+ EXT_INIT_CSS_FILES();
+ } // END - if
+
+ // Add the entry
+ $GLOBALS['css_files'][] = $file;
+}
+
+// Setter for EXT_ALWAYS_ACTIVE flag
+function EXT_SET_ALWAYS_ACTIVE ($active) {
+ $GLOBALS['ext_always_active'][EXT_GET_CURR_NAME()] = (string) $active;
+}
+
+// Getter for EXT_ALWAYS_ACTIVE flag
+function EXT_GET_ALWAYS_ACTIVE () {
+ return $GLOBALS['ext_always_active'][EXT_GET_CURR_NAME()];
+}
+
+// Setter for EXT_VERSION flag
+function EXT_SET_VERSION ($version) {
+ $GLOBALS['ext_version'][EXT_GET_CURR_NAME()] = (string) $version;
+}
+
+// Getter for EXT_VERSION flag
+function EXT_GET_VERSION () {
+ return $GLOBALS['ext_version'][EXT_GET_CURR_NAME()];
+}
+
+// Setter for EXT_DEPRECATED flag
+function EXT_SET_DEPRECATED ($deprecated) {
+ $GLOBALS['ext_deprecated'][EXT_GET_CURR_NAME()] = (string) $deprecated;
+}
+
+// Getter for EXT_DEPRECATED flag
+function EXT_GET_DEPRECATED () {
+ return $GLOBALS['ext_deprecated'][EXT_GET_CURR_NAME()];
+}
+
+// Setter for EXT_UPDATE_DEPENDS flag
+function EXT_ADD_UPDATE_DEPENDS ($updateDepends) {
+ // Is the update depency empty? (NEED TO BE FIXED!)
+ if (empty($updateDepends)) {
+ // Please report this bug!
+ debug_report_bug("updateDepends is left empty!");
+ } // END - if
+
+ // Is it not yet added?
+ if (!in_array($updateDepends, $GLOBALS['ext_running_updates'])) {
+ //* DEBUG */ DEBUG_LOG(__FUNCTION__, __LINE__, "currName=".EXT_GET_CURR_NAME().'/'.$updateDepends);
+ // Add it to the list of extension update depencies map
+ $GLOBALS['ext_update_depends'][EXT_GET_CURR_NAME()][] = (string) $updateDepends;
+
+ // Remember it in the list of running updates
+ $GLOBALS['ext_running_updates'][] = $updateDepends;
+ } // END - if
+}
+
+// Checks wether the given extension registration is in progress
+function EXT_IS_REGISTER_RUNNING ($ext_name) {
+ return ((isset($GLOBALS['ext_register_running'])) && (in_array($ext_name, $GLOBALS['ext_register_running'])));
+}
+
+// Init EXT_UPDATE_DEPENDS flag
+function EXT_INIT_UPDATE_DEPENDS () {
+ //* DEBUG: */ DEBUG_LOG(__FUNCTION__, __LINE__, "currName=".EXT_GET_CURR_NAME());
+
+ // Init update depency map automatically if not found
+ if (!EXT_IS_UPDATE_DEPENDS_INIT()) {
+ //* DEBUG: */ DEBUG_LOG(__FUNCTION__, __LINE__, "currName=".EXT_GET_CURR_NAME()." - INIT!");
+ $GLOBALS['ext_update_depends'][EXT_GET_CURR_NAME()] = array();
+ } // END - if
+
+ // Init running updates array
+ EXT_INIT_RUNNING_UPDATES();
+}
+
+// Adds an extension as "registration in progress"
+function EXT_ADD_RUNNING_REGISTRATION ($ext_name) {
+ // Is it running?
+ if (!EXT_IS_REGISTER_RUNNING($ext_name)) {
+ // Then add it!
+ $GLOBALS['ext_register_running'][] = $ext_name;
+ } // END - if
+}
+
+// Checks wether EXT_UPDATE_DEPENDS is initialized
+function EXT_IS_UPDATE_DEPENDS_INIT () {
+ //* DEBUG: */ DEBUG_LOG(__FUNCTION__, __LINE__, "currName=".EXT_GET_CURR_NAME());
+ return (isset($GLOBALS['ext_update_depends'][EXT_GET_CURR_NAME()]));
+}
+
+// Initializes the list of running updates
+function EXT_INIT_RUNNING_UPDATES () {
+ // Auto-init ext_running_updates
+ if (!isset($GLOBALS['ext_running_updates'])) {
+ $GLOBALS['ext_running_updates'] = array();
+ $GLOBALS['ext_register_running'] = array();
+ } // END - if
+}
+
+// Getter for EXT_UPDATE_DEPENDS flag
+function EXT_GET_UPDATE_DEPENDS () {
+ //* DEBUG: */ DEBUG_LOG(__FUNCTION__, __LINE__, "currName=".EXT_GET_CURR_NAME());
+ return $GLOBALS['ext_update_depends'][EXT_GET_CURR_NAME()];
+}
+
+// Getter for next iterator depency
+function EXT_GET_ITERATOR_UPDATE_DEPENDS () {
+ //* DEBUG: */ DEBUG_LOG(__FUNCTION__, __LINE__, "currName=".EXT_GET_CURR_NAME());
+ return ($GLOBALS['ext_update_depends'][EXT_GET_CURR_NAME()][EXT_GET_UPDATE_ITERATOR()]);
+}
+
+// Counter for extension update depencies
+function EXT_COUNT_UPDATE_DEPENDS () {
+ //* DEBUG: */ DEBUG_LOG(__FUNCTION__, __LINE__, "currName=".EXT_GET_CURR_NAME());
+ return count($GLOBALS['ext_update_depends'][EXT_GET_CURR_NAME()]);
+}
+
+// Removes given extension from update denpency list
+function EXT_REMOVE_UPDATE_DEPENDS ($ext_name) {
+ // Look it up
+ $key = array_search($ext_name, EXT_GET_UPDATE_DEPENDS());
+
+ // Is it valid?
+ if ($key !== false) {
+ // Then remove it
+ unset($GLOBALS['ext_update_depends'][EXT_GET_CURR_NAME()][$key]);
+
+ // And sort the array
+ ksort($GLOBALS['ext_update_depends'][EXT_GET_CURR_NAME()]);
+ } // END - if
+}
+
+// Init iterator for update depencies
+function EXT_INIT_UPDATE_ITERATOR () {
+ //* DEBUG: */ DEBUG_LOG(__FUNCTION__, __LINE__, "currName=".EXT_GET_CURR_NAME());
+ $GLOBALS['ext_depend_iterator'][EXT_GET_CURR_NAME()] = 0;
+}
+
+// Getter for depency iterator
+function EXT_GET_UPDATE_ITERATOR () {
+ // Auto-init iterator
+ if (!isset($GLOBALS['ext_depend_iterator'][EXT_GET_CURR_NAME()])) EXT_INIT_UPDATE_ITERATOR();
+
+ // Return it
+ //* DEBUG: */ DEBUG_LOG(__FUNCTION__, __LINE__, "currName=".EXT_GET_CURR_NAME().'/'.$GLOBALS['ext_depend_iterator'][EXT_GET_CURR_NAME()]);
+ return $GLOBALS['ext_depend_iterator'][EXT_GET_CURR_NAME()];
+}
+
+// Increments the update iterator
+function EXT_INCREMENT_UPDATE_INTERATOR () {
+ //* DEBUG: */ DEBUG_LOG(__FUNCTION__, __LINE__, "currName=".EXT_GET_CURR_NAME());
+ $GLOBALS['ext_depend_iterator'][EXT_GET_CURR_NAME()]++;
+}
+
+// Setter for EXT_REPORTS_FAILURE flag
+function EXT_SET_REPORTS_FAILURE ($reportsFailure) {
+ $GLOBALS['ext_reports_failure'] = (bool) $reportsFailure;
+}
+
+// Getter for EXT_REPORTS_FAILURE flag
+function EXT_GET_REPORTS_FAILURE () {
+ return $GLOBALS['ext_reports_failure'];
+}
+
+// Setter for EXT_VER_HISTORY flag
+function EXT_SET_VER_HISTORY ($verHistory) {
+ $GLOBALS['ext_ver_history'] = (array) $verHistory;
+}
+
+// Getter for EXT_VER_HISTORY array
+function EXT_GET_VER_HISTORY () {
+ return $GLOBALS['ext_ver_history'];
+}
+
+// Setter for EXT_UPDATE_NOTES flag
+function EXT_SET_UPDATE_NOTES ($updateNotes) {
+ $GLOBALS['ext_update_notes'] = (string) $updateNotes;
+}
+
+// Getter for EXT_UPDATE_NOTES flag
+function EXT_GET_UPDATE_NOTES () {
+ return $GLOBALS['ext_update_notes'];
+}
+
+// Init extension notice
+function EXT_INIT_NOTES () {
+ $GLOBALS['ext_notes'] = '';
+}
+
+// Append extension notice
+function EXT_APPEND_NOTES ($notes) {
+ $GLOBALS['ext_notes'] .= (string) $notes;
+}
+
+// Getter for extension notes
+function EXT_GET_NOTES () {
+ return $GLOBALS['ext_notes'];
+}
+
+// Setter for current extension name
+function EXT_SET_CURR_NAME ($ext_name) {
+ $GLOBALS['curr_ext_name'] = (string) $ext_name;
+}
+
+// Getter for current extension name
+function EXT_GET_CURR_NAME () {
+ if (isset($GLOBALS['curr_ext_name'])) {
+ return $GLOBALS['curr_ext_name'];
+ } // END - if
+
+ // Not set!
+ debug_report_bug(__FUNCTION__.": curr_ext_name not initialized. Please execute INIT_EXT_SQLS() before calling this function.");
+}
+
+// Init SQLs array for current extension
+function INIT_EXT_SQLS () {
+ // Auto-init the array now...
+ if (!isset($GLOBALS['ext_sqls'][EXT_GET_CURR_NAME()])) {
+ $GLOBALS['ext_sqls'][EXT_GET_CURR_NAME()] = array();
+ } // END - if
+}
+
+// Adds SQLs to the SQLs array but "assigns" it with current extension name
+function ADD_EXT_SQL ($sql) {
+ $GLOBALS['ext_sqls'][EXT_GET_CURR_NAME()][] = $sql;
+}
+
+// Getter for SQLs array for current extension
+function GET_EXT_SQLS () {
+ // Output debug backtrace if not found (SHOULD NOT HAPPEN!)
+ if (!isset($GLOBALS['ext_sqls'][EXT_GET_CURR_NAME()])) {
+ // Not found, should not happen
+ debug_report_bug(sprintf("ext_sqls is empty, current extension: %s",
+ EXT_GET_CURR_NAME()
+ ));
+ } // END - if
+
+ // Return the array
+ return $GLOBALS['ext_sqls'][EXT_GET_CURR_NAME()];
+}
+
+// Removes SQLs for current extension
+function UNSET_EXT_SQLS () {
+ unset($GLOBALS['ext_sqls'][EXT_GET_CURR_NAME()]);
+}
+
+// Auto-initializes the removal list
+function EXT_INIT_REMOVAL_LIST () {
+ // Is the remove list there?
+ if (!isset($GLOBALS['ext_update_remove'])) {
+ // Then create it
+ $GLOBALS['ext_update_remove'] = array();
+ } // END - if
+}
+
+// Checks wether the current extension is on the removal list
+function EXT_IS_ON_REMOVAL_LIST () {
+ // Init removal list
+ EXT_INIT_REMOVAL_LIST();
+
+ // Is it there?
+ return (in_array(EXT_GET_CURR_NAME(), $GLOBALS['ext_update_remove']));
+}
+
+// Adds the current extension to the removal list
+function EXT_ADD_CURRENT_TO_REMOVAL_LIST () {
+ // Simply add it
+ $GLOBALS['ext_update_remove'][] = EXT_GET_CURR_NAME();
+}
+
+// Getter for removal list
+function EXT_GET_REMOVAL_LIST () {
+ // Return the removal list
+ return $GLOBALS['ext_update_remove'];
+}
+
+// Redirects if the provided extension is not installed
+function redirectOnUninstalledExtension ($ext_name) {
+ // So is the extension there?
+ if (!EXT_IS_ACTIVE($ext_name)) {
+ // Redirect to index
+ redirectToUrl('modules.php?module=index&msg=' . getCode('EXTENSION_PROBLEM') . '&ext=' . $ext_name);
+ } // END - if
+}
+