/**
  * Check tags attributes requirements 
  *
  * @param array $tag : the reference tag to compute
  * @param array $requirements : tag attributes requirements at the following format :
  *		array(string attributeName => mixed attributeType)
  *		With attributeType in :
  *		- boolean true : check only presence of an attribute value
  *		- alphanum : attribute value must be a simple alphanumeric value without special chars
  *		- language : attribute value must be a valid language code
  *		- orderType : attribute value must be a valid order type
  *		- valid PERL regular expression : attribute value must be mattch the regular expression
  * @return string indented php code
  * @access public
  */
 function checkTagRequirements(&$tag, $requirements)
 {
     if (!is_array($requirements)) {
         $this->raiseError('Tag requirements must be an array');
         return false;
     }
     foreach ($requirements as $name => $requirementType) {
         //check parameter existence
         if (!isset($tag['attributes'][$name])) {
             if ($this->_mode == self::CHECK_PARSING_MODE) {
                 $this->_parsingError .= "\n" . 'Malformed ' . $tag['nodename'] . ' tag : missing \'' . $name . '\' attribute';
                 return false;
             } else {
                 $this->raiseError('Malformed ' . $tag['nodename'] . ' tag : missing \'' . $name . '\' attribute');
                 return false;
             }
         } elseif ($requirementType !== true) {
             //if any, check value requirement
             switch ($requirementType) {
                 case 'alphanum':
                     if ($tag['attributes'][$name] != sensitiveIO::sanitizeAsciiString($tag['attributes'][$name], '', '_')) {
                         if ($this->_mode == self::CHECK_PARSING_MODE) {
                             $this->_parsingError .= "\n" . 'Malformed ' . $tag['nodename'] . ' tag : \'' . $name . '\' attribute must only be composed with alphanumeric caracters (0-9a-z_) : ' . $tag['attributes'][$name];
                             return false;
                         } else {
                             $this->raiseError('Malformed ' . $tag['nodename'] . ' tag : \'' . $name . '\' attribute must only be composed with alphanumeric caracters (0-9a-z_) : ' . $tag['attributes'][$name]);
                             return false;
                         }
                     }
                     break;
                 case 'language':
                     if (isset($this->_parameters['module'])) {
                         $languages = CMS_languagesCatalog::getAllLanguages($this->_parameters['module']);
                     } else {
                         $languages = CMS_languagesCatalog::getAllLanguages();
                     }
                     if (!isset($languages[$tag['attributes'][$name]])) {
                         if ($this->_mode == self::CHECK_PARSING_MODE) {
                             $this->_parsingError .= "\n" . 'Malformed ' . $tag['nodename'] . ' tag : \'' . $name . '\' attribute must only be a valid language code : ' . $tag['attributes'][$name];
                             return false;
                         } else {
                             $this->raiseError('Malformed ' . $tag['nodename'] . ' tag : \'' . $name . '\' attribute must only be a valid language code : ' . $tag['attributes'][$name]);
                             return false;
                         }
                     }
                     break;
                 case 'object':
                     if (!sensitiveIO::isPositiveInteger(io::substr($tag['attributes'][$name], 9, -3))) {
                         if ($this->_mode == self::CHECK_PARSING_MODE) {
                             $this->_parsingError .= "\n" . 'Malformed ' . $tag['nodename'] . ' tag : \'' . $name . '\' attribute does not represent a valid object';
                             return false;
                         } else {
                             $this->raiseError('Malformed ' . $tag['nodename'] . ' tag : \'' . $name . '\' attribute does not represent a valid object');
                             return false;
                         }
                     }
                     break;
                 case 'field':
                     if (strrpos($tag['attributes'][$name], 'fields') === false || !sensitiveIO::isPositiveInteger(io::substr($tag['attributes'][$name], strrpos($tag['attributes'][$name], 'fields') + 9, -2))) {
                         if ($this->_mode == self::CHECK_PARSING_MODE) {
                             $this->_parsingError .= "\n" . 'Malformed ' . $tag['nodename'] . ' tag : \'' . $name . '\' attribute does not represent a valid object field';
                             return false;
                         } else {
                             $this->raiseError('Malformed ' . $tag['nodename'] . ' tag : \'' . $name . '\' attribute does not represent a valid object field');
                             return false;
                         }
                     }
                     break;
                 case 'paramType':
                     if (!in_array($tag['attributes'][$name], CMS_object_search::getStaticSearchConditionTypes()) && !sensitiveIO::isPositiveInteger($tag['attributes'][$name]) && io::substr($tag['attributes'][$name], -12) != "['fieldID']}") {
                         if ($this->_mode == self::CHECK_PARSING_MODE) {
                             $this->_parsingError .= "\n" . 'Malformed ' . $tag['nodename'] . ' tag : \'' . $name . '\' attribute, must be one of these values : ' . implode(', ', CMS_object_search::getStaticSearchConditionTypes());
                             return false;
                         } else {
                             $this->raiseError('Malformed ' . $tag['nodename'] . ' tag : \'' . $name . '\' attribute, must be one of these values : ' . implode(', ', CMS_object_search::getStaticSearchConditionTypes()));
                             return false;
                         }
                     }
                     break;
                 case 'orderType':
                     if (!in_array($tag['attributes'][$name], CMS_object_search::getStaticOrderConditionTypes()) && !sensitiveIO::isPositiveInteger($tag['attributes'][$name]) && io::substr($tag['attributes'][$name], -12) != "['fieldID']}") {
                         if ($this->_mode == self::CHECK_PARSING_MODE) {
                             $this->_parsingError .= "\n" . 'Malformed ' . $tag['nodename'] . ' tag : \'' . $name . '\' attribute, must be one of these values : ' . implode(', ', CMS_object_search::getStaticOrderConditionTypes());
                             return false;
                         } else {
                             $this->raiseError('Malformed ' . $tag['nodename'] . ' tag : \'' . $name . '\' attribute, must be one of these values : ' . implode(', ', CMS_object_search::getStaticOrderConditionTypes()));
                             return false;
                         }
                     }
                     break;
                 default:
                     //check
                     if (!preg_match('#^' . $requirementType . '$#i', $tag['attributes'][$name])) {
                         if ($this->_mode == self::CHECK_PARSING_MODE) {
                             $this->_parsingError .= "\n" . 'Malformed ' . $tag['nodename'] . ' tag : \'' . $name . '\' attribute must match expression \'' . $requirementType . '\' : ' . $tag['attributes'][$name];
                             return false;
                         } else {
                             $this->raiseError('Malformed ' . $tag['nodename'] . ' tag : \'' . $name . '\' attribute must match expression \'' . $requirementType . '\' : ' . $tag['attributes'][$name]);
                             return false;
                         }
                     }
                     break;
             }
         }
     }
     return true;
 }