You are here

class AvailabilityCalendarsCssGenerator in Availability Calendars 7.2

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

Hierarchy

Expanded class hierarchy of AvailabilityCalendarsCssGenerator

File

./availability_calendars.styles.inc, line 463

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
      ->createWeekNotesCss();
    $css .= $this
      ->createDaysCss();
    $css .= $this
      ->createStatesCss();
    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 = 'public://availability_calendars';
    if ($result = file_prepare_directory($path, FILE_CREATE_DIRECTORY)) {
      $file = $path . '/' . 'availability_calendars.css';
      if ($result = file_save_data($css, $file, FILE_EXISTS_REPLACE) !== FALSE) {

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

  /**
   * @return string
   *   The CSS for the table.
   */
  protected function createTableCss() {
    $category = 'table';
    $css = '';
    $css .= "/* Month (table) */\n";
    $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 .= "/* Month name and year (caption) */\n";
    $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 .= "/* Weekday names (header row) */\n";
    $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 .= "/* Week notes (header column) */\n";
    $css .= $this
      ->cssSelector(".cal tbody th");
    $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 .= "/* Days (td) */\n";
    $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 = '';
    $css .= "/* Edit calendar form */\n";
    $css .= $this
      ->cssSelector(".form-item-availability-states label");
    $css .= $this
      ->cssDeclaration('padding', '5px 10px');
    $css .= $this
      ->cssSelectorEnd();
    $css .= "/* Whole day coloring, -pm states are a fallback for a change of the split day setting\n";
    $css .= " * and for IE6: IE6 does not display split states: show PM state as whole day state */\n";
    foreach ($states as $class => $stateRecord) {
      $state = $stateRecord['css_class'];

      // Whole day state.
      $selector = ".{$state}, .{$state} > div, .{$state} > span, .{$state}-pm > div, .{$state}-pm > span";
      $css .= $this
        ->cssSelector($selector);
      $css .= $this
        ->addCssColorDeclaration($category, array(
        $state => 'background-color',
      ));
      $css .= $this
        ->cssSelectorEnd();
    }

    // Get the width and heigth
    $cellWidth = (int) $this
      ->getStyle('days', 'width');
    $cellWidthUnit = 'px';

    // We have to subtract pixels, so this value can only be in pixels
    $cellHeight = (int) $this
      ->getStyle('days', 'height');
    $cellHeightUnit = 'px';
    if (!empty($splitDay)) {
      $css .= "/* Split day coloring */\n";

      // Styles for the state colors
      // The border color definitions for the pm state should be superfluous as
      // the background-color is the same. However I did get some artifacts in
      // at least firefox.
      foreach ($states as $class => $stateRecord) {
        $state = $stateRecord['css_class'];
        $css .= $this
          ->cssSelector(".cal .{$state}-am > span, .cal .{$state} > span");
        switch ($splitDay) {
          case '/':
            $css .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-left-color',
            ));
            $css .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-top-color',
            ));
            break;
          case '\\':
            $css .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-left-color',
            ));
            $css .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-bottom-color',
            ));
            break;
          case '|':
            $css .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-left-color',
            ));
            break;
          case '―':
            $css .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-top-color',
            ));
            break;
        }
        $css .= $this
          ->cssSelectorEnd();
        $css .= $this
          ->cssSelector(".cal .{$state}-pm > span, .cal .{$state} > span");
        switch ($splitDay) {
          case '/':
            $css .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-right-color',
            ));
            $css .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-bottom-color',
            ));
            break;
          case '\\':
            $css .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-right-color',
            ));
            $css .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-top-color',
            ));
            break;
          case '|':
            $css .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-right-color',
            ));
            break;
          case '―':
            $css .= $this
              ->addCssColorDeclaration($category, array(
              $state => 'border-bottom-color',
            ));
            break;
        }
        $css .= $this
          ->cssSelectorEnd();
      }

      // Styles for the outer span that takes care of the background coloring of split days.
      $css .= "/* Split day dimensioning and positioning */\n";
      $css .= $this
        ->cssSelector('.cal td > span');
      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();

      // Styles for the inner span within the td that contains the day number.
      $css .= $this
        ->cssSelector('.cal td > span > span');
      switch ($splitDay) {
        case '/':
          $css .= $this
            ->cssDeclaration('top', -floor($cellWidth / 2) . $cellWidthUnit);
          $css .= $this
            ->cssDeclaration('left', -floor($cellHeight / 2) . $cellHeightUnit);
          break;
        case '\\':
          $css .= $this
            ->cssDeclaration('top', -floor($cellWidth / 2) . $cellWidthUnit);
          $css .= $this
            ->cssDeclaration('left', -ceil($cellHeight / 2) . $cellHeightUnit);
          break;
        case '|':
          $css .= $this
            ->cssDeclaration('top', '0');
          $css .= $this
            ->cssDeclaration('left', -floor($cellWidth / 2) . $cellWidthUnit);
          break;
        case '―':
          $css .= $this
            ->cssDeclaration('top', -floor($cellHeight / 2) . $cellHeightUnit);
          $css .= $this
            ->cssDeclaration('left', '0');
          break;
      }
      $css .= $this
        ->cssSelectorEnd();
    }

    // Subtract border of 1px.
    $css .= "/* Dimensions and other properties for element containing day number */\n";
    $cellWidth -= 2;
    $cellHeight -= 2;
    $css .= $this
      ->cssSelector('.cal td > div, .cal td > span > span');
    $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
      ->cssSelectorEnd();
    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