zoukankan      html  css  js  c++  java
  • Drupal所能够理解的资源

    Drupal能够识别哪些资源类型?

    profile,不知道怎么翻译,应该是指安装类型,固定地存放于profiles目录下。

    module,模块,可以存在于多个目录下:modules、profiles/{profile}/modules、sites/all/modules、sites/{$site}/modules。
    theme,主题,可以存在于多个目录下:themes、profiles/{profile}/themes、sites/all/themes、sites/{$site}/themes。
    theme_engine,主题引擎,可以存在于多个目录下:themes/engines、profiles/{profile}/themes/engines、sites/all/themes/engines、sites/{$site}/themes/engines。

    Drupal识别的这些资源都可以注册到系统表system里面,用资源主文件作为key,用type字段表示资源类型。

    Drupal如何找到指定的资源?

    Drupal使用drupal_get_filename()和drupal_system_listing()两个函数配合来寻找指定的资源。

    最先进入的是drupal_get_filename()函数,该函数以资源类型和资源名称作为传入参数:

    function drupal_get_filename($type, $name, $filename = NULL)  { ... ... }

      

    profile资源固定地存放在profiles目录下,这是在代码里面固定写死了的:

    if ($type == 'profile') {
        $profile_filename = "profiles/$name/$name.profile";
        $files[$type][$name] = file_exists($profile_filename) ? $profile_filename : FALSE;
      }

    然后在系统表system中搜索对应的资源类型和名称是否有存在。若存在,代表该资源已经安装过,直接返回其key就是资源主文件。

    if (function_exists('db_query')) {
      $file = db_query("SELECT filename FROM {system} WHERE name = :name AND type = :type", array(':name' => $name, ':type' => $type))->fetchField();
      if (file_exists(DRUPAL_ROOT . '/' . $file)) {
        $files[$type][$name] = $file;
      }
    }

    在system表找不到对应的资源,Drupal就直接去检查对应的目录是否存在。Drupal规定了每种资源的目录和主文件命名规则:

    $dir = $type . 's';
    if ($type == 'theme_engine') {
      $dir = 'themes/engines';
      $extension = 'engine';
    }
    elseif ($type == 'theme') {
      $extension = 'info';
    }
    else {
      $extension = $type;
    }

    资源目录命名规则是以资源类型加上s后缀,theme_engine例外,theme_engine目录是themes/engines。
    资源主文件命名规则是资源名称加上资源类型后缀。theme和theme_engine的后缀例外,theme后缀是info,theme_engine后缀是engine。

    每种资源都有多个目录可以存放,Drupal使用drupal_system_listing()函数定义其搜索顺序。

    function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1) {
      $config = conf_path();
    
      $searchdir = array($directory);
      $files = array();
    
      // The 'profiles' directory contains pristine collections of modules and
      // themes as organized by a distribution. It is pristine in the same way
      // that /modules is pristine for core; users should avoid changing anything
      // there in favor of sites/all or sites/<domain> directories.
      $profiles = array();
      $profile = drupal_get_profile();
    
      // In case both profile directories contain the same extension, the actual
      // profile always has precedence.
      $profiles[] = $profile;
      foreach ($profiles as $profile) {
        if (file_exists("profiles/$profile/$directory")) {
          $searchdir[] = "profiles/$profile/$directory";
        }
      }
    
      // Always search sites/all/* as well as the global directories.
      $searchdir[] = 'sites/all/' . $directory;
    
      if (file_exists("$config/$directory")) {
        $searchdir[] = "$config/$directory";
      }
    
      // Get current list of items.
      if (!function_exists('file_scan_directory')) {
        require_once DRUPAL_ROOT . '/includes/file.inc';
      }
      foreach ($searchdir as $dir) {
        $files_to_add = file_scan_directory($dir, $mask, array('key' => $key, 'min_depth' => $min_depth));
    
        // Duplicate files found in later search directories take precedence over
        // earlier ones, so we want them to overwrite keys in our resulting
        // $files array.
        // The exception to this is if the later file is from a module or theme not
        // compatible with Drupal core. This may occur during upgrades of Drupal
        // core when new modules exist in core while older contrib modules with the
        // same name exist in a directory such as sites/all/modules/.
        foreach (array_intersect_key($files_to_add, $files) as $file_key => $file) {
          // If it has no info file, then we just behave liberally and accept the
          // new resource on the list for merging.
          if (file_exists($info_file = dirname($file->uri) . '/' . $file->name . '.info')) {
            // Get the .info file for the module or theme this file belongs to.
            $info = drupal_parse_info_file($info_file);
    
            // If the module or theme is incompatible with Drupal core, remove it
            // from the array for the current search directory, so it is not
            // overwritten when merged with the $files array.
            if (isset($info['core']) && $info['core'] != DRUPAL_CORE_COMPATIBILITY) {
              unset($files_to_add[$file_key]);
            }
          }
        }
        $files = array_merge($files, $files_to_add);
      }
    
      return $files;
    }

    这里举一个搜索hello模块的例子来说明搜索的过程。根据上面的资源命名规则可以知道,模块目录的命名规则是资源类型加s后缀,也就是modules。然后模块主文件的命名规则是资源名称加上资源类型后缀,也就是hello.module。好了,现在我们要找的就是modules/hello/hello.module文件。那到哪里去找这个文件呢?drupal_system_listing()会依次搜索以下四个位置:

    • modules/hello/hello.module
    • profiles/drupal_get_profile()/modules/hello/hello.module
    • sites/all/modules/hello/hello.module
    • sites/conf_path()/modules/hello/hello.module

    找到了就OK,找不到就说明hello模块不存在。

    Drupal如何载入指定资源?

    Drupal用drupal_load()函数载入资源。首先用drupal_get_filename()得到资源主文件,然后简单的include_once就完了。

    function drupal_load($type, $name) {
      static $files = array();
    
      if (isset($files[$type][$name])) {
        return TRUE;
      }
    
      $filename = drupal_get_filename($type, $name);
    
      if ($filename) {
        include_once DRUPAL_ROOT . '/' . $filename;
        $files[$type][$name] = TRUE;
    
        return TRUE;
      }
    
      return FALSE;
    }
  • 相关阅读:
    BZOJ3752 : Hack
    XIV Open Cup named after E.V. Pankratiev. GP of SPb
    XIII Open Cup named after E.V. Pankratiev. GP of Ukraine
    BZOJ2087 : [Poi2010]Sheep
    BZOJ2080 : [Poi2010]Railway
    BZOJ2082 : [Poi2010]Divine divisor
    Moscow Pre-Finals Workshop 2016. National Taiwan U Selection
    XIII Open Cup named after E.V. Pankratiev. GP of Asia and South Caucasus
    XIII Open Cup named after E.V. Pankratiev. GP of Azov Sea
    XIII Open Cup named after E.V. Pankratiev. GP of SPb
  • 原文地址:https://www.cnblogs.com/eastson/p/3368493.html
Copyright © 2011-2022 走看看