You are here

class AvailabilityCalendarsCssGenerator in Availability Calendars 6.2

Same name and namespace in other branches
  1. 7.2 availability_calendars.styles.inc \AvailabilityCalendarsCssGenerator

Hierarchy

Expanded class hierarchy of AvailabilityCalendarsCssGenerator

File

./availability_calendars.styles.inc, line 448

View source
class AvailabilityCalendarsCssGenerator {

  /* @var $styles array */
  protected $styles = NULL;
  public function __construct($styles) {
    $this->styles = $styles;
  }

  /**
   * Creates and writes the CSS file for Availability Calendars
   *
   * @return boolean Whether the generation was successful.
   */
  public function exec() {
    $css = $this
      ->createCss();
    $result = $this
      ->writeCss($css);
    return $result;
  }

  /**
   * Creates the css.
   *
   * @return string The created css
   */
  protected function createCss() {
    $css = '';
    $css .= $this
      ->createTableCss();
    $css .= $this
      ->createCaptionCss();
    $css .= $this
      ->createHeaderCss();
    $css .= $this
      ->createDaysCss();
    $css .= $this
      ->createStatesCss();
    $css .= $this
      ->createWeekNotesCss();
    return $css;
  }

  /**
   * Writes the created CSS to a file.
   *
   * @param string $css
   * @return boolean Whether the generation was successful.
   */
  protected function writeCss($css) {
    $result = false;
    $path = file_directory_path() . '/availability_calendars';
    if ($result = file_check_directory($path, FILE_CREATE_DIRECTORY)) {
      $file = $path . '/' . 'availability_calendars.css';
      if ($result = file_save_data($css, $file, FILE_EXISTS_REPLACE) === $file) {

        // Set file permissions for webserver-generated files. I use 0666 as
        // often, the ftp account is not the webserver user nor in its group.
        chmod($file, 0666);
      }
    }
    return $result;
  }

  /**
   * @return string The CSS for the table
   */
  protected function createTableCss() {
    $category = 'table';
    $css = '';
    $css .= $this
      ->cssSelector(".cal");
    $css .= $this
      ->addCssDeclaration($category, 'font-size');
    $css .= $this
      ->addCssColorDeclaration($category, 'color');
    $css .= $this
      ->addCssColorDeclaration($category, 'background-color');
    $css .= $this
      ->addCssLengthDeclaration($category, 'border-width');
    $css .= $this
      ->addCssColorDeclaration($category, 'border-color');
    $css .= "}\n";
    return $css;
  }

  /**
   * @return string The CSS for the caption
   */
  protected function createCaptionCss() {
    $category = 'caption';
    $css = '';
    $css .= $this
      ->cssSelector(".cal caption");
    $css .= $this
      ->addCssDeclaration($category, 'text-align');
    $css .= $this
      ->addCssDeclaration($category, 'font-weight');
    $css .= $this
      ->addCssDeclaration($category, 'font-style');
    $css .= $this
      ->addCssDeclaration($category, 'font-size');
    $css .= $this
      ->cssSelectorEnd();
    return $css;
  }

  /**
   * @return string The CSS for the header
   */
  protected function createHeaderCss() {
    $category = 'header';
    $css = '';
    $css .= $this
      ->cssSelector(".cal thead th");
    $css .= $this
      ->addCssLengthDeclaration($category, 'height');
    $css .= $this
      ->addCssDeclaration($category, 'text-align');
    $css .= $this
      ->addCssDeclaration($category, 'font-weight');
    $css .= $this
      ->addCssDeclaration($category, 'font-style');
    $css .= $this
      ->addCssDeclaration($category, 'font-size');
    $css .= $this
      ->cssSelectorEnd();
    return $css;
  }

  /**
   * @return string The CSS for the WeekNotes
   */
  protected function createWeekNotesCss() {
    $category = 'week_notes';
    $css = '';
    $css .= $this
      ->cssSelector("td.calweeknote");
    $css .= $this
      ->addCssLengthDeclaration($category, 'width');
    $css .= $this
      ->cssSelectorEnd();
    return $css;
  }

  /**
   * @return string The CSS for the day cells
   */
  protected function createDaysCss() {
    $category = 'days';
    $css = '';
    $css .= $this
      ->cssSelector(".cal td");
    $css .= $this
      ->addCssLengthDeclaration($category, 'width');
    $css .= $this
      ->addCssLengthDeclaration($category, 'height');
    $css .= $this
      ->addCssDeclaration($category, 'text-align');
    $css .= $this
      ->addCssDeclaration($category, 'vertical-align');
    $css .= $this
      ->cssSelectorEnd();
    return $css;
  }

