You are here

class ReportFileSystem in Forena Reports 8

Hierarchy

Expanded class hierarchy of ReportFileSystem

5 files declare their use of ReportFileSystem
ForenaController.php in src/Controller/ForenaController.php
FrxAPI.php in src/FrxAPI.php
FrxAPI.incL General Forena Reporting Class
ReportManager.php in src/ReportManager.php
Implements \Drupal\forena\File\ReportFileSystem
Skin.php in src/Skin.php
Implements \Drupal\forena\Skins
TestingReportFileSystem.php in tests/src/Unit/Mock/TestingReportFileSystem.php

File

src/File/ReportFileSystem.php, line 8

Namespace

Drupal\forena\File
View source
class ReportFileSystem extends FileSystemBase {
  const CACHE_KEY = 'forena_report_file_system';
  protected static $instance;
  private $report_cache = array();
  public $language = 'en';
  public $default_language = 'en';

  /**
   * Singleton Factory
   * @return \Drupal\forena\File\ReportFileSystem
   */
  public static function instance($force_new = FALSE) {
    if (static::$instance === NULL || $force_new) {
      static::$instance = new static();
    }
    return static::$instance;
  }

  /**
   * Constructor
   *   Sets the initial reort directory
   */
  public function __construct() {
    parent::__construct();

    //@TODO: Find out drupal languages

    //$this->language = $language->language;

    //$this->language = language_default();

    // Load default directory from configuration.
    $report_path = \Drupal::config('forena.settings')
      ->get('report_repos');
    if (!$report_path) {

      // @TODO: determine default file configuration.
      $report_path = \Drupal::service('file_system')
        ->realpath('public://') . '/reports';
      if (!file_exists($report_path)) {
        @mkdir($report_path, 0777, TRUE);
      }
    }
    $default_directory = rtrim($report_path, '/');
    $this->dir = $default_directory;

    // Load directories from module.forena.yml files
    $providers = AppService::instance()
      ->getForenaProviders();
    $directories = [];
    foreach ($providers as $module_name => $provider) {
      if (isset($provider['report directory'])) {
        $directories[] = $provider['report directory'];
      }
    }

    // Add directories form module hooks.
    $directories += \Drupal::moduleHandler()
      ->invokeAll('forena_report_directory');
    foreach ($directories as $dir) {
      $this->includes[] = rtrim($dir, '/');
    }
  }

  /**
   * List all the reports for a language.
   * @return array
   *   array containing all reports.
   */
  public function allReports() {
    $this
      ->scan();
    $reports = array();
    $data = $this
      ->allMetadataForExt('frx');
    $def_language = $this->default_language;
    if ($data) {
      foreach ($data as $base_name => $obj) {
        if ($obj->metaData) {
          if ($obj->metaData['language'] != 'en') {
            $rpt_name = substr($base_name, strlen($obj->metaData['language']) + 1);
          }
          else {
            $rpt_name = $base_name;
          }
          if ($obj->metaData['language'] == $this->language) {
            $reports[$rpt_name] = $obj;
          }
          elseif ($obj->metaData['language'] == $def_language && (!isset($reports[$rpt_name]) || $reports[$rpt_name]->metaData['language'] == 'en')) {
            $reports[$rpt_name] = $obj;
          }
          elseif ($obj->metaData['language'] == 'en' && !isset($reports[$rpt_name])) {
            $reports[$rpt_name] = $obj;
          }
        }
      }
    }
    uasort($reports, [
      $this,
      'reportCompare',
    ]);
    return $reports;
  }

  /**
   * Sort compare function for sorting data by category then title.
   * @param object $a
   *   Report metatdata
   * @param object $b
   *   Report metadata
   * @return number
   */
  public function reportCompare($a, $b) {
    $c = strnatcasecmp($a->metaData['category'], $b->metaData['category']);
    if (!$c) {
      $c = strnatcasecmp($a->metaData['title'], $b->metaData['title']);
    }
    return $c;
  }
  public function reportTitleCompare($a, $b) {
    $c = strnatcasecmp($a['title'], $b['title']);
    return $c;
  }

  /**
   * Get the cached information for a single report.
   * @param string $name
   * @return object
   */
  public function getReportCacheInfo($name) {
    global $language;
    $this
      ->validateAllCache();
    $data = $this
      ->getCache('frx');
    if ($language->language != 'en') {
      $lang = $language->language;
      $name = "{$lang}/{$name}";
    }
    return @$data[$name];
  }
  public function menuReports() {
    global $language;
    $this
      ->validateAllCache();
    $data = $this
      ->getCache('frx');
    $reports = array();
    foreach ($data as $base_name => $obj) {
      if ($obj->cache && isset($obj->cache['menu']['path']) && ($obj->cache['language'] == $language->language || $obj->cache['language'] == 'en' && !isset($obj->cache['menu']['path']))) {
        if ($obj->cache['language'] != 'en') {
          $obj->name = substr($base_name, 3);
        }
        else {
          $obj->name = $base_name;
        }
        $reports[$obj->cache['menu']['path']] = $obj;
      }
    }
    return $reports;
  }

