• 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;
    }
  • 相关阅读:
    matplotlib: ylabel on the right
    ssh 密钥管理
    [转]Linux下创建静态、动态库
    Perl命令行应用介绍
    zz:快速编辑Shell命令行
    zz Makefile学习教程: 跟我一起写 Makefile
    Eureka服务剔除下线
    数据结构可视化
    aeImageResize jQuery图片等比缩放调整插件
    最全的CSS浏览器兼容问题整理(IE6.0、IE7.0 与 FireFox)
  • 原文地址:https://www.cnblogs.com/eastson/p/3368493.html
Copyright © 2020-2023  润新知