  /**
   * @return string The CSS for the states
   */
  protected function createStatesCss() {
    $category = 'states';
    $splitDay = $this
      ->getStyle($category, 'split-day');
    $states = availability_calendars_get_states();
    $css = empty($splitDay) ? "/* Whole days only*/\n" : "/* Whole days, -pm states are IE6 fallback: IE6 does not display split states: show PM state as whole day state */\n";
    foreach ($states as $class => $stateRecord) {
      $state = $stateRecord['class'];

      // Whole day state
      $css .= $this
        ->cssSelector(empty($splitDay) ? ".{$state} > span" : ".{$state} > span, .{$state}-pm > span");
      $css .= $this
        ->addCssColorDeclaration($category, array(
        $class => 'background-color',
      ));
      $css .= $this
        ->cssSelectorEnd();
    }
    $splitDay = $this
      ->getStyle($category, 'split-day');
    if (!empty($splitDay)) {
      $pattern = '/^([0-9.]+)([a-zA-Z%]*)$/';
      $value = $this
        ->getStyle('days', 'width');
      $parts = array();
      preg_match($pattern, $value, $parts);
      $cellWidth = $parts[1];
      $cellWidthUnit = count($parts) > 2 ? $parts[2] : 'px';
      $value = $this
        ->getStyle('days', 'height');
      $parts = array();
      preg_match($pattern, $value, $parts);
      $cellHeight = $parts[1];
      $cellHeightUnit = count($parts) > 2 ? $parts[2] : 'px';
      $css .= "/* Split days */\n";

      // Styles for the outer span within the td that contains the day number and an absolutle positioned span
      $css .= $this
        ->cssSelector('.cal td > span');
      $css .= $this
        ->cssDeclaration('display', 'block');
      $css .= $this
        ->cssDeclaration('position', 'relative');
      $css .= $this
        ->cssDeclaration('width', $cellWidth . $cellWidthUnit);
      $css .= $this
        ->cssDeclaration('height', $cellHeight . $cellHeightUnit);
      $css .= $this
        ->cssDeclaration('line-height', $cellHeight . $cellHeightUnit);
      $css .= $this
        ->addCssDeclaration('days', 'text-align');
      $css .= $this
        ->addCssDeclaration('days', 'vertical-align');
      $css .= $this
        ->cssDeclaration('z-index', 1);
      $css .= $this
        ->cssSelectorEnd();

      // Styles for the inner span that takes care of the background coloring of split days
      $css .= $this
        ->cssSelector('.cal td > span > span');
      $css .= $this
        ->cssDeclaration('position', 'absolute');
      $css .= $this
        ->cssDeclaration('top', '0');
      $css .= $this
        ->cssDeclaration('left', '0');
      $css .= $this
        ->cssDeclaration('z-index', -1);
      $css .= $this
        ->cssDeclaration('border-style', 'solid');
      switch ($splitDay) {
        case '/':
          $css .= $this
            ->cssDeclaration('width', '0');
          $css .= $this
            ->cssDeclaration('height', '0');
          $css .= $this
            ->cssDeclaration('border-left-width', floor($cellWidth / 2) . $cellWidthUnit);
          $css .= $this
            ->cssDeclaration('border-top-width', floor($cellHeight / 2) . $cellHeightUnit);
          $css .= $this
            ->cssDeclaration('border-right-width', ceil($cellWidth / 2) . $cellWidthUnit);
          $css .= $this
            ->cssDeclaration('border-bottom-width', ceil($cellHeight / 2) . $cellHeightUnit);
          break;
        case '\\':
          $css .= $this
            ->cssDeclaration('width', '0');
          $css .= $this
            ->cssDeclaration('height', '0');
          $css .= $this
            ->cssDeclaration('border-left-width', floor($cellWidth / 2) . $cellWidthUnit);
          $css .= $this
            ->cssDeclaration('border-bottom-width', floor($cellHeight / 2) . $cellHeightUnit);
          $css .= $this
            ->cssDeclaration('border-right-width', ceil($cellWidth / 2) . $cellWidthUnit);
          $css .= $this
            ->cssDeclaration('border-top-width', ceil($cellHeight / 2) . $cellHeightUnit);
          break;
        case '|':
          $css .= $this
            ->cssDeclaration('width', '0');
          $css .= $this
            ->addCssLengthDeclaration('days', 'height');
          $css .= $this
            ->cssDeclaration('border-left-width', floor($cellWidth / 2) . $cellWidthUnit);
          $css .= $this
            ->cssDeclaration('border-right-width', ceil($cellWidth / 2) . $cellWidthUnit);
          break;
        case '―':
          $css .= $this
            ->addCssLengthDeclaration('days', 'width');
          $css .= $this
            ->cssDeclaration('height', '0');
          $css .= $this
            ->cssDeclaration('border-top-width', floor($cellHeight / 2) . $cellHeightUnit);
          $css .= $this
            ->cssDeclaration('border-bottom-width', ceil($cellHeight / 2) . $cellHeightUnit);
          break;
      }
      $css .= $this
        ->cssSelectorEnd();
      foreach ($states as $class => $stateRecord) {
        $state = $stateRecord['class'];
        $cssAm = $this
          ->cssSelector(".{$state}-am > span > span, .{$state} > span > span");
        $cssPm = $this
          ->cssSelector(".{$state}-pm > span > span, .{$state} > span > span");
        switch ($splitDay) {
          case '/':
            $cssAm .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-left-color',
            ));
            $cssAm .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-top-color',
            ));
            $cssPm .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-right-color',
            ));
            $cssPm .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-bottom-color',
            ));
            break;
          case '\\':
            $cssAm .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-left-color',
            ));
            $cssAm .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-bottom-color',
            ));
            $cssPm .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-right-color',
            ));
            $cssPm .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-top-color',
            ));
            break;
          case '|':
            $cssAm .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-left-color',
            ));
            $cssPm .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-right-color',
            ));
            break;
          case '―':
            $cssAm .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-top-color',
            ));
            $cssPm .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-bottom-color',
            ));
            break;
        }
        $cssAm .= $this
          ->cssSelectorEnd();
        $cssPm .= $this
          ->cssSelectorEnd();
        $css .= $cssAm;
        $css .= $cssPm;
      }
    }
    return $css;
  }

  /**
   * Single place that specifies how to format selectors.
   */
  protected function cssSelector($selector) {
    return "{$selector} {\n";
  }

  /**
   * Single place that specifies how to format selectors ends.
   */
  protected function cssSelectorEnd() {
    return "}\n\n";
  }

  /**
   * Creates a CSS declaration for a length property.
   * @see addCssDeclaration for param and return info
   */
  protected function addCssLengthDeclaration($category, $name) {
    $value = $this
      ->getStyle($category, $name);

    // Pixels are the default for numeric values
    if (!empty($value) && is_numeric($value)) {
      $value .= 'px';
    }
    return $this
      ->cssDeclaration($name, $value);
  }

  /**
   * Creates a CSS declaration for a color property.
   * @see addCssDeclaration for param and return info
   */
  protected function addCssColorDeclaration($category, $name) {
    $value = $this
      ->getStyle($category, $name);

    // Color codes may be given without #
    if (!empty($value) && ctype_xdigit($value)) {
      $value = '#' . $value;
    }
    return $this
      ->cssDeclaration($name, $value);
  }

  /**
   * Creates a CSS declaration.
   *
   * @param string $category The name of the category in which the setting is stored.
   * @param string|array $name The name of the setting and property. If $name is an array it should
   *   be an array with 1 element of the form <setting name> => <property name>. Use this if the
   *   setting name is not the name of the property.
   * @return string The generated CSS declaration: "  property: value;"
   */
  protected function addCssDeclaration($category, $name) {
    $value = $this
      ->getStyle($category, $name);
    return $this
      ->cssDeclaration($name, $value);
  }

  /**
   * Helper method to specify in one single place whether and how to output spaces and new lines.
   */
  protected function cssDeclaration($property, $value) {
    if (is_array($property)) {
      $property = current($property);
    }
    return $value != '' ? "  {$property}: {$value};\n" : '';
  }

  /**
   * Helper method to return 1 style setting (to not repeat the taking care of not being set,
   * defaults, etc).
   *
   * @param string $category
   * @param string|array $name
   * @param mixed $default
   */
  protected function getStyle($category, $name, $default = '') {
    if (is_array($name)) {
      $name = key($name);
    }
    return isset($this->styles[$category][$name]) && $this->styles[$category][$name] !== '<none>' ? $this->styles[$category][$name] : $default;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AvailabilityCalendarsCssGenerator::$styles protected property
AvailabilityCalendarsCssGenerator::addCssColorDeclaration protected function Creates a CSS declaration for a color property.
AvailabilityCalendarsCssGenerator::addCssDeclaration protected function Creates a CSS declaration.
AvailabilityCalendarsCssGenerator::addCssLengthDeclaration protected function Creates a CSS declaration for a length property.
AvailabilityCalendarsCssGenerator::createCaptionCss protected function
AvailabilityCalendarsCssGenerator::createCss protected function Creates the css.
AvailabilityCalendarsCssGenerator::createDaysCss protected function
AvailabilityCalendarsCssGenerator::createHeaderCss protected function
AvailabilityCalendarsCssGenerator::createStatesCss protected function
AvailabilityCalendarsCssGenerator::createTableCss protected function
AvailabilityCalendarsCssGenerator::createWeekNotesCss protected function
AvailabilityCalendarsCssGenerator::cssDeclaration protected function Helper method to specify in one single place whether and how to output spaces and new lines.
AvailabilityCalendarsCssGenerator::cssSelector protected function Single place that specifies how to format selectors.
AvailabilityCalendarsCssGenerator::cssSelectorEnd protected function Single place that specifies how to format selectors ends.
AvailabilityCalendarsCssGenerator::exec public function Creates and writes the CSS file for Availability Calendars
AvailabilityCalendarsCssGenerator::getStyle protected function Helper method to return 1 style setting (to not repeat the taking care of not being set, defaults, etc).
AvailabilityCalendarsCssGenerator::writeCss protected function Writes the created CSS to a file.
AvailabilityCalendarsCssGenerator::__construct public function