class AvailabilityCalendarCssGenerator in Availability Calendars 7.4
Same name and namespace in other branches
- 7.5 availability_calendar.styles.inc \AvailabilityCalendarCssGenerator
- 7.3 availability_calendar.styles.inc \AvailabilityCalendarCssGenerator
Hierarchy
Expanded class hierarchy of AvailabilityCalendarCssGenerator
File
- ./
availability_calendar.styles.inc, line 488
View source
class AvailabilityCalendarCssGenerator {
/** @var array */
protected $styles = NULL;
public function __construct($styles) {
$this->styles = $styles;
}
/**
* Creates and writes the CSS file for availability calendar fields.
*
* @return boolean
* Whether the generation was successful.
*/
public function exec() {
$css = $this
->createCss();
$result = $this
->writeCss($css);
if ($result) {
$css = $this
->createRtlCss();
$result = $this
->writeRtlCss($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;
}
/**
* Creates the RTL css.
*
* @return string
* The created css.
*/
protected function createRtlCss() {
$css = '';
$css .= $this
->createCaptionRtlCss();
$css .= $this
->createHeaderRtlCss();
$css .= $this
->createDaysRtlCss();
$css .= $this
->createStatesRtlCss();
return $css;
}
/**
* Writes the created CSS to a file.
*
* @param string $css
* @return boolean
* Whether the generation was successful.
*/
protected function writeCss($css) {
return $this
->writeFile('public://availability_calendar', 'availability_calendar.css', $css);
}
/**
* Writes the created RTL CSS to a file.
*
* @param string $css
* @return boolean
* Whether the generation was successful.
*/
protected function writeRtlCss($css) {
return $this
->writeFile('public://availability_calendar', 'availability_calendar-rtl.css', $css);
}
/**
* Writes the created RTL CSS to a file.
*
* @param string $path
* @param string $file
* @param string $css
*
* @return boolean
* Whether the generation was successful.
*/
protected function writeFile($path, $file, $css) {
$result = false;
if ($result = file_prepare_directory($path, FILE_CREATE_DIRECTORY)) {
$file = $path . '/' . $file;
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 table");
$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 .= $this
->cssDeclaration('border-style', 'solid');
$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 RTL CSS for the caption.
*/
protected function createCaptionRtlCss() {
$category = 'caption';
$css = '';
$value = $this
->getRtlTextAlign($category, 'text-align');
if (!empty($value)) {
$css .= "/* Month name and year (caption) */\n";
$css .= $this
->cssSelector(".cal caption");
$css .= $this
->cssDeclaration('text-align', $value);
$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');
$line_height = $this
->getStyle($category, 'height');
// @todo: subtract border from line-height, but for that we need to add border as a style in this UI.
$css .= $this
->cssDeclaration('line-height', $line_height . 'px');
$css .= $this
->addCssDeclaration($category, 'text-align');
$css .= $this
->addCssDeclaration($category, 'font-weight');
$css .= $this
->addCssDeclaration($category, 'font-style');
$css .= $this
->addCssDeclaration($category, 'font-size');
// Add color also to th cells to override Bartik
$css .= $this
->addCssColorDeclaration('table', 'color');
// Add width to first row to assure that IE7 works fine.
// Will be overridden for the column that contains the week number/notes.
$css .= $this
->addCssLengthDeclaration('days', 'width');
$css .= $this
->cssSelectorEnd();
return $css;
}
/**
* @return string
* The RTL CSS for the header.
*/
protected function createHeaderRtlCss() {
$category = 'header';
$css = '';
$value = $this
->getRtlTextAlign($category, 'text-align');
if (!empty($value)) {
$css .= "/* Weekday names (header row) */\n";
$css .= $this
->cssSelector(".cal thead th");
$css .= $this
->cssDeclaration('text-align', $value);
$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, .cal thead th.cal-weekno-header");
$css .= $this
->addCssLengthDeclaration($category, 'width');
// Add color also to th cells to override Bartik
$css .= $this
->addCssColorDeclaration('table', 'color');
$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');
// Add color also to td cells to override themes that give cells a color.
$css .= $this
->addCssColorDeclaration('table', 'color');
$css .= $this
->cssSelectorEnd();
return $css;
}
/**
* @return string
* The RTL CSS for the day cells.
*/
protected function createDaysRtlCss() {
$category = 'days';
$css = '';
$value = $this
->getRtlTextAlign($category, 'text-align');
if (!empty($value)) {
$css .= "/* Days (td) */\n";
$css .= $this
->cssSelector(".cal td");
$css .= $this
->cssDeclaration('text-align', $value);
$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_calendar_get_states();
$css = '';
$css .= "/* Whole day coloring */\n";
foreach ($states as $sid => $state) {
$class = $state['css_class'];
// Whole day state.
$selector = ".{$class}, .{$class} > div";
$css .= $this
->cssSelector($selector);
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'background-color',
));
$css .= $this
->cssSelectorEnd();
}
// Get the width and heigth.
$cellWidth = (int) $this
->getStyle('days', 'width');
// We have to subtract pixels, so this value can only be in pixels.
$cellWidthUnit = 'px';
$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 $sid => $state) {
$class = $state['css_class'];
$css .= $this
->cssSelector("html[dir=ltr] .cal .{$class}-am > span");
switch ($splitDay) {
case '/':
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-left-color',
));
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-top-color',
));
break;
case '\\':
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-left-color',
));
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-bottom-color',
));
break;
case '|':
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-left-color',
));
break;
case '―':
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-top-color',
));
break;
}
$css .= $this
->cssSelectorEnd();
$css .= $this
->cssSelector("html[dir=ltr] .cal .{$class}-pm > span");
switch ($splitDay) {
case '/':
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-right-color',
));
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-bottom-color',
));
break;
case '\\':
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-right-color',
));
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-top-color',
));
break;
case '|':
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-right-color',
));
break;
case '―':
$css .= $this
->addCssColorDeclaration($category, array(
$class => '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($cellHeight / 2) . $cellHeightUnit);
$css .= $this
->cssDeclaration('left', -floor($cellWidth / 2) . $cellWidthUnit);
break;
case '\\':
$css .= $this
->cssDeclaration('top', -floor($cellHeight / 2) . $cellHeightUnit);
$css .= $this
->cssDeclaration('left', -ceil($cellWidth / 2) . $cellWidthUnit);
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();
}
$css .= "/* Dimensions and other properties for element containing day number */\n";
$css .= $this
->cssSelector('.cal td > div, .cal td > span > span');
if ($cellWidth >= 2 && $cellHeight >= 2) {
// Subtract border of 1px.
$cellWidth -= 2;
$cellHeight -= 2;
$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;
}
/**
* @return string
* The RTL specific CSS for the states.
*/
protected function createStatesRtlCss() {
$category = 'states';
$splitDay = $this
->getStyle($category, 'split-day');
$states = availability_calendar_get_states();
$css = '';
// Get the width and height
$cellWidth = (int) $this
->getStyle('days', 'width');
// We have to subtract pixels, so this value can only be in pixels
$cellWidthUnit = 'px';
$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 $sid => $state) {
$class = $state['css_class'];
$css .= $this
->cssSelector("html[dir=rtl] .cal .{$class}-am > span");
switch ($splitDay) {
case '/':
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-right-color',
));
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-top-color',
));
break;
case '\\':
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-right-color',
));
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-bottom-color',
));
break;
case '|':
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-right-color',
));
break;
case '―':
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-top-color',
));
break;
}
$css .= $this
->cssSelectorEnd();
$css .= $this
->cssSelector("html[dir=rtl] .cal .{$class}-pm > span");
switch ($splitDay) {
case '/':
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-left-color',
));
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-bottom-color',
));
break;
case '\\':
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-left-color',
));
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-top-color',
));
break;
case '|':
$css .= $this
->addCssColorDeclaration($category, array(
$class => 'border-left-color',
));
break;
case '―':
$css .= $this
->addCssColorDeclaration($category, array(
$class => '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('border-left-width', ceil($cellWidth / 2) . $cellWidthUnit);
$css .= $this
->cssDeclaration('border-right-width', floor($cellWidth / 2) . $cellWidthUnit);
break;
case '\\':
$css .= $this
->cssDeclaration('border-left-width', ceil($cellWidth / 2) . $cellWidthUnit);
$css .= $this
->cssDeclaration('border-right-width', floor($cellWidth / 2) . $cellWidthUnit);
break;
case '|':
$css .= $this
->cssDeclaration('border-left-width', ceil($cellWidth / 2) . $cellWidthUnit);
$css .= $this
->cssDeclaration('border-right-width', floor($cellWidth / 2) . $cellWidthUnit);
break;
case '―':
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('left', 'auto');
$css .= $this
->cssDeclaration('right', -floor($cellWidth / 2) . $cellWidthUnit);
break;
case '\\':
$css .= $this
->cssDeclaration('left', 'auto');
$css .= $this
->cssDeclaration('right', -ceil($cellWidth / 2) . $cellWidthUnit);
break;
case '|':
$css .= $this
->cssDeclaration('left', 'auto');
$css .= $this
->cssDeclaration('right', -floor($cellWidth / 2) . $cellWidthUnit);
break;
case '―':
$css .= $this
->cssDeclaration('left', 'auto');
$css .= $this
->cssDeclaration('right', '0');
break;
}
$css .= $this
->cssSelectorEnd();
}
$value = $this
->getRtlTextAlign('days', 'text-align');
if (!empty($value)) {
$css .= "/* Dimensions and other properties for element containing day number */\n";
$css .= $this
->cssSelector('.cal td > div, .cal td > span > span');
$css .= $this
->cssDeclaration('text-align', $value);
$css .= $this
->cssSelectorEnd();
}
return $css;
}
protected function getRtlTextAlign($category, $name) {
$value = $this
->getStyle($category, $name);
switch ($value) {
case 'left':
$value = 'right';
break;
case 'right':
$value = 'left';
break;
default:
$value = '';
break;
}
return $value;
}
/**
* 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 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.
*
* @param string $category
* @param string|array $name
* @param mixed $default
*
* @return string
*/
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;
}
}