Beispiel #1
0
def install_page(content):
    """
   Generate a themed installation page.
  
   Note: this function is not themeable.
  
   @param content
     The page content to show.
  """
    drupal_set_header('Content-Type: text/html; charset=utf-8')
    # Assign content.
    variables['content'] = content
    # Delay setting the message variable so it can be processed below.
    variables['show_messages'] = False
    # The maintenance preprocess function is recycled here.
    template_preprocess_maintenance_page(variables)
    # Special handling of error messages
    messages = drupal_set_message()
    if (php.isset(messages, 'error')):
        title = (st('The following errors must be resolved before you can ' + \
          'continue the installation process') if \
          (php.count(messages['error']) > 1) else \
          st('The following error must be resolved before you can ' + \
          'continue the installation process'))
        variables['messages'] += '<h3>' + title + ':</h3>'
        variables['messages'] += theme('status_messages', 'error')
        variables['content'] += '<p>' + st('Please check the error ' + \
          'messages and <a href="not url">try again</a>.', \
          {'not url' : request_uri()}) + '</p>'
    # Special handling of warning messages
    if (php.isset(messages, 'warning')):
        title = (st('The following installation warnings should be ' + \
          'carefully reviewed') if \
          (php.count(messages['warning']) > 1) else \
          st('The following installation warning should be carefully reviewed'))
        variables['messages'] += '<h4>' + title + ':</h4>'
        variables['messages'] += theme('status_messages', 'warning')
    # Special handling of status messages
    if (php.isset(messages, 'status')):
        title = (st('The following installation warnings should be ' + \
          'carefully reviewed, but in most cases may be safely ignored') if \
          (php.count(messages['status']) > 1) else st('The following ' + \
          'installation warning should be carefully reviewed, but in ' + \
          'most cases may be safely ignored'))
        variables['messages'] += '<h4>' + title + ':</h4>'
        variables['messages'] += theme('status_messages', 'status')
    # This was called as a theme hook (not template), so we need to
    # fix path_to_theme() for the template, to point at the actual
    # theme rather than system plugin as owner of the hook.
    lib_appglobals.theme_path = 'themes/garland'
    return theme_render_template('themes/garland/maintenance-page.tpl.py', \
      variables)
def install_page(content):
  """
   Generate a themed installation page.
  
   Note: this function is not themeable.
  
   @param content
     The page content to show.
  """
  drupal_set_header('Content-Type: text/html; charset=utf-8')
  # Assign content.
  variables['content'] = content
  # Delay setting the message variable so it can be processed below.
  variables['show_messages'] = False
  # The maintenance preprocess function is recycled here.
  template_preprocess_maintenance_page(variables)
  # Special handling of error messages
  messages = drupal_set_message()
  if (php.isset(messages, 'error')):
    title = (st('The following errors must be resolved before you can ' + \
      'continue the installation process') if \
      (php.count(messages['error']) > 1) else \
      st('The following error must be resolved before you can ' + \
      'continue the installation process'))
    variables['messages'] += '<h3>' + title + ':</h3>'
    variables['messages'] += theme('status_messages', 'error')
    variables['content'] += '<p>' + st('Please check the error ' + \
      'messages and <a href="not url">try again</a>.', \
      {'not url' : request_uri()}) + '</p>'
  # Special handling of warning messages
  if (php.isset(messages, 'warning')):
    title = (st('The following installation warnings should be ' + \
      'carefully reviewed') if \
      (php.count(messages['warning']) > 1) else \
      st('The following installation warning should be carefully reviewed'))
    variables['messages'] += '<h4>' + title + ':</h4>'
    variables['messages'] += theme('status_messages', 'warning')
  # Special handling of status messages
  if (php.isset(messages, 'status')):
    title = (st('The following installation warnings should be ' + \
      'carefully reviewed, but in most cases may be safely ignored') if \
      (php.count(messages['status']) > 1) else st('The following ' + \
      'installation warning should be carefully reviewed, but in ' + \
      'most cases may be safely ignored'))
    variables['messages'] += '<h4>' + title + ':</h4>'
    variables['messages'] += theme('status_messages', 'status')
  # This was called as a theme hook (not template), so we need to
  # fix path_to_theme() for the template, to point at the actual
  # theme rather than system plugin as owner of the hook.
  lib_appglobals.theme_path = 'themes/garland'
  return theme_render_template('themes/garland/maintenance-page.tpl.py', \
    variables)
