def _create_field_sql(name, spec): """ Create an SQL string for a field to be used in table creation or alteration. Before passing a field out of a schema definition into this function it has to be processed by _db_process_field(). @param name Name of the field. @param spec The field specification, as per the schema data structure format. """ sql = "`" + name + "` " . spec['mysql_type'] if (php.isset(spec, 'length')): sql += '(' + spec['length'] + ')' elif (php.isset(spec, 'precision') and php.isset(spec, 'scale')): sql += '(' + spec['precision'] + ', ' + spec['scale'] + ')' if (not php.empty(spec['unsigned'])): sql += ' unsigned' if (not php.empty(spec['not None'])): sql += ' NOT None' if (not php.empty(spec['auto_increment'])): sql += ' auto_increment' if (php.isset(spec, 'default')): if (is_string(spec['default'])): spec['default'] = "'" + spec['default'] + "'" sql += ' DEFAULT ' + spec['default'] if (php.empty(spec['not None']) and not php.isset(spec, 'default')): sql += ' DEFAULT None' return sql
def _create_field_sql(name, spec): """ Create an SQL string for a field to be used in table creation or alteration. Before passing a field out of a schema definition into this function it has to be processed by _db_process_field(). @param name Name of the field. @param spec The field specification, as per the schema data structure format. """ sql = "`" + name + "` ".spec['mysql_type'] if (php.isset(spec, 'length')): sql += '(' + spec['length'] + ')' elif (php.isset(spec, 'precision') and php.isset(spec, 'scale')): sql += '(' + spec['precision'] + ', ' + spec['scale'] + ')' if (not php.empty(spec['unsigned'])): sql += ' unsigned' if (not php.empty(spec['not None'])): sql += ' NOT None' if (not php.empty(spec['auto_increment'])): sql += ' auto_increment' if (php.isset(spec, 'default')): if (is_string(spec['default'])): spec['default'] = "'" + spec['default'] + "'" sql += ' DEFAULT ' + spec['default'] if (php.empty(spec['not None']) and not php.isset(spec, 'default')): sql += ' DEFAULT None' return sql
def theme_preprocess_page(vars_): """ Override or insert variables into the page template. """ php.Reference.check(vars_) vars_['tabs2'] = menu_secondary_local_tasks() vars_['primary_nav'] = (lib_theme.theme('links', \ vars_['main_menu'], {'class' : 'links main-menu'}) if \ php.isset(vars_, 'main_menu') else False) vars_['secondary_nav'] = (lib_theme.theme('links', \ vars_['secondary_menu'], \ {'class' : 'links secondary-menu'}) if \ php.isset(vars_, 'secondary_menu') else False) vars_['ie_styles'] = get_ie_styles() # Prepare header site_fields = [] if (not php.empty(vars_['site_name'])): site_fields.append( check_plain(vars_['site_name']) ) if (not php.empty(vars_['site_slogan'])): site_fields.append( check_plain(vars_['site_slogan']) ) vars_['site_title'] = php.implode(' ', site_fields) if (not php.empty(site_fields)): site_fields[0] = '<span>' + site_fields[0] + '</span>' vars_['site_html'] = php.implode(' ', site_fields) # Hook into color.module if (lib_plugin.exists('color')): lib_plugin.plugins['color']._page_alter(vars_)
def _create_keys_sql(spec): keys = {} if (not php.empty(spec['primary key'])): keys.append( 'PRIMARY KEY (' + \ _db_create_key_sql(spec['primary key']) + ')' ) if (not php.empty(spec['unique keys'])): for key, fields in spec['unique keys'].items(): keys.append( 'UNIQUE KEY ' + key + \ ' (' + _db_create_key_sql(fields) + ')' ) if (not php.empty(spec['indexes'])): for index, fields in spec['indexes'].items(): keys.append( 'INDEX ' + index + ' (' + \ _db_create_key_sql(fields) + ')' ) return keys
def _create_keys_sql(spec): keys = {} if (not php.empty(spec['primary key'])): keys.append( 'PRIMARY KEY (' + \ _db_create_key_sql(spec['primary key']) + ')' ) if (not php.empty(spec['unique keys'])): for key,fields in spec['unique keys'].items(): keys.append( 'UNIQUE KEY ' + key + \ ' (' + _db_create_key_sql(fields) + ')' ) if (not php.empty(spec['indexes'])): for index,fields in spec['indexes'].items(): keys.append( 'INDEX ' + index + ' (' + \ _db_create_key_sql(fields) + ')' ) return keys
def rewrite_sql(query, primary_table = 'n', primary_field = 'nid', args = []): join_, where, distinct = _rewrite_sql(query, primary_table, \ primary_field, args) if (distinct): query = distinct_field(primary_table, primary_field, query) if (not php.empty(where) or not php.empty(join_)): pattern = \ '{ ' + \ ' # Beginning of the string ' + \ ' ^ ' + \ ' ((?P<anonymous_view> ' + \ ' # Everything within this set of parentheses ' + \ ' # is named "anonymous view ' + \ ' (?: ' + \ ' # anything not parentheses ' + \ ' [^()]++ ' + \ ' | ' + \ ' # an open parenthesis, more anonymous view and ' + \ ' # finally a close parenthesis. ' + \ ' \( (?P>anonymous_view) \) ' + \ ' )* ' + \ ' )[^()]+WHERE) ' + \ '}X' matches = [] php.preg_match(pattern, query, matches) if (where): n = php.strlen(matches[1]) second_part = php.substr(query, n) first_part = php.substr(matches[1], 0, n - 5) + \ " join WHERE where AND ( " # PHP 4 does not support strrpos for strings. We emulate it. haystack_reverse = php.strrev(second_part) # No need to use strrev on the needle, we supply GROUP, ORDER, LIMIT # reversed. for needle_reverse in ('PUORG', 'REDRO', 'TIMIL'): pos = php.strpos(haystack_reverse, needle_reverse) if (pos != False): # All needles are five characters long. pos += 5 break if (pos == False): query = first_part + second_part + ')' else: query = first_part + substr(second_part, 0, -pos) + ')' + \ php.substr(second_part, -pos) else: query = matches[1] + " join " + \ php.substr(query, php.strlen(matches[1])) return query
def create_table_sql(name, table): """ Generate SQL to create a new table from a Drupal schema definition. @param name The name of the table to create. @param table A Schema API table definition array. @return An array of SQL statements to create the table. """ if (php.empty(table['mysql_suffix'])): table['mysql_suffix'] = "/*not 40100 DEFAULT CHARACTER SET UTF8 */" sql = "CREATE TABLE {" + name + "} (\n" # Add the SQL statement for each field. for field_name,field in table['fields'].items(): sql += _db_create_field_sql(field_name, _db_process_field(field)) + ", \n" # Process keys & indexes. keys = _db_create_keys_sql(table) if (php.count(keys)): sql += php.implode(", \n", keys) + ", \n" # Remove the last comma and space. sql = php.substr(sql, 0, -3) + "\n) " sql += table['mysql_suffix'] return array(sql)
def disable(plugin_list_): """ Disable a given set of plugins. @param plugin_list An array of plugin names. """ invoke_plugins = [] for plugin_ in plugin_list_: if (plugin_exists(plugin_)): # Check if node_access table needs rebuilding. if (not node_access_needs_rebuild() and plugin_hook(plugin_, \ 'node_grants')): node_access_needs_rebuild(True) plugin_load_install(plugin_) plugin_invoke(plugin_, 'disable') db_query(\ "UPDATE {system} SET status = %d " + \ "WHERE type = '%s' AND name = '%s'", 0, 'plugin', plugin_) invoke_plugins.append(plugin) if (not php.empty(invoke_plugins)): # Refresh the plugin list to exclude the disabled plugins. plugin_list(True, False) # Force to regenerate the stored list of hook implementations. registry_rebuild() # If there remains no more node_access plugin, rebuilding will be # straightforward, we can do it right now. if (node_access_needs_rebuild() and \ php.count(plugin_implements('node_grants')) == 0): node_access_rebuild()
def enable(plugin_list_): """ Enable a given list of plugins. @param plugin_list An array of plugin names. """ invoke_plugins = [] for plugin_ in plugin_list_: existing = db_fetch_object(db_query(\ "SELECT status FROM {system} " + \ "WHERE type = '%s' AND name = '%s'", 'plugin', plugin)) if (existing.status == 0): plugin_load_install(plugin_) db_query(\ "UPDATE {system} SET status = %d " + \ "WHERE type = '%s' AND name = '%s'", 1, 'plugin', plugin_) drupal_load('plugin', plugin_) invoke_plugins.append(plugin) if (not php.empty(invoke_plugins)): # Refresh the plugin list to include the new enabled plugin. plugin_list(True, False) # Force to regenerate the stored list of hook implementations. registry_rebuild() for plugin_ in invoke_plugins: plugin_invoke(plugin_, 'enable') # Check if node_access table needs rebuilding. # We check for the existence of node_access_needs_rebuild() since # at install time, plugin_enable() could be called while node.plugin # is not enabled yet. if (drupal_function_exists('node_access_needs_rebuild') and \ not node_access_needs_rebuild() and \ plugin_hook(plugin_, 'node_grants')): node_access_needs_rebuild(True)
def cell(cell, header, ts, i): """ Format a table cell. Adds a class attribute to all cells in the currently active column. @param cell The cell to format. @param header An array of column headers in the format described in theme_table(). @param ts The current table sort context as returned from hook_init(). @param i The index of the cell's table column. @return A properly formatted cell, ready for _theme_table_cell(). """ if (php.isset(header[i]['data']) and header[i]['data'] == ts['name'] and not php.empty(header[i]['field'])): if php.is_array(cell): if php.isset(cell['class']): cell['class'] += ' active' else: cell['class'] = 'active' else: cell = {'data': cell, 'class': 'active'} return cell
def url_rewrite(path, options): """ Rewrite URL's with language based prefix. Parameters are the same as those of the url() function. """ # Only modify relative (insite) URLs. if (not options['external']): # Language can be passed as an option, or we go for current language. if (not php.isset(options, 'language')): options['language'] = lib_appglobals.language lang_type = variable_get('language_negotiation', \ lib_bootstrap.LANGUAGE_NEGOTIATION_NONE) if lang_type == lib_bootstrap.LANGUAGE_NEGOTIATION_NONE: # No language dependent path allowed in this mode. del (options['language']) return elif lang_type == lib_bootstrap.LANGUAGE_NEGOTIATION_DOMAIN: if (options['language'].domain): # Ask for an absolute URL with our modified base_url. options['absolute'] = True options['base_url'] = options['language'].domain return elif lang_type == lib_bootstrap.LANGUAGE_NEGOTIATION_PATH_DEFAULT: default = language_default() if (options['language'].language == default.language): return if lang_type == lib_bootstrap.LANGUAGE_NEGOTIATION_PATH: if (not php.empty(options['language'].prefix)): options['prefix'] = options['language'].prefix + '/' return
def enable(plugin_list_): """ Enable a given list of plugins. @param plugin_list An array of plugin names. """ invoke_plugins = [] for plugin_ in plugin_list_: existing = db_fetch_object(db_query(\ "SELECT status FROM {system} " + \ "WHERE type = '%s' AND name = '%s'", 'plugin', plugin)) if (existing.status == 0): plugin_load_install(plugin_) db_query(\ "UPDATE {system} SET status = %d " + \ "WHERE type = '%s' AND name = '%s'", 1, 'plugin', plugin_) drupal_load('plugin', plugin_) invoke_plugins.append( plugin ) if (not php.empty(invoke_plugins)): # Refresh the plugin list to include the new enabled plugin. plugin_list(True, False) # Force to regenerate the stored list of hook implementations. registry_rebuild() for plugin_ in invoke_plugins: plugin_invoke(plugin_, 'enable') # Check if node_access table needs rebuilding. # We check for the existence of node_access_needs_rebuild() since # at install time, plugin_enable() could be called while node.plugin # is not enabled yet. if (drupal_function_exists('node_access_needs_rebuild') and \ not node_access_needs_rebuild() and \ plugin_hook(plugin_, 'node_grants')): node_access_needs_rebuild(True)
def drupal_get_messages(type=None, clear_queue=True): """ Return all messages that have been set. @param type (optional) Only return messages of this type. @param clear_queue (optional) Set to FALSE if you do not want to clear the messages queue @return An associative array, the key is the message type, the value an array of messages. If the type parameter is passed, you get only that type, or an empty array if there are no such messages. If type is not passed, all message types are returned, or an empty array if none exist. """ messages = drupal_set_message() if not php.empty("messages"): if type != None and type != False: if clear_queue: del (php.SESSION["messages"][type]) if php.isset(messages, type): return {type: messages[type]} else: if clear_queue: del (php.SESSION["messages"]) return messages return {}
def url_rewrite(path, options): """ Rewrite URL's with language based prefix. Parameters are the same as those of the url() function. """ # Only modify relative (insite) URLs. if (not options['external']): # Language can be passed as an option, or we go for current language. if (not php.isset(options, 'language')): options['language'] = lib_appglobals.language lang_type = variable_get('language_negotiation', \ lib_bootstrap.LANGUAGE_NEGOTIATION_NONE) if lang_type == lib_bootstrap.LANGUAGE_NEGOTIATION_NONE: # No language dependent path allowed in this mode. del(options['language']) return elif lang_type == lib_bootstrap.LANGUAGE_NEGOTIATION_DOMAIN: if (options['language'].domain): # Ask for an absolute URL with our modified base_url. options['absolute'] = True options['base_url'] = options['language'].domain return elif lang_type == lib_bootstrap.LANGUAGE_NEGOTIATION_PATH_DEFAULT: default = language_default() if (options['language'].language == default.language): return if lang_type == lib_bootstrap.LANGUAGE_NEGOTIATION_PATH: if (not php.empty(options['language'].prefix)): options['prefix'] = options['language'].prefix + '/' return
def ip_address(reset=False): """ If Drupal is behind a reverse proxy, we use the X-Forwarded-For header instead of $_SERVER['REMOTE_ADDR'], which would be the IP address of the proxy server, and not the client's. If Drupal is run in a cluster we use the X-Cluster-Client-Ip header instead. @param $reset Reset the current IP address saved in static. @return IP address of client machine, adjusted for reverse proxy and/or cluster environments. """ php.static(ip_address, "ip_address") if ip_address.ip_address is None or reset: ip_address.ip_address = php.SERVER["REMOTE_ADDR"] if variable_get("reverse_proxy", 0): if php.array_key_exists("HTTP_X_FORWARDED_FOR", php.SERVER): # If an array of known reverse proxy IPs is provided, then trust # the XFF header if request really comes from one of them. reverse_proxy_addresses = variable_get("reverse_proxy_addresses", tuple()) if not php.empty(reverse_proxy_addresses) and php.in_array( ip_address.ip_address, reverse_proxy_addresses, True ): # If there are several arguments, we need to check the most # recently added one, i.e. the last one. ip_address.ip_address = php.array_pop(php.explode(",", php.SERVER["HTTP_X_FORWARDED_FOR"])) # When Drupal is run in a cluster environment, # REMOTE_ADDR contains the IP # address of a server in the cluster, while the IP address # of the client is # stored in HTTP_X_CLUSTER_CLIENT_IP. if php.array_key_exists("HTTP_X_CLUSTER_CLIENT_IP", php.SERVER): ip_address.ip_address = php.SERVER["HTTP_X_CLUSTER_CLIENT_IP"] return ip_address.ip_address
def create_table_sql(name, table): """ Generate SQL to create a new table from a Drupal schema definition. @param name The name of the table to create. @param table A Schema API table definition array. @return An array of SQL statements to create the table. """ if (php.empty(table['mysql_suffix'])): table['mysql_suffix'] = "/*not 40100 DEFAULT CHARACTER SET UTF8 */" sql = "CREATE TABLE {" + name + "} (\n" # Add the SQL statement for each field. for field_name, field in table['fields'].items(): sql += _db_create_field_sql(field_name, _db_process_field(field)) + ", \n" # Process keys & indexes. keys = _db_create_keys_sql(table) if (php.count(keys)): sql += php.implode(", \n", keys) + ", \n" # Remove the last comma and space. sql = php.substr(sql, 0, -3) + "\n) " sql += table['mysql_suffix'] return array(sql)
def drupal_get_messages(type=None, clear_queue=True): """ Return all messages that have been set. @param type (optional) Only return messages of this type. @param clear_queue (optional) Set to FALSE if you do not want to clear the messages queue @return An associative array, the key is the message type, the value an array of messages. If the type parameter is passed, you get only that type, or an empty array if there are no such messages. If type is not passed, all message types are returned, or an empty array if none exist. """ messages = drupal_set_message() if (not php.empty('messages')): if (type != None and type != False): if (clear_queue): del (php.SESSION['messages'][type]) if (php.isset(messages, type)): return { type: messages[type] } else: if (clear_queue): del (php.SESSION['messages']) return messages return {}
def rebuild_cache(): """ Rebuild the database cache of plugin files. @return The array of filesystem objects used to rebuild the cache. """ # Get current list of plugins files = drupal_system_listing('\.plugin$', 'plugins', 'name', 0) # Extract current files from database. system_get_files_database(files, 'plugin') ksort(files) # Set defaults for plugin info defaults = { 'dependencies': [], 'dependents': [], 'description': '', 'version': None, 'php': DRUPAL_MINIMUM_PHP, } for filename, file in files.items(): # Look for the info file. file.info = drupal_parse_info_file(php.dirname(file.filename) + '/' + \ file.name + '.info') # Skip plugins that don't provide info. if (php.empty(file.info)): del (files[filename]) continue # Merge in defaults and save. files[filename].info = file.info + defaults # Invoke hook_system_info_alter() to give installed plugins a chance to # modify the data in the .info files if necessary. drupal_alter('system_info', files[filename].info, files[filename]) # Log the critical hooks implemented by this plugin. bootstrap = 0 for hook in bootstrap_hooks(): if (plugin_hook(file.name, hook)): bootstrap = 1 break # Update the contents of the system table: if (php.isset(file, 'status') or (php.isset(file, 'old_filename') and \ file.old_filename != file.filename)): db_query(\ "UPDATE {system} SET info = '%s', name = '%s', " + \ "filename = '%s', bootstrap = %d WHERE filename = '%s'", \ php.serialize(files[filename].info), file.name, \ file.filename, bootstrap, file.old_filename) else: # This is a new plugin. files[filename].status = 0 db_query(\ "INSERT INTO {system} (name, info, type, " + \ "filename, status, bootstrap) VALUES " + \ "('%s', '%s', '%s', '%s', %d, %d)", \ file.name, php.serialize(files[filename].info), \ 'plugin', file.filename, 0, bootstrap) files = _plugin_build_dependencies(files) return files
def rebuild_cache(): """ Rebuild the database cache of plugin files. @return The array of filesystem objects used to rebuild the cache. """ # Get current list of plugins files = drupal_system_listing('\.plugin$', 'plugins', 'name', 0) # Extract current files from database. system_get_files_database(files, 'plugin') ksort(files) # Set defaults for plugin info defaults = { 'dependencies' : [], 'dependents' : [], 'description' : '', 'version' : None, 'php' : DRUPAL_MINIMUM_PHP, } for filename,file in files.items(): # Look for the info file. file.info = drupal_parse_info_file(php.dirname(file.filename) + '/' + \ file.name + '.info') # Skip plugins that don't provide info. if (php.empty(file.info)): del(files[filename]) continue # Merge in defaults and save. files[filename].info = file.info + defaults # Invoke hook_system_info_alter() to give installed plugins a chance to # modify the data in the .info files if necessary. drupal_alter('system_info', files[filename].info, files[filename]) # Log the critical hooks implemented by this plugin. bootstrap = 0 for hook in bootstrap_hooks(): if (plugin_hook(file.name, hook)): bootstrap = 1 break # Update the contents of the system table: if (php.isset(file, 'status') or (php.isset(file, 'old_filename') and \ file.old_filename != file.filename)): db_query(\ "UPDATE {system} SET info = '%s', name = '%s', " + \ "filename = '%s', bootstrap = %d WHERE filename = '%s'", \ php.serialize(files[filename].info), file.name, \ file.filename, bootstrap, file.old_filename) else: # This is a new plugin. files[filename].status = 0 db_query(\ "INSERT INTO {system} (name, info, type, " + \ "filename, status, bootstrap) VALUES " + \ "('%s', '%s', '%s', '%s', %d, %d)", \ file.name, php.serialize(files[filename].info), \ 'plugin', file.filename, 0, bootstrap) files = _plugin_build_dependencies(files) return files
def drupal_init_path(): """ Initialize the php.GET['q'] variable to the proper normal path. """ if (php.isset(php.GET, 'q') and not php.empty(php.GET['q'])): php.GET['q'] = drupal_get_normal_path(php.trim(php.GET['q'], '/')) else: php.GET['q'] = drupal_get_normal_path( \ lib_bootstrap.variable_get('site_frontpage', 'node'))
def drupal_unpack(obj, field='data'): """ Unserializes and appends elements from a serialized string. @param obj The object to which the elements are appended. @param field The attribute of obj whose value should be unserialized. """ if hasattr(obj, field) and not php.empty(getattr(obj, field)): data = php.unserialize(getattr(obj, field)) else: data = None if (hasattr(obj, field) and not php.empty(data)): for key, value in data.items(): if (not php.isset(obj, key)): setattr(obj, key, value) return obj
def drupal_unpack(obj, field="data"): """ Unserializes and appends elements from a serialized string. @param obj The object to which the elements are appended. @param field The attribute of obj whose value should be unserialized. """ if hasattr(obj, field) and not php.empty(getattr(obj, field)): data = php.unserialize(getattr(obj, field)) else: data = None if hasattr(obj, field) and not php.empty(data): for key, value in data.items(): if not php.isset(obj, key): setattr(obj, key, value) return obj
def initialize(): """ Choose a language for the page, based on language negotiation settings. """ # Configured presentation language mode. mode = variable_get('language_negotiation', \ lib_bootstrap.LANGUAGE_NEGOTIATION_NONE) # Get a list of enabled languages. languages = lib_bootstrap.language_list('enabled') languages = languages[1] if mode == lib_bootstrap.LANGUAGE_NEGOTIATION_NONE: return language_default() elif mode == lib_bootstrap.LANGUAGE_NEGOTIATION_DOMAIN: for language in languages: parts = php.parse_url(language.domain) if (not php.empty(parts['host']) and \ (php.SERVER['php.SERVER_NAME'] == parts['host'])): return language return language_default() elif mode == lib_bootstrap.LANGUAGE_NEGOTIATION_PATH_DEFAULT or \ mode == lib_bootstrap.LANGUAGE_NEGOTIATION_PATH: # _GET['q'] might not be available at this time, because # path initialization runs after the language bootstrap phase. args = (php.explode('/', _GET['q']) if php.isset(_GET, 'q') else []) prefix = php.array_shift(args) # Search prefix within enabled languages. for language in languages: if (not php.empty(language.prefix) and language.prefix == prefix): # Rebuild php.GET['q'] with the language removed. php.GET['q'] = php.implode('/', args) return language if (mode == LANGUAGE_NEGOTIATION_PATH_DEFAULT): # If we did not found the language by prefix, choose the default. return language_default() # User language. if (lib_appglobals.user.uid and \ php.isset(languages[lib_appglobals.user.language])): return languages[lib_appglobals.user.language] # Browser accept-language parsing. language = language_from_browser() if (language): return language # Fall back on the default if everything else fails. return language_default()
def write(key, value): # If saving of session data is disabled or if the client # doesn't have a session, # and one isn't being created ($value), do nothing. # This keeps crawlers out of # the session table. This reduces memory and server load, # and gives more useful # statistics. We can't eliminate anonymous session table rows # without breaking # the "Who's Online" block. if (not session_save_session() or \ (php.empty(php.COOKIE[php.session_name()]) and php.empty(value))): return True result = db_result(db_query("SELECT COUNT(*) FROM {sessions} " + \ "WHERE sid = '%s'", key)) lib_database.query(\ "UPDATE {sessions} SET " + \ "uid = %d, cache = %d, hostname = '%s', " + \ "session = '%s', timestamp = %d WHERE sid = '%s'", \ lib_appglobals.user.uid, (lib_appglobals.user.cache if \ php.isset(lib_appglobals.user.cache) else ''), \ ip_address(), value, php.time_(), key) if (lib_database.affected_rows()): # Last access time is updated no more frequently than once # every 180 seconds. # This reduces contention in the users table. if (lib_appglobals.user.uid and \ drupy_time() - lib_appglobals.user.access > \ variable_get('session_write_interval', 180)): db_query("UPDATE {users} SET access = %d WHERE uid = %d", \ php.time_(), lib_appglobals.user.uid) else: # If this query fails, another parallel request probably got here first. # In that case, any session data generated in this request is discarded. lib_databae.query(\ "INSERT INTO {sessions} " + \ "(sid, uid, cache, hostname, session, timestamp) " + \ "VALUES ('%s', %d, %d, '%s', '%s', %d)", \ key, lib_appglobals.user.uid, (lib_appglobals.user.cache if \ php.isset(lib_appglobals.user.cache) else ''), \ ip_address(), value, php.time_()) return True
def theme_breadcrumb(breadcrumb): """ Return a themed breadcrumb trail. @param breadcrumb An array containing the breadcrumb links. @return a string containing the breadcrumb output. """ if (not php.empty(breadcrumb)): return '<div class="breadcrumb">' + \ php.implode(' › ', breadcrumb) + '</div>'
def _rewrite_sql(query = '', primary_table = 'n', primary_field = 'nid', \ args = []): where = [] join_ = [] distinct = False for plugin in lib_plugin.implements('db_rewrite_sql'): result = lib_plugin.invoke(plugin, 'db_rewrite_sql', query, \ primary_table, primary_field, args) if (php.isset(result) and php.is_array(result)): if (php.isset(result['where'])): where.append( result['where'] ) if (php.isset(result['join'])): join_.append( result['join'] ) if (php.isset(result['distinct']) and result['distinct']): distinct = True elif (php.isset(result)): where.append( result ) where = ('' if php.empty(where) else \ ('(' + php.implode(') AND (', where) + ')') ) join_ = ('' if php.empty(join) else php.implode(' ', join)) return (join, where, distinct)
def drupal_get_schema(table=None, rebuild=False): """ Get the schema definition of a table, or the whole database schema. The returned schema will include any modifications made by any module that implements hook_schema_alter(). @param $table The name of the table. If not given, the schema of all tables is returned. @param $rebuild If true, the schema will be rebuilt instead of retrieved from the cache. """ php.static(drupal_get_schema, "schema", []) if php.empty(drupal_get_schema.schema) or rebuild: # Try to load the schema from cache. cached = lib_cache.get("schema") if not rebuild and cached: drupal_get_schema.schema = cached.data # Otherwise, rebuild the schema cache. else: drupal_get_schema.schema = [] # Load the .install files to get hook_schema. # On some databases this function may be called before bootstrap has # been completed, so we force the functions we need to load just in case. if drupal_function_exists("module_load_all_includes"): # There is currently a bug in module_list() where it caches what it # was last called with, which is not always what you want. # module_load_all_includes() calls module_list(), but if this function # is called very early in the bootstrap process then it will be # uninitialized and therefore return no modules. Instead, we have to # "prime" module_list() here to to values we want, specifically # "yes rebuild the list and don't limit to bootstrap". # TODO: Remove this call after http://drupal.org/node/222109 is fixed. lib_plugin.list(True, False) lib_plugin.load_all_includes("install") # Invoke hook_schema for all modules. for module in module_implements("schema"): current = lib_plugin.invoke(module, "schema") if drupal_function_exists("_drupal_initialize_schema"): _drupal_initialize_schema(module, current) schema = php.array_merge(schema, current) if drupal_function_exists("drupal_alter"): drupal_alter("schema", schema) if drupal_get_bootstrap_phase() == DRUPAL_BOOTSTRAP_FULL: cache_set("schema", schema) if table is None: return schema elif php.isset(schema, table): return schema[table] else: return False
def drupal_get_schema(table=None, rebuild=False): """ Get the schema definition of a table, or the whole database schema. The returned schema will include any modifications made by any module that implements hook_schema_alter(). @param $table The name of the table. If not given, the schema of all tables is returned. @param $rebuild If true, the schema will be rebuilt instead of retrieved from the cache. """ php.static(drupal_get_schema, 'schema', []) if (php.empty(drupal_get_schema.schema) or rebuild): # Try to load the schema from cache. cached = lib_cache.get('schema') if (not rebuild and cached): drupal_get_schema.schema = cached.data # Otherwise, rebuild the schema cache. else: drupal_get_schema.schema = [] # Load the .install files to get hook_schema. # On some databases this function may be called before bootstrap has # been completed, so we force the functions we need to load just in case. if (drupal_function_exists('module_load_all_includes')): # There is currently a bug in module_list() where it caches what it # was last called with, which is not always what you want. # module_load_all_includes() calls module_list(), but if this function # is called very early in the bootstrap process then it will be # uninitialized and therefore return no modules. Instead, we have to # "prime" module_list() here to to values we want, specifically # "yes rebuild the list and don't limit to bootstrap". # TODO: Remove this call after http://drupal.org/node/222109 is fixed. lib_plugin.list(True, False) lib_plugin.load_all_includes('install') # Invoke hook_schema for all modules. for module in module_implements('schema'): current = lib_plugin.invoke(module, 'schema') if (drupal_function_exists('_drupal_initialize_schema')): _drupal_initialize_schema(module, current) schema = php.array_merge(schema, current) if (drupal_function_exists('drupal_alter')): drupal_alter('schema', schema) if (drupal_get_bootstrap_phase() == DRUPAL_BOOTSTRAP_FULL): cache_set('schema', schema) if (table is None): return schema elif (php.isset(schema, table)): return schema[table] else: return False
def registry_load_path_files(return_=False): """ registry_load_path_files """ php.static(registry_load_path_files, 'file_cache_data', []) if (return_): sort(registry_load_path_files.file_cache_data) return registry_load_path_files.file_cache_data menu = menu_get_item() cache = cache_get('registry:' + menu['path'], 'cache_registry') if (not php.empty(cache.data)): for file in php.explode(';', cache.data): php.require_once(file) registry_load_path_files.file_cache_data.append(file)
def registry_load_path_files(return_=False): """ registry_load_path_files """ php.static(registry_load_path_files, "file_cache_data", []) if return_: sort(registry_load_path_files.file_cache_data) return registry_load_path_files.file_cache_data menu = menu_get_item() cache = cache_get("registry:" + menu["path"], "cache_registry") if not php.empty(cache.data): for file in php.explode(";", cache.data): php.require_once(file) registry_load_path_files.file_cache_data.append(file)
def validate_is_image(file): """ Check that the file is recognized by image_get_info() as an image. @param file A Drupal file object. @return An array + If the file is not an image, it will contain an error message. """ errors = [] info = image_get_info(file.filepath) if (not info or not php.isset(info, 'extension') or \ php.empty(info['extension'])): errors.append( t('Only JPEG, PNG and GIF images are allowed.') ) return errors
def validate_is_image(file): """ Check that the file is recognized by image_get_info() as an image. @param file A Drupal file object. @return An array + If the file is not an image, it will contain an error message. """ errors = [] info = image_get_info(file.filepath) if (not info or not php.isset(info, 'extension') or \ php.empty(info['extension'])): errors.append(t('Only JPEG, PNG and GIF images are allowed.')) return errors
def header(cell, header, ts): """ Format a column header. If the cell in question is the column header for the current sort criterion, it gets special formatting. All possible sort criteria become links. @param cell The cell to format. @param header An array of column headers in the format described in theme_table(). @param ts The current table sort context as returned from hook_init(). @return A properly formatted cell, ready for _theme_table_cell(). """ # Special formatting for the currently sorted column header. if php.is_array(cell) and php.isset(cell['field']): title = t('sort by @s', {'@s': cell['data']}) if cell['data'] == ts['name']: ts['sort'] = ('desc' if (ts['sort'] == 'asc') else 'asc') if php.isset(cell['class']): cell['class'] += ' active' else: cell['class'] = 'active' image = lib_theme.theme('tablesort_indicator', ts['sort']) else: # If the user clicks a different header, we want to sort ascending # initially. ts['sort'] = 'asc' image = '' if not php.empty(ts['query_string']): ts['query_string'] = '&' + ts['query_string'] cell['data'] = l( cell['data'] + image, php.GET['q'], { 'attributes': { 'title': title, 'query': 'sort=' + ts['sort'] + '&order=' + rawurlencode(cell['data']) + ts['query_string'], 'html': TRUE } } ) php.unset(cell['field'], cell['sort']) return cell
def add_field(ret, table, field, spec, keys_new=[]): """ Add a new field to a table. @param ret Array to which query results will be added. @param table Name of the table to be altered. @param field Name of the field to be added. @param spec The field specification array, as taken from a schema definition. The specification may also contain the key 'initial', the newly created field will be set to the value of the key in all rows. This is most useful for creating NOT None columns with no default value in existing tables. @param keys_new Optional keys and indexes specification to be created on the table along with adding the field. The format is the same as a table specification but without the 'fields' element. If you are adding a type 'serial' field, you MUST specify at least one key or index including it in this array. @see db_change_field for more explanation why. """ php.Reference.check(ret) fixNone = False if (not php.empty(spec['not None']) and not php.isset(spec, 'default')): fixNone = True spec['not None'] = False query = 'ALTER TABLE {' + table + '} ADD ' query += _db_create_field_sql(field, _db_process_field(spec)) if (php.count(keys_new)): query += ', ADD ' + php.implode(', ADD ', _db_create_keys_sql(keys_new)) ret.append(update_sql(query)) if (php.isset(spec, 'initial')): # All this because update_sql does not support %-placeholders. sql = 'UPDATE {' + table + '} SET ' + field + ' = ' + \ db_type_placeholder(spec['type']) result = db_query(sql, spec['initial']) ret.append( {'success' : result != False, \ 'query' : check_plain(sql + ' (' + spec['initial'] + ')')}) if (fixNone): spec['not None'] = True db_change_field(ret, table, field, field, spec)
def add_field(ret, table, field, spec, keys_new = []): """ Add a new field to a table. @param ret Array to which query results will be added. @param table Name of the table to be altered. @param field Name of the field to be added. @param spec The field specification array, as taken from a schema definition. The specification may also contain the key 'initial', the newly created field will be set to the value of the key in all rows. This is most useful for creating NOT None columns with no default value in existing tables. @param keys_new Optional keys and indexes specification to be created on the table along with adding the field. The format is the same as a table specification but without the 'fields' element. If you are adding a type 'serial' field, you MUST specify at least one key or index including it in this array. @see db_change_field for more explanation why. """ php.Reference.check(ret) fixNone = False if (not php.empty(spec['not None']) and not php.isset(spec, 'default')): fixNone = True spec['not None'] = False query = 'ALTER TABLE {' + table + '} ADD ' query += _db_create_field_sql(field, _db_process_field(spec)) if (php.count(keys_new)): query += ', ADD ' + php.implode(', ADD ', _db_create_keys_sql(keys_new)) ret.append( update_sql(query) ) if (php.isset(spec, 'initial')): # All this because update_sql does not support %-placeholders. sql = 'UPDATE {' + table + '} SET ' + field + ' = ' + \ db_type_placeholder(spec['type']) result = db_query(sql, spec['initial']) ret.append( {'success' : result != False, \ 'query' : check_plain(sql + ' (' + spec['initial'] + ')')}) if (fixNone): spec['not None'] = True db_change_field(ret, table, field, field, spec)
def load_include(type_, plugin_, name=None): """ Load a plugin include file. @param type The include file's type (file extension). @param plugin The plugin to which the include file belongs. @param name Optionally, specify the file name. If not set, the plugin's name is used. """ if (php.empty(name)): name = plugin_ file = './' + drupal_get_path('plugin', plugin) + "/name.type" if (php.is_file(file)): php.require_once(file) return file else: return False
def load_include(type_, plugin_, name = None): """ Load a plugin include file. @param type The include file's type (file extension). @param plugin The plugin to which the include file belongs. @param name Optionally, specify the file name. If not set, the plugin's name is used. """ if (php.empty(name)): name = plugin_ file = './' + drupal_get_path('plugin', plugin) + "/name.type" if (php.is_file(file)): php.require_once( file ) return file else: return False
def implements(hook_, sort=False, refresh=False): """ Determine which plugins are implementing a hook. @param hook The name of the hook (e.g. "help" or "menu"). @param sort By default, plugins are ordered by weight and filename, settings this option to True, plugin list will be ordered by plugin name. @param refresh For internal use only: Whether to force the stored list of hook implementations to be regenerated (such as after enabling a new plugin, before processing hook_enable). @return An array with the names of the plugins which are implementing this hook. """ php.static(implements, 'implementations', {}) if (refresh): implements.implementations = {} elif (not lib_bootstrap.MAINTENANCE_MODE and \ php.empty(implements.implementations)): cache = lib_cache.get('hooks', 'cache_registry') if (cache): implements.implementations = cache.data implements.implementations = \ lib_bootstrap.registry_get_hook_implementations_cache() if (not php.isset(implements.implementations, hook)): implements.implementations[hook_] = [] for plugin_ in list_(): if (hook(plugin_, hook_)): implements.implementations[hook_].append(plugin_) lib_bootstrap.registry_cache_hook_implementations({'hook' : hook_, \ 'plugins' : implements.implementations[hook_]}) # The explicit cast forces a copy to be made. This is needed because # implementations[hook] is only a reference to an element of # implementations and if there are nested foreaches (due to nested node # API calls, for example), they would both manipulate the same array's # references, which causes some plugins' hooks not to be called. # See also http://www.zend.com/zend/art/ref-count.php. return implements.implementations[hook_]
def implements(hook_, sort = False, refresh = False): """ Determine which plugins are implementing a hook. @param hook The name of the hook (e.g. "help" or "menu"). @param sort By default, plugins are ordered by weight and filename, settings this option to True, plugin list will be ordered by plugin name. @param refresh For internal use only: Whether to force the stored list of hook implementations to be regenerated (such as after enabling a new plugin, before processing hook_enable). @return An array with the names of the plugins which are implementing this hook. """ php.static(implements, 'implementations', {}) if (refresh): implements.implementations = {} elif (not lib_bootstrap.MAINTENANCE_MODE and \ php.empty(implements.implementations)): cache = lib_cache.get('hooks', 'cache_registry') if (cache): implements.implementations = cache.data; implements.implementations = \ lib_bootstrap.registry_get_hook_implementations_cache() if (not php.isset(implements.implementations, hook)): implements.implementations[hook_] = [] for plugin_ in list_(): if (hook(plugin_, hook_)): implements.implementations[hook_].append( plugin_ ) lib_bootstrap.registry_cache_hook_implementations({'hook' : hook_, \ 'plugins' : implements.implementations[hook_]}); # The explicit cast forces a copy to be made. This is needed because # implementations[hook] is only a reference to an element of # implementations and if there are nested foreaches (due to nested node # API calls, for example), they would both manipulate the same array's # references, which causes some plugins' hooks not to be called. # See also http://www.zend.com/zend/art/ref-count.php. return implements.implementations[hook_]
def page_get_cache(): """ Retrieve the current page from the cache. Note: we do not serve cached pages when status messages are waiting (from a redirected form submission which was completed). @param status_only When set to TRUE, retrieve the status of the page cache only (whether it was started in this request or not). """ cache = None if (not lib_appglobals.user.uid and \ (php.SERVER['REQUEST_METHOD'] == 'GET' or \ php.SERVER['REQUEST_METHOD'] == 'HEAD') and \ php.count(drupal_set_message()) == 0): cache = lib_cache.get(lib_appglobals.base_root + request_uri(), \ 'cache_page') if (php.empty(cache)): ob_start() return cache
def page_get_cache(): """ Retrieve the current page from the cache. Note: we do not serve cached pages when status messages are waiting (from a redirected form submission which was completed). @param status_only When set to TRUE, retrieve the status of the page cache only (whether it was started in this request or not). """ cache = None if ( not lib_appglobals.user.uid and (php.SERVER["REQUEST_METHOD"] == "GET" or php.SERVER["REQUEST_METHOD"] == "HEAD") and php.count(drupal_set_message()) == 0 ): cache = lib_cache.get(lib_appglobals.base_root + request_uri(), "cache_page") if php.empty(cache): ob_start() return cache
def ip_address(reset=False): """ If Drupal is behind a reverse proxy, we use the X-Forwarded-For header instead of $_SERVER['REMOTE_ADDR'], which would be the IP address of the proxy server, and not the client's. If Drupal is run in a cluster we use the X-Cluster-Client-Ip header instead. @param $reset Reset the current IP address saved in static. @return IP address of client machine, adjusted for reverse proxy and/or cluster environments. """ php.static(ip_address, 'ip_address') if (ip_address.ip_address is None or reset): ip_address.ip_address = php.SERVER['REMOTE_ADDR'] if (variable_get('reverse_proxy', 0)): if (php.array_key_exists('HTTP_X_FORWARDED_FOR', php.SERVER)): # If an array of known reverse proxy IPs is provided, then trust # the XFF header if request really comes from one of them. reverse_proxy_addresses = variable_get('reverse_proxy_addresses', \ tuple()) if (not php.empty(reverse_proxy_addresses) and \ php.in_array(ip_address.ip_address, reverse_proxy_addresses, \ True)): # If there are several arguments, we need to check the most # recently added one, i.e. the last one. ip_address.ip_address = php.array_pop(\ php.explode(',', php.SERVER['HTTP_X_FORWARDED_FOR'])) # When Drupal is run in a cluster environment, # REMOTE_ADDR contains the IP # address of a server in the cluster, while the IP address # of the client is # stored in HTTP_X_CLUSTER_CLIENT_IP. if (php.array_key_exists('HTTP_X_CLUSTER_CLIENT_IP', php.SERVER)): ip_address.ip_address = php.SERVER['HTTP_X_CLUSTER_CLIENT_IP'] return ip_address.ip_address
def conf_init(): """ Loads the configuration and sets the base URL, cookie domain, and session name correctly. """ # These will come from settings # db_url, db_prefix, cookie_domain, conf, installed_profile, update_free_access if lib_appglobals.base_url != None: # Parse fixed base URL from settings.php. parts = php.parse_url(lib_appglobals.base_url) if not php.isset(parts, "path"): parts["path"] = "" lib_appglobals.base_path = parts["path"] + "/" # Build base_root (everything until first slash after "scheme://"). lib_appglobals.base_root = php.substr( lib_appglobals.base_url, 0, php.strlen(lib_appglobals.base_url) - php.strlen(parts["path"]) ) else: # Create base URL lib_appglobals.base_root = ( "https" if (php.isset(php.SERVER, "HTTPS") and php.SERVER["HTTPS"] == "on") else "http" ) # As php.SERVER['HTTP_HOST'] is user input, ensure it only contains # characters allowed in hostnames. lib_appglobals.base_root += "://" + php.preg_replace("/[^a-z0-9-:._]/i", "", php.SERVER["HTTP_HOST"]) lib_appglobals.base_url = lib_appglobals.base_root # php.SERVER['SCRIPT_NAME'] can, in contrast to php.SERVER['PHP_SELF'], not # be modified by a visitor. dir = php.trim(php.dirname(php.SERVER["SCRIPT_NAME"]), "\,/") if len(dir) > 0: lib_appglobals.base_path = "/dir" lib_appglobals.base_url += lib_appglobals.base_path lib_appglobals.base_path += "/" else: lib_appglobals.base_path = "/" if settings.cookie_domain != None: # If the user specifies the cookie domain, also use it for session name. session_name_ = settings.cookie_domain else: # Otherwise use base_url as session name, without the protocol # to use the same session identifiers across http and https. session_name_ = php.explode("://", lib_appglobals.base_url, 2)[1] # We escape the hostname because it can be modified by a visitor. if not php.empty(php.SERVER["HTTP_HOST"]): settings.cookie_domain = check_plain(php.SERVER["HTTP_HOST"]) # To prevent session cookies from being hijacked, a user can configure the # SSL version of their website to only transfer session cookies via SSL by # using PHP's session.cookie_secure setting. The browser will then use two # separate session cookies for the HTTPS and HTTP versions of the site. So we # must use different session identifiers for HTTPS and HTTP to prevent a # cookie collision. if php.ini_get("session.cookie_secure"): session_name_ += "SSL" # Strip leading periods, www., and port numbers from cookie domain. settings.cookie_domain = php.ltrim(settings.cookie_domain, ".") if php.strpos(settings.cookie_domain, "www.") == 0: settings.cookie_domain = php.substr(settings.cookie_domain, 4) settings.cookie_domain = php.explode(":", settings.cookie_domain) settings.cookie_domain = "." + settings.cookie_domain[0] # Per RFC 2109, cookie domains must contain at least one dot other than the # first. For hosts such as 'localhost' or IP Addresses we don't set a # cookie domain. if php.count(php.explode(".", settings.cookie_domain)) > 2 and not php.is_numeric( php.str_replace(".", "", settings.cookie_domain) ): php.ini_set("session.cookie_domain", settings.cookie_domain) # print session_name; lib_session.name("SESS" + php.md5(session_name_))
def template_preprocess_maintenance_page(variables): """ The variables generated here is a mirror of template_preprocess_page(). This preprocessor will run it's course when theme_maintenance_page() is invoked. It is also used in theme_install_page() and theme_update_page() to keep all the variables consistent. An alternate template file of "maintenance-page-offline.tpl.php" can be used when the database is offline to hide errors and completely replace the content. The variables array contains the following arguments: - content - show_blocks @see maintenance-page.tpl.php """ php.Reference.check(variables) # Add favicon if (theme_get_setting('toggle_favicon')): drupal_set_html_head('<link rel="shortcut icon" href="' + \ check_url(theme_get_setting('favicon')) + '" type="image/x-icon" />') # Retrieve the theme data to list all available regions. theme_data = _system_theme_data() regions = theme_data[lib_appglobals.theme].info['regions'] # Get all region content set with drupal_set_content(). for region in php.array_keys(regions): # Assign region to a region variable. region_content = drupal_get_content(region) if php.isset(variables, region): variables[region] += region_content else: variables[region] = region_content # Setup layout variable. variables['layout'] = 'none' if (not php.empty(variables['left'])): variables['layout'] = 'left' if (not php.empty(variables['right'])): variables['layout'] = ('both' if \ (variables['layout'] == 'left') else 'right') # Construct page title if (drupal_get_title()): head_title = [strip_tags(drupal_get_title()), \ variable_get('site_name', 'Drupal')] else: head_title = [variable_get('site_name', 'Drupal')] if (variable_get('site_slogan', '')): head_title.append(variable_get('site_slogan', '')) variables['head_title'] = php.implode(' | ', head_title) variables['base_path'] = base_path() variables['front_page'] = url() variables['breadcrumb'] = '' variables['feed_icons'] = '' variables['footer_message'] = \ filter_xss_admin(variable_get('site_footer', FALSE)) variables['head'] = drupal_get_html_head() variables['help'] = '' variables['language'] = lib_appglobals.language variables['language'].dir = \ ('rtl' if lib_appglobals.language.direction else 'ltr') variables['logo'] = theme_get_setting('logo') variables['messages'] = (theme('status_messages') if \ variables['show_messages'] else '') variables['mission'] = '' variables['main_menu'] = [] variables['secondary_menu'] = [] variables['search_box'] = '' variables['site_name'] = \ (variable_get('site_name', 'Drupal') if \ theme_get_setting('toggle_name') else '') variables['site_slogan'] = (variable_get('site_slogan', '') if \ theme_get_setting('toggle_slogan') else '') variables['css'] = drupal_add_css() variables['styles'] = drupal_get_css() variables['scripts'] = drupal_get_js() variables['tabs'] = '' variables['title'] = drupal_get_title() variables['closure'] = '' # Compile a list of classes that are going to be applied to the body element. body_classes = [] body_classes.append('in-maintenance') if (php.isset(variables, 'db_is_active') and \ not variables['db_is_active']): body_classes.append('db-offline') if (variables['layout'] == 'both'): body_classes.append('two-sidebars') elif (variables['layout'] == 'none'): body_classes.append('no-sidebars') else: body_classes.append('one-sidebar sidebar-' + variables['layout']) variables['body_classes'] = php.implode(' ', body_classes) # Dead databases will show error messages so supplying this template will # allow themers to override the page and the content completely. if (php.isset(variables, 'db_is_active') and \ not variables['db_is_active']): variables['template_file'] = 'maintenance-page-offline'
def template_preprocess_maintenance_page(variables): """ The variables generated here is a mirror of template_preprocess_page(). This preprocessor will run it's course when theme_maintenance_page() is invoked. It is also used in theme_install_page() and theme_update_page() to keep all the variables consistent. An alternate template file of "maintenance-page-offline.tpl.php" can be used when the database is offline to hide errors and completely replace the content. The variables array contains the following arguments: - content - show_blocks @see maintenance-page.tpl.php """ php.Reference.check(variables) # Add favicon if (theme_get_setting('toggle_favicon')): drupal_set_html_head('<link rel="shortcut icon" href="' + \ check_url(theme_get_setting('favicon')) + '" type="image/x-icon" />'); # Retrieve the theme data to list all available regions. theme_data = _system_theme_data() regions = theme_data[lib_appglobals.theme].info['regions'] # Get all region content set with drupal_set_content(). for region in php.array_keys(regions): # Assign region to a region variable. region_content = drupal_get_content(region) if php.isset(variables, region): variables[region] += region_content else: variables[region] = region_content # Setup layout variable. variables['layout'] = 'none' if (not php.empty(variables['left'])): variables['layout'] = 'left' if (not php.empty(variables['right'])): variables['layout'] = ('both' if \ (variables['layout'] == 'left') else 'right') # Construct page title if (drupal_get_title()): head_title = [strip_tags(drupal_get_title()), \ variable_get('site_name', 'Drupal')]; else: head_title = [variable_get('site_name', 'Drupal')] if (variable_get('site_slogan', '')): head_title.append( variable_get('site_slogan', '') ) variables['head_title'] = php.implode(' | ', head_title) variables['base_path'] = base_path() variables['front_page'] = url() variables['breadcrumb'] = '' variables['feed_icons'] = '' variables['footer_message'] = \ filter_xss_admin(variable_get('site_footer', FALSE)) variables['head'] = drupal_get_html_head() variables['help'] = '' variables['language'] = lib_appglobals.language variables['language'].dir = \ ('rtl' if lib_appglobals.language.direction else 'ltr') variables['logo'] = theme_get_setting('logo'); variables['messages'] = (theme('status_messages') if \ variables['show_messages'] else '') variables['mission'] = ''; variables['main_menu'] = []; variables['secondary_menu'] = []; variables['search_box'] = ''; variables['site_name'] = \ (variable_get('site_name', 'Drupal') if \ theme_get_setting('toggle_name') else '') variables['site_slogan'] = (variable_get('site_slogan', '') if \ theme_get_setting('toggle_slogan') else '') variables['css'] = drupal_add_css() variables['styles'] = drupal_get_css() variables['scripts'] = drupal_get_js() variables['tabs'] = '' variables['title'] = drupal_get_title(); variables['closure'] = '' # Compile a list of classes that are going to be applied to the body element. body_classes = [] body_classes.append( 'in-maintenance' ) if (php.isset(variables, 'db_is_active') and \ not variables['db_is_active']): body_classes.append( 'db-offline' ) if (variables['layout'] == 'both'): body_classes.append( 'two-sidebars' ) elif (variables['layout'] == 'none'): body_classes.append( 'no-sidebars' ) else: body_classes.append( 'one-sidebar sidebar-' + variables['layout'] ) variables['body_classes'] = php.implode(' ', body_classes) # Dead databases will show error messages so supplying this template will # allow themers to override the page and the content completely. if (php.isset(variables, 'db_is_active') and \ not variables['db_is_active']): variables['template_file'] = 'maintenance-page-offline';
def save_upload(source, validators = {}, dest = False, \ replace = FILE_EXISTS_RENAME): """ Saves a file upload to a new location + The source file is validated as a proper upload and handled as such. The file will be added to the files table as a temporary file. Temporary files are periodically cleaned + To make the file permanent file call file_set_status() to change its status. @param source A string specifying the name of the upload field to save. @param validators An optional, associative array of callback functions used to validate the file + The keys are function names and the values arrays of callback parameters which will be passed in after the user and file objects + The functions should return an array of error messages, an empty array indicates that the file passed validation. The functions will be called in the order specified. @param dest A string containing the directory source should be copied to + If this is not provided or is not writable, the temporary directory will be used. @param replace A boolean indicating whether an existing file of the same name in the destination directory should overwritten + A False value will generate a new, unique filename in the destination directory. @return An object containing the file information, or False in the event of an error. """ php.static(file_save_upload, 'upload_cache', {}) # Add in our check of the the file name length. validators['file_validate_name_length'] = {} # Return cached objects without processing since the file will have # already been processed and the paths in FILES will be invalid. if (php.isset(file_save_upload.uploadcache, source)): return file_save_upload.uploadcache[source] # If a file was uploaded, process it. if (php.isset(p.FILES, 'files') and p.FILES['files']['name'][source] and \ php.is_uploaded_file(p.FILES['files']['tmp_name'][source])): # Check for file upload errors and return False if a # lower level system error occurred. # @see http://php.net/manual/en/features.file-upload.errors.php if p.FILES['files']['error'][source] == UPLOAD_ERR_OK: pass elif p.FILES['files']['error'][source] == UPLOAD_ERR_INI_SIZE or \ p.FILES['files']['error'][source] == UPLOAD_ERR_FORM_SIZE: drupal_set_message(t(\ 'The file %file could not be saved, because it exceeds %maxsize, ' + \ 'the maximum allowed size for uploads.', \ {'%file' : source, '%maxsize' : \ format_size(file_upload_max_size())}), 'error') return False elif p.FILES['files']['error'][source] == UPLOAD_ERR_PARTIAL or \ p.FILES['files']['error'][source] == UPLOAD_ERR_NO_FILE: drupal_set_message(t('The file %file could not be saved, ' + \ 'because the upload did not complete.', {'%file' : source}), 'error') return False # Unknown error else: drupal_set_message(t('The file %file could not be saved. ' + \ 'An unknown error has occurred.', {'%file' : source}), 'error') return False # Build the list of non-munged extensions. # @todo: this should not be here + we need to figure out the right place. extensions = '' for rid,name in lib_appglobals.user.roles.items(): extensions += ' ' + variable_get("upload_extensions_rid", variable_get('upload_extensions_default', \ 'jpg jpeg gif png txt html doc xls pdf ppt pps odt ods odp')) # Begin building file object. file = php.stdClass() file.filename = file_munge_filename(php.trim(\ basename(p.FILES['files']['name'][source]), '.'), extensions) file.filepath = p.FILES['files']['tmp_name'][source] file.filemime = p.FILES['files']['type'][source] # Rename potentially executable files, to help prevent exploits. if (php.preg_match('/\.(php|pl|py|cgi|asp|js)$/i', file.filename) and \ (php.substr(file.filename, -4) != '.txt')): file.filemime = 'text/plain' file.filepath += '.txt' file.filename += '.txt' # If the destination is not provided, or is not writable, then use the # temporary directory. if (php.empty(dest) or file_check_path(dest) == False): dest = file_directory_temp() file.source = source file.destination = file_destination(file_create_path(dest + '/' + \ file.filename), replace) file.filesize = FILES['files']['size'][source] # Call the validation functions. errors = {} for function,args in validators.items(): array_unshift(args, file) errors = php.array_merge(errors, function(*args)) # Check for validation errors. if (not php.empty(errors)): message = t('The selected file %name could not be uploaded.', \ {'%name' : file.filename}) if (php.count(errors) > 1): message += '<ul><li>' + php.implode('</li><li>', errors) + '</li></ul>' else: message += ' ' + php.array_pop(errors) form_set_error(source, message) return False # Move uploaded files from PHP's upload_tmp_dir to # Drupal's temporary directory. # This overcomes open_basedir restrictions for future file operations. file.filepath = file.destination if (not move_uploaded_file(p.FILES['files']['tmp_name'][source], \ file.filepath)): form_set_error(source, t('File upload error. ' + \ 'Could not move uploaded file.')) watchdog('file', 'Upload error + Could not move uploaded file ' + \ '%file to destination %destination.', \ {'%file' : file.filename, '%destination' : file.filepath}) return False # If we made it this far it's safe to record this file in the database. file.uid = lib_appglobals.user.uid file.status = FILE_STATUS_TEMPORARY file.timestamp = time() drupal_write_record('files', file) # Add file to the cache. file_save_upload.upload_cache[source] = file return file return False
def conf_init(): """ Loads the configuration and sets the base URL, cookie domain, and session name correctly. """ # These will come from settings # db_url, db_prefix, cookie_domain, conf, installed_profile, update_free_access if (lib_appglobals.base_url != None): # Parse fixed base URL from settings.php. parts = php.parse_url(lib_appglobals.base_url) if (not php.isset(parts, 'path')): parts['path'] = '' lib_appglobals.base_path = parts['path'] + '/' # Build base_root (everything until first slash after "scheme://"). lib_appglobals.base_root = \ php.substr(lib_appglobals.base_url, 0, \ php.strlen(lib_appglobals.base_url) - \ php.strlen(parts['path'])) else: # Create base URL lib_appglobals.base_root = \ ('https' if (php.isset(php.SERVER, 'HTTPS') and \ php.SERVER['HTTPS'] == 'on') else 'http') # As php.SERVER['HTTP_HOST'] is user input, ensure it only contains # characters allowed in hostnames. lib_appglobals.base_root += '://' + \ php.preg_replace('/[^a-z0-9-:._]/i', '', \ php.SERVER['HTTP_HOST']) lib_appglobals.base_url = lib_appglobals.base_root # php.SERVER['SCRIPT_NAME'] can, in contrast to php.SERVER['PHP_SELF'], not # be modified by a visitor. dir = php.trim(php.dirname(php.SERVER['SCRIPT_NAME']), '\,/') if (len(dir) > 0): lib_appglobals.base_path = "/dir" lib_appglobals.base_url += lib_appglobals.base_path lib_appglobals.base_path += '/' else: lib_appglobals.base_path = '/' if (settings.cookie_domain != None): # If the user specifies the cookie domain, also use it for session name. session_name_ = settings.cookie_domain else: # Otherwise use base_url as session name, without the protocol # to use the same session identifiers across http and https. session_name_ = php.explode('://', lib_appglobals.base_url, 2)[1] # We escape the hostname because it can be modified by a visitor. if (not php.empty(php.SERVER['HTTP_HOST'])): settings.cookie_domain = check_plain(php.SERVER['HTTP_HOST']) # To prevent session cookies from being hijacked, a user can configure the # SSL version of their website to only transfer session cookies via SSL by # using PHP's session.cookie_secure setting. The browser will then use two # separate session cookies for the HTTPS and HTTP versions of the site. So we # must use different session identifiers for HTTPS and HTTP to prevent a # cookie collision. if (php.ini_get('session.cookie_secure')): session_name_ += 'SSL' # Strip leading periods, www., and port numbers from cookie domain. settings.cookie_domain = php.ltrim(settings.cookie_domain, '.') if (php.strpos(settings.cookie_domain, 'www.') == 0): settings.cookie_domain = php.substr(settings.cookie_domain, 4) settings.cookie_domain = php.explode(':', settings.cookie_domain) settings.cookie_domain = '.' + settings.cookie_domain[0] # Per RFC 2109, cookie domains must contain at least one dot other than the # first. For hosts such as 'localhost' or IP Addresses we don't set a # cookie domain. if (php.count(php.explode('.', settings.cookie_domain)) > 2 and not \ php.is_numeric(php.str_replace('.', '', settings.cookie_domain))): php.ini_set('session.cookie_domain', settings.cookie_domain) #print session_name; lib_session.name('SESS' + php.md5(session_name_))
def save_upload(source, validators = {}, dest = False, \ replace = FILE_EXISTS_RENAME): """ Saves a file upload to a new location + The source file is validated as a proper upload and handled as such. The file will be added to the files table as a temporary file. Temporary files are periodically cleaned + To make the file permanent file call file_set_status() to change its status. @param source A string specifying the name of the upload field to save. @param validators An optional, associative array of callback functions used to validate the file + The keys are function names and the values arrays of callback parameters which will be passed in after the user and file objects + The functions should return an array of error messages, an empty array indicates that the file passed validation. The functions will be called in the order specified. @param dest A string containing the directory source should be copied to + If this is not provided or is not writable, the temporary directory will be used. @param replace A boolean indicating whether an existing file of the same name in the destination directory should overwritten + A False value will generate a new, unique filename in the destination directory. @return An object containing the file information, or False in the event of an error. """ php.static(file_save_upload, 'upload_cache', {}) # Add in our check of the the file name length. validators['file_validate_name_length'] = {} # Return cached objects without processing since the file will have # already been processed and the paths in FILES will be invalid. if (php.isset(file_save_upload.uploadcache, source)): return file_save_upload.uploadcache[source] # If a file was uploaded, process it. if (php.isset(p.FILES, 'files') and p.FILES['files']['name'][source] and \ php.is_uploaded_file(p.FILES['files']['tmp_name'][source])): # Check for file upload errors and return False if a # lower level system error occurred. # @see http://php.net/manual/en/features.file-upload.errors.php if p.FILES['files']['error'][source] == UPLOAD_ERR_OK: pass elif p.FILES['files']['error'][source] == UPLOAD_ERR_INI_SIZE or \ p.FILES['files']['error'][source] == UPLOAD_ERR_FORM_SIZE: drupal_set_message(t(\ 'The file %file could not be saved, because it exceeds %maxsize, ' + \ 'the maximum allowed size for uploads.', \ {'%file' : source, '%maxsize' : \ format_size(file_upload_max_size())}), 'error') return False elif p.FILES['files']['error'][source] == UPLOAD_ERR_PARTIAL or \ p.FILES['files']['error'][source] == UPLOAD_ERR_NO_FILE: drupal_set_message(t('The file %file could not be saved, ' + \ 'because the upload did not complete.', {'%file' : source}), 'error') return False # Unknown error else: drupal_set_message(t('The file %file could not be saved. ' + \ 'An unknown error has occurred.', {'%file' : source}), 'error') return False # Build the list of non-munged extensions. # @todo: this should not be here + we need to figure out the right place. extensions = '' for rid, name in lib_appglobals.user.roles.items(): extensions += ' ' + variable_get("upload_extensions_rid", variable_get('upload_extensions_default', \ 'jpg jpeg gif png txt html doc xls pdf ppt pps odt ods odp')) # Begin building file object. file = php.stdClass() file.filename = file_munge_filename(php.trim(\ basename(p.FILES['files']['name'][source]), '.'), extensions) file.filepath = p.FILES['files']['tmp_name'][source] file.filemime = p.FILES['files']['type'][source] # Rename potentially executable files, to help prevent exploits. if (php.preg_match('/\.(php|pl|py|cgi|asp|js)$/i', file.filename) and \ (php.substr(file.filename, -4) != '.txt')): file.filemime = 'text/plain' file.filepath += '.txt' file.filename += '.txt' # If the destination is not provided, or is not writable, then use the # temporary directory. if (php.empty(dest) or file_check_path(dest) == False): dest = file_directory_temp() file.source = source file.destination = file_destination(file_create_path(dest + '/' + \ file.filename), replace) file.filesize = FILES['files']['size'][source] # Call the validation functions. errors = {} for function, args in validators.items(): array_unshift(args, file) errors = php.array_merge(errors, function(*args)) # Check for validation errors. if (not php.empty(errors)): message = t('The selected file %name could not be uploaded.', \ {'%name' : file.filename}) if (php.count(errors) > 1): message += '<ul><li>' + php.implode('</li><li>', errors) + '</li></ul>' else: message += ' ' + php.array_pop(errors) form_set_error(source, message) return False # Move uploaded files from PHP's upload_tmp_dir to # Drupal's temporary directory. # This overcomes open_basedir restrictions for future file operations. file.filepath = file.destination if (not move_uploaded_file(p.FILES['files']['tmp_name'][source], \ file.filepath)): form_set_error(source, t('File upload error. ' + \ 'Could not move uploaded file.')) watchdog('file', 'Upload error + Could not move uploaded file ' + \ '%file to destination %destination.', \ {'%file' : file.filename, '%destination' : file.filepath}) return False # If we made it this far it's safe to record this file in the database. file.uid = lib_appglobals.user.uid file.status = FILE_STATUS_TEMPORARY file.timestamp = time() drupal_write_record('files', file) # Add file to the cache. file_save_upload.upload_cache[source] = file return file return False