Advanced aggregation validation module.
Fichier
-
advagg_validator/
advagg_validator.inc
View source
<?php
/**
* @file
* Advanced aggregation validation module.
*/
/**
* Test all css files used by AdvAgg.
*
* @return array
* An array of files with the result from the w3c validator.
*/
function advagg_validator_test_advagg_css($options = array()) {
// Get list of files.
$query_files = db_select('advagg_files', 'af')->fields('af', array(
'filename_hash',
'filename',
))
->condition('af.filetype', 'css')
->orderBy('filename', 'ASC')
->execute()
->fetchAllKeyed();
$files = array_values($query_files);
// Test and return list.
return advagg_validator_test_css_files($files, $options);
}
/**
* Recursively scan the drupal webroot and test all css files.
*
* @return array
* An array of files with the result from the w3c validator.
*/
function advagg_validator_test_all_css($options = array()) {
// Get list of files.
$files = advagg_validator_scan_all_dirs('css');
// Test and return list.
return advagg_validator_test_css_files($files, $options);
}
/**
* Recursively scan the drupal webroot for files matching the given extension.
*
* @param string $ext
* Usually css or js.
*
* @return array
* An array of files.
*/
function advagg_validator_scan_all_dirs($ext) {
$options = array(
'nodirmask' => '/(\\.git|.*\\/files*)/',
);
$output = advagg_validator_file_scan_directory(DRUPAL_ROOT, '/.*\\.' . $ext . '$/', $options);
$files = array();
foreach ($output as $values) {
$files[] = str_replace(DRUPAL_ROOT . '/', '', $values->uri);
}
return $files;
}
/**
* Test all given files with the w3c validator.
*
* @return array
* An array of files with the result from the w3c validator.
*/
function advagg_validator_test_css_files($files, $options = array()) {
$output = array();
foreach ($files as $filename) {
// Skip missing files.
if (!file_exists($filename)) {
continue;
}
$file_contents = (string) @advagg_file_get_contents($filename);
$lines = file($filename);
$filename_hash = drupal_hash_base64($filename);
$content_hash = drupal_hash_base64($file_contents);
// See if this file needs to be scanned.
$file_ok = db_select('advagg_validator', 'av')->fields('av', array(
'content_hash',
'data',
))
->condition('filename_hash', $filename_hash)
->condition('filetype', 'css')
->execute()
->fetchAllKeyed();
if (!empty($file_ok)) {
foreach ($file_ok as $content_hash_db => $serialized_data) {
if ($content_hash_db == $content_hash) {
$output[$filename] = unserialize($serialized_data);
continue 2;
}
}
}
// Run jigsaw.w3.org validator.
$output[$filename]['jigsaw.w3.org'] = advagg_validator_test_css_file_w3c($filename, $options);
// Get extra context for errors.
if (!empty($output[$filename]['jigsaw.w3.org']['errors'])) {
foreach ($output[$filename]['jigsaw.w3.org']['errors'] as &$value) {
if (isset($value['line'])) {
$value['linedata'] = $lines[$value['line'] - 1];
if (strlen($value['linedata']) > 512) {
unset($value['linedata']);
}
}
}
unset($value);
}
if (!empty($output[$filename]['jigsaw.w3.org']['warnings'])) {
foreach ($output[$filename]['jigsaw.w3.org']['warnings'] as &$value) {
if (isset($value['line'])) {
$value['linedata'] = $lines[$value['line'] - 1];
if (strlen($value['linedata']) > 512) {
unset($value['linedata']);
}
}
}
unset($value);
}
// Save data.
if (empty($output[$filename]['jigsaw.w3.org']['error'])) {
$record = array(
'filename' => $filename,
'filename_hash' => $filename_hash,
'content_hash' => $content_hash,
'filetype' => 'css',
'data' => serialize($output[$filename]),
);
db_merge('advagg_validator')->key(array(
'filename_hash' => $record['filename_hash'],
))
->fields($record)
->execute();
}
}
return $output;
}
/**
* Given a CSS file, test to make sure it is valid CSS.
*
* @param string $filename
* The name of the file.
* @param array $validator_options
* List of options to pass along to the CSS Validator.
*
* @return array
* Info from the w3c server.
*/
function advagg_validator_test_css_file_w3c($filename, array &$validator_options = array()) {
// Get CSS files contents.
$validator_options['text'] = (string) @advagg_file_get_contents($filename);
// Add in defaults.
$validator_options += array(
'output' => 'soap12',
'warning' => '1',
'profile' => 'css3',
'usermedium' => 'all',
'lang' => 'en',
);
// Build request URL.
// API Documentation http://jigsaw.w3.org/css-validator/api.html
$request_url = 'http://jigsaw.w3.org/css-validator/validator';
$query = http_build_query($validator_options, '', '&');
$url = $request_url . '?' . $query;
// Send request.
$result = drupal_http_request($url);
if (!empty($result->data) && $result->code == 200) {
// Parse XML and return info.
$return = advagg_validator_parse_soap_response_w3c($result->data);
$return['filename'] = $filename;
if (isset($validator_options['text'])) {
unset($validator_options['text']);
}
$return['options'] = $validator_options;
return $return;
}
return array(
'error' => t('W3C Server did not return a 200 or request data was empty.'),
);
}
/**
* Parse an XML response from the validator.
*
* This function parses a SOAP 1.2 response XML string from the validator.
*
* @param string $xml
* The raw SOAP 1.2 XML response from the validator.
*
* @return array
* Info from the w3c server.
*/
function advagg_validator_parse_soap_response_w3c($xml) {
$doc = new DOMDocument();
$response = array();
// Try to load soap 1.2 XML response, and suppress warning reports if any.
if (!@$doc->loadXML($xml)) {
// Could not load the XML document.
return $response;
}
// Get the standard CDATA elements.
$cdata = array(
'uri',
'checkedby',
'csslevel',
'date',
);
foreach ($cdata as $var) {
$element = $doc->getElementsByTagName($var);
if ($element->length) {
$response[$var] = $element->item(0)->nodeValue;
}
}
// Handle the element validity and get errors if not valid.
$element = $doc->getElementsByTagName('validity');
if ($element->length && $element->item(0)->nodeValue === 'true') {
$response['validity'] = TRUE;
}
else {
$response['validity'] = FALSE;
$errors = $doc->getElementsByTagName('error');
foreach ($errors as $error) {
$response['errors'][] = advagg_validator_dom_extractor($error);
}
}
// Get warnings.
$warnings = $doc->getElementsByTagName('warning');
foreach ($warnings as $warning) {
$response['warnings'][] = advagg_validator_dom_extractor($warning);
}
// Return response array.
return $response;
}
/**
* Extract info from the DOMNode Object.
*
* @param object $dom
* DOMNode Class.
*
* @return array
* Key Value pair from the DOM Node.
*/
function advagg_validator_dom_extractor($dom) {
$node = $dom->firstChild;
$output = array();
do {
$text = trim($node->nodeValue);
if (!empty($text)) {
$key = str_replace('m:', '', $node->nodeName);
$output[$key] = $text;
}
} while ($node = $node->nextSibling);
return $output;
}
/**
* Finds all files that match a given mask in a given directory.
*
* Directories and files beginning with a period are excluded; this
* prevents hidden files and directories (such as SVN working directories)
* from being scanned.
*
* @param string $dir
* The base directory or URI to scan, without trailing slash.
* @param string $mask
* The preg_match() regular expression of the files to find.
* @param array $options
* An associative array of additional options, with the following elements:
* - 'nomask': The preg_match() regular expression of the files to ignore.
* Defaults to '/(\.\.?|CVS)$/'.
* - 'nomask': The preg_match() regular expression of the dirs to ignore.
* Defaults to '/(\.git)/'.
* - 'callback': The callback function to call for each match. There is no
* default callback.
* - 'recurse': When TRUE, the directory scan will recurse the entire tree
* starting at the provided directory. Defaults to TRUE.
* - 'key': The key to be used for the returned associative array of files.
* Possible values are 'uri', for the file's URI; 'filename', for the
* basename of the file; and 'name' for the name of the file without the
* extension. Defaults to 'uri'.
* - 'min_depth': Minimum depth of directories to return files from. Defaults
* to 0.
* @param int $depth
* Current depth of recursion. This parameter is only used internally and
* should not be passed in.
*
* @return array
* An associative array (keyed on the chosen key) of objects with 'uri',
* 'filename', and 'name' members corresponding to the matching files.
*/
function advagg_validator_file_scan_directory($dir, $mask, array $options = array(), $depth = 0) {
// Merge in defaults.
$options += array(
'nomask' => '/(\\.\\.?|CVS)$/',
'nodirmask' => '/(\\.git)/',
'callback' => 0,
'recurse' => TRUE,
'key' => 'uri',
'min_depth' => 0,
);
$options['key'] = in_array($options['key'], array(
'uri',
'filename',
'name',
)) ? $options['key'] : 'uri';
$files = array();
// @ignore druplart_andor_assignment
if (is_dir($dir) && ($handle = opendir($dir))) {
while (FALSE !== ($filename = readdir($handle))) {
if (!preg_match($options['nomask'], $filename) && $filename[0] !== '.') {
$uri = "{$dir}/{$filename}";
$uri = file_stream_wrapper_uri_normalize($uri);
if (is_dir($uri) && $options['recurse'] && !preg_match($options['nodirmask'], $uri)) {
// Give priority to files in this folder by merging them in after any
// subdirectory files.
$files = array_merge(advagg_validator_file_scan_directory($uri, $mask, $options, $depth + 1), $files);
}
elseif ($depth >= $options['min_depth'] && preg_match($mask, $filename)) {
// Always use this match over anything already set in $files with the
// same $$options['key'].
$file = new stdClass();
$file->uri = $uri;
$file->filename = $filename;
$file->name = pathinfo($filename, PATHINFO_FILENAME);
$key = $options['key'];
$files[$file->{$key}] = $file;
if ($options['callback']) {
$options['callback']($uri);
}
}
}
}
closedir($handle);
}
return $files;
}
Functions
Titre | Deprecated | Résumé |
---|---|---|
advagg_validator_dom_extractor | Extract info from the DOMNode Object. | |
advagg_validator_file_scan_directory | Finds all files that match a given mask in a given directory. | |
advagg_validator_parse_soap_response_w3c | Parse an XML response from the validator. | |
advagg_validator_scan_all_dirs | Recursively scan the drupal webroot for files matching the given extension. | |
advagg_validator_test_advagg_css | Test all css files used by AdvAgg. | |
advagg_validator_test_all_css | Recursively scan the drupal webroot and test all css files. | |
advagg_validator_test_css_files | Test all given files with the w3c validator. | |
advagg_validator_test_css_file_w3c | Given a CSS file, test to make sure it is valid CSS. |