Beispiel #3
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)
def update_page(content, show_messages = True):
  """
   Generate a themed update page.
  
   Note: this function is not themeable.
  
   @param content
     The page content to show.
   @param show_messages
     Whether to output status and error messages.
     False can be useful to postpone the messages to a subsequent page.
  """
  # Set required headers.
  drupal_set_header('Content-Type: text/html; charset=utf-8')
  # Assign content and show message flag.
  variables['content'] = content
  variables['show_messages'] = show_messages
  # The maintenance preprocess function is recycled here.
  template_preprocess_maintenance_page(variables)
  # Special handling of warning messages.
  messages = drupal_set_message()
  if (php.isset(messages['warning'])):
    title = ('The following update warnings should be carefully ' + \
      'reviewed before continuing' if \
      (php.count(messages['warning']) > 1) else \
        'The following update warning should be carefully ' + \
        'reviewed before continuing')
    variables['messages'] += '<h4>' + title + ':</h4>'
    variables['messages'] += theme('status_messages', 'warning')
  # This was called as a theme hook (not template), so we need to
  # fix path_to_theme() for the template, to point at the actual
  # theme rather than system plugin as owner of the hook.
  lib_appglobals.theme_path = 'themes/garland'
  return theme_render_template('themes/garland/maintenance-page.tpl.php', \
    variables)
Beispiel #5
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()
Beispiel #6
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()
Beispiel #7
0
def update_page(content, show_messages=True):
    """
   Generate a themed update page.
  
   Note: this function is not themeable.
  
   @param content
     The page content to show.
   @param show_messages
     Whether to output status and error messages.
     False can be useful to postpone the messages to a subsequent page.
  """
    # Set required headers.
    drupal_set_header('Content-Type: text/html; charset=utf-8')
    # Assign content and show message flag.
    variables['content'] = content
    variables['show_messages'] = show_messages
    # The maintenance preprocess function is recycled here.
    template_preprocess_maintenance_page(variables)
    # Special handling of warning messages.
    messages = drupal_set_message()
    if (php.isset(messages['warning'])):
        title = ('The following update warnings should be carefully ' + \
          'reviewed before continuing' if \
          (php.count(messages['warning']) > 1) else \
            'The following update warning should be carefully ' + \
            'reviewed before continuing')
        variables['messages'] += '<h4>' + title + ':</h4>'
        variables['messages'] += theme('status_messages', 'warning')
    # This was called as a theme hook (not template), so we need to
    # fix path_to_theme() for the template, to point at the actual
    # theme rather than system plugin as owner of the hook.
    lib_appglobals.theme_path = 'themes/garland'
    return theme_render_template('themes/garland/maintenance-page.tpl.php', \
      variables)
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)
Beispiel #9
0
def placeholders(arguments, type = 'int'):
  """
   Generate placeholders for an array of query arguments of a single type.
  
   Given a Schema API field type, return correct %-placeholders to
   embed in a query
  
   @param arguments
    An array with at least one element.
   @param type
     The Schema API type of a field (e.g. 'int', 'text', or 'varchar').
  """
  placeholder = db_type_placeholder(type);
  return php.implode(',', php.array_fill(0, php.count(arguments), \
    placeholder));
Beispiel #10
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)
Beispiel #12
0
def download():
  """
   Call plugins that implement hook_file_download() to find out if a file is
   accessible and what headers it should be transferred with + If a plugin
   returns -1 drupal_access_denied() will be returned + If one or more plugins
   returned headers the download will start with the returned headers + If no
   plugins respond drupal_not_found() will be returned.
  """
  # Merge remainder of arguments from php.GET['q'], into relative file path.
  args = func_get_args()
  filepath = php.implode('/', args)
  # Maintain compatibility with old ?file=paths saved in node bodies.
  if (php.isset(php.GET, 'file')):
    filepath =  php.GET['file']
  if (php.file_exists(file_create_path(filepath))):
    headers = plugin_invoke_all('file_download', filepath)
    if (php.in_array(-1, headers)):
      return drupal_access_denied()
    if (php.count(headers)):
      file_transfer(filepath, headers)
  return drupal_not_found()
