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
Exemple #2
0
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
Exemple #3
0
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_)
Exemple #4
0
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
Exemple #6
0
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)
Exemple #8
0
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()
Exemple #9
0
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)
Exemple #10
0
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
Exemple #11
0
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
Exemple #12
0
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)
Exemple #13
0
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 {}
Exemple #14
0
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()
Exemple #15
0
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
Exemple #16
0
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
Exemple #17
0
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)
Exemple #18
0
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 {}
Exemple #19
0
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
Exemple #20
0
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
Exemple #21
0
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'))
Exemple #22
0
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
Exemple #23
0
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'))
Exemple #24
0
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
Exemple #25
0
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()
Exemple #26
0
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()
Exemple #27
0
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
Exemple #28
0
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(' &#8250; ', breadcrumb)  + '</div>'
Exemple #29
0
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)
Exemple #30
0
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
Exemple #31
0
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
Exemple #32
0
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)
Exemple #33
0
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)
Exemple #34
0
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
Exemple #35
0
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
Exemple #36
0
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
Exemple #37
0
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)
Exemple #39
0
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
Exemple #40
0
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
Exemple #41
0
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_]
Exemple #42
0
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_]
Exemple #43
0
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
Exemple #44
0
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
Exemple #45
0
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
Exemple #46
0
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_))
Exemple #47
0
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';
Exemple #49
0
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
Exemple #50
0
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_))
Exemple #51
0
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