  /**
   * Generate an ordered  list of reports by category
   * @param $categories
   * @return array Categories
   */
  public function reportsByCategory($categories = array()) {
    $this
      ->scan();
    $data = $this
      ->allReports();
    $reports = array();
    if ($data) {
      foreach ($data as $base_name => $obj) {
        if ($obj->metaData && @$obj->metaData['category'] && empty($obj->metaData['hidden'])) {
          $cache = $obj->metaData;
          if (!$categories || array_search($cache['category'], $categories) !== FALSE) {

            // Check each callback function to see if we have an error.
            $access = TRUE;
            if (@$cache['access']) {
              $access = FALSE;
              foreach ($cache['access'] as $provider => $rights) {
                $m = DataManager::instance()
                  ->repository($provider);
                foreach ($rights as $right) {
                  if ($m
                    ->access($right)) {
                    $access = TRUE;
                  }
                }
              }
            }
            if ($access) {
              $reports[$cache['category']][] = array(
                'title' => $cache['title'],
                'category' => $cache['category'],
                'report_name' => $base_name,
              );
            }
          }
        }
      }
    }
    $sort = defined('SORT_NATURAL') ? SORT_NATURAL : SORT_REGULAR;

    // Sort the reports
    if ($reports) {
      foreach ($reports as $category => $list) {
        uasort($reports[$category], [
          $this,
          'reportTitleCompare',
        ]);
      }
    }
    ksort($reports, $sort);
    return $reports;
  }
  public function skins() {
    $skins = array();
    $this
      ->scan();

    // First find YML files
    $files = $this
      ->allMetadataForExt('skin.yml');
    foreach ($files as $name => $obj) {
      $skins[$name] = isset($obj->metaData['name']) ? $obj->metaData['name'] : $name;
    }
    return $skins;
  }

  // Abstract drupal function
  public function localeEnabled() {
    return \Drupal::moduleHandler()
      ->moduleExists('locale');
  }

  /**
   * @param $html
   * @return Report
   *   Report object created.
   * Get cache data from the report.
   */
  public function createReport(&$html) {

    // Load the report
    $r = @new Report($html);
    return $r;
  }

  /**
   * Should load cache data based on that.
   * @see FrxFile::buildCache()
   */
  public function extractMetaData(&$object) {
    switch ($object->ext) {
      case 'frx':
        $r_xml = file_get_contents($object->file);
        $r = $this
          ->createReport($r_xml);

        // Save language info
        $lang = 'en';
        if ($this
          ->localeEnabled()) {
          @(list($tlang, $tname) = explode('/', $object->basename, 2));
          if (array_key_exists($tlang, locale_translatable_language_list())) {
            $lang = $tlang;
          }
        }

        // Get the security caches from the reports
        $cache = [];
        if ($r->rpt_xml) {
          $cache['title'] = $r->title;
          $cache['language'] = $lang;
          $cache['category'] = $r->category;
          $cache['hidden'] = @$r->options['hidden'];
          $cache['access'] = $r->access;
        }
        $object->metaData = $cache;
        if ($r) {
          $r
            ->__destruct();
        }
        unset($r);
        break;
      case 'skin.yml':
        $object->metaData = Skin::parseYml(file_get_contents($object->file));
        break;
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
FileSystemBase::$cache public property
FileSystemBase::$cacheKey public property
FileSystemBase::$dir public property
FileSystemBase::$includes public property
FileSystemBase::$name_index public property
FileSystemBase::$needSave public property
FileSystemBase::$needScan public property
FileSystemBase::$type_index public property
FileSystemBase::$validated public property
FileSystemBase::$write_dir public property
FileSystemBase::allMetadataForExt protected function Get all metadata for files of a specific extension.
FileSystemBase::contents public function Return the contents of a file located in the report directory Overrides FileInterface::contents
FileSystemBase::delete public function Delete a file from the directory. Overrides FileInterface::delete 1
FileSystemBase::deleteMissingEntries private function
FileSystemBase::directory public function Return the directory portion of a report filename.
FileSystemBase::exists public function Return whether the file exists. Overrides FileInterface::exists
FileSystemBase::getDirectoryState public function 1
FileSystemBase::getMetaData public function Returns the cache entry based on a filename. Overrides FileInterface::getMetaData
FileSystemBase::includeExists public function Determine if the file exists in the include path.
FileSystemBase::isCustom public function Determine whether the file is a cusomt implmentation. Overrides FileInterface::isCustom
FileSystemBase::isOverriden public function Test whether file is overriding code provided files. Overrides FileInterface::isOverriden
FileSystemBase::isWritable public function Return an indicator as to whether the file is savable. New files can be saved if the directory is writabel. Overrides FileInterface::isWritable
FileSystemBase::path public function Return the full path to the filename
FileSystemBase::pathinfo public function Retrieve path info
FileSystemBase::revert public function Revert an individual report
FileSystemBase::save public function Save a file into the report directory. Overrides FileInterface::save 1
FileSystemBase::scan public function
FileSystemBase::scanDirectory private function Recursive function which scans the directory and loads the base indexes.
FileSystemBase::scanInclude protected function Parse a drectory
FileSystemBase::setDirectoryState public function 1
FileSystemBase::setFilesToDelete private function
FileSystemBase::verifyDirectory function
ReportFileSystem::$default_language public property
ReportFileSystem::$instance protected static property
ReportFileSystem::$language public property
ReportFileSystem::$report_cache private property
ReportFileSystem::allReports public function List all the reports for a language.
ReportFileSystem::CACHE_KEY constant Overrides FileSystemBase::CACHE_KEY
ReportFileSystem::createReport public function
ReportFileSystem::extractMetaData public function Should load cache data based on that. Overrides FileInterface::extractMetaData
ReportFileSystem::getReportCacheInfo public function Get the cached information for a single report.
ReportFileSystem::instance public static function Singleton Factory
ReportFileSystem::localeEnabled public function 1
ReportFileSystem::menuReports public function
ReportFileSystem::reportCompare public function Sort compare function for sorting data by category then title.
ReportFileSystem::reportsByCategory public function Generate an ordered list of reports by category
ReportFileSystem::reportTitleCompare public function
ReportFileSystem::skins public function
ReportFileSystem::__construct public function Constructor Sets the initial reort directory Overrides FileSystemBase::__construct 1