Beispiel #13
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
Beispiel #14
0
def download():
    """
   Call plugins that implement hook_file_download() to find out if a file is
   accessible and what headers it should be transferred with + If a plugin
   returns -1 drupal_access_denied() will be returned + If one or more plugins
   returned headers the download will start with the returned headers + If no
   plugins respond drupal_not_found() will be returned.
  """
    # Merge remainder of arguments from php.GET['q'], into relative file path.
    args = func_get_args()
    filepath = php.implode('/', args)
    # Maintain compatibility with old ?file=paths saved in node bodies.
    if (php.isset(php.GET, 'file')):
        filepath = php.GET['file']
    if (php.file_exists(file_create_path(filepath))):
        headers = plugin_invoke_all('file_download', filepath)
        if (php.in_array(-1, headers)):
            return drupal_access_denied()
        if (php.count(headers)):
            file_transfer(filepath, headers)
    return drupal_not_found()
Beispiel #15
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
Beispiel #16
0
def from_browser():
    """
   Identify language from the Accept-language HTTP php.header we got.
  """
    # Specified by the user via the browser's Accept Language setting
    # Samples: "hu, en-us;q=0.66, en;q=0.33", "hu,en-us;q=0.5"
    browser_langs = []
    if (php.isset(php.SERVER, 'HTTP_ACCEPT_LANGUAGE')):
        browser_accept = php.explode(",", php.SERVER['HTTP_ACCEPT_LANGUAGE'])
        for i in range(php.count(browser_accept)):
            # The language part is either a code or a code with a quality.
            # We cannot do anything with a * code, so it is skipped.
            # If the quality is missing, it is assumed to be 1 according to the RFC.
            if (php.preg_match("not ([a-z-]+)(;q=([0-9\\.]+))?not ", \
                php.trim(browser_accept[i]), found)):
                browser_langs[found[1]] = (float(found[3]) if \
                  php.isset(found, 3) else 1.0)
    # Order the codes by quality
    arsort(browser_langs)
    # Try to find the first preferred language we have
    languages = language_list('enabled')
    for langcode, q in browser_langs.items():
        if (php.isset(languages['1'], langcode)):
            return languages['1'][langcode]
Beispiel #17
0
def from_browser():
  """
   Identify language from the Accept-language HTTP php.header we got.
  """
  # Specified by the user via the browser's Accept Language setting
  # Samples: "hu, en-us;q=0.66, en;q=0.33", "hu,en-us;q=0.5"
  browser_langs = []
  if (php.isset(php.SERVER, 'HTTP_ACCEPT_LANGUAGE')):
    browser_accept = php.explode(",", php.SERVER['HTTP_ACCEPT_LANGUAGE'])
    for i in range(php.count(browser_accept)):
      # The language part is either a code or a code with a quality.
      # We cannot do anything with a * code, so it is skipped.
      # If the quality is missing, it is assumed to be 1 according to the RFC.
      if (php.preg_match("not ([a-z-]+)(;q=([0-9\\.]+))?not ", \
          php.trim(browser_accept[i]), found)):
        browser_langs[found[1]] = (float(found[3]) if \
          php.isset(found, 3) else 1.0)
  # Order the codes by quality
  arsort(browser_langs)
  # Try to find the first preferred language we have
  languages = language_list('enabled')
  for langcode,q in browser_langs.items():
    if (php.isset(languages['1'], langcode)):
      return languages['1'][langcode]
Beispiel #18
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
Beispiel #19
0
def change_field(ret, table, field, field_new, spec, keys_new=[]):
    """
   Change a field definition.
  
   IMPORTANT NOTE: To maintain database portability, you have to explicitly
   recreate all indices and primary keys that are using the changed field.
  
   That means that you have to drop all affected keys and indexes with
   db_drop_{primary_key,unique_key,index}() before calling db_change_field().
   To recreate the keys and indices, pass the key definitions as the
   optional keys_new argument directly to db_change_field().
  
   For example, suppose you have:
   @code
   schema['foo'] = array(
     'fields' : array(
       'bar' : array('type' : 'int', 'not None' : True)
     ),
     'primary key' : array('bar')
   )
   @endcode
   and you want to change foo.bar to be type serial, leaving it as the
   primary key.  The correct sequence is:
   @code
   db_drop_primary_key(ret, 'foo')
   db_change_field(ret, 'foo', 'bar', 'bar',
     array('type' : 'serial', 'not None' : True),
     array('primary key' : array('bar')))
   @endcode
  
   The reasons for this are due to the different database engines:
  
   On PostgreSQL, changing a field definition involves adding a new field
   and dropping an old one which* causes any indices, primary keys and
   sequences (from serial-type fields) that use the changed field to be
   dropped.
  
   On MySQL, all type 'serial' fields must be part of at least one key
   or index as soon as they are created.  You cannot use
   db_add_{primary_key,unique_key,index}() for this purpose because
   the ALTER TABLE command will fail to add the column without a key
   or index specification.  The solution is to use the optional
   keys_new argument to create the key or index at the same time as
   field.
  
   You could use db_add_{primary_key,unique_key,index}() in all cases
   unless you are converting a field to be type serial. You can use
   the keys_new argument in all cases.
  
   @param ret
     Array to which query results will be added.
   @param table
     Name of the table.
   @param field
     Name of the field to change.
   @param field_new
     New name for the field (set to the same as field if you don't want to
     change the name).
   @param spec
     The field specification for the new field.
   @param keys_new
     Optional keys and indexes specification to be created on the
     table along with changing the field. The format is the same as a
     table specification but without the 'fields' element.
  """
    php.Reference.check(ret)
    sql = 'ALTER TABLE {' +  table  + '} CHANGE ' + field + ' ' + \
      _db_create_field_sql(field_new, _db_process_field(spec))
    if (php.count(keys_new) > 0):
        sql += ', ADD ' + php.implode(', ADD ', _db_create_keys_sql(keys_new))
    ret.append(update_sql(sql))
Beispiel #20
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_))
def change_field(ret, table, field, field_new, spec, keys_new = []):
  """
   Change a field definition.
  
   IMPORTANT NOTE: To maintain database portability, you have to explicitly
   recreate all indices and primary keys that are using the changed field.
  
   That means that you have to drop all affected keys and indexes with
   db_drop_{primary_key,unique_key,index}() before calling db_change_field().
   To recreate the keys and indices, pass the key definitions as the
   optional keys_new argument directly to db_change_field().
  
   For example, suppose you have:
   @code
   schema['foo'] = array(
     'fields' : array(
       'bar' : array('type' : 'int', 'not None' : True)
     ),
     'primary key' : array('bar')
   )
   @endcode
   and you want to change foo.bar to be type serial, leaving it as the
   primary key.  The correct sequence is:
   @code
   db_drop_primary_key(ret, 'foo')
   db_change_field(ret, 'foo', 'bar', 'bar',
     array('type' : 'serial', 'not None' : True),
     array('primary key' : array('bar')))
   @endcode
  
   The reasons for this are due to the different database engines:
  
   On PostgreSQL, changing a field definition involves adding a new field
   and dropping an old one which* causes any indices, primary keys and
   sequences (from serial-type fields) that use the changed field to be
   dropped.
  
   On MySQL, all type 'serial' fields must be part of at least one key
   or index as soon as they are created.  You cannot use
   db_add_{primary_key,unique_key,index}() for this purpose because
   the ALTER TABLE command will fail to add the column without a key
   or index specification.  The solution is to use the optional
   keys_new argument to create the key or index at the same time as
   field.
  
   You could use db_add_{primary_key,unique_key,index}() in all cases
   unless you are converting a field to be type serial. You can use
   the keys_new argument in all cases.
  
   @param ret
     Array to which query results will be added.
   @param table
     Name of the table.
   @param field
     Name of the field to change.
   @param field_new
     New name for the field (set to the same as field if you don't want to
     change the name).
   @param spec
     The field specification for the new field.
   @param keys_new
     Optional keys and indexes specification to be created on the
     table along with changing the field. The format is the same as a
     table specification but without the 'fields' element.
  """
  php.Reference.check(ret)
  sql = 'ALTER TABLE {' +  table  + '} CHANGE ' + field + ' ' + \
    _db_create_field_sql(field_new, _db_process_field(spec))
  if (php.count(keys_new) > 0):
    sql += ', ADD ' +  php.implode(', ADD ', _db_create_keys_sql(keys_new))
  ret.append( update_sql(sql) )
Beispiel #22
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_))
Beispiel